Subversion Repositories Kolibri OS

Rev

Rev 2624 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2554 hidnplayr 1
 
2
 
2578 hidnplayr 3
        stack           rb 0
4
5
        home_dir        rb 1024         ; home directory in wich the user is locked, asciiz
2554 hidnplayr 6
 
2610 hidnplayr 7
        fpath           rb 1024*3       ; file path, combination of home_dir, work_dir and filename
8
                                        ; Will also be used to temporarily store username
9
10
        type            db ?    ; ASCII/EBDIC/IMAGE/..
2578 hidnplayr 11
 
12
        socketnum       dd ?    ; Commands socket
13
        state           dd ?    ; disconnected/logging in/logged in/..
14
        passivesocknum  dd ?    ; when in passive mode, this is the listening socket
15
        datasocketnum   dd ?    ; socket used for data transfers
16
        permissions     dd ?    ; read/write/execute/....
17
        buffer_ptr      dd ?
2610 hidnplayr 18
        pid             dd ?    ; Process id of the current thread
2598 hidnplayr 19
2624 hidnplayr 20
        datasock        sockaddr_in
2578 hidnplayr 21
 
22
        buffer          rb BUFFERSIZE
23
 
24
25
;------------------------------------------------
26
 
2598 hidnplayr 27
;
28
; Internal function wich uses the 'commands'
29
;  table to call an appropriate cmd_xx function.
30
;
31
; input: esi = ptr to ascii commands
32
;        ecx = number of bytes input
33
;        ebp = pointer to thread_data structure
34
;
2609 hidnplayr 35
; output: none
2598 hidnplayr 36
;
37
;------------------------------------------------
38
align 4
39
parse_cmd:                              ; esi must point to command
2554 hidnplayr 40
41
        cmp     byte [esi], 0x20        ; skip all leading characters
42
 
2578 hidnplayr 43
        inc     esi
44
        dec     ecx
45
        cmp     ecx, 3
46
        jb      .error
47
        jmp     parse_cmd
2598 hidnplayr 48
  .ok:
49
        cmp     byte [esi+3], 0x20
2578 hidnplayr 50
        ja      @f
2557 hidnplayr 51
        mov     byte [esi+3], 0
2598 hidnplayr 52
       @@:
2557 hidnplayr 53
54
        mov     eax, [esi]
55
 
2554 hidnplayr 56
        mov     edi, commands           ; list of commands to scan
57
  .scanloop:
58
        cmp     eax, [edi]
59
        je      .got_it
60
2598 hidnplayr 61
        add     edi, 5*4
2554 hidnplayr 62
 
2609 hidnplayr 63
        jne     .scanloop
2554 hidnplayr 64
65
  .error:
66
 
67
        jb      login_first
2609 hidnplayr 68
        sendFTP "500 Unsupported command"
2598 hidnplayr 69
        ret
70
2554 hidnplayr 71
  .got_it:
72
 
2598 hidnplayr 73
        jmp     dword [edi + 4 + eax]
2609 hidnplayr 74
2598 hidnplayr 75
2554 hidnplayr 76
 
2598 hidnplayr 77
 
2554 hidnplayr 78
commands:               ; all commands must be in uppercase
2635 hidnplayr 79
2562 hidnplayr 80
        dd 'ABOR', login_first, login_first, login_first, cmdABOR
2554 hidnplayr 81
 
2609 hidnplayr 82
;        dd 'APPE', login_first, login_first, login_first, cmd_APPE
83
        dd 'CDUP', login_first, login_first, login_first, cmdCDUP
84
        dd 'CWD',  login_first, login_first, login_first, cmdCWD
85
        dd 'DELE', login_first, login_first, login_first, cmdDELE
86
;        dd 'HELP', login_first, login_first, login_first, cmd_HELP
87
        dd 'LIST', login_first, login_first, login_first, cmdLIST
88
;        dd 'MDTM', login_first, login_first, login_first, cmd_MDTM
89
;        dd 'MKD',  login_first, login_first, login_first, cmd_MKD
90
;        dd 'MODE', login_first, login_first, login_first, cmd_MODE
91
        dd 'NLST', login_first, login_first, login_first, cmdNLST
92
        dd 'NOOP', login_first, login_first, login_first, cmdNOOP
93
        dd 'PASS', cmdPASS.0,   cmdPASS    , cmdPASS.2,   cmdPASS.3
94
        dd 'PASV', login_first, login_first, login_first, cmdPASV
95
        dd 'PORT', login_first, login_first, login_first, cmdPORT
96
        dd 'PWD',  login_first, login_first, login_first, cmdPWD
97
        dd 'QUIT', cmdQUIT,     cmdQUIT,     cmdQUIT,     cmdQUIT
98
;        dd 'REIN', login_first, login_first, login_first, cmd_REIN
99
;        dd 'REST', login_first, login_first, login_first, cmd_REST
100
        dd 'RETR', login_first, login_first, login_first, cmdRETR
101
;        dd 'RMD', login_first, login_first, login_first, cmd_RMD
102
;        dd 'RNFR', login_first, login_first, login_first, cmd_RNFR
103
;        dd 'RNTO', login_first, login_first, login_first, cmd_RNTO
104
;        dd 'SITE', login_first, login_first, login_first, cmd_SITE
105
;        dd 'SIZE', login_first, login_first, login_first, cmd_SIZE
106
;        dd 'STAT', login_first, login_first, login_first, cmd_STAT
107
        dd 'STOR', login_first, login_first, login_first, cmdSTOR
