예제 #1
0
        private byte[] CmdData(SMTPClientData clientData, Stream stream)
        {
            Write(stream, StartMailInput);
            byte[] data      = new byte[MaxMailSize];
            byte[] buffer    = new byte[1024];
            int    lastIndex = 0;

            while (true)
            {
                int startIndex = (lastIndex > 5) ? lastIndex - 5: 0;
                var bytesRead  = stream.Read(buffer, 0, buffer.Length);
                Array.Copy(buffer, 0, data, lastIndex, bytesRead);
                lastIndex = GetEndOfDataIndex(buffer, startIndex);
                if (lastIndex >= 0)
                {
                    break;
                }
                lastIndex += bytesRead;
                if (lastIndex >= data.Length)
                {
                    return(MaxMailSizeExceeded);
                }
            }
            clientData.body = new byte[lastIndex];
            Array.Copy(data, clientData.body, clientData.body.Length);
            return(OkReply);
        }
예제 #2
0
 private byte[] CmdHello(string[] cmd, SMTPClientData clientData)
 {
     if (cmd.Length < 2 || clientData.hostname != null)
     {
         return(ParameterSyntaxError);               //TODO
     }
     clientData.hostname = cmd[1].ToLower();
     return(OkReply);
 }
예제 #3
0
        private byte[] CmdMail(string[] cmd, SMTPClientData clientData)
        {
            if (cmd.Length < 2)
            {
                return(ParameterSyntaxError);
            }
            var segments = cmd[1].Split(':');

            if (segments[0] != "FROM")
            {
                return(ParameterSyntaxError);
            }
            var sender = segments[1];

            if (sender[0] != '<' || sender[sender.Length - 1] != '>')
            {
                return(ParameterSyntaxError);
            }
            clientData.from = sender;
            return(OkReply);
        }
예제 #4
0
        private byte[] CmdAddRecipient(string[] cmd, SMTPClientData clientData)
        {
            if (cmd.Length < 2)
            {
                return(ParameterSyntaxError);
            }
            var segments = cmd[1].Split(':');

            if (segments[0] != "TO")
            {
                return(ParameterSyntaxError);
            }
            var recipient = segments[1];

            if (recipient[0] != '<' || recipient[recipient.Length - 1] != '>')
            {
                return(ParameterSyntaxError);
            }
            clientData.Recipients.Add(recipient);
            return(OkReply);
        }
예제 #5
0
        private void HandleClient(TcpClient client)
        {
            Console.WriteLine("[==] BeepBoop: connection on " + port);
            //client.ReceiveTimeout = client.SendTimeout = timeout;
            Stream stream = client.GetStream();

            if (Certificate != null)
            {
                var sslStream = new SslStream(stream, false);
                Console.WriteLine("Authenticating...");


                sslStream.AuthenticateAsServer(Certificate, false, SslProtocols.Tls, true);
                Console.WriteLine("Authenticated");
                stream = sslStream;
            }
            Write(stream, ServiceReadyReply);

            byte[] reply;
            var    clientData = new SMTPClientData();

            while (client.Connected)
            {
                var cmd = Read(stream)?.Split(' ');
                if (cmd == null)
                {
                    continue;
                }

                switch (cmd[0].ToUpper())
                {
                case "DATA":
                    reply = CmdData(clientData, stream);
                    break;

                case "EXPN":
                    reply = NotImplemented;
                    break;

                case "HELO":
                    reply = CmdHello(cmd, clientData);
                    break;

                case "HELP":
                    reply = NotImplemented;
                    break;

                case "MAIL":
                    reply = CmdMail(cmd, clientData);
                    break;

                case "NOOP":
                    reply = OkReply;
                    break;

                case "QUIT":
                    goto quit;

                case "RCPT":
                    reply = CmdAddRecipient(cmd, clientData);
                    break;

                case "RSET":
                    clientData.Clear();
                    reply = OkReply;
                    break;

                case "SAML":
                    reply = NotImplemented;
                    break;

                case "SEND":
                    reply = NotImplemented;
                    break;

                case "SOML":
                    reply = NotImplemented;
                    break;

                case "TURN":
                    reply = NotImplemented;
                    break;

                case "VRFY":
                    reply = NotImplemented;
                    break;

                default:
                    reply = CommandSyntaxError;
                    break;
                }
                Write(stream, reply);
            }

quit:
            Write(stream, ByeReply);
            client.Close();
            OnMailReceived.Invoke(clientData);
        }