Implemented Passive mode and LIST command in new FTP daemon (net branch)

git-svn-id: svn://kolibrios.org@2562 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2012-04-04 13:08:07 +00:00
parent 74a8292f46
commit 0833e5c02d
2 changed files with 249 additions and 33 deletions

View File

@ -35,52 +35,38 @@ commands: ; all commands must be in uppercase
db 'ABOR' db 'ABOR'
dd cmdABOR dd cmdABOR
db 'CWD', 0 db 'CWD', 0
dd cmdCWD dd cmdCWD
db 'DELE' db 'DELE'
dd cmdDELE dd cmdDELE
db 'LIST' db 'LIST'
dd cmdLIST dd cmdLIST
db 'NLST' db 'NLST'
dd cmdNLST dd cmdNLST
db 'NOOP' db 'NOOP'
dd cmdNOOP dd cmdNOOP
db 'PASS' db 'PASS'
dd cmdPASS dd cmdPASS
db 'PASV'
dd cmdPASV
db 'PWD', 0 ; Print Working Directory db 'PWD', 0 ; Print Working Directory
dd cmdPWD dd cmdPWD
db 'PORT' db 'PORT'
dd cmdPORT dd cmdPORT
db 'QUIT' db 'QUIT'
dd cmdQUIT dd cmdQUIT
db 'RETR' db 'RETR'
dd cmdRETR dd cmdRETR
db 'STOR' db 'STOR'
dd cmdSTOR dd cmdSTOR
db 'SYST' db 'SYST'
dd cmdSYST dd cmdSYST
db 'TYPE' db 'TYPE'
dd cmdTYPE dd cmdTYPE
db 'USER' db 'USER'
dd cmdUSER dd cmdUSER
db 'XPWD' db 'XPWD'
dd cmdPWD dd cmdPWD
db 0 ; end marker db 0 ; end marker
@ -102,6 +88,143 @@ cmdDELE:
align 4 align 4
cmdLIST: cmdLIST:
cmp [mode], MODE_ACTIVE
jne @f
mcall connect, [datasocketnum], datasock, datasock.length
cmp eax, -1
je .err
@@:
mcall send, [socketnum2], str150, str150.length, 0 ; here it comes..
push FA_READONLY + FA_FOLDER
push str_mask
push home_dir
call [file.find.first]
mov edi, buffer
jmp .parse_file
.checknextfile:
push edx
call [file.find.next]
.parse_file:
test eax, eax
jz .done
mov edx, eax
; first, convert the attributes
test [eax + FileInfoA.Attributes], FA_FOLDER
jnz .folder
test [eax + FileInfoA.Attributes], FA_READONLY
jnz .readonly
mov eax, '-rw-'
stosd
jmp .attr
.folder:
mov eax, 'drwx'
stosb
jmp .attr
.readonly:
mov eax, '-r--'
stosd
.attr:
mov eax, 'rw-r'
stosd
mov ax, 'w-'
stosw
mov al, ' '
stosb
; now..
mov ax, '1 '
stosw
; now write owner, everything is owned by FTP, woohoo!
mov eax, 'FTP '
stosd
stosd
; now the filesize in ascii
mov ebx, dword [edx + FileInfoA.FileSize]
call dword_to_ascii
mov al, ' '
stosb
; then date (month/day/year)
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.month]
mov eax, [months + 4*ebx]
stosd
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.day]
call dword_to_ascii
mov al, ' '
stosb
movzx ebx, [edx + FileInfoA.DateModify + FileDateTime.year]
call dword_to_ascii
mov al, ' '
stosb
; and last but not least, filename
lea esi, [edx + FileInfoA.FileName]
mov ecx, 250
.nameloop:
lodsb
test al, al
jz .namedone
stosb
loop .nameloop
.namedone:
mov ax, 0x0d0a
stosw
jmp .checknextfile
.done:
push edx
call [file.find.close]
xor al, al
stosb
push buffer
call [con_write_asciiz]
lea esi, [edi - buffer]
mcall send, [datasocketnum], buffer, , 0
mcall close, [datasocketnum]
cmp [mode], MODE_PASSIVE_OK
jne @f
mov [mode], MODE_PASSIVE_WAIT
@@:
mcall send, [socketnum2], str226, str226.length, 0 ; transfer ok
ret
.err:
pushd 0x0c
call [con_set_flags]
push str_err1
call [con_write_asciiz]
pushd 0x07
call [con_set_flags]
ret ret
align 4 align 4
@ -129,13 +252,47 @@ cmdPASS:
align 4 align 4
cmdPASV: cmdPASV:
mov [mode], MODE_PASSIVE
; TODO: open the UDP socket and return our IP + port
; 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) ; 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number. ; where a1.a2.a3.a4 is the IP address and p1*256+p2 is the port number.
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
; je .err
mov [passivesocknum], eax
mov [datasock.port], 2000
mov [datasock.ip], 0
mcall bind, [passivesocknum], datasock, datasock.length
cmp eax, -1
je bind_err
mcall listen, [passivesocknum], 1
mov [mode], MODE_PASSIVE_WAIT
mov edi, buffer
mov eax, '227 ' ; FIXME (now hardcoded to 127.0.0.1:2000)
stosd
mov eax, '(127'
stosd
mov eax, ',0,0'
stosd
mov eax, ',1,7'
stosd
mov eax, ',208'
stosd
mov al, ')'
stosb
mov ax, 0x0d0a
stosw
xor al, al
stosb
lea esi, [edi - buffer]
mcall send, [socketnum2], buffer, ,0
ret ret
align 4 align 4
@ -161,6 +318,10 @@ cmdPWD:
mcall send, [socketnum2], buffer, , 0 mcall send, [socketnum2], buffer, , 0
; push work_dir
; push str_pwd
; call [con_printf]
ret ret
align 4 align 4
@ -198,15 +359,11 @@ cmdPORT:
mov [datasock.port], dx mov [datasock.port], dx
mcall socket, AF_INET4, SOCK_DGRAM, 0 mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1 cmp eax, -1
je .err je .err
mov [datasocketnum], eax mov [datasocketnum], eax
mcall connect, [datasocketnum], datasock, datasock.length
cmp eax, -1
je .err
mcall send, [socketnum2], str225, str225.length, 0 mcall send, [socketnum2], str225, str225.length, 0
ret ret
@ -226,6 +383,23 @@ cmdQUIT:
align 4 align 4
cmdRETR: cmdRETR:
; mcall connect, [datasocketnum], datasock, datasock.length
; cmp eax, -1
; je .err
; push O_READ
; push home_dir
; call [file.open]
; test eax, eax
; jz .cannot_open
;
; push BUFFERSIZE
; push buffer
; push eax
; call [file.read]
; cmp eax, -1
; jz .cannot_open
ret ret
align 4 align 4
@ -360,11 +534,20 @@ ascii_to_byte:
.done: .done:
ret ret
align 4
dword_to_ascii: ; edi = ptr where to write, ebx is number
mov eax, '1'
stosb
ret
str150 db '150 Here it comes...', 13, 10 str150 db '150 Here it comes...', 13, 10
.length = $ - str150
str200 db '200 Command OK.', 13, 10 str200 db '200 Command OK.', 13, 10
.length = $ - str200 .length = $ - str200
str215 db '215 UNIX type: L8', 13, 10 str215 db '215 UNIX type: L8', 13, 10
@ -376,6 +559,7 @@ str221 db '221 Bye!', 13, 10
str225 db '225 Data connection open', 13, 10 str225 db '225 Data connection open', 13, 10
.length = $ - str225 .length = $ - str225
str226 db '226 Transfer OK, Closing connection', 13, 10 str226 db '226 Transfer OK, Closing connection', 13, 10
.length = $ - str226
str230 db '230 You are now logged in.', 13, 10 str230 db '230 You are now logged in.', 13, 10
.length = $ - str230 .length = $ - str230
str250 db '250 command successful', 13, 10 str250 db '250 command successful', 13, 10