108
;        dd 'STOU', login_first, login_first, login_first, cmd_STOU
109
;        dd 'STRU', login_first, login_first, login_first, cmd_STRU
110
        dd 'SYST', login_first, login_first, login_first, cmdSYST
111
        dd 'TYPE', login_first, login_first, login_first, cmdTYPE
112
        dd 'USER', cmdUSER,     cmdUSER,     cmdUSER,     cmdUSER.2
113
        db 0    ; end marker
114
endg
115
2635 hidnplayr 116
align 4
2554 hidnplayr 117
 
2598 hidnplayr 118
        sendFTP "530 Please login with USER and PASS"
119
        ret
120
121
align 4
2554 hidnplayr 122
 
123
        sendFTP "550 Permission denied"
2598 hidnplayr 124
        ret
125
126
align 4
2554 hidnplayr 127
 
2598 hidnplayr 128
        invoke  con_set_flags, 0x0c
129
        invoke  con_write_asciiz, str_sockerr
2602 hidnplayr 130
        invoke  con_set_flags, 0x07
131
132
        sendFTP "425 Can't open data connection"
2578 hidnplayr 133
 
2598 hidnplayr 134
2554 hidnplayr 135
align 4
136
 
137
        and     [ebp + thread_data.permissions], not ABORT
2598 hidnplayr 138
        mov     [ebp + thread_data.mode], MODE_NOTREADY
2609 hidnplayr 139
        invoke  file.close, ebx
140
        mcall   close, [ebp + thread_data.datasocketnum]
2602 hidnplayr 141
2609 hidnplayr 142
        sendFTP "530 Transfer aborted"
2602 hidnplayr 143
 
2598 hidnplayr 144
145
align 4
146
 
147
148
        call    ascii_to_byte
149
 
150
        cmp     byte [esi], cl
2602 hidnplayr 151
        jne     .err
2598 hidnplayr 152
        inc     esi
153
2602 hidnplayr 154
        call    ascii_to_byte
2598 hidnplayr 155
 
156
        cmp     byte [esi], cl
157
        jne     .err
158
        inc     esi
159
2602 hidnplayr 160
        shl     ebx, 16
161
 
2598 hidnplayr 162
        call    ascii_to_byte
163
 
164
        cmp     byte [esi], cl
2602 hidnplayr 165
        jne     .err
2598 hidnplayr 166
        inc     esi
167
2602 hidnplayr 168
        call    ascii_to_byte
2598 hidnplayr 169
 
170
171
        ror     ebx, 16
172
 
173
174
  .err:
175
 
176
        ret
177
178
align 4         ; esi = ptr to str, output in eax
179
 
180
181
        xor     eax, eax
182
 
183
184
  .loop:
185
 
186
        sub     bl, '0'
187
        jb      .done
188
        cmp     bl, 9
189
        ja      .done
190
        lea     eax, [eax*4 + eax]      ;
191
        shl     eax, 1                  ; eax = eax * 10
192
        add     eax, ebx
193
        inc     esi
194
195
        jmp     .loop
196
 
197
  .done:
198
 
199
        ret
200
201
align 4
202
 
203
204
        push    edx ebx ecx
205
 
206
        xor     ecx, ecx
207
208
       @@:
209
 
210
        div     ebx
211
        add     edx, '0'
212
        pushw   dx
213
        inc     ecx
214
        test    eax, eax
215
        jnz     @r
216
217
       @@:
218
 
219
        stosb
220
        dec     ecx
221
        jnz     @r
222
223
        pop     ecx ebx edx
224
 
225
226
align 4
227
 
228
229
        lea     edi, [ebp + thread_data.fpath]
230
 
2609 hidnplayr 231
        mov     ecx, 1024
232
  .loop1:
2598 hidnplayr 233
        lodsb
234
        cmp     al, 0x20
235
        jb      .next
2602 hidnplayr 236
        stosb
237
        loop    .loop1
2598 hidnplayr 238
  .next:
239
240
        cmp     byte[edi-1], '/'
241
 
242
        dec     edi
243
       @@:
244
245
        lea     esi, [ebp + thread_data.work_dir]
246
 
2609 hidnplayr 247
  .loop2:
2598 hidnplayr 248
        lodsb
249
        cmp     al, 0x20
250
        jb      .done
2602 hidnplayr 251
        stosb
252
        loop    .loop2
2598 hidnplayr 253
254
  .done:
255
 
256
        stosb
2602 hidnplayr 257
        ret
2598 hidnplayr 258
259
260
 
2610 hidnplayr 261
 
262
263
        inc     [pasv_port]
264
 
265
        mov     ax, [pasv_port]
266
 
267
        jb      .restart
268
        cmp     ax, [pasv_end]
269
        ja      .restart
270
271
        ret
272
 
273
  .restart:
274
 
275
        popw    [pasv_port]
276
277
        ret
278
 
279
280
 
281
 
2598 hidnplayr 282
;
283
; This command aborts the current filetransfer.
284
;
285
;------------------------------------------------
286
align 4
287
cmdABOR:
288
289
        or      [ebp + thread_data.permissions], ABORT
290
 
2609 hidnplayr 291
        ret
2598 hidnplayr 292
293
;------------------------------------------------
294
 
