Subversion Repositories Kolibri OS

Rev

Rev 2958 | 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
 
2892 hidnplayr 282
283
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_OK
284
 
285
286
; If we are in active mode, it's time to open a data socket..
287
 
288
        jne     .not_active
289
        mov     ecx, [ebp + thread_data.datasocketnum]
290
        lea     edx, [ebp + thread_data.datasock]
291
        mov     esi, sizeof.thread_data.datasock
292
        mcall   connect
293
        cmp     eax, -1
294
        jne     .start
295
296
  .socketerror:
297
 
298
        jmp     socketerror
299
300
; If we are still in passive_wait, it's time we accept an incomming call..
301
 
302
        cmp     [ebp + thread_data.mode], MODE_PASSIVE_WAIT
303
        jne     .socketerror
304
305
  .try_now:
306
 
307
        lea     edx, [ebp + thread_data.datasock]
308
        mov     esi, sizeof.thread_data.datasock
309
        mcall   accept
310
        cmp     eax, -1
311
        jne     .pasv_ok
312
        mov     [ebp + thread_data.mode], MODE_PASSIVE_FAILED                   ; assume that we will fail
313
        mcall   23, 200
314
        mcall   accept
315
        cmp     eax, -1
316
        je      .socketerror
317
  .pasv_ok:
318
        mov     [ebp + thread_data.datasocketnum], eax
319
        mov     [ebp + thread_data.mode], MODE_PASSIVE_OK
320
        mcall   close   ; [ebp + thread_data.passivesocknum]
321
        mov     [ebp + thread_data.passivesocknum], -1
322
        invoke  con_write_asciiz, str_datasock
323
324
  .start:
325
 
326
327
328
 
329
 
2598 hidnplayr 330
;
331
; This command aborts the current filetransfer.
332
;
333
;------------------------------------------------
334
align 4
335
cmdABOR:
336
337
        or      [ebp + thread_data.permissions], ABORT
338
 
2609 hidnplayr 339
        ret
2598 hidnplayr 340
341
;------------------------------------------------
342
 
343
;
344
; Change the directory to move up one level.
345
;
346
;------------------------------------------------
347
align 4
348
cmdCDUP:
349
2571 hidnplayr 350
        test    [ebp + thread_data.permissions], PERMISSION_CD
351
 
2609 hidnplayr 352
2598 hidnplayr 353
        cmp     byte [ebp + thread_data.work_dir+1], 0  ; are we in "/" ?
354
 
2610 hidnplayr 355
356
; find the end of asciiz string work_dir
2571 hidnplayr 357
 
2610 hidnplayr 358
        xor     al, al
2571 hidnplayr 359
        lea     edi, [ebp + thread_data.work_dir]
360
        repne   scasb
2609 hidnplayr 361
; return 2 characters (right before last /)
2571 hidnplayr 362
        sub     edi, 3
2610 hidnplayr 363
; and now search backwards, for a '/'
2609 hidnplayr 364
        mov     al,'/'
2610 hidnplayr 365
        neg     ecx
2609 hidnplayr 366
        add     ecx, 1024
367
        std
368
        repne   scasb
2610 hidnplayr 369
        cld
2585 hidnplayr 370
; terminate the string here
2571 hidnplayr 371
        mov     byte[edi+2], 0
2610 hidnplayr 372
373
  .done:
2571 hidnplayr 374
 
375
        lea     eax, [ebp + thread_data.work_dir]
2585 hidnplayr 376
        invoke  con_write_asciiz, eax
2609 hidnplayr 377
        invoke  con_write_asciiz, str_newline
2610 hidnplayr 378
379
        sendFTP "250 Command succesul"
2585 hidnplayr 380
 
2598 hidnplayr 381
2571 hidnplayr 382
;------------------------------------------------
383
 
2598 hidnplayr 384
;
385
; Change Working Directory.
386
;
387
;------------------------------------------------
388
align 4
389
cmdCWD:
2571 hidnplayr 390
2598 hidnplayr 391
        test    [ebp + thread_data.permissions], PERMISSION_CD
