Subversion Repositories Kolibri OS

Rev

Rev 2995 | 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
        mov     ax, [pasv_port]
722
        xchg    al, ah
3144 hidnplayr 723
        mov     [ebp + thread_data.datasock.sin_port], ax
724
725
        mcall   bind
2610 hidnplayr 726
 
2581 hidnplayr 727
        je      .next_port
2562 hidnplayr 728
2610 hidnplayr 729
; And set it to listen!
2562 hidnplayr 730
 
2578 hidnplayr 731
        cmp     eax, -1
2598 hidnplayr 732
        je      socketerror
733
2610 hidnplayr 734
; Tell our thread we are ready to accept incoming calls
2562 hidnplayr 735
 
2578 hidnplayr 736
2609 hidnplayr 737
; Now tell the client where to connect to in this format:
2562 hidnplayr 738
 
2578 hidnplayr 739
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
740
741
; '227 ('
2598 hidnplayr 742
 
743
        mov     eax, '227 '
2609 hidnplayr 744
        stosd
2610 hidnplayr 745
        mov     al, '('
2562 hidnplayr 746
        stosb
2598 hidnplayr 747
; ip
2562 hidnplayr 748
        movzx   eax, byte [serverip]
2598 hidnplayr 749
        call    dword_to_ascii
2610 hidnplayr 750
        mov     al, ','
2598 hidnplayr 751
        stosb
752
        movzx   eax, byte [serverip+1]
2562 hidnplayr 753
        call    dword_to_ascii
2610 hidnplayr 754
        mov     al, ','
2598 hidnplayr 755
        stosb
756
        movzx   eax, byte [serverip+2]
757
        call    dword_to_ascii
2610 hidnplayr 758
        mov     al, ','
2598 hidnplayr 759
        stosb
760
        movzx   eax, byte [serverip+3]
761
        call    dword_to_ascii
2610 hidnplayr 762
        mov     al, ','
2598 hidnplayr 763
        stosb
764
; port
765
        movzx   eax, byte [ebp + thread_data.datasock.sin_port]
766
        call    dword_to_ascii
2995 hidnplayr 767
        mov     al, ','
2598 hidnplayr 768
        stosb
769
        movzx   eax, byte [ebp + thread_data.datasock.sin_port+1]
770
        call    dword_to_ascii
2995 hidnplayr 771
; ')', 13, 10, 0
2598 hidnplayr 772
        mov     eax, ')' + 0x000a0d00
773
        stosd
774
775
        lea     esi, [edi - thread_data.buffer]
2562 hidnplayr 776
 
2578 hidnplayr 777
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 778
        lea     edx, [ebp + thread_data.buffer]
779
        xor     edi, edi
780
        mcall   send
2602 hidnplayr 781
2581 hidnplayr 782
        ret
2562 hidnplayr 783
 
2560 hidnplayr 784
;------------------------------------------------
785
 
2598 hidnplayr 786
;
787
; Print the current working directory.
788
;
789
;------------------------------------------------
790
align 4
791
cmdPWD:
2560 hidnplayr 792
2598 hidnplayr 793
        mov     dword [ebp + thread_data.buffer], '257 '
2554 hidnplayr 794
 
2609 hidnplayr 795
796
        lea     edi, [ebp + thread_data.buffer+5]
2560 hidnplayr 797
 
2609 hidnplayr 798
        mov     ecx, 1024
799
  .loop:
2560 hidnplayr 800
        lodsb
801
        or      al, al
802
        jz      .ok
803
        stosb
804
        dec     ecx
805
        jnz     .loop
806
807
  .ok:
808
 
809
        lea     esi, [edi - thread_data.buffer + 4]
2578 hidnplayr 810
        sub     esi, ebp
811
        mov     ecx, [ebp + thread_data.socketnum]
2609 hidnplayr 812
        lea     edx, [ebp + thread_data.buffer]
813
        xor     edi, edi
814
        mcall   send
2585 hidnplayr 815
816
; Print the new working dir on the console
2560 hidnplayr 817
 