295
;
296
; Change the directory to move up one level.
297
;
298
;------------------------------------------------
299
align 4
300
cmdCDUP:
301
2571 hidnplayr 302
        test    [ebp + thread_data.permissions], PERMISSION_CD
303
 
2609 hidnplayr 304
2598 hidnplayr 305
        cmp     byte [ebp + thread_data.work_dir+1], 0  ; are we in "/" ?
306
 
2610 hidnplayr 307
308
; find the end of asciiz string work_dir
2571 hidnplayr 309
 
2610 hidnplayr 310
        xor     al, al
2571 hidnplayr 311
        lea     edi, [ebp + thread_data.work_dir]
312
        repne   scasb
2609 hidnplayr 313
; return 2 characters (right before last /)
2571 hidnplayr 314
        sub     edi, 3
2610 hidnplayr 315
; and now search backwards, for a '/'
2609 hidnplayr 316
        mov     al,'/'
2610 hidnplayr 317
        neg     ecx
2609 hidnplayr 318
        add     ecx, 1024
319
        std
320
        repne   scasb
2610 hidnplayr 321
        cld
2585 hidnplayr 322
; terminate the string here
2571 hidnplayr 323
        mov     byte[edi+2], 0
2610 hidnplayr 324
325
  .done:
2571 hidnplayr 326
 
327
        lea     eax, [ebp + thread_data.work_dir]
2585 hidnplayr 328
        invoke  con_write_asciiz, eax
2609 hidnplayr 329
        invoke  con_write_asciiz, str_newline
2610 hidnplayr 330
331
        sendFTP "250 Command succesul"
2585 hidnplayr 332
 
2598 hidnplayr 333
2571 hidnplayr 334
;------------------------------------------------
335
 
2598 hidnplayr 336
;
337
; Change Working Directory.
338
;
339
;------------------------------------------------
340
align 4
341
cmdCWD:
2571 hidnplayr 342
2598 hidnplayr 343
        test    [ebp + thread_data.permissions], PERMISSION_CD
2554 hidnplayr 344
 
2609 hidnplayr 345
2598 hidnplayr 346
; do we have enough parameters?
347
 
2610 hidnplayr 348
        jbe     .err
2563 hidnplayr 349
2610 hidnplayr 350
; get ready to copy the path
351
 
352
        mov     ecx, 1024
2563 hidnplayr 353
        lea     edi, [ebp + thread_data.work_dir]
2609 hidnplayr 354
355
; if received dir starts with '/', we will simply copy it
2610 hidnplayr 356
 
357
        cmp     byte [esi], '/'
358
        je      .copyloop
2609 hidnplayr 359
2610 hidnplayr 360
; Find the end of work_dir string.
2609 hidnplayr 361
 
2610 hidnplayr 362
  .find_zero:
363
        repne   scasb
2578 hidnplayr 364
        dec     edi
2610 hidnplayr 365
366
; and now append work_dir with received string
2563 hidnplayr 367
 
2610 hidnplayr 368
369
; scan for end byte, or '.'
2563 hidnplayr 370
 
2610 hidnplayr 371
        lodsb
372
        cmp     al, 0x20
2563 hidnplayr 373
        jb      .done
374
;;;        cmp     al, '.'         ; '..' means we must go up one dir   TODO
375
;;;        je      .up
2610 hidnplayr 376
        stosb
377
        loop    .copyloop
2563 hidnplayr 378
2610 hidnplayr 379
; now, now make sure it ends with '/', 0
380
 
381
        cmp     byte [edi-1], '/'
2563 hidnplayr 382
        je      @f
383
        mov     byte [edi], '/'
384
        inc     edi
385
       @@:
386
        mov     byte [edi], 0
387
388
; Print the new working dir on the console
389
 
2585 hidnplayr 390
        invoke  con_write_asciiz, eax
2609 hidnplayr 391
        invoke  con_write_asciiz, str_newline
2610 hidnplayr 392
393
        sendFTP "250 Command succesful"
2585 hidnplayr 394
 
2598 hidnplayr 395
2554 hidnplayr 396
  .err:
397
 
2563 hidnplayr 398
        ret
2598 hidnplayr 399
2563 hidnplayr 400
;------------------------------------------------
401
 
2598 hidnplayr 402
;
403
; Delete a file from the server.
404
;
405
;------------------------------------------------
406
align 4
407
cmdDELE:
2554 hidnplayr 408
409
        test    [ebp + thread_data.permissions], PERMISSION_DELETE
410
 
2609 hidnplayr 411
2598 hidnplayr 412
        ret
413
 
2554 hidnplayr 414
;------------------------------------------------
415
 
2598 hidnplayr 416
;
417
; List the files in the current working directory.
418
;
419
;------------------------------------------------
420
align 4
421
cmdLIST:
2554 hidnplayr 422
423
        test    [ebp + thread_data.permissions], PERMISSION_EXEC
424
 
2609 hidnplayr 425
2598 hidnplayr 426
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_OK
427
 
2610 hidnplayr 428
429
; If we are in active mode, it's time to open a data socket..
430
 
2563 hidnplayr 431
        jne     .not_active
2609 hidnplayr 432
        mov     ecx, [ebp + thread_data.datasocketnum]
2610 hidnplayr 433
        lea     edx, [ebp + thread_data.datasock]
2609 hidnplayr 434
        mov     esi, sizeof.thread_data.datasock
435
        mcall   connect
2578 hidnplayr 436
        cmp     eax, -1