2554 hidnplayr 392
 
2609 hidnplayr 393
2598 hidnplayr 394
; do we have enough parameters?
395
 
2610 hidnplayr 396
        jbe     .err
2563 hidnplayr 397
2610 hidnplayr 398
; get ready to copy the path
399
 
400
        mov     ecx, 1024
2563 hidnplayr 401
        lea     edi, [ebp + thread_data.work_dir]
2609 hidnplayr 402
403
; if received dir starts with '/', we will simply copy it
2610 hidnplayr 404
 
405
        cmp     byte [esi], '/'
406
        je      .copyloop
2609 hidnplayr 407
2610 hidnplayr 408
; Find the end of work_dir string.
2609 hidnplayr 409
 
2610 hidnplayr 410
  .find_zero:
411
        repne   scasb
2578 hidnplayr 412
        dec     edi
2610 hidnplayr 413
414
; and now append work_dir with received string
2563 hidnplayr 415
 
2610 hidnplayr 416
417
; scan for end byte, or '.'
2563 hidnplayr 418
 
2610 hidnplayr 419
        lodsb
420
        cmp     al, 0x20
2563 hidnplayr 421
        jb      .done
422
;;;        cmp     al, '.'         ; '..' means we must go up one dir   TODO
423
;;;        je      .up
2610 hidnplayr 424
        stosb
425
        loop    .copyloop
2563 hidnplayr 426
2610 hidnplayr 427
; now, now make sure it ends with '/', 0
428
 
429
        cmp     byte [edi-1], '/'
2563 hidnplayr 430
        je      @f
431
        mov     byte [edi], '/'
432
        inc     edi
433
       @@:
434
        mov     byte [edi], 0
435
436
; Print the new working dir on the console
437
 
2585 hidnplayr 438
        invoke  con_write_asciiz, eax
2609 hidnplayr 439
        invoke  con_write_asciiz, str_newline
2610 hidnplayr 440
441
        sendFTP "250 Command succesful"
2585 hidnplayr 442
 
2598 hidnplayr 443
2554 hidnplayr 444
  .err:
445
 
2563 hidnplayr 446
        ret
2598 hidnplayr 447
2563 hidnplayr 448
;------------------------------------------------
449
 
2598 hidnplayr 450
;
451
; Delete a file from the server.
452
;
453
;------------------------------------------------
454
align 4
455
cmdDELE:
2554 hidnplayr 456
457
        test    [ebp + thread_data.permissions], PERMISSION_DELETE
458
 
2609 hidnplayr 459
2598 hidnplayr 460
        ret
461
 
2554 hidnplayr 462
;------------------------------------------------
463
 
2598 hidnplayr 464
;
465
; List the files in the current working directory.
466
;
467
;------------------------------------------------
468
align 4
469
cmdLIST:
2554 hidnplayr 470
471
        test    [ebp + thread_data.permissions], PERMISSION_EXEC
472
 
2609 hidnplayr 473
2598 hidnplayr 474
        call    open_datasock
475
 
2892 hidnplayr 476
; Create fpath from home_dir and work_dir
2610 hidnplayr 477
 
2563 hidnplayr 478
479
        lea     ebx, [ebp + thread_data.fpath]
480
 
2609 hidnplayr 481
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 482
483
; Start the search
2571 hidnplayr 484
 
2563 hidnplayr 485
        test    eax, eax
2945 hidnplayr 486
        jz      .nosuchdir
2578 hidnplayr 487
488
        lea     edi, [ebp + thread_data.buffer]
489
 
2609 hidnplayr 490
        test    eax, eax        ; did we find a file?
2562 hidnplayr 491
        jz      .done
2563 hidnplayr 492
        mov     ebx, eax        ; yes, save the descripter in ebx
2562 hidnplayr 493
2578 hidnplayr 494
; first, convert the attributes
2562 hidnplayr 495
 
496
        jnz     .folder