2585 hidnplayr 818
        invoke  con_write_asciiz, eax
2609 hidnplayr 819
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 820
821
        ret
2562 hidnplayr 822
 
2554 hidnplayr 823
;------------------------------------------------
824
 
2598 hidnplayr 825
;
826
; Initiate an active dataconnection.
827
;
828
;------------------------------------------------
829
align 4
830
cmdPORT:
2554 hidnplayr 831
832
; PORT a1,a2,a3,a4,p1,p2
833
 
2560 hidnplayr 834
835
; Convert the IP
836
 
2598 hidnplayr 837
        mov     cl, ','
2560 hidnplayr 838
        call    ip_to_dword
2598 hidnplayr 839
; And put it in datasock
840
        mov     [ebp + thread_data.datasock.sin_addr], ebx
2578 hidnplayr 841
2609 hidnplayr 842
; Now the same with portnumber
2560 hidnplayr 843
 
2578 hidnplayr 844
        call    ascii_to_byte
2602 hidnplayr 845
        mov     byte[ebp + thread_data.datasock.sin_port], al
2560 hidnplayr 846
        inc     esi
2995 hidnplayr 847
        call    ascii_to_byte
2560 hidnplayr 848
        mov     byte[ebp + thread_data.datasock.sin_port+1], al
849
2995 hidnplayr 850
; We will open the socket, but do not connect yet!
2560 hidnplayr 851
 
2578 hidnplayr 852
        mcall   socket, AF_INET4, SOCK_STREAM, 0
2609 hidnplayr 853
        cmp     eax, -1
2562 hidnplayr 854
        je      socketerror
2560 hidnplayr 855
2578 hidnplayr 856
        mov     [ebp + thread_data.datasocketnum], eax
2598 hidnplayr 857
 
2609 hidnplayr 858
859
        sendFTP "225 Data connection open"
2560 hidnplayr 860
 
2598 hidnplayr 861
2554 hidnplayr 862
;------------------------------------------------
863
 
2598 hidnplayr 864
;
865
; Close the connection with client.
866
;
867
;------------------------------------------------
868
align 4
869
cmdQUIT:
2554 hidnplayr 870
871
        sendFTP "221 Bye!"
872
 
2602 hidnplayr 873
        mcall   close, [ebp + thread_data.socketnum]
2609 hidnplayr 874
875
        add     esp, 4          ; get rid of call return address
2598 hidnplayr 876
 
2581 hidnplayr 877
878
2554 hidnplayr 879
 
2598 hidnplayr 880
 
881
;
882
; Retrieve a file from the ftp server.
883
;
884
;------------------------------------------------
885
align 4
886
cmdRETR:
2554 hidnplayr 887
888
        test    [ebp + thread_data.permissions], PERMISSION_READ
889
 
2609 hidnplayr 890
2598 hidnplayr 891
        cmp     ecx, 1024 + 5
892
 
2602 hidnplayr 893
894
        sub     ecx, 5
895
 
2571 hidnplayr 896
897
        call    open_datasock
898
 
2892 hidnplayr 899
        call    create_path
2610 hidnplayr 900
 
2571 hidnplayr 901
        lea     esi, [ebp + thread_data.buffer + 5]
902
        mov     ecx, 1024
2892 hidnplayr 903
        cmp     byte [esi], '/'
2610 hidnplayr 904
        jne     .loop
2958 hidnplayr 905
        inc     esi
906
  .loop:
907
        lodsb
2571 hidnplayr 908
        cmp     al, 0x20
909
        jl      .done
910
        stosb
911
        loop    .loop
912
  .done:
913
        xor     al, al
914
        stosb
915
916
        lea     ebx, [ebp + thread_data.fpath]
2563 hidnplayr 917
 
2609 hidnplayr 918
        invoke  con_write_asciiz, str_newline
2602 hidnplayr 919
920
        invoke  file.open, ebx, O_READ
2571 hidnplayr 921
 