437
        je      socketerror
2562 hidnplayr 438
        jmp     .start
2571 hidnplayr 439
2610 hidnplayr 440
; If we are still in passive_wait, it's time we accept an incomming call..
2562 hidnplayr 441
 
2610 hidnplayr 442
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_WAIT
443
        jne     socketerror
444
  .try_now:
445
        mov     ecx, [ebp + thread_data.passivesocknum]
446
        lea     edx, [ebp + thread_data.datasock]
447
        mov     esi, sizeof.thread_data.datasock
448
        mcall   accept
449
        cmp     eax, -1
450
        jne     .pasv_ok
451
        mov     [ebp + thread_data.mode], MODE_PASSIVE_FAILED                   ; assume that we will fail
452
        mcall   23, 200
2624 hidnplayr 453
        mcall   accept
2610 hidnplayr 454
        cmp     eax, -1
455
        je      socketerror
456
  .pasv_ok:
457
        mov     [ebp + thread_data.datasocketnum], eax
458
        mov     [ebp + thread_data.mode], MODE_PASSIVE_OK
459
        mcall   close   ; [ebp + thread_data.passivesocknum]
460
        mov     [ebp + thread_data.passivesocknum], -1
461
        invoke  con_write_asciiz, str_datasock
462
463
  .start:
464
 
465
        call    create_path
2563 hidnplayr 466
467
        lea     ebx, [ebp + thread_data.fpath]
468
 
2609 hidnplayr 469
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 470
471
; Start the search
2571 hidnplayr 472
 
2563 hidnplayr 473
        test    eax, eax
2609 hidnplayr 474
        jz      .nosuchdir
2578 hidnplayr 475
476
        lea     edi, [ebp + thread_data.buffer]
477
 
2609 hidnplayr 478
        test    eax, eax        ; did we find a file?
2562 hidnplayr 479
        jz      .done
2563 hidnplayr 480
        mov     ebx, eax        ; yes, save the descripter in ebx
2562 hidnplayr 481
2578 hidnplayr 482
; first, convert the attributes
2562 hidnplayr 483
 
484
        jnz     .folder
2578 hidnplayr 485
2562 hidnplayr 486
        test    [ebx + FileInfoA.Attributes], FA_READONLY
487
 
2578 hidnplayr 488
2562 hidnplayr 489
        mov     eax, '-rw-'
490
 
491
        jmp     .attr
492
493
  .folder:
494
 
495
        stosd
496
        jmp     .attr
2563 hidnplayr 497
2562 hidnplayr 498
  .readonly:
499
 
500
        stosd
501
502
  .attr:
503
 
504
        stosd
505
        mov     ax, 'w-'
506
        stosw
507
        mov     al, ' '
508
        stosb
509
510
; now..
511
 
512
        stosw
513
514
; now write owner, everything is owned by FTP, woohoo!
515
 
516
        stosd
517
        stosd
518
519
; now the filesize in ascii
520
 
521
        call    dword_to_ascii
2578 hidnplayr 522
        mov     al, ' '
2562 hidnplayr 523
        stosb
524
525
; then date (month/day/year)
526
 
527
        cmp     eax, 12
2578 hidnplayr 528
        ja      @f
2602 hidnplayr 529
        mov     eax, [months - 4 + 4*eax]
530
        stosd
531
       @@:
2562 hidnplayr 532
2602 hidnplayr 533
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.day]
2562 hidnplayr 534
 
2578 hidnplayr 535
        mov     al, ' '
2562 hidnplayr 536
        stosb
537
538
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.year]
539
 
2578 hidnplayr 540
        mov     al, ' '
2562 hidnplayr 541
        stosb
542
543
; and last but not least, filename
544
 
545
        mov     ecx, 264
2578 hidnplayr 546
  .nameloop:
547
        lodsb
2562 hidnplayr 548
        test    al, al
549
        jz      .namedone
550
        stosb
551
        loop    .nameloop
552
553
; insert a cr lf
554
 
2563 hidnplayr 555
        mov     ax, 0x0a0d
2562 hidnplayr 556
        stosw
2571 hidnplayr 557
2562 hidnplayr 558
        test    [ebp + thread_data.permissions], ABORT          ; Did we receive ABOR command from client?
559
 
2609 hidnplayr 560
2602 hidnplayr 561
; check next file
2598 hidnplayr 562
 
2563 hidnplayr 563
        jmp     .parse_file
2609 hidnplayr 564
565
; close file desc
2563 hidnplayr 566
 
567
        invoke  file.find.close, ebx                            ; ebx is descriptor of last file, eax will be -1 !!
2562 hidnplayr 568
2624 hidnplayr 569
; append the string with a 0
2562 hidnplayr 570
 
2563 hidnplayr 571
        stosb
2562 hidnplayr 572
573
; Warn the client we're about to send the data
574
 
2571 hidnplayr 575
        sendFTP "150 Here it comes.."
2598 hidnplayr 576
        pop     esi
577
578
; and send it to the client
2562 hidnplayr 579
 
2563 hidnplayr 580
        lea     edx, [ebp + thread_data.buffer]                 ; buffer ptr
2624 hidnplayr 581
        sub     esi, edx                                        ; length
582
        xor     edi, edi                                        ; flags
583
        mcall   send
584
2578 hidnplayr 585
; close the data socket..
2562 hidnplayr 586
 