2578 hidnplayr 497
2562 hidnplayr 498
        test    [ebx + FileInfoA.Attributes], FA_READONLY
499
 
2578 hidnplayr 500
2562 hidnplayr 501
        mov     eax, '-rw-'
502
 
503
        jmp     .attr
504
505
  .folder:
506
 
507
        stosd
508
        jmp     .attr
2563 hidnplayr 509
2562 hidnplayr 510
  .readonly:
511
 
512
        stosd
513
514
  .attr:
515
 
516
        stosd
517
        mov     ax, 'w-'
518
        stosw
519
        mov     al, ' '
520
        stosb
521
522
; now..
523
 
524
        stosw
525
526
; now write owner, everything is owned by FTP, woohoo!
527
 
528
        stosd
529
        stosd
530
531
; now the filesize in ascii
532
 
533
        call    dword_to_ascii
2578 hidnplayr 534
        mov     al, ' '
2562 hidnplayr 535
        stosb
536
537
; then date (month/day/year)
538
 
539
        cmp     eax, 12
2578 hidnplayr 540
        ja      @f
2602 hidnplayr 541
        mov     eax, [months - 4 + 4*eax]
542
        stosd
543
       @@:
2562 hidnplayr 544
2602 hidnplayr 545
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.day]
2562 hidnplayr 546
 
2578 hidnplayr 547
        mov     al, ' '
2562 hidnplayr 548
        stosb
549
550
        movzx   eax, [ebx + FileInfoA.DateModify + FileDateTime.year]
551
 
2578 hidnplayr 552
        mov     al, ' '
2562 hidnplayr 553
        stosb
554
555
; and last but not least, filename
556
 
557
        mov     ecx, 264
2578 hidnplayr 558
  .nameloop:
559
        lodsb
2562 hidnplayr 560
        test    al, al
561
        jz      .namedone
562
        stosb
563
        loop    .nameloop
564
565
; insert a cr lf
566
 
2563 hidnplayr 567
        mov     ax, 0x0a0d
2562 hidnplayr 568
        stosw
2571 hidnplayr 569
2562 hidnplayr 570
        test    [ebp + thread_data.permissions], ABORT          ; Did we receive ABOR command from client?
571
 
2609 hidnplayr 572
2945 hidnplayr 573
; check next file
2598 hidnplayr 574
 
2563 hidnplayr 575
        jmp     .parse_file
2609 hidnplayr 576
577
; close file desc
2563 hidnplayr 578
 
579
        invoke  file.find.close, ebx                            ; ebx is descriptor of last file, eax will be -1 !!
2562 hidnplayr 580
2624 hidnplayr 581
; append the string with a 0
2562 hidnplayr 582
 
2563 hidnplayr 583
        stosb
2562 hidnplayr 584
585
; Warn the client we're about to send the data
586
 
2571 hidnplayr 587
        sendFTP "150 Here it comes.."
2598 hidnplayr 588
        pop     esi
589
590
; and send it to the client
2562 hidnplayr 591
 
2563 hidnplayr 592
        lea     edx, [ebp + thread_data.buffer]                 ; buffer ptr
2624 hidnplayr 593
        sub     esi, edx                                        ; length
594
        xor     edi, edi                                        ; flags
595
        mcall   send
596
2578 hidnplayr 597
; close the data socket..
2562 hidnplayr 598
 
2563 hidnplayr 599
        mcall   close, [ebp + thread_data.datasocketnum]
2609 hidnplayr 600
601
        sendFTP "226 Transfer OK"
2562 hidnplayr 602
 
2598 hidnplayr 603
2554 hidnplayr 604
  .nosuchdir:
605
 
2578 hidnplayr 606
        ret
2598 hidnplayr 607
2578 hidnplayr 608
;------------------------------------------------
609
 
2598 hidnplayr 610
;
611
; List the filenames of the files in the current working directory.
612
;
613
;------------------------------------------------
614
align 4
615
cmdNLST:
2554 hidnplayr 616
617
        test    [ebp + thread_data.permissions], PERMISSION_EXEC
