Subversion Repositories Kolibri OS

Rev

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