2563 hidnplayr 587
        mcall   close, [ebp + thread_data.datasocketnum]
2609 hidnplayr 588
589
        sendFTP "226 Transfer OK"
2562 hidnplayr 590
 
2598 hidnplayr 591
2554 hidnplayr 592
  .nosuchdir:
593
 
2578 hidnplayr 594
        ret
2598 hidnplayr 595
2578 hidnplayr 596
;------------------------------------------------
597
 
2598 hidnplayr 598
;
599
; List the filenames of the files in the current working directory.
600
;
601
;------------------------------------------------
602
align 4
603
cmdNLST:
2554 hidnplayr 604
605
        test    [ebp + thread_data.permissions], PERMISSION_EXEC
606
 
2609 hidnplayr 607
2598 hidnplayr 608
        ; TODO: same as list but simpler output format
609
 
2578 hidnplayr 610
        ret
611
 
2554 hidnplayr 612
;------------------------------------------------
613
 
2598 hidnplayr 614
;
615
; No operation, just keep the connection alive.
616
;
617
;------------------------------------------------
618
align 4
619
cmdNOOP:
2554 hidnplayr 620
621
        sendFTP "200 Command OK"
622
 
2602 hidnplayr 623
2554 hidnplayr 624
;------------------------------------------------
625
 
2598 hidnplayr 626
;
627
; Second phase of login process, client provides password.
628
;
629
;------------------------------------------------
630
align 4
631
cmdPASS:
2554 hidnplayr 632
2557 hidnplayr 633
; read the password from users.ini
2602 hidnplayr 634
 
635
        lea     ebx, [ebp + thread_data.fpath]                  ; temp username
2609 hidnplayr 636
        invoke  ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity
637
        test    eax, eax                                        ; unable to read password? fail!
2602 hidnplayr 638
        jnz     .incorrect
2610 hidnplayr 639
        cmp     dword [edi], -1                                 ; no key, section or file found.. fail!
2598 hidnplayr 640
        je      .incorrect
2610 hidnplayr 641
;;;        cmp     byte [edi], 0                                   ; zero password? ok!
2602 hidnplayr 642
;;;        je      .ok
2624 hidnplayr 643
644
        add     esi, 5
2557 hidnplayr 645
 
2610 hidnplayr 646
        jbe     .incorrect                                      ; no password given? but hey, we need one! fail..
647
648
; compare with received password
649
 
2602 hidnplayr 650
        cmp     byte [esi-1], 0x20                              ; printeable characters left?
2598 hidnplayr 651
        jae     .incorrect
2610 hidnplayr 652
        cmp     byte [edi-1], 0
2598 hidnplayr 653
        jne     .incorrect
2610 hidnplayr 654
2598 hidnplayr 655
  .ok:
656
 
2610 hidnplayr 657
        mov     [ebp + thread_data.permissions], eax
2602 hidnplayr 658
2609 hidnplayr 659
        invoke  con_write_asciiz, str_pass_ok
2598 hidnplayr 660
 
2602 hidnplayr 661
        sendFTP "230 You are now logged in"
2609 hidnplayr 662
        ret
2598 hidnplayr 663
664
  .2:
2557 hidnplayr 665
 
2598 hidnplayr 666
        invoke  con_write_asciiz, str_pass_err
667
        mov     [ebp + thread_data.state], STATE_CONNECTED      ; reset state
2610 hidnplayr 668
        sendFTP "530 Login incorrect"
669
        ret
2598 hidnplayr 670
2557 hidnplayr 671
  .0:
672
 
2598 hidnplayr 673
        ret
674
675
  .3:
676
 
677
        ret
678
679
;------------------------------------------------
680
 
681
;
682
; Initiate a passive dataconnection.
683
;
684
;------------------------------------------------
685
align 4
686
cmdPASV:
687
2560 hidnplayr 688
        cmp     [ebp + thread_data.passivesocknum], -1
689
 
2610 hidnplayr 690
        mcall   close, [ebp + thread_data.passivesocknum]       ; if there is still a socket open, close it
691
       @@:
692
693
; Open a new TCP socket
694
 
2578 hidnplayr 695
        cmp     eax, -1
2562 hidnplayr 696
        je      socketerror
697
        mov     [ebp + thread_data.passivesocknum], eax
2578 hidnplayr 698
2609 hidnplayr 699
; Bind it to a known local port
2562 hidnplayr 700
 
2578 hidnplayr 701
        mov     [ebp + thread_data.datasock.sin_addr], 0
2609 hidnplayr 702
703
        mov     ecx, eax                                        ; passivesocketnum
2562 hidnplayr 704
 
2598 hidnplayr 705
        mov     esi, sizeof.thread_data.datasock
2609 hidnplayr 706
2581 hidnplayr 707
  .next_port:                                                   ; TODO: break the endless loop
2610 hidnplayr 708
 
709
        pushw   [pasv_port]
710
        popw    [ebp + thread_data.datasock.sin_port]
711
712
        mcall   bind
713
 
2581 hidnplayr 714
        je      .next_port
2562 hidnplayr 715
2610 hidnplayr 716
; And set it to listen!
2562 hidnplayr 717
 
2578 hidnplayr 718
        cmp     eax, -1
2598 hidnplayr 719
        je      socketerror
720
2610 hidnplayr 721
; Tell our thread we are ready to accept incoming calls
2562 hidnplayr 722
 