618
 
2609 hidnplayr 619
2598 hidnplayr 620
        ; TODO: same as list but simpler output format
621
 
2578 hidnplayr 622
        ret
623
 
2554 hidnplayr 624
;------------------------------------------------
625
 
2598 hidnplayr 626
;
627
; No operation, just keep the connection alive.
628
;
629
;------------------------------------------------
630
align 4
631
cmdNOOP:
2554 hidnplayr 632
633
        sendFTP "200 Command OK"
634
 
2602 hidnplayr 635
2554 hidnplayr 636
;------------------------------------------------
637
 
2598 hidnplayr 638
;
639
; Second phase of login process, client provides password.
640
;
641
;------------------------------------------------
642
align 4
643
cmdPASS:
2554 hidnplayr 644
2557 hidnplayr 645
; read the password from users.ini
2602 hidnplayr 646
 
647
        lea     ebx, [ebp + thread_data.fpath]                  ; temp username
2609 hidnplayr 648
        invoke  ini.get_str, path2, ebx, str_pass, edi, 512, str_infinity
649
        test    eax, eax                                        ; unable to read password? fail!
2602 hidnplayr 650
        jnz     .incorrect
2610 hidnplayr 651
        cmp     dword [edi], -1                                 ; no key, section or file found.. fail!
2598 hidnplayr 652
        je      .incorrect
2610 hidnplayr 653
        cmp     byte [edi], 0                                   ; zero password? ok!
2602 hidnplayr 654
        je      .ok
2958 hidnplayr 655
656
        add     esi, 5
2557 hidnplayr 657
 
2610 hidnplayr 658
        jbe     .incorrect                                      ; no password given? but hey, we need one! fail..
659
660
; compare with received password
661
 
2602 hidnplayr 662
        cmp     byte [esi-1], 0x20                              ; printeable characters left?
2598 hidnplayr 663
        jae     .incorrect
2610 hidnplayr 664
        cmp     byte [edi-1], 0
2598 hidnplayr 665
        jne     .incorrect
2610 hidnplayr 666
2598 hidnplayr 667
  .ok:
668
 
2610 hidnplayr 669
        mov     [ebp + thread_data.permissions], eax
2602 hidnplayr 670
2609 hidnplayr 671
        invoke  con_write_asciiz, str_pass_ok
2598 hidnplayr 672
 
2602 hidnplayr 673
        sendFTP "230 You are now logged in"
2609 hidnplayr 674
        ret
2598 hidnplayr 675
676
  .2:
2557 hidnplayr 677
 
2598 hidnplayr 678
        invoke  con_write_asciiz, str_pass_err
679
        mov     [ebp + thread_data.state], STATE_CONNECTED      ; reset state
2610 hidnplayr 680
        sendFTP "530 Login incorrect"
681
        ret
2598 hidnplayr 682
2557 hidnplayr 683
  .0:
684
 
2598 hidnplayr 685
        ret
686
687
  .3:
688
 
689
        ret
690
691
;------------------------------------------------
692
 
693
;
694
; Initiate a passive dataconnection.
695
;
696
;------------------------------------------------
697
align 4
698
cmdPASV:
699
2560 hidnplayr 700
;        cmp     [ebp + thread_data.passivesocknum], -1
701
 
2892 hidnplayr 702
;        mcall   close, [ebp + thread_data.passivesocknum]       ; if there is still a socket open, close it
703
;       @@:
704
705
; Open a new TCP socket
2610 hidnplayr 706
 
2578 hidnplayr 707
        cmp     eax, -1
2562 hidnplayr 708
        je      socketerror
709
        mov     [ebp + thread_data.passivesocknum], eax
2578 hidnplayr 710
2609 hidnplayr 711
; Bind it to a known local port
2562 hidnplayr 712
 
2578 hidnplayr 713
        mov     [ebp + thread_data.datasock.sin_addr], 0
