Beispiel #1
0
        // Runs the server continuously until quit
        public static void Run(FTPSocket socket)
        {
            var stop = false;

            while (!stop)
            {
                stop = HandleCommand(socket);
            }
        }
Beispiel #2
0
        // Main function accepts command line arguments
        static void Main(string[] args)
        {
            Debug   = false;
            Passive = false;

            if (args.Length == 0 || args.Length > 2)
            {
                Console.WriteLine("Usage: ftp <server> [port]");
                return;
            }

            // Get host and port from arguments
            var host = args[0];
            var port = 21;

            if (args.Length == 2)
            {
                int.TryParse(args[1], out port);
            }

            try
            {
                // Creates an FTP command socket and runs the command handler with it
                using (var ftp = new FTPSocket(host, port))
                {
                    FTPClient.Run(ftp);
                }
            }
            catch (SocketException)
            {
                Console.WriteLine("Unable to resolve or connect to host");
            }
            catch (TimeoutException)
            {
                Console.WriteLine("421 Timeout.");
            }
            catch
            {
                Console.WriteLine("An unexpected error occurred.");
            }
        }
Beispiel #3
0
        // Creates a new socket wrapper using the given command connection
        public DataSocket(FTPSocket ftp)
        {
            if (Program.Passive)
            {
                // If in passive mode, send a PASV command
                ftp.Write("PASV");
                var(status, message) = ftp.ReadStatus();

                if (status != 227)
                {
                    Console.WriteLine(message);
                    return;
                }

                var match   = Regex.Match(message, @"\((\d+,\d+,\d+,\d+),(\d+),(\d+)\)");
                var address = IPAddress.Parse(match.Groups[1].Value.Replace(',', '.'));
                var port    = int.Parse(match.Groups[2].Value) * 256 + int.Parse(match.Groups[3].Value);

                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(address, port);
            }
            else
            {
                // In in active mode, create a listening server for the connection
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                var address = ftp.LocalIP;
                listener.Bind(new IPEndPoint(address, 0));
                listener.Listen(1);

                var ip   = address.ToString().Replace('.', ',');
                var port = ((IPEndPoint)listener.LocalEndPoint).Port;

                ftp.Write("PORT {0},{1},{2}", ip, port / 256, port % 256);
                var(status, message) = ftp.ReadStatus();

                if (status != 200)
                {
                    throw new Exception("Data connection failed");
                }
            }
        }
Beispiel #4
0
        // Handles a command from the client using the given socket
        static bool HandleCommand(FTPSocket socket)
        {
            // Writes a user prompt and extracts the command and arguments from user input
            Console.Write("  > ");
            var input = Console.ReadLine();
            var match = Regex.Match(input, @"([^ ]+)(?: (.+))?");

            var command   = "";
            var arguments = "";

            if (match.Groups[1].Success)
            {
                command = match.Groups[1].Value.ToUpper();
            }
            if (match.Groups[2].Success)
            {
                arguments = match.Groups[2].Value;
            }

            switch (command)
            {
            // Sets the server to transfer in ASCII mode
            case "ASCII":
                socket.Write("TYPE A");
                Console.WriteLine(socket.Read());
                break;

            // Makes the server transfer in binary mode
            case "BINARY":
                socket.Write("TYPE I");
                Console.WriteLine(socket.Read());
                break;

            // Changes the server to the given directory
            case "CD":
                if (arguments.Length == 0)
                {
                    Console.WriteLine("    CD requires a path argument");
                    break;
                }

                socket.Write("CWD {0}", arguments);
                Console.WriteLine(socket.Read());
                break;

            // Navigates up one directory on the server
            case "CDUP":
                socket.Write("CDUP");
                Console.WriteLine(socket.Read());
                break;

            // Endables debug mode, printing messages for each message sent over the data connection
            case "DEBUG":
                Program.Debug = !Program.Debug;
                if (Program.Debug)
                {
                    Console.WriteLine("    Debug mode enabled");
                }
                else
                {
                    Console.WriteLine("    Debug mode disabled");
                }
                break;

            // Prints a directory listing for the current directory
            case "DIR":
                using (var data = new DataSocket(socket))
                {
                    socket.Write("LIST");
                    var(status2, message) = socket.ReadStatus();
                    Console.WriteLine(message);
                    if (status2 == 150)
                    {
                        Console.WriteLine(data.ReadText());
                        Console.WriteLine(socket.Read());
                    }
                }
                break;

            // Gets the specified file from the server
            case "GET":
                using (var data = new DataSocket(socket))
                {
                    socket.Write("RETR {0}", arguments);
                    var(status2, message) = socket.ReadStatus();
                    Console.WriteLine(message);
                    if (status2 == 150)
                    {
                        var path = arguments.Split('/');
                        data.ReadToFile(path[path.Length - 1]);
                        Console.WriteLine(socket.Read());
                    }
                }
                break;

            // Prints a help message
            case "HELP":
                Console.WriteLine("Available commands:");
                Console.WriteLine("ASCII: sets the server to ASCII transfer mode");
                Console.WriteLine("BINARY: sets the server to binary transfer mode");
                Console.WriteLine("CD <path>: navigates to the given path on the server");
                Console.WriteLine("CDUP: naigates up one directory on the server");
                Console.WriteLine("DEBUG: toggles debug mode, which prints all commands sent");
                Console.WriteLine("DIR: prints a directory listing for the current server directory");
                Console.WriteLine("GET <file>: downloads the specified file from the server");
                Console.WriteLine("HELP: prints this help message");
                Console.WriteLine("PASSIVE: toggles passive file transfer mode");
                Console.WriteLine("PWD: prints the current directory from the server");
                Console.WriteLine("QUIT: closes the FTP connection and exits");
                break;

            // Switches between passive and active transfer
            case "PASSIVE":
                Program.Passive = !Program.Passive;
                if (Program.Passive)
                {
                    Console.WriteLine("    Passive mode enabled");
                }
                else
                {
                    Console.WriteLine("    Passive mode disabled");
                }
                break;

            // Prints the current directory on the server
            case "PWD":
                socket.Write("PWD");
                Console.WriteLine(socket.Read());
                break;

            // Quits the FTP connetion
            case "QUIT":
                socket.Write("QUIT");
                Console.WriteLine(socket.Read());
                return(true);

            // Handles unknown commands
            default:
                Console.WriteLine("    Command not recognized");
                break;
            }

            return(false);
        }