Subversion Repositories Kolibri OS

Rev

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