2609 hidnplayr 714
715
        mov     ecx, eax                                        ; passivesocketnum
2562 hidnplayr 716
 
2598 hidnplayr 717
        mov     esi, sizeof.thread_data.datasock
2609 hidnplayr 718
2581 hidnplayr 719
  .next_port:                                                   ; TODO: break the endless loop
2610 hidnplayr 720
 
721
        pushw   [pasv_port]
722
        popw    [ebp + thread_data.datasock.sin_port]
723
724
        mcall   bind
725
 
2581 hidnplayr 726
        je      .next_port
2562 hidnplayr 727
2610 hidnplayr 728
; And set it to listen!
2562 hidnplayr 729
 
2578 hidnplayr 730
        cmp     eax, -1
2598 hidnplayr 731
        je      socketerror
732
2610 hidnplayr 733
; Tell our thread we are ready to accept incoming calls
2562 hidnplayr 734
 
2578 hidnplayr 735
2609 hidnplayr 736
; Now tell the client where to connect to in this format:
2562 hidnplayr 737
 
2578 hidnplayr 738
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
739
740
; '227 ('
2598 hidnplayr 741
 
742
        mov     eax, '227 '
2609 hidnplayr 743
        stosd
2610 hidnplayr 744
        mov     al, '('
2562 hidnplayr 745
        stosb
2598 hidnplayr 746
; ip
2562 hidnplayr 747
        movzx   eax, byte [serverip]
2598 hidnplayr 748
        call    dword_to_ascii
2610 hidnplayr 749
        mov     al, ','
2598 hidnplayr 750
        stosb
751
        movzx   eax, byte [serverip+1]
2562 hidnplayr 752
        call    dword_to_ascii
2610 hidnplayr 753
        mov     al, ','
2598 hidnplayr 754
        stosb
755
        movzx   eax, byte [serverip+2]
756
        call    dword_to_ascii
2610 hidnplayr 757
        mov     al, ','
2598 hidnplayr 758
        stosb
759
        movzx   eax, byte [serverip+3]
760
        call    dword_to_ascii
2610 hidnplayr 761
        mov     al, ','
2598 hidnplayr 762
        stosb
763
; port
764
        movzx   eax, byte [ebp + thread_data.datasock.sin_port]
765
        call    dword_to_ascii
2995 hidnplayr 766
        mov     al, ','
2598 hidnplayr 767
        stosb
768
        movzx   eax, byte [ebp + thread_data.datasock.sin_port+1]
769
        call    dword_to_ascii
2995 hidnplayr 770
; ')', 13, 10, 0
2598 hidnplayr 771
        mov     eax, ')' + 0x000a0d00
772
        stosd
773
774
        lea     esi, [edi - thread_data.buffer]
2562 hidnplayr 775
 
2578 hidnplayr 776
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 777
        lea     edx, [ebp + thread_data.buffer]
778
        xor     edi, edi
779
        mcall   send
2602 hidnplayr 780
2581 hidnplayr 781
        ret
2562 hidnplayr 782
 
2560 hidnplayr 783
;------------------------------------------------
784
 
2598 hidnplayr 785
;
786
; Print the current working directory.
787
;
788
;------------------------------------------------
789
align 4
790
cmdPWD:
2560 hidnplayr 791
2598 hidnplayr 792
        mov     dword [ebp + thread_data.buffer], '257 '
2554 hidnplayr 793
 
2609 hidnplayr 794
795
        lea     edi, [ebp + thread_data.buffer+5]
2560 hidnplayr 796
 
2609 hidnplayr 797
        mov     ecx, 1024
798
  .loop:
2560 hidnplayr 799
        lodsb
800
        or      al, al
801
        jz      .ok
802
        stosb
803
        dec     ecx
804
        jnz     .loop
805
806
  .ok:
807
 
808
        lea     esi, [edi - thread_data.buffer + 4]
2578 hidnplayr 809
        sub     esi, ebp
810
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 811
        lea     edx, [ebp + thread_data.buffer]