View File

@ -28,7 +28,8 @@ TYPE_LOCAL = 10000000b ; bits per byte must be specified
MODE_NOTREADY = 0 MODE_NOTREADY = 0
MODE_ACTIVE = 1 MODE_ACTIVE = 1
MODE_PASSIVE = 2 MODE_PASSIVE_WAIT = 2
MODE_PASSIVE_OK = 3
use32 use32
db 'MENUET01' ; signature db 'MENUET01' ; signature
@ -44,6 +45,8 @@ include '../macros.inc'
purge mov,add,sub purge mov,add,sub
include '../proc32.inc' include '../proc32.inc'
include '../dll.inc' include '../dll.inc'
include '../struct.inc'
include '../libio.inc'
include '../network.inc' include '../network.inc'
include 'commands.inc' include 'commands.inc'
@ -131,14 +134,27 @@ start:
.loop: .loop:
mcall 10 mcall 10
cmp [mode], MODE_PASSIVE_WAIT
jne @f
mcall accept, [passivesocknum], datasock, datasock.length
cmp eax, -1
je @f
mov [datasocketnum], eax
mov [mode], MODE_PASSIVE_OK
push str_datasock
call [con_write_asciiz]
@@:
mcall recv, [socketnum2], buffer, buffer.length mcall recv, [socketnum2], buffer, buffer.length
cmp eax, -1 cmp eax, -1
je .loop je .loop
or eax, eax
jz .loop
push eax push eax
mov byte[buffer+eax], 0 mov byte[buffer+eax], 0
pushd 0x0a pushd 0x0a
call [con_set_flags] call [con_set_flags]
@ -213,6 +229,18 @@ str8 db 'Error accepting connection',10,10,0
str_logged_in db 'Login ok',10,10,0 str_logged_in db 'Login ok',10,10,0
str_pass_ok db 'Password ok - Logged in',10,10,0 str_pass_ok db 'Password ok - Logged in',10,10,0
str_pwd db 'Current directory is "%s"\n',0
str_err1 db 'ERROR: cannot connect to remote socket',10,10,0
str_err2 db 'ERROR: cannot open directory',10,10,0
str_datasock db 'Passive data socket connected!',10,10,0
str_mask db '*', 0
months:
dd 'Jan ','Feb ','Mar ','Apr ','May ','Jun '
dd 'Jul ','Aug ','Sep ','Oct ','Nov ','Dec '
filename db '.ini', 0 filename db '.ini', 0
str_port db 'port', 0 str_port db 'port', 0
@ -255,7 +283,10 @@ import libio, \
file.size , 'file_size' , \ file.size , 'file_size' , \
file.open , 'file_open' , \ file.open , 'file_open' , \
file.read , 'file_read' , \ file.read , 'file_read' , \
file.close , 'file_close' file.close , 'file_close' , \
file.find.first , 'file_find_first', \
file.find.next , 'file_find_next', \
file.find.close , 'file_find_close'
i_end: i_end:
@ -266,11 +297,12 @@ socketnum dd ?
; thread specific data ; thread specific data
socketnum2 dd ? socketnum2 dd ?
state dd ? state dd ?
home_dir rb 1024 home_dir db '/rd/1/',0
work_dir rb 1024 work_dir rb 1024
type db ? type db ?
mode db ? ; active/passive mode db ? ; active/passive
passivesocknum dd ?
datasocketnum dd ? datasocketnum dd ?
datasock: datasock: