[TOC]
june 06 WRITE AN FTP CLIENT
CREDITS - http://members.aol.com/DSC30574/sockets/winsock.html - RFC959
because ftp.exe from dos/win doesn't do passive use an ftp server on my cpu (disconnected) to test first uses winsock (because i haven't figured out dos and don't have linux)
server connects through tcp socket (winsock) no problem (port 21)
returns "220 Connected to 127.0.0.1 ready..." with a '\n'
server wants first: USER username
server then wants: PASS password
6/21
- cerberus fully functional server helps dev, but what are improperly formatted reqs from my client?
- can't figure out substring in c, and how port 1112 = ,4,88?
6/23
- much better understanding of SOCKADDR_IN and sockets
- finished parsing for passive - now live testing against beyondcaliforni
- crashing the whole os - need better fault protection
- found the correct formatting of ftp protocol commands:
send(socket,"PASS happy123\r\nn",sizeof("PASS happy123\r\n"),0);
NOTICE no '\0'
6/24
- passive is only for the data connection - but what about cmds:
- interactive mode?
- using GuildFTP server because cerberus kept crashing windows
- But Guild uses multi line & multi send opening! What a headache!
- Reformatted the whole buffer processing function(s). At least it's more robust... ;)
- Maybe now I have a start formal parsing of response codes.
- Still doesn't work with beyondcalifornia - at the password!
6/25
With GuildFTP: USER,PASS,PWD,NOOP,SYST,HELP,CWD,PASV, NLST & LIST!!!
found error - forgot =socket(AF_INET,SOCK_STREAM,0) after sPASV. - then connect to sPASV with: connect( sPASV, (SOCKADDR*) &pasvData, sizeof(pasvData) );
- Read the command socket: 150 Opening ASCII mode data connection for /bin/ls - and receive NLST/LIST data with the data socket (sPASV) nReceived = recv(sPASV,buffer,sizeof(buffer),0);
- Then receive again on the command socket: 226 Transfer successful. - ON CerberusFTP there's no 226 successful message, so I need to implement a timeout system and a loop to check if the server has something to say or no. - Cleaned up Socket setup/connect code - I have a better understanding and can reuse some - also implementing the default data socket (port 20) - Changed from Winmain() to main() - it was leftover as a legacy of my earlyfailures with winsocklib
1. a verb consisting of alphabetic ASCII characters;
2. optionally, a space followed by a parameter; and
3. \015\012.
RETR report.ps \015\012
150-This is the first line of a mark
123-This line does not end the mark; note the hyphen
150 This line ends the mark
226-This is the first line of the second response
226 This line does not end the response; note the leading space
226 This is the last line of the response, using code 226
The server's initial response to the client must use code 220 or 421. 220 = accept, 421 = deny
The server normally accepts PASV with code 227. Its response is a single line showing the IP address of the server and the TCP port number where the server is accepting connections.
Normally the client will connect to this TCP port, from the same IP address that the client is using for the FTP connection, and then send a RETR request. However, the client may send some other requests first, such as REST.
A USER request has a parameter showing a username. Subsequent pathnames are interpreted relative to this username.
The server may accept USER with code 230, meaning that the client has permission to access files under that username; or with code 331 or 332, meaning that permission might be granted after a PASS request.
In theory, the server may reject USER with code 530, meaning that the username is unacceptable. In practice, the server does not check the username until after a PASS request.
A PASS request has a parameter called a password. The client must not send a PASS request except immediately after a USER request.
The server may accept PASS with code 230, meaning that permission to access files under this username has been granted; or with code 202, meaning that permission was already granted in response to USER; or with code 332, meaning that permission might be granted after an ACCT request. The server may reject PASS with code 503 if the previous request was not USER or with code 530 if this username and password are jointly unacceptable.
A TYPE request controls the binary flag. It has a parameter. There are four possibilities for the parameter:
* A: Turn the binary flag off.
* A N: Turn the binary flag off.
* I: Turn the binary flag on.
* L 8: Turn the binary flag on.
A QUIT request asks the server to close the connection:
220 Features: a .
QUIT
221 Bye.
The client can simply close the connection without sending QUIT. This saves time and memory for both the client and the server.
"Active", client requests that server start data connection and terminate at an IP address and port number of the client's choosing.
Client: "connect to me at port 1931 at IP 192.168.1.2, then send the data."
Server: "OK"
Client: PORT 192,168,1,2,7,139
Server: 200 PORT command successful.
"passive", the client can request that the server to assign an IP address and port number on the server side and have the client originate a connection to the server address. The client connects out to the server.
Client: "Please tell me where I can get the data."
Server: "Connect to me at port 4023 on 172.16.62.36."
Client: PASV
Server: Entering Passive Mode (172,16,62,36,133,111)
/struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address };
struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr };
struct in_addr { // Internet address (a structure for historical reasons)
unsigned long s_addr; // that's a 32-bit long, or 4 bytes };
ina.sin_addr.s_addr = inet_addr("10.12.110.57");
// nReceived = connect( s, (struct sockaddr ) &a, sizeof(a) );
*/
* 1yz: Positive Preliminary reply. The action requested is being initiated but there will be another reply before it begins.
* 2yz: Positive Completion reply. The action requested has been completed. The client may now issue a new command.
* 3yz: Positive Intermediate reply. The command was successful, but a further command is required before the server can act upon the request.
* 4yz: Transient Negative Completion reply. The command was not successful, but the client is free to try the command again as the failure is only temporary.
* 5yz: Permanent Negative Completion reply. The command was not successful and the client should not attempt to repeat it again.
* x0z: The failure was due to a syntax error.
* x1z: This response is a reply to a request for information.
* x2z: This response is a reply relating to connection information.
* x3z: This response is a reply relating to accounting and authorisation.
* x4z: Unspecified.
* x5z: This response is a reply relating to the file system.
COMMANDS TO IMITATE
user USER
pass PASS
syst SYST
help -
pwd PWD
ls LIST passive data port (DTP)
cd CWD
rename RNFR/RNTO
mkdir MKD
rmdir RMD
delete DELE
send STOR
recv RETR
ascii
binary
help site
help
status STAT used only during transfer