812
        xor     edi, edi
813
        mcall   send
2585 hidnplayr 814
815
; Print the new working dir on the console
2560 hidnplayr 816
 
2585 hidnplayr 817
        invoke  con_write_asciiz, eax
2609 hidnplayr 818
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 819
820
        ret
2562 hidnplayr 821
 
2554 hidnplayr 822
;------------------------------------------------
823
 
2598 hidnplayr 824
;
825
; Initiate an active dataconnection.
826
;
827
;------------------------------------------------
828
align 4
829
cmdPORT:
2554 hidnplayr 830
831
; PORT a1,a2,a3,a4,p1,p2
832
 
2560 hidnplayr 833
834
; Convert the IP
835
 
2598 hidnplayr 836
        mov     cl, ','
2560 hidnplayr 837
        call    ip_to_dword
2598 hidnplayr 838
; And put it in datasock
839
        mov     [ebp + thread_data.datasock.sin_addr], ebx
2578 hidnplayr 840
2609 hidnplayr 841
; Now the same with portnumber
2560 hidnplayr 842
 
2578 hidnplayr 843
        call    ascii_to_byte
2602 hidnplayr 844
        mov     byte[ebp + thread_data.datasock.sin_port], al
2560 hidnplayr 845
        inc     esi
2995 hidnplayr 846
        call    ascii_to_byte
2560 hidnplayr 847
        mov     byte[ebp + thread_data.datasock.sin_port+1], al
848
2995 hidnplayr 849
; We will open the socket, but do not connect yet!
2560 hidnplayr 850
 
2578 hidnplayr 851
        mcall   socket, AF_INET4, SOCK_STREAM, 0
2609 hidnplayr 852
        cmp     eax, -1
2562 hidnplayr 853
        je      socketerror
2560 hidnplayr 854
2578 hidnplayr 855
        mov     [ebp + thread_data.datasocketnum], eax
2598 hidnplayr 856
 
2609 hidnplayr 857
858
        sendFTP "225 Data connection open"
2560 hidnplayr 859
 
2598 hidnplayr 860
2554 hidnplayr 861
;------------------------------------------------
862
 
2598 hidnplayr 863
;
864
; Close the connection with client.
865
;
866
;------------------------------------------------
867
align 4
868
cmdQUIT:
2554 hidnplayr 869
870
        sendFTP "221 Bye!"
871
 
2602 hidnplayr 872
        mcall   close, [ebp + thread_data.socketnum]
2609 hidnplayr 873
874
        add     esp, 4          ; get rid of call return address
2598 hidnplayr 875
 
2581 hidnplayr 876
877
2554 hidnplayr 878
 
2598 hidnplayr 879
 
880
;
881
; Retrieve a file from the ftp server.
882
;
883
;------------------------------------------------
884
align 4
885
cmdRETR:
2554 hidnplayr 886
887
        test    [ebp + thread_data.permissions], PERMISSION_READ
888
 
2609 hidnplayr 889
2598 hidnplayr 890
        cmp     ecx, 1024 + 5
891
 
2602 hidnplayr 892
893
        sub     ecx, 5
894
 
2571 hidnplayr 895
896
        call    open_datasock
897
 
2892 hidnplayr 898
        call    create_path
2610 hidnplayr 899
 
2571 hidnplayr 900
        lea     esi, [ebp + thread_data.buffer + 5]
901
        mov     ecx, 1024
2892 hidnplayr 902
        cmp     byte [esi], '/'
2610 hidnplayr 903
        jne     .loop
2958 hidnplayr 904
        inc     esi
905
  .loop:
906
        lodsb
2571 hidnplayr 907
        cmp     al, 0x20
908
        jl      .done
909
        stosb
910
        loop    .loop
911
  .done:
912
        xor     al, al
913
        stosb
914
915
        lea     ebx, [ebp + thread_data.fpath]
2563 hidnplayr 916
 
2609 hidnplayr 917
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 918
919
        invoke  file.open, ebx, O_READ