2578 hidnplayr 723
2609 hidnplayr 724
; Now tell the client where to connect to in this format:
2562 hidnplayr 725
 
2578 hidnplayr 726
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
727
728
; '227 ('
2598 hidnplayr 729
 
730
        mov     eax, '227 '
2609 hidnplayr 731
        stosd
2610 hidnplayr 732
        mov     al, '('
2562 hidnplayr 733
        stosb
2598 hidnplayr 734
; ip
2562 hidnplayr 735
        movzx   eax, byte [serverip]
2598 hidnplayr 736
        call    dword_to_ascii
2610 hidnplayr 737
        mov     al, ','
2598 hidnplayr 738
        stosb
739
        movzx   eax, byte [serverip+1]
2562 hidnplayr 740
        call    dword_to_ascii
2610 hidnplayr 741
        mov     al, ','
2598 hidnplayr 742
        stosb
743
        movzx   eax, byte [serverip+2]
744
        call    dword_to_ascii
2610 hidnplayr 745
        mov     al, ','
2598 hidnplayr 746
        stosb
747
        movzx   eax, byte [serverip+3]
748
        call    dword_to_ascii
2610 hidnplayr 749
        mov     al, ','
2598 hidnplayr 750
        stosb
751
; port
752
        movzx   eax, byte [ebp + thread_data.datasock.sin_port + 1]
753
        call    dword_to_ascii
2609 hidnplayr 754
        mov     al, ','
2598 hidnplayr 755
        stosb
756
        movzx   eax, byte [ebp + thread_data.datasock.sin_port]
757
        call    dword_to_ascii
2609 hidnplayr 758
; ')', 13, 10, 0
2598 hidnplayr 759
        mov     eax, ')' + 0x000a0d00
760
        stosd
761
762
        lea     esi, [edi - thread_data.buffer]
2562 hidnplayr 763
 
2578 hidnplayr 764
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 765
        lea     edx, [ebp + thread_data.buffer]
766
        xor     edi, edi
767
        mcall   send
2602 hidnplayr 768
2581 hidnplayr 769
        ret
2562 hidnplayr 770
 
2560 hidnplayr 771
;------------------------------------------------
772
 
2598 hidnplayr 773
;
774
; Print the current working directory.
775
;
776
;------------------------------------------------
777
align 4
778
cmdPWD:
2560 hidnplayr 779
2598 hidnplayr 780
        mov     dword [ebp + thread_data.buffer], '257 '
2554 hidnplayr 781
 
2609 hidnplayr 782
783
        lea     edi, [ebp + thread_data.buffer+5]
2560 hidnplayr 784
 
2609 hidnplayr 785
        mov     ecx, 1024
786
  .loop:
2560 hidnplayr 787
        lodsb
788
        or      al, al
789
        jz      .ok
790
        stosb
791
        dec     ecx
792
        jnz     .loop
793
794
  .ok:
795
 
796
        lea     esi, [edi - thread_data.buffer + 4]
2578 hidnplayr 797
        sub     esi, ebp
798
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 799
        lea     edx, [ebp + thread_data.buffer]
800
        xor     edi, edi
801
        mcall   send
2585 hidnplayr 802
803
; Print the new working dir on the console
2560 hidnplayr 804
 
2585 hidnplayr 805
        invoke  con_write_asciiz, eax
2609 hidnplayr 806
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 807
808
        ret
2562 hidnplayr 809
 
2554 hidnplayr 810
;------------------------------------------------
811
 
2598 hidnplayr 812
;
813
; Initiate an active dataconnection.
814
;
815
;------------------------------------------------
816
align 4
817
cmdPORT:
2554 hidnplayr 818
819
; PORT a1,a2,a3,a4,p1,p2
820
 
2560 hidnplayr 821
822
; Convert the IP
823
 
2598 hidnplayr 824
        mov     cl, ','
2560 hidnplayr 825
        call    ip_to_dword
2598 hidnplayr 826
; And put it in datasock
827
        mov     [ebp + thread_data.datasock.sin_addr], ebx
2578 hidnplayr 828
2609 hidnplayr 829
; Now the same with portnumber
2560 hidnplayr 830
 
2578 hidnplayr 831
        call    ascii_to_byte
2602 hidnplayr 832
        mov     bh, al
2560 hidnplayr 833
        inc     esi
2578 hidnplayr 834
        call    ascii_to_byte
2560 hidnplayr 835
        mov     bl, al
836
2578 hidnplayr 837
; Save it in datasock too
2560 hidnplayr 838
 
2578 hidnplayr 839
2609 hidnplayr 840
; We will open the socket, but do not connect yet!
2560 hidnplayr 841
 
2578 hidnplayr 842
        mcall   socket, AF_INET4, SOCK_STREAM, 0
2609 hidnplayr 843
        cmp     eax, -1
2562 hidnplayr 844
        je      socketerror
2560 hidnplayr 845
2578 hidnplayr 846
        mov     [ebp + thread_data.datasocketnum], eax
2598 hidnplayr 847
 
2609 hidnplayr 848
849
        sendFTP "225 Data connection open"
2560 hidnplayr 850
 
2598 hidnplayr 851
2554 hidnplayr 852
;------------------------------------------------
853
 
2598 hidnplayr 854
;
855
; Close the connection with client.
856
;
857
;------------------------------------------------
858
align 4
859
cmdQUIT:
2554 hidnplayr 860
861
        sendFTP "221 Bye!"
862
 
