A multithreaded FTP server following the RFC959 protocol.
The server require users to authenticate. Below the list of default users; anonymouys does not require a password.
user | password |
---|---|
anonymous | |
pedro | drops |
gaetan | qwasar |
New users may be added in the .users
config file. Each user entry has a user
and password
field delimited by a :
. Users are separated by a new line(\n
) like so
user1:password1
user2:passowrd2
To create users without password set the password to 0
user_without_password:0
My FTP creates a directory .root/
in the same directory as the running binary. Clients only have access to files within .root/
while
the remaining of the server's filesystem remain private and inaccessible. This is reflected in perspective of what the absolute path is between the client and server.
Server absolute path
/home/username/.root/file.jpg
Client absolute path
file.jpg
Clients are unable to CDUP
out of the .root
directory.
The server has 3 types of log messages: Error
(red),Info
(blue) and Debug
(yellow). The Debug
logs are somewhat noisy and they can be turned on or
off by removing/adding the macro #define DEBUG
to/from the include/logger.hpp
header.
Build
make
Run
./bin/ftp <port-number>
Run server with unit testing
./bin/ftp <port-number> --test
Clean
make clean
The server listens to new connections (accept
) as well as to connected sockets control requests in the main thread. This logic is ran in a single thread using a polling system.
Once a request is received from a client, the server will create a Service
object and dispatch it to a threadpool. An available thread will then call Service.work()
to execute this request.
Note that only the control connection is managed in the main thread. Data connection are always established from a separated thread within the context of a Service
.
The program revolves around modifying a Request
object that is created when the server first receives a message from
Connection
. This Request
is then populated with the request info such as the socket fd of the requesting client, data received etc
and is passed on to a Service
that, in its turn will parse and route this request to specific controller.
The threadpool will use all the available threads in you system with std::thread::hardware_concurrency
. To avoid the CPU usage going out of control, the threadpool implements a simple throttling logic.
As the server goes idle the loop checking for new jobs will get throttled with longer and longer sleep times from 50ms all the way to 500ms.
Command | Description |
---|---|
CDUP | Change to parent directory |
QUIT | Disconnects from server |
PASV | Enter passive mode |
PWD | Print working directory |
SYST | Get server operating system |
NOOP | No Operation (used mostly on keepalives) |
USER | Authenticate username |
PASS | Authenticate passowrd |
CWD | Change directory |
PORT | Specifies an address and port to which the server should connect |
TYPE | Sets the transfer mode to ASCII or Binary(Image) |
RETR | Retrives a copy of a file |
STOU | Stores a file uniquely |
RNFR | Select the file to rename |
RNTO | Sets the new filename to rename to |
DELE | Deletes a file |
RMD | Removes a directory |
MKD | Creates a directory |
LIST | Returns info of a file or directory if specified, else info of the current working directory |
NLST | Returns a list of filenames in a specified directory |
STAT | Returns the server status, including the status of the current connection |
HELP | Display help of an specific command |
FEAT | Responds with server features |
ABOR | No support |
ACCT | No support |
SMNT | No support |
STRU | No support |
MODE | No support |
REIN | No support |
APPE | No support |
SITE | No support |
ALLO | No support |
LPRT | No support |
LPSV | No support |
REST | No support |
Reply | Description |
---|---|
100 series | The requested action is being initiated, expect another reply before proceeding with a new command. |
110 | Restart marker replay . In this case, the text is exact and not left to the particular implementation; |
120 | Service ready in nnn minutes. |
125 | Data connection already open; transfer starting. |
150 | File status okay; about to open data connection. |
200 series | The requested action has been successfully completed. |
202 | Command not implemented, superfluous at this site. |
211 | System status, or system help reply. |
212 | Directory status. |
213 | File status. |
214 | Help message. Explains how to use the server or the meaning of a particular non-standard command. This reply is useful only to the human user. |
215 | NAME system type. Where NAME is an official system name from the registry kept by IANA. |
220 | Service ready for new user. |
221 | Service closing control connection. |
225 | Data connection open; no transfer in progress. |
226 | Closing data connection. Requested file action successful (for example, file transfer or file abort). |
227 | Entering Passive Mode (h1,h2,h3,h4,p1,p2). |
228 | Entering Long Passive Mode (long address, port). |
229 | Entering Extended Passive Mode ( |
230 | User logged in, proceed. Logged out if appropriate. |
231 | User logged out; service terminated. |
232 | Logout command noted, will complete when transfer done. |
234 | Specifies that the server accepts the authentication mechanism specified by the client, and the exchange of security data is complete. |
250 | Requested file action okay, completed. |
257 | "PATHNAME" created. |
300 series | The command has been accepted, but the requested action is on hold, pending receipt of further information. |
331 | User name okay, need password. |
332 | Need account for login. |
350 | Requested file action pending further information |
400 series | The command was not accepted and the requested action did not take place, but the error condition is temporary and the action may be requested again. |
421 | Service not available, closing control connection. This may be a reply to any command if the service knows it must shut down. |
425 | Can't open data connection. |
426 | Connection closed; transfer aborted. |
430 | Invalid username or password |
434 | Requested host unavailable. |
450 | Requested file action not taken. |
451 | Requested action aborted. Local error in processing. |
452 | Requested action not taken. Insufficient storage space in system. File unavailable (e.g., file busy). |
500 series | Syntax error, command unrecognized and the requested action did not take place. This may include errors such as command line too long. |
501 | Syntax error in parameters or arguments. |
502 | Command not implemented. |
503 | Bad sequence of commands. |
504 | Command not implemented for that parameter. |
530 | Not logged in. |
532 | Need account for storing files. |
534 | Could Not Connect to Server - Policy Requires SSL |
550 | Requested action not taken. File unavailable (e.g., file not found, no access). |
551 | Requested action aborted. Page type unknown. |
552 | Requested file action aborted. Exceeded storage allocation (for current directory or dataset). |
553 | Requested action not taken. File name not allowed. |
600 series | Replies regarding confidentiality and integrity |
631 | Integrity protected reply. |
632 | Confidentiality and integrity protected reply. |
633 | Confidentiality protected reply. |