2571 hidnplayr 920
 
2602 hidnplayr 921
        jz      .cannot_open
2571 hidnplayr 922
923
        push    eax
2563 hidnplayr 924
 
2602 hidnplayr 925
        pop     ebx
2598 hidnplayr 926
2571 hidnplayr 927
  .read_more:
2563 hidnplayr 928
 
929
        jnz     abort_transfer
2609 hidnplayr 930
2598 hidnplayr 931
        lea     eax, [ebp + thread_data.buffer]                 ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
932
 
2609 hidnplayr 933
        cmp     eax, -1
2602 hidnplayr 934
        je      .cannot_open                                    ; FIXME: this is not the correct error
2571 hidnplayr 935
2602 hidnplayr 936
        invoke  con_write_asciiz, str2
2562 hidnplayr 937
 
2892 hidnplayr 938
        push    eax ebx
939
 
2598 hidnplayr 940
        mov     ecx, [ebp + thread_data.datasocketnum]
2563 hidnplayr 941
        lea     edx, [ebp + thread_data.buffer]
2609 hidnplayr 942
        xor     edi, edi
943
        mcall   send
944
        pop     ebx ecx
2581 hidnplayr 945
        cmp     eax, -1
2598 hidnplayr 946
        je      socketerror                                     ; FIXME: not the correct error
2571 hidnplayr 947
2609 hidnplayr 948
;        cmp     eax, ecx
2563 hidnplayr 949
 
2602 hidnplayr 950
951
        cmp     ecx, BUFFERSIZE
952
 
2563 hidnplayr 953
954
        invoke  file.close, ebx
955
 
2602 hidnplayr 956
        invoke  con_write_asciiz, str2b
957
 
2892 hidnplayr 958
        mov     [ebp + thread_data.mode], MODE_NOTREADY
959
 
2609 hidnplayr 960
961
        sendFTP "226 Transfer OK, closing connection"
2563 hidnplayr 962
 
2598 hidnplayr 963
2554 hidnplayr 964
  .cannot_open:
965
 
2571 hidnplayr 966
        invoke  con_write_asciiz, str_notfound
2602 hidnplayr 967
        invoke  con_set_flags, 0x07
968
969
        sendFTP "550 No such file"
2571 hidnplayr 970
 
2598 hidnplayr 971
2571 hidnplayr 972
973
 
2598 hidnplayr 974
 
975
 
976
;
977
; Store a file on the server.
978
;
979
;------------------------------------------------
980
align 4
981
cmdSTOR:
2554 hidnplayr 982
983
        test    [ebp + thread_data.permissions], PERMISSION_WRITE
984
 
2609 hidnplayr 985
2598 hidnplayr 986
2578 hidnplayr 987
 
2598 hidnplayr 988
 
989
        jnz     abort_transfer
2609 hidnplayr 990
2598 hidnplayr 991
;;;;
992
 
993
        ret
994
 
2554 hidnplayr 995
;------------------------------------------------
996
 
2598 hidnplayr 997
;
998
; Send information about the system.
999
;
1000
;------------------------------------------------
1001
align 4
1002
cmdSYST:
2554 hidnplayr 1003
1004
        sendFTP "215 UNIX type: L8"
1005
 
2598 hidnplayr 1006
2554 hidnplayr 1007
;------------------------------------------------
1008
 
2598 hidnplayr 1009
;
1010
; Choose the file transfer type.
1011
;
1012
;------------------------------------------------
1013
align 4
1014
cmdTYPE:
2554 hidnplayr 1015
1016
        cmp     ecx, 6
1017
 
2560 hidnplayr 1018
1019
        mov     al, byte[esi+5]
1020
 
1021
1022
        cmp     al, 'A'
1023
 
1024
        cmp     al, 'E'
1025
        je      .ebdic
1026
        cmp     al, 'I'
1027
        je      .image
1028
        cmp     al, 'L'
1029
        je      .local
1030
1031
        jmp     parse_cmd.error