2602 hidnplayr 922
        jz      .cannot_open
2571 hidnplayr 923
924
        push    eax
2563 hidnplayr 925
 
2602 hidnplayr 926
        pop     ebx
2598 hidnplayr 927
2571 hidnplayr 928
  .read_more:
2563 hidnplayr 929
 
930
        jnz     abort_transfer
2609 hidnplayr 931
2598 hidnplayr 932
        lea     eax, [ebp + thread_data.buffer]                 ; FIXME: use another buffer!! if we receive something on control connection now, we screw up!
933
 
2609 hidnplayr 934
        cmp     eax, -1
2602 hidnplayr 935
        je      .cannot_open                                    ; FIXME: this is not the correct error
2571 hidnplayr 936
2602 hidnplayr 937
        invoke  con_write_asciiz, str2
2562 hidnplayr 938
 
2892 hidnplayr 939
        push    eax ebx
940
 
2598 hidnplayr 941
        mov     ecx, [ebp + thread_data.datasocketnum]
2563 hidnplayr 942
        lea     edx, [ebp + thread_data.buffer]
2609 hidnplayr 943
        xor     edi, edi
944
        mcall   send
945
        pop     ebx ecx
2581 hidnplayr 946
        cmp     eax, -1
2598 hidnplayr 947
        je      socketerror                                     ; FIXME: not the correct error
2571 hidnplayr 948
2609 hidnplayr 949
;        cmp     eax, ecx
2563 hidnplayr 950
 
2602 hidnplayr 951
952
        cmp     ecx, BUFFERSIZE
953
 
2563 hidnplayr 954
955
        invoke  file.close, ebx
956
 
2602 hidnplayr 957
        invoke  con_write_asciiz, str2b
958
 
2892 hidnplayr 959
        mov     [ebp + thread_data.mode], MODE_NOTREADY
960
 
2609 hidnplayr 961
962
        sendFTP "226 Transfer OK, closing connection"
2563 hidnplayr 963
 
2598 hidnplayr 964
2554 hidnplayr 965
  .cannot_open:
966
 
2571 hidnplayr 967
        invoke  con_write_asciiz, str_notfound
2602 hidnplayr 968
        invoke  con_set_flags, 0x07
969
970
        sendFTP "550 No such file"
2571 hidnplayr 971
 
2598 hidnplayr 972
2571 hidnplayr 973
974
 
2598 hidnplayr 975
 
976
 
977
;
978
; Store a file on the server.
979
;
980
;------------------------------------------------
981
align 4
982
cmdSTOR:
2554 hidnplayr 983
984
        test    [ebp + thread_data.permissions], PERMISSION_WRITE
985
 
2609 hidnplayr 986
2598 hidnplayr 987
2578 hidnplayr 988
 
2598 hidnplayr 989
 
990
        jnz     abort_transfer
2609 hidnplayr 991
2598 hidnplayr 992
;;;;
993
 
994
        ret
995
 
2554 hidnplayr 996
;------------------------------------------------
997
 
2598 hidnplayr 998
;
999
; Send information about the system.
1000
;
1001
;------------------------------------------------
1002
align 4
1003
cmdSYST:
2554 hidnplayr 1004
1005
        sendFTP "215 UNIX type: L8"
1006
 
2598 hidnplayr 1007
2554 hidnplayr 1008
;------------------------------------------------
1009
 
2598 hidnplayr 1010
;
1011
; Choose the file transfer type.
1012
;
1013
;------------------------------------------------
1014
align 4
1015
cmdTYPE:
2554 hidnplayr 1016
1017
        cmp     ecx, 6
1018
 
2560 hidnplayr 1019
1020
        mov     al, byte[esi+5]
1021
 
1022
1023
        cmp     al, 'A'
1024
 
1025
        cmp     al, 'E'
1026
        je      .ebdic
1027
        cmp     al, 'I'
1028
        je      .image
1029
        cmp     al, 'L'
1030
        je      .local
1031
1032
        jmp     parse_cmd.error