2602 hidnplayr 863
        mcall   close, [ebp + thread_data.socketnum]
2609 hidnplayr 864
865
        add     esp, 4          ; get rid of call return address
2598 hidnplayr 866
 
2581 hidnplayr 867
868
2554 hidnplayr 869
 
2598 hidnplayr 870
 
871
;
872
; Retrieve a file from the ftp server.
873
;
874
;------------------------------------------------
875
align 4
876
cmdRETR:
2554 hidnplayr 877
878
        test    [ebp + thread_data.permissions], PERMISSION_READ
879
 
2609 hidnplayr 880
2598 hidnplayr 881
        cmp     ecx, 1024 + 5
882
 
2602 hidnplayr 883
884
        sub     ecx, 5
885
 
2571 hidnplayr 886
887
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_OK
888
 
2610 hidnplayr 889
890
; If we are in active mode, it's time to open a data socket..
891
 
892
        jne     .not_active
2609 hidnplayr 893
        mov     ecx, [ebp + thread_data.datasocketnum]
2610 hidnplayr 894
        lea     edx, [ebp + thread_data.datasock]
2609 hidnplayr 895
        mov     esi, sizeof.thread_data.datasock
896
        mcall   connect
2581 hidnplayr 897
        cmp     eax, -1
898
        je      socketerror
2571 hidnplayr 899
        jmp     .start
900
2610 hidnplayr 901
; If we are still in passive_wait, it's time we accept an incomming call..
2562 hidnplayr 902
 
2610 hidnplayr 903
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_WAIT
904
        jne     socketerror
905
        mov     [ebp + thread_data.mode], MODE_PASSIVE_FAILED                   ; assume that we will fail
906
  .try_now:
907
        mov     ecx, [ebp + thread_data.passivesocknum]
908
        lea     edx, [ebp + thread_data.datasock]
909
        mov     esi, sizeof.thread_data.datasock
910
        mcall   accept
911
        cmp     eax, -1
912
        jne     .pasv_ok
913
        mcall   23, 200
914
        mcall   accept
915
        cmp     eax, -1
916
        je      socketerror
917
  .pasv_ok:
918
        mov     [ebp + thread_data.datasocketnum], eax
919
        mov     [ebp + thread_data.mode], MODE_PASSIVE_OK
920
        mcall   close   ; [ebp + thread_data.passivesocknum]
921
        mov     [ebp + thread_data.passivesocknum], -1
922
        invoke  con_write_asciiz, str_datasock
923
924
  .start:
925
 
926
        dec     edi
2571 hidnplayr 927
        add     esi, 5
928
929
        lea     esi, [ebp + thread_data.buffer]                         ; FIXME
2602 hidnplayr 930
 
2610 hidnplayr 931
  .loop:
932
        lodsb
2571 hidnplayr 933
        cmp     al, 0x20
934
        jl      .done
935
        stosb
936
        loop    .loop
937
  .done:
938
        xor     al, al
939
        stosb
940
941
        lea     ebx, [ebp + thread_data.fpath]
2563 hidnplayr 942
 
2609 hidnplayr 943
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 944
945
        invoke  file.open, ebx, O_READ
2571 hidnplayr 946
 
2602 hidnplayr 947
        jz      .cannot_open
2571 hidnplayr 948
949
        push    eax
2563 hidnplayr 950
 
2602 hidnplayr 951
        pop     ebx
2598 hidnplayr 952
2571 hidnplayr 953
  .read_more:
2563 hidnplayr 954
 
955
        jnz     abort_transfer
2609 hidnplayr 956
2598 hidnplayr 957
        lea     eax, [ebp + thread_data.buffer]                 ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
958
 
2609 hidnplayr 959
        cmp     eax, -1
2602 hidnplayr 960
        je      .cannot_open                                    ; FIXME: this is not the correct error
2571 hidnplayr 961
2602 hidnplayr 962
        push    eax ebx
2562 hidnplayr 963
 
2598 hidnplayr 964
        mov     ecx, [ebp + thread_data.datasocketnum]
2563 hidnplayr 965
        lea     edx, [ebp + thread_data.buffer]
2609 hidnplayr 966
        xor     edi, edi
967
        mcall   send
968
        pop     ebx ecx
2581 hidnplayr 969
        cmp     eax, -1
2598 hidnplayr 970
        je      socketerror                                     ; FIXME: not the correct error
2571 hidnplayr 971
2609 hidnplayr 972
;        cmp     eax, ecx
2563 hidnplayr 973
 
2602 hidnplayr 974
975
        cmp     ecx, BUFFERSIZE
976
 
2563 hidnplayr 977
978
        invoke  file.close, ebx
979
 
2602 hidnplayr 980
        mov     [ebp + thread_data.mode], MODE_NOTREADY
981
 
2609 hidnplayr 982
983
        sendFTP "226 Transfer OK, closing connection"
2563 hidnplayr 984
 
2598 hidnplayr 985
2554 hidnplayr 986
  .cannot_open:
987
 
2571 hidnplayr 988
        invoke  con_write_asciiz, str_notfound
2602 hidnplayr 989
        invoke  con_set_flags, 0x07
990
991
        sendFTP "550 No such file"
2571 hidnplayr 992
 
2598 hidnplayr 993
2571 hidnplayr 994
995
 
2598 hidnplayr 996
 
997
 