1032
 
1033
  .ascii:
1034
 
1035
        jmp     .subtype
2609 hidnplayr 1036
2560 hidnplayr 1037
  .ebdic:
1038
 
1039
2609 hidnplayr 1040
  .subtype:
2560 hidnplayr 1041
 
1042
        jb      .non_print
1043
1044
        mov     al, byte[esi+7]
1045
 
1046
1047
        cmp     al, 'N'
1048
 
1049
        cmp     al, 'T'
1050
        je      .telnet
1051
        cmp     al, 'C'
1052
        je      .asacc
1053
        cmp     al, 0x20
1054
        jb      .non_print
2878 hidnplayr 1055
1056
        jmp     parse_cmd.error
2560 hidnplayr 1057
 
1058
  .non_print:
1059
 
1060
        jmp     .ok
2609 hidnplayr 1061
2560 hidnplayr 1062
  .telnet:
1063
 
1064
        jmp     .ok
2609 hidnplayr 1065
2560 hidnplayr 1066
  .asacc:
1067
 
1068
        jmp     .ok
2609 hidnplayr 1069
2560 hidnplayr 1070
  .image:
1071
 
1072
        jmp     .ok
2609 hidnplayr 1073
2560 hidnplayr 1074
  .local:
1075
 
1076
        jb      parse_cmd.error
1077
1078
        mov     al, byte[esi+7]
1079
 
1080
        jb      parse_cmd.error                         ; FIXME: this is not the correct errormessage
1081
        cmp     al, 9
2602 hidnplayr 1082
        ja      parse_cmd.error                         ; FIXME
2560 hidnplayr 1083
        or      al, TYPE_LOCAL
2602 hidnplayr 1084
        mov     [ebp + thread_data.type], al
2560 hidnplayr 1085
2609 hidnplayr 1086
  .ok:
2560 hidnplayr 1087
 
1088
        ret
2598 hidnplayr 1089
2554 hidnplayr 1090
;------------------------------------------------
1091
 
2598 hidnplayr 1092
;
1093
; Login to the server, step one of two.                         ;;; TODO: prevent buffer overflow!
1094
;
2602 hidnplayr 1095
;------------------------------------------------
2598 hidnplayr 1096
align 4
1097
cmdUSER:
2554 hidnplayr 1098
1099
        lea     esi, [esi + 5]
1100
 
2598 hidnplayr 1101
  .loop:
2609 hidnplayr 1102
        lodsb
2602 hidnplayr 1103
        stosb
2563 hidnplayr 1104
        cmp     al, 0x20
1105
        jae     .loop
2598 hidnplayr 1106
        mov     byte [edi-1], 0
1107
1108
        lea     esi, [ebp + thread_data.fpath]
2562 hidnplayr 1109
 
2609 hidnplayr 1110
        invoke  ini.get_str, path2, esi, str_home, eax, 1024, str_infinity
1111
        cmp     eax, -1
2602 hidnplayr 1112
        je      .login_fail
2598 hidnplayr 1113
        cmp     dword [esi], -1
1114
        je      .login_fail
2602 hidnplayr 1115
1116
        mov     word [ebp + thread_data.work_dir], "/"          ; "/", 0
2562 hidnplayr 1117
 
2609 hidnplayr 1118
        invoke  con_write_asciiz, str_logged_in
2563 hidnplayr 1119
 
2602 hidnplayr 1120
  .sendstr:
2609 hidnplayr 1121
        sendFTP "331 Please specify the password"
2598 hidnplayr 1122
        ret
1123
2563 hidnplayr 1124
  .login_fail:
1125
 
2598 hidnplayr 1126
        mov     [ebp + thread_data.state], STATE_LOGIN_FAIL
2610 hidnplayr 1127
        jmp     .sendstr
2609 hidnplayr 1128
2598 hidnplayr 1129
align 4
2571 hidnplayr 1130
 
2598 hidnplayr 1131
        sendFTP "530 Can't change to another user"
1132
        ret
1133