Subversion Repositories Kolibri OS

Rev

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