998
;
999
; Store a file on the server.
1000
;
1001
;------------------------------------------------
1002
align 4
1003
cmdSTOR:
2554 hidnplayr 1004
1005
        test    [ebp + thread_data.permissions], PERMISSION_WRITE
1006
 
2609 hidnplayr 1007
2598 hidnplayr 1008
2578 hidnplayr 1009
 
2598 hidnplayr 1010
 
1011
        jnz     abort_transfer
2609 hidnplayr 1012
2598 hidnplayr 1013
;;;;
1014
 
1015
        ret
1016
 
2554 hidnplayr 1017
;------------------------------------------------
1018
 
2598 hidnplayr 1019
;
1020
; Send information about the system.
1021
;
1022
;------------------------------------------------
1023
align 4
1024
cmdSYST:
2554 hidnplayr 1025
1026
        sendFTP "215 UNIX type: L8"
1027
 
2598 hidnplayr 1028
2554 hidnplayr 1029
;------------------------------------------------
1030
 
2598 hidnplayr 1031
;
1032
; Choose the file transfer type.
1033
;
1034
;------------------------------------------------
1035
align 4
1036
cmdTYPE:
2554 hidnplayr 1037
1038
        cmp     ecx, 6
1039
 
2560 hidnplayr 1040
1041
        mov     al, byte[esi+5]
1042
 
1043
1044
        cmp     al, 'A'
1045
 
1046
        cmp     al, 'E'
1047
        je      .ebdic
1048
        cmp     al, 'I'
1049
        je      .image
1050
        cmp     al, 'L'
1051
        je      .local
1052
1053
        jmp     parse_cmd.error
1054
 
1055
  .ascii:
1056
 
1057
        jmp     .subtype
2609 hidnplayr 1058
2560 hidnplayr 1059
  .ebdic:
1060
 
1061
2609 hidnplayr 1062
  .subtype:
2560 hidnplayr 1063
 
1064
        jb      .non_print
1065
1066
        mov     al, byte[esi+7]
1067
 
1068
1069
        cmp     al, 'N'
1070
 
1071
        cmp     al, 'T'
1072
        je      .telnet
1073
        cmp     al, 'C'
1074
        je      .asacc
1075
1076
        jmp     parse_cmd.error
1077
 
1078
  .non_print:
1079
 
1080
        jmp     .ok
2609 hidnplayr 1081
2560 hidnplayr 1082
  .telnet:
1083
 
1084
        jmp     .ok
2609 hidnplayr 1085
2560 hidnplayr 1086
  .asacc:
1087
 
1088
        jmp     .ok
2609 hidnplayr 1089
2560 hidnplayr 1090
  .image:
1091
 
1092
        jmp     .ok
2609 hidnplayr 1093
2560 hidnplayr 1094
  .local:
1095
 
1096
        jb      parse_cmd.error
1097
1098
        mov     al, byte[esi+7]
1099
 
1100
        jb      parse_cmd.error                         ; FIXME: this is not the correct errormessage
1101
        cmp     al, 9
2602 hidnplayr 1102
        ja      parse_cmd.error                         ; FIXME
2560 hidnplayr 1103
        or      al, TYPE_LOCAL
2602 hidnplayr 1104
        mov     [ebp + thread_data.type], al
2560 hidnplayr 1105
2609 hidnplayr 1106
  .ok:
2560 hidnplayr 1107
 
1108
        ret
2598 hidnplayr 1109
2554 hidnplayr 1110
;------------------------------------------------
1111
 
2598 hidnplayr 1112
;
1113
; Login to the server, step one of two.                         ;;; TODO: prevent buffer overflow!
1114
;
2602 hidnplayr 1115
;------------------------------------------------
2598 hidnplayr 1116
align 4
1117
cmdUSER:
2554 hidnplayr 1118
1119
        lea     esi, [esi + 5]
1120
 
2598 hidnplayr 1121
  .loop:
2609 hidnplayr 1122
        lodsb
2602 hidnplayr 1123
        stosb
2563 hidnplayr 1124
        cmp     al, 0x20
1125
        jae     .loop
2598 hidnplayr 1126
        mov     byte [edi-1], 0
1127
1128
        lea     esi, [ebp + thread_data.fpath]
2562 hidnplayr 1129
 
2609 hidnplayr 1130
        invoke  ini.get_str, path2, esi, str_home, eax, 1024, str_infinity
1131
        cmp     eax, -1
2602 hidnplayr 1132
        je      .login_fail
2598 hidnplayr 1133
        cmp     dword [esi], -1
1134
        je      .login_fail
2602 hidnplayr 1135
1136
        mov     word [ebp + thread_data.work_dir], "/"          ; "/", 0
2562 hidnplayr 1137
 
2609 hidnplayr 1138
        invoke  con_write_asciiz, str_logged_in
2563 hidnplayr 1139
 
2602 hidnplayr 1140
  .sendstr:
2609 hidnplayr 1141
        sendFTP "331 Please specify the password"
2598 hidnplayr 1142
        ret
1143
2563 hidnplayr 1144
  .login_fail:
1145
 
2598 hidnplayr 1146
        mov     [ebp + thread_data.state], STATE_LOGIN_FAIL
2610 hidnplayr 1147
        jmp     .sendstr
2609 hidnplayr 1148
2598 hidnplayr 1149
align 4
2571 hidnplayr 1150
 
2598 hidnplayr 1151
        sendFTP "530 Can't change to another user"
1152
        ret
1153