Subversion Repositories Kolibri OS

Rev

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