Details | 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 |
8 | |||
9 | type db ? ; ASCII/EBDIC/IMAGE/.. |
||
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 | |||
16 | datasock sockaddr_in |
||
17 | |||
18 | buffer rb BUFFERSIZE |
||
19 | |||
20 | |||
21 | |||
22 | |||
23 | |||
24 | |||
25 | |||
2554 | hidnplayr | 26 | |
27 | cmp byte [esi], 0x20 ; skip all leading characters |
||
28 | |||
2578 | hidnplayr | 29 | inc esi |
30 | dec ecx |
||
31 | cmp ecx, 3 |
||
32 | ja parse_cmd |
||
33 | ret |
||
34 | .ok: |
||
35 | |||
36 | cmp byte [esi+3], 0x20 |
||
37 | |||
2557 | hidnplayr | 38 | mov byte [esi+3], 0 |
39 | @@: |
||
40 | |||
41 | mov eax, [esi] |
||
42 | |||
2554 | hidnplayr | 43 | mov edi, commands ; list of commands to scan |
44 | .scanloop: |
||
45 | cmp eax, [edi] |
||
46 | jne .try_next |
||
47 | |||
2557 | hidnplayr | 48 | jmp dword [edi+4] |
2554 | hidnplayr | 49 | |
50 | .try_next: |
||
51 | |||
52 | cmp byte [edi], 0 |
||
53 | jne .scanloop |
||
54 | |||
55 | .error: |
||
56 | |||
57 | |||
2578 | hidnplayr | 58 | ret |
2557 | hidnplayr | 59 | |
2554 | hidnplayr | 60 | |
61 | |||
62 | |||
63 | |||
2562 | hidnplayr | 64 | db 'ABOR' |
2554 | hidnplayr | 65 | |
66 | db 'CDUP' |
||
67 | dd cmdCDUP |
||
2571 | hidnplayr | 68 | db 'CWD', 0 |
69 | dd cmdCWD |
||
2554 | hidnplayr | 70 | db 'DELE' |
71 | dd cmdDELE |
||
72 | db 'LIST' |
||
73 | dd cmdLIST |
||
74 | db 'NLST' |
||
75 | dd cmdNLST |
||
76 | db 'NOOP' |
||
77 | dd cmdNOOP |
||
78 | db 'PASS' |
||
79 | dd cmdPASS |
||
2557 | hidnplayr | 80 | db 'PASV' |
81 | dd cmdPASV |
||
2562 | hidnplayr | 82 | db 'PWD', 0 |
83 | dd cmdPWD |
||
2563 | hidnplayr | 84 | db 'PORT' |
2554 | hidnplayr | 85 | dd cmdPORT |
86 | db 'QUIT' |
||
87 | dd cmdQUIT |
||
88 | db 'RETR' |
||
89 | dd cmdRETR |
||
90 | db 'STOR' |
||
91 | dd cmdSTOR |
||
92 | db 'SYST' |
||
93 | dd cmdSYST |
||
94 | db 'TYPE' |
||
95 | dd cmdTYPE |
||
96 | db 'USER' |
||
97 | dd cmdUSER |
||
98 | db 'XPWD' |
||
99 | dd cmdPWD |
||
100 | db 0 ; end marker |
||
101 | |||
2562 | hidnplayr | 102 | |
2554 | hidnplayr | 103 | |
104 | |||
105 | |||
106 | ; TODO: abort the current filetransfer |
||
107 | |||
2578 | hidnplayr | 108 | ret |
109 | |||
2554 | hidnplayr | 110 | align 4 |
111 | |||
112 | |||
2571 | hidnplayr | 113 | cmp byte [edx + thread_data.work_dir+1], 0 |
114 | |||
2578 | hidnplayr | 115 | |
2571 | hidnplayr | 116 | mov ecx, 1024 |
117 | |||
118 | lea edi, [edx + thread_data.work_dir+1024] |
||
119 | repne scasb |
||
2578 | hidnplayr | 120 | std |
2571 | hidnplayr | 121 | dec edi |
122 | mov al,'/' |
||
123 | scasb |
||
124 | cld |
||
125 | mov byte[edi], 0 |
||
126 | |||
127 | .done: |
||
128 | |||
129 | ret |
||
2578 | hidnplayr | 130 | |
2571 | hidnplayr | 131 | align 4 |
132 | |||
133 | |||
2563 | hidnplayr | 134 | sub ecx, 4 |
2554 | hidnplayr | 135 | |
2563 | hidnplayr | 136 | add esi, 4 |
137 | |||
138 | .scan: |
||
2571 | hidnplayr | 139 | |
140 | push ecx |
||
2578 | hidnplayr | 141 | mov ecx, 1024 |
142 | .find_zero: |
||
143 | cmp byte [edi], 0 |
||
144 | je .found_zero |
||
145 | inc edi |
||
146 | loop .find_zero |
||
147 | .found_zero: |
||
148 | pop ecx |
||
149 | .scan2: |
||
150 | |||
2581 | hidnplayr | 151 | cmp byte [esi], '/' |
2563 | hidnplayr | 152 | |
153 | inc esi |
||
154 | dec ecx |
||
155 | jz .done |
||
156 | @@: |
||
157 | |||
158 | .loop: |
||
159 | |||
160 | cmp al, 0x20 |
||
161 | jb .done |
||
162 | cmp al, '.' |
||
163 | je .up |
||
2571 | hidnplayr | 164 | .continue: |
165 | stosb |
||
166 | loop .loop |
||
2563 | hidnplayr | 167 | .done: |
168 | cmp byte [edi-1], '/' |
||
169 | je @f |
||
170 | mov byte [edi], '/' |
||
171 | inc edi |
||
172 | @@: |
||
173 | mov byte [edi], 0 |
||
174 | |||
175 | mcall send, [edx + thread_data.socketnum], str250, str250.length, 0 |
||
176 | |||
2578 | hidnplayr | 177 | ret |
2563 | hidnplayr | 178 | |
2554 | hidnplayr | 179 | .up: |
180 | |||
2571 | hidnplayr | 181 | cmp al, '.' |
182 | jne .continue |
||
183 | |||
184 | ;;;; TODO: find second last '\' in work_dir and make next char zero |
||
185 | |||
2581 | hidnplayr | 186 | |
187 | jmp .scan2 |
||
2571 | hidnplayr | 188 | |
2581 | hidnplayr | 189 | .err: |
190 | |||
2563 | hidnplayr | 191 | |
2578 | hidnplayr | 192 | ret |
2563 | hidnplayr | 193 | |
194 | align 4 |
||
195 | |||
2554 | hidnplayr | 196 | |
197 | ret |
||
198 | |||
199 | align 4 |
||
200 | |||
201 | |||
202 | ; If we are in active mode, it's time to open a data socket.. |
||
203 | |||
2563 | hidnplayr | 204 | jne @f |
2578 | hidnplayr | 205 | mov ecx, [edx + thread_data.datasocketnum] |
2562 | hidnplayr | 206 | lea edx, [edx + thread_data.datasock] |
2578 | hidnplayr | 207 | mov esi, sizeof.thread_data.datasock |
208 | mcall connect |
||
209 | mov edx, [esp+4] ; thread_data pointer |
||
210 | cmp eax, -1 |
||
211 | je socketerror |
||
2562 | hidnplayr | 212 | @@: |
2571 | hidnplayr | 213 | |
2562 | hidnplayr | 214 | ; Create fpath from home_dir and work_dir |
215 | |||
2563 | hidnplayr | 216 | |
217 | lea eax, [edx + thread_data.fpath] |
||
218 | |||
2578 | hidnplayr | 219 | call [con_write_asciiz] |
220 | push str_newline |
||
2571 | hidnplayr | 221 | call [con_write_asciiz] |
222 | |||
223 | ; Start the search |
||
224 | |||
2563 | hidnplayr | 225 | push str_mask |
2571 | hidnplayr | 226 | lea eax, [edx + thread_data.fpath] |
2562 | hidnplayr | 227 | push eax |
2578 | hidnplayr | 228 | call [file.find.first] |
229 | |||
2562 | hidnplayr | 230 | test eax, eax |
231 | |||
2578 | hidnplayr | 232 | |
233 | lea edi, [edx + thread_data.buffer] |
||
234 | |||
235 | |||
2562 | hidnplayr | 236 | test eax, eax ; did we find a file? |
2581 | hidnplayr | 237 | |
2563 | hidnplayr | 238 | mov ebx, eax ; yes, save the descripter in ebx |
2562 | hidnplayr | 239 | |
2578 | hidnplayr | 240 | ; first, convert the attributes |
2562 | hidnplayr | 241 | |
242 | jnz .folder |
||
2578 | hidnplayr | 243 | |
2562 | hidnplayr | 244 | test [ebx + FileInfoA.Attributes], FA_READONLY |
245 | |||
2578 | hidnplayr | 246 | |
2562 | hidnplayr | 247 | mov eax, '-rw-' |
248 | |||
249 | jmp .attr |
||
250 | |||
251 | .folder: |
||
252 | |||
253 | stosd |
||
254 | jmp .attr |
||
2563 | hidnplayr | 255 | |
2562 | hidnplayr | 256 | .readonly: |
257 | |||
258 | stosd |
||
259 | |||
260 | .attr: |
||
261 | |||
262 | stosd |
||
263 | mov ax, 'w-' |
||
264 | stosw |
||
265 | mov al, ' ' |
||
266 | stosb |
||
267 | |||
268 | ; now.. |
||
269 | |||
270 | stosw |
||
271 | |||
272 | ; now write owner, everything is owned by FTP, woohoo! |
||
273 | |||
274 | stosd |
||
275 | stosd |
||
276 | |||
277 | ; now the filesize in ascii |
||
278 | |||
279 | call dword_to_ascii |
||
2578 | hidnplayr | 280 | |
2562 | hidnplayr | 281 | mov al, ' ' |
282 | |||
283 | |||
284 | ; then date (month/day/year) |
||
285 | |||
286 | mov eax, [months + 4*eax] |
||
2578 | hidnplayr | 287 | stosd |
288 | |||
2562 | hidnplayr | 289 | movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.day] |
290 | |||
2578 | hidnplayr | 291 | |
2562 | hidnplayr | 292 | mov al, ' ' |
293 | |||
294 | |||
295 | movzx eax, [ebx + FileInfoA.DateModify + FileDateTime.year] |
||
296 | |||
2578 | hidnplayr | 297 | |
2562 | hidnplayr | 298 | mov al, ' ' |
299 | |||
300 | |||
301 | ; and last but not least, filename |
||
302 | |||
303 | mov ecx, 264 |
||
2578 | hidnplayr | 304 | .nameloop: |
305 | lodsb |
||
2562 | hidnplayr | 306 | test al, al |
307 | jz .namedone |
||
308 | stosb |
||
309 | loop .nameloop |
||
310 | |||
311 | ; insert a cr lf |
||
312 | |||
2563 | hidnplayr | 313 | mov ax, 0x0a0d |
2562 | hidnplayr | 314 | stosw |
2571 | hidnplayr | 315 | |
2562 | hidnplayr | 316 | ; check next file |
317 | |||
2563 | hidnplayr | 318 | call [file.find.next] |
2578 | hidnplayr | 319 | jmp .parse_file |
2563 | hidnplayr | 320 | |
321 | ; close file desc |
||
322 | |||
323 | push ebx |
||
2562 | hidnplayr | 324 | call [file.find.close] |
2578 | hidnplayr | 325 | |
2562 | hidnplayr | 326 | ; append the string with a 0 |
327 | |||
2563 | hidnplayr | 328 | stosb |
2562 | hidnplayr | 329 | |
330 | ; Warn the client we're about to send the data |
||
331 | |||
2571 | hidnplayr | 332 | mcall send, [edx + thread_data.socketnum], str150, str150.length, 0 ; here it comes.. |
2578 | hidnplayr | 333 | pop edx esi |
334 | |||
335 | ; and send it to the client |
||
2562 | hidnplayr | 336 | |
2563 | hidnplayr | 337 | lea edx, [edx + thread_data.buffer] |
2578 | hidnplayr | 338 | sub esi, edx |
339 | xor edi, edi |
||
340 | mcall send |
||
341 | |||
342 | ; close the data socket.. |
||
2562 | hidnplayr | 343 | |
2563 | hidnplayr | 344 | mcall close, [edx + thread_data.datasocketnum] |
2578 | hidnplayr | 345 | |
346 | cmp [edx + thread_data.mode], MODE_PASSIVE_OK |
||
2562 | hidnplayr | 347 | |
2578 | hidnplayr | 348 | mov [edx + thread_data.mode], MODE_NOTREADY |
2562 | hidnplayr | 349 | @@: |
2578 | hidnplayr | 350 | |
2562 | hidnplayr | 351 | ; And send "transfer ok" on the base connection |
352 | |||
2563 | hidnplayr | 353 | |
2578 | hidnplayr | 354 | ret |
2562 | hidnplayr | 355 | |
2554 | hidnplayr | 356 | .nosuchdir: |
357 | |||
2578 | hidnplayr | 358 | |
359 | ret |
||
2562 | hidnplayr | 360 | |
2578 | hidnplayr | 361 | |
362 | |||
363 | |||
2554 | hidnplayr | 364 | |
365 | ; TODO: same as list but simpler output format |
||
366 | |||
2578 | hidnplayr | 367 | ret |
368 | |||
2554 | hidnplayr | 369 | align 4 |
370 | |||
371 | |||
372 | ret |
||
373 | |||
374 | align 4 |
||
375 | |||
376 | |||
2557 | hidnplayr | 377 | ; TODO: verify password |
378 | |||
2578 | hidnplayr | 379 | mcall send, [edx + thread_data.socketnum], str230, str230.length, 0 |
2560 | hidnplayr | 380 | |
2578 | hidnplayr | 381 | push str_pass_ok |
382 | |||
2560 | hidnplayr | 383 | |
384 | mov edx, [esp+4] ; thread_data pointer |
||
385 | |||
2578 | hidnplayr | 386 | |
387 | ret |
||
2557 | hidnplayr | 388 | |
389 | align 4 |
||
390 | |||
391 | |||
2560 | hidnplayr | 392 | ; Open a new TCP socket |
393 | |||
2578 | hidnplayr | 394 | mov edx, [esp+4] ; thread_data pointer |
2562 | hidnplayr | 395 | cmp eax, -1 |
2578 | hidnplayr | 396 | je socketerror |
2562 | hidnplayr | 397 | mov [edx + thread_data.passivesocknum], eax |
2578 | hidnplayr | 398 | |
399 | ; Bind it to a known local port |
||
2562 | hidnplayr | 400 | |
2578 | hidnplayr | 401 | mov [edx + thread_data.datasock.sin_port], 2000 |
402 | mov [edx + thread_data.datasock.sin_addr], 0 |
||
403 | |||
404 | mov ecx, eax ;[edx + thread_data.passivesocknum] |
||
2562 | hidnplayr | 405 | |
2578 | hidnplayr | 406 | mov esi, sizeof.thread_data.datasock |
407 | mcall bind |
||
2581 | hidnplayr | 408 | mov edx, [esp+4] ; thread_data pointer |
409 | cmp eax, -1 |
||
2578 | hidnplayr | 410 | je bind_err |
2562 | hidnplayr | 411 | |
412 | ; And set it to listen! |
||
413 | |||
2578 | hidnplayr | 414 | |
415 | ; Tell our thread we are ready to accept incoming calls |
||
2562 | hidnplayr | 416 | |
2578 | hidnplayr | 417 | mov [edx + thread_data.mode], MODE_PASSIVE_WAIT |
418 | |||
419 | ; Now tell the client where to connect to in this format: |
||
2562 | hidnplayr | 420 | |
2578 | hidnplayr | 421 | ; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number. |
422 | lea edi, [edx + thread_data.buffer] |
||
423 | mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000) |
||
424 | stosd |
||
2562 | hidnplayr | 425 | mov eax, '(127' |
426 | stosd |
||
427 | mov eax, ',0,0' |
||
428 | stosd |
||
429 | mov eax, ',1,7' |
||
430 | stosd |
||
431 | mov eax, ',208' |
||
432 | stosd |
||
433 | mov al, ')' |
||
434 | stosb |
||
435 | mov ax, 0x0a0d |
||
436 | stosw |
||
2571 | hidnplayr | 437 | xor al, al |
2562 | hidnplayr | 438 | stosb |
439 | |||
440 | lea esi, [edi - thread_data.buffer] |
||
441 | |||
2578 | hidnplayr | 442 | mov ecx, [edx + thread_data.socketnum] |
443 | lea edx, [edx + thread_data.buffer] |
||
444 | xor esi, esi |
||
445 | mcall send |
||
2581 | hidnplayr | 446 | |
447 | ret |
||
2562 | hidnplayr | 448 | |
2560 | hidnplayr | 449 | align 4 |
450 | |||
451 | |||
2563 | hidnplayr | 452 | mov dword [edx + thread_data.buffer], '257 ' |
2554 | hidnplayr | 453 | |
2578 | hidnplayr | 454 | |
455 | lea edi, [edx + thread_data.buffer+5] |
||
2560 | hidnplayr | 456 | |
2578 | hidnplayr | 457 | mov ecx, 1024 |
458 | .loop: |
||
2560 | hidnplayr | 459 | lodsb |
460 | or al, al |
||
461 | jz .ok |
||
462 | stosb |
||
463 | dec ecx |
||
464 | jnz .loop |
||
465 | |||
466 | .ok: |
||
467 | |||
468 | lea esi, [edi - thread_data.buffer + 4] |
||
2578 | hidnplayr | 469 | sub esi, edx |
470 | mov ecx, [edx + thread_data.socketnum] |
||
471 | lea edx, [edx + thread_data.buffer] |
||
472 | mcall send, , , , 0 |
||
473 | |||
474 | ; push work_dir |
||
2560 | hidnplayr | 475 | |
2562 | hidnplayr | 476 | ; call [con_printf] |
477 | |||
478 | ret |
||
479 | |||
2554 | hidnplayr | 480 | align 4 |
481 | |||
482 | |||
483 | ; PORT a1,a2,a3,a4,p1,p2 |
||
484 | |||
2560 | hidnplayr | 485 | |
486 | mov [edx + thread_data.mode], MODE_ACTIVE |
||
487 | |||
2578 | hidnplayr | 488 | lea esi, [esi+5] |
2560 | hidnplayr | 489 | |
490 | call ascii_to_byte |
||
2578 | hidnplayr | 491 | mov bl, al |
2560 | hidnplayr | 492 | inc esi ; skip past ',' |
2581 | hidnplayr | 493 | call ascii_to_byte |
2578 | hidnplayr | 494 | mov bh, al |
2560 | hidnplayr | 495 | shl ebx, 16 |
2581 | hidnplayr | 496 | inc esi |
2578 | hidnplayr | 497 | call ascii_to_byte |
2560 | hidnplayr | 498 | mov bl, al |
499 | inc esi |
||
2581 | hidnplayr | 500 | call ascii_to_byte |
2560 | hidnplayr | 501 | mov bh, al |
502 | inc esi |
||
2581 | hidnplayr | 503 | rol ebx, 16 |
2560 | hidnplayr | 504 | |
2581 | hidnplayr | 505 | ; And put it in datasock |
2560 | hidnplayr | 506 | |
2578 | hidnplayr | 507 | |
508 | ; Now the same with portnumber |
||
2560 | hidnplayr | 509 | |
2578 | hidnplayr | 510 | mov bh, al |
2560 | hidnplayr | 511 | inc esi |
2578 | hidnplayr | 512 | call ascii_to_byte |
2560 | hidnplayr | 513 | mov bl, al |
514 | |||
2578 | hidnplayr | 515 | ; Save it in datasock too |
2560 | hidnplayr | 516 | |
2578 | hidnplayr | 517 | |
518 | ; We will open the socket, but do not connect yet! |
||
2560 | hidnplayr | 519 | |
2578 | hidnplayr | 520 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
521 | mov edx, [esp+4] ; thread_data pointer |
||
2562 | hidnplayr | 522 | cmp eax, -1 |
2578 | hidnplayr | 523 | je socketerror |
2560 | hidnplayr | 524 | mov [edx + thread_data.datasocketnum], eax |
2578 | hidnplayr | 525 | |
526 | ; Tell the client we are ready |
||
2560 | hidnplayr | 527 | |
2578 | hidnplayr | 528 | mcall send, [edx + thread_data.socketnum], str225, str225.length, 0 |
529 | ret |
||
530 | |||
2554 | hidnplayr | 531 | |
532 | |||
2560 | hidnplayr | 533 | |
2554 | hidnplayr | 534 | |
535 | mcall close, [edx + thread_data.datasocketnum] |
||
536 | |||
2578 | hidnplayr | 537 | mcall close;, [edx + thread_data.socketnum] |
538 | |||
539 | add esp, 4 ; get rid of call return address |
||
2557 | hidnplayr | 540 | |
2581 | hidnplayr | 541 | |
542 | align 4 |
||
2554 | hidnplayr | 543 | |
544 | |||
545 | sub ecx, 5 |
||
546 | |||
2571 | hidnplayr | 547 | |
548 | cmp [edx + thread_data.mode], MODE_ACTIVE |
||
549 | |||
2578 | hidnplayr | 550 | push esi |
2563 | hidnplayr | 551 | mov ecx, [edx + thread_data.datasocketnum] |
2571 | hidnplayr | 552 | lea edx, [edx + thread_data.datasock] |
2578 | hidnplayr | 553 | mov esi, sizeof.thread_data.datasock |
554 | mcall connect |
||
2581 | hidnplayr | 555 | pop esi |
556 | mov edx, [esp+4] ; thread_data pointer |
||
2571 | hidnplayr | 557 | cmp eax, -1 |
2578 | hidnplayr | 558 | je socketerror |
2571 | hidnplayr | 559 | @@: |
560 | |||
2563 | hidnplayr | 561 | push esi |
2562 | hidnplayr | 562 | |
2571 | hidnplayr | 563 | pop esi |
564 | dec edi |
||
565 | add esi, 5 |
||
566 | mov ecx, 1024 |
||
567 | .loop: |
||
568 | lodsb |
||
569 | cmp al, 0x20 |
||
570 | jl .done |
||
571 | stosb |
||
572 | loop .loop |
||
573 | .done: |
||
574 | xor al, al |
||
575 | stosb |
||
576 | |||
577 | lea eax, [edx + thread_data.fpath] |
||
2563 | hidnplayr | 578 | |
2578 | hidnplayr | 579 | call [con_write_asciiz] |
580 | push str_newline |
||
2571 | hidnplayr | 581 | call [con_write_asciiz] |
582 | |||
583 | push O_READ |
||
584 | |||
2563 | hidnplayr | 585 | push eax |
2578 | hidnplayr | 586 | call [file.open] |
587 | test eax, eax |
||
2563 | hidnplayr | 588 | jz .cannot_open |
2571 | hidnplayr | 589 | |
590 | push eax |
||
2563 | hidnplayr | 591 | |
2571 | hidnplayr | 592 | pop ebx |
2578 | hidnplayr | 593 | |
2571 | hidnplayr | 594 | mov edx, [esp+4] ; thread_data pointer |
2563 | hidnplayr | 595 | |
2578 | hidnplayr | 596 | push BUFFERSIZE |
2563 | hidnplayr | 597 | lea eax, [edx + thread_data.buffer] |
598 | push eax |
||
2578 | hidnplayr | 599 | push ebx |
600 | call [file.read] |
||
2563 | hidnplayr | 601 | cmp eax, -1 |
602 | je .cannot_open ; fixme: this is not the correct error |
||
2571 | hidnplayr | 603 | |
604 | push eax |
||
2562 | hidnplayr | 605 | |
2563 | hidnplayr | 606 | mov esi, eax |
607 | mov ecx, [edx + thread_data.datasocketnum] |
||
608 | lea edx, [edx + thread_data.buffer] |
||
2578 | hidnplayr | 609 | xor esi, esi |
610 | mcall send |
||
2581 | hidnplayr | 611 | pop ebx |
612 | pop ecx |
||
2563 | hidnplayr | 613 | mov edx, [esp+4] ; thread_data pointer |
614 | cmp eax, -1 |
||
2578 | hidnplayr | 615 | je socketerror |
2571 | hidnplayr | 616 | |
617 | cmp ecx, BUFFERSIZE |
||
2563 | hidnplayr | 618 | |
619 | |||
620 | mcall close, [edx + thread_data.datasocketnum] |
||
621 | |||
2578 | hidnplayr | 622 | cmp [edx + thread_data.mode], MODE_PASSIVE_OK |
2563 | hidnplayr | 623 | |
2578 | hidnplayr | 624 | mov [edx + thread_data.mode], MODE_PASSIVE_WAIT |
2563 | hidnplayr | 625 | @@: |
2578 | hidnplayr | 626 | |
2563 | hidnplayr | 627 | mcall send, [edx + thread_data.socketnum], str226, str226.length, 0 ; transfer ok |
628 | |||
2578 | hidnplayr | 629 | ret |
2563 | hidnplayr | 630 | |
2554 | hidnplayr | 631 | .cannot_open: |
632 | |||
2571 | hidnplayr | 633 | call [con_set_flags] |
634 | push str_notfound |
||
635 | call [con_write_asciiz] |
||
636 | pushd 0x07 |
||
637 | call [con_set_flags] |
||
638 | |||
639 | mcall send, [edx + thread_data.socketnum], str550, str550.length, 0 ; file not found |
||
640 | |||
2578 | hidnplayr | 641 | ret |
2571 | hidnplayr | 642 | |
643 | align 4 |
||
644 | |||
2554 | hidnplayr | 645 | |
646 | ; TODO: check if user has write permission, and write file if so |
||
647 | |||
2578 | hidnplayr | 648 | ret |
649 | |||
2554 | hidnplayr | 650 | align 4 |
651 | |||
652 | |||
653 | mcall send, [edx + thread_data.socketnum], str215, str215.length, 0 |
||
654 | |||
2578 | hidnplayr | 655 | ret |
2557 | hidnplayr | 656 | |
2554 | hidnplayr | 657 | align 4 |
658 | |||
659 | |||
660 | cmp ecx, 6 |
||
661 | |||
2560 | hidnplayr | 662 | |
663 | mov al, byte[esi+5] |
||
664 | |||
665 | |||
666 | cmp al, 'A' |
||
667 | |||
668 | cmp al, 'E' |
||
669 | je .ebdic |
||
670 | cmp al, 'I' |
||
671 | je .image |
||
672 | cmp al, 'L' |
||
673 | je .local |
||
674 | |||
675 | jmp parse_cmd.error |
||
676 | |||
677 | .ascii: |
||
678 | |||
679 | jmp .subtype |
||
2578 | hidnplayr | 680 | |
2560 | hidnplayr | 681 | .ebdic: |
682 | |||
683 | |||
2578 | hidnplayr | 684 | .subtype: |
2560 | hidnplayr | 685 | |
686 | cmp ecx, 8 |
||
687 | |||
688 | |||
689 | mov al, byte[esi+7] |
||
690 | |||
691 | |||
692 | cmp al, 'N' |
||
693 | |||
694 | cmp al, 'T' |
||
695 | je .telnet |
||
696 | cmp al, 'C' |
||
697 | je .asacc |
||
698 | |||
699 | jmp parse_cmd.error |
||
700 | |||
701 | .non_print: |
||
702 | |||
703 | jmp .ok |
||
2578 | hidnplayr | 704 | |
2560 | hidnplayr | 705 | .telnet: |
706 | |||
707 | jmp .ok |
||
2578 | hidnplayr | 708 | |
2560 | hidnplayr | 709 | .asacc: |
710 | |||
711 | jmp .ok |
||
2578 | hidnplayr | 712 | |
2560 | hidnplayr | 713 | .image: |
714 | |||
715 | jmp .ok |
||
2578 | hidnplayr | 716 | |
2560 | hidnplayr | 717 | .local: |
718 | |||
719 | jb parse_cmd.error |
||
720 | |||
721 | mov al, byte[esi+7] |
||
722 | |||
723 | jb parse_cmd.error |
||
724 | cmp al, 9 |
||
725 | ja parse_cmd.error |
||
726 | or al, TYPE_LOCAL |
||
727 | mov [edx + thread_data.type], al |
||
728 | |||
2578 | hidnplayr | 729 | .ok: |
2560 | hidnplayr | 730 | |
731 | |||
2578 | hidnplayr | 732 | ret |
2560 | hidnplayr | 733 | |
2554 | hidnplayr | 734 | align 4 |
735 | |||
736 | |||
737 | ; TODO: check user and set home directory (and permissions) |
||
738 | |||
2578 | hidnplayr | 739 | mcall send, [edx + thread_data.socketnum], str331, str331.length, 0 |
2557 | hidnplayr | 740 | |
2578 | hidnplayr | 741 | mov [edx + thread_data.state], STATE_LOGIN |
742 | |||
743 | mov byte [edx + thread_data.work_dir], "/" |
||
2560 | hidnplayr | 744 | |
2578 | hidnplayr | 745 | |
746 | push str_logged_in |
||
747 | |||
2560 | hidnplayr | 748 | |
749 | ret |
||
750 | |||
2554 | hidnplayr | 751 | |
752 | |||
753 | |||
754 | |||
2578 | hidnplayr | 755 | |
2560 | hidnplayr | 756 | xor eax, eax |
757 | |||
2578 | hidnplayr | 758 | |
759 | .loop: |
||
2560 | hidnplayr | 760 | |
761 | sub bl, '0' |
||
2578 | hidnplayr | 762 | jb .done |
763 | cmp bl, 9 |
||
2560 | hidnplayr | 764 | ja .done |
2578 | hidnplayr | 765 | lea eax, [eax*4 + eax] ; |
2560 | hidnplayr | 766 | shl eax, 1 ; eax = eax * 10 |
2578 | hidnplayr | 767 | add eax, ebx |
768 | inc esi |
||
769 | |||
2560 | hidnplayr | 770 | jmp .loop |
771 | |||
772 | .done: |
||
773 | |||
774 | ret |
||
2578 | hidnplayr | 775 | |
2560 | hidnplayr | 776 | align 4 |
777 | |||
2562 | hidnplayr | 778 | |
2578 | hidnplayr | 779 | mov eax, '1' |
2560 | hidnplayr | 780 | |
2562 | hidnplayr | 781 | |
782 | ret |
||
2560 | hidnplayr | 783 | |
2562 | hidnplayr | 784 | align 4 |
2560 | hidnplayr | 785 | |
2563 | hidnplayr | 786 | |
787 | lea edi, [edx + thread_data.fpath] |
||
2581 | hidnplayr | 788 | |
2578 | hidnplayr | 789 | mov ecx, 1024 |
790 | .loop1: |
||
2563 | hidnplayr | 791 | lodsb |
792 | or al, al |
||
793 | jz .next |
||
794 | stosb |
||
795 | loop .loop1 |
||
796 | .next: |
||
797 | |||
798 | cmp byte[edi-1], '/' |
||
2562 | hidnplayr | 799 | |
2563 | hidnplayr | 800 | dec edi |
801 | @@: |
||
802 | |||
803 | lea esi, [edx + thread_data.work_dir] |
||
2562 | hidnplayr | 804 | |
2578 | hidnplayr | 805 | .loop2: |
2563 | hidnplayr | 806 | lodsb |
807 | or al, al |
||
808 | jz .done |
||
809 | stosb |
||
810 | loop .loop2 |
||
811 | |||
812 | .done: |
||
813 | |||
814 | |||
815 | ret |
||
816 | |||
817 | |||
818 | |||
819 | |||
2571 | hidnplayr | 820 | |
821 | pushd 0x0c |
||
2563 | hidnplayr | 822 | |
2571 | hidnplayr | 823 | push str_sockerr |
824 | call [con_write_asciiz] |
||
825 | pushd 0x07 |
||
826 | call [con_set_flags] |
||
827 | |||
828 | mcall send, [edx + thread_data.socketnum], str425, str425.length, 0 ; data connection error |
||
2563 | hidnplayr | 829 | |
2578 | hidnplayr | 830 | ret |
2571 | hidnplayr | 831 | |
832 | |||
833 | |||
834 | |||
835 | |||
836 | |||
2554 | hidnplayr | 837 | str200 db '200 Command OK.', 13, 10 |
2562 | hidnplayr | 838 | .length = $ - str200 |
2554 | hidnplayr | 839 | str215 db '215 UNIX type: L8', 13, 10 |
2560 | hidnplayr | 840 | .length = $ - str215 |
2554 | hidnplayr | 841 | str220 db '220 KolibriOS FTP Daemon 1.0', 13, 10 |
2557 | hidnplayr | 842 | .length = $ - str220 |
2554 | hidnplayr | 843 | str221 db '221 Bye!', 13, 10 |
844 | .length = $ - str221 |
||
845 | str225 db '225 Data connection open', 13, 10 |
||
2557 | hidnplayr | 846 | .length = $ - str225 |
2560 | hidnplayr | 847 | str226 db '226 Transfer OK, Closing connection', 13, 10 |
848 | .length = $ - str226 |
||
2554 | hidnplayr | 849 | str230 db '230 You are now logged in.', 13, 10 |
2562 | hidnplayr | 850 | .length = $ - str230 |
2554 | hidnplayr | 851 | str250 db '250 command successful', 13, 10 |
2557 | hidnplayr | 852 | .length = $ - str250 |
2554 | hidnplayr | 853 | str331 db '331 Please specify the password.', 13, 10 |
2563 | hidnplayr | 854 | .length = $ - str331 |
2554 | hidnplayr | 855 | str421 db '421 Timeout!', 13, 10 |
2557 | hidnplayr | 856 | .length = $ - str421 |
2560 | hidnplayr | 857 | str425 db '425 Cant open data connection.', 13, 10 |
858 | .length = $ - str425 |
||
859 | str500 db '500 Unsupported command', 13, 10 |
||
860 | .length = $ - str500 |
||
2554 | hidnplayr | 861 | str550 db '550 No such file', 13, 10 |
2557 | hidnplayr | 862 | .length = $ - str550 |
2563 | hidnplayr | 863 |