1033
 
1034
  .ascii:
1035
 
1036
        jmp     .subtype
2609 hidnplayr 1037
2560 hidnplayr 1038
  .ebdic:
1039
 
1040
2609 hidnplayr 1041
  .subtype:
2560 hidnplayr 1042
 
1043
        jb      .non_print
1044
1045
        mov     al, byte[esi+7]
1046
 
1047
1048
        cmp     al, 'N'
1049
 
1050
        cmp     al, 'T'
1051
        je      .telnet
1052
        cmp     al, 'C'
1053
        je      .asacc
1054
        cmp     al, 0x20
1055
        jb      .non_print
2878 hidnplayr 1056
1057
        jmp     parse_cmd.error
2560 hidnplayr 1058
 
1059
  .non_print:
1060
 
1061
        jmp     .ok
2609 hidnplayr 1062
2560 hidnplayr 1063
  .telnet:
1064
 
1065
        jmp     .ok
2609 hidnplayr 1066
2560 hidnplayr 1067
  .asacc:
1068
 
1069
        jmp     .ok
2609 hidnplayr 1070
2560 hidnplayr 1071
  .image:
1072
 
1073
        jmp     .ok
2609 hidnplayr 1074
2560 hidnplayr 1075
  .local:
1076
 
1077
        jb      parse_cmd.error
1078
1079
        mov     al, byte[esi+7]
1080
 
1081
        jb      parse_cmd.error                         ; FIXME: this is not the correct errormessage
1082
        cmp     al, 9
2602 hidnplayr 1083
        ja      parse_cmd.error                         ; FIXME
2560 hidnplayr 1084
        or      al, TYPE_LOCAL
2602 hidnplayr 1085
        mov     [ebp + thread_data.type], al
2560 hidnplayr 1086
2609 hidnplayr 1087
  .ok:
2560 hidnplayr 1088
 
1089
        ret
2598 hidnplayr 1090
2554 hidnplayr 1091
;------------------------------------------------
1092
 
2598 hidnplayr 1093
;
1094
; Login to the server, step one of two.                         ;;; TODO: prevent buffer overflow!
1095
;
2602 hidnplayr 1096
;------------------------------------------------
2598 hidnplayr 1097
align 4
1098
cmdUSER:
2554 hidnplayr 1099
1100
        lea     esi, [esi + 5]
1101
 
2598 hidnplayr 1102
  .loop:
2609 hidnplayr 1103
        lodsb
2602 hidnplayr 1104
        stosb
2563 hidnplayr 1105
        cmp     al, 0x20
1106
        jae     .loop
2598 hidnplayr 1107
        mov     byte [edi-1], 0
1108
1109
        lea     esi, [ebp + thread_data.fpath]
2562 hidnplayr 1110
 
2609 hidnplayr 1111
        invoke  ini.get_str, path2, esi, str_home, eax, 1024, str_infinity
1112
        cmp     eax, -1
2602 hidnplayr 1113
        je      .login_fail
2598 hidnplayr 1114
        cmp     dword [esi], -1
1115
        je      .login_fail
2602 hidnplayr 1116
1117
        mov     word [ebp + thread_data.work_dir], "/"          ; "/", 0
2562 hidnplayr 1118
 
2609 hidnplayr 1119
        invoke  con_write_asciiz, str_logged_in
2563 hidnplayr 1120
 
2602 hidnplayr 1121
  .sendstr:
2609 hidnplayr 1122
        sendFTP "331 Please specify the password"
2598 hidnplayr 1123
        ret
1124
2563 hidnplayr 1125
  .login_fail:
1126
 
2598 hidnplayr 1127
        mov     [ebp + thread_data.state], STATE_LOGIN_FAIL
2610 hidnplayr 1128
        jmp     .sendstr
2609 hidnplayr 1129
2598 hidnplayr 1130
align 4
2571 hidnplayr 1131
 
2598 hidnplayr 1132
        sendFTP "530 Can't change to another user"
1133
        ret
1134