예제 #1
0
        private void Data(SmtpContext context)
        {
            context.WriteLine(MESSAGE_START_DATA);

            SmtpMessage   message        = context.Message;
            IPEndPoint    clientEndPoint = (IPEndPoint)context.Socket.RemoteEndPoint;
            StringBuilder header         = new StringBuilder();

            header.Append(String.Format("Received: from ({0} [{1}])", context.ClientDomain, clientEndPoint.Address));
            header.Append("\r\n");
            header.Append("     " + System.DateTime.Now);
            header.Append("\r\n");

            message.AddData(header.ToString());

            header.Length = 0;

            String line = context.ReadLine();

            while (!line.Equals("."))
            {
                message.AddData(line);
                message.AddData("\r\n");
                line = context.ReadLine();
            }

            // Spool the message
            lock (messageSpool)
                messageSpool.Add(message);

            context.WriteLine(MESSAGE_OK);

            // Reset the connection.
            context.Reset();
        }
예제 #2
0
        /// <summary>
        /// Handle the MAIL FROM:&lt;address&gt; command.
        /// </summary>
        private void Mail(SmtpContext context, string argument)
        {
            bool addressValid = false;

            if (context.LastCommand == COMMAND_HELO)
            {
                string address = this.ParseAddress(argument);
                if (address != null)
                {
                    try
                    {
                        // EmailAddress emailAddress = new EmailAddress(address);
                        // context.Message.FromAddress = emailAddress;
                        context.LastCommand = COMMAND_MAIL;
                        addressValid        = true;
                        context.WriteLine(MESSAGE_OK);
                    }
                    catch
                    {
                        // This is fine, just fall through.
                    }
                }

                // If the address is invalid, inform the client.
                if (!addressValid)
                {
                    context.WriteLine(MESSAGE_INVALID_ADDRESS);
                }
            }
            else
            {
                context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
            }
        }
예제 #3
0
 /// <summary>
 /// Handle the RCPT TO:&lt;address&gt; command.
 /// </summary>
 private void Rcpt(SmtpContext context, string argument)
 {
     if (context.LastCommand == COMMAND_MAIL || context.LastCommand == COMMAND_RCPT)
     {
         string address = this.ParseAddress(argument);
         if (address != null)
         {
             try
             {
                 EmailAddress emailAddress = new EmailAddress(address);
                 context.Message.AddRecipient(emailAddress);
                 context.LastCommand = COMMAND_RCPT;
                 context.WriteLine(MESSAGE_OK);
             }
             catch
             {
                 context.WriteLine(MESSAGE_INVALID_ADDRESS);
             }
         }
         else
         {
             context.WriteLine(MESSAGE_INVALID_ADDRESS);
         }
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #4
0
 /// <summary>
 /// ProcessConnection handles a connected TCP Client
 /// and performs all necessary interaction with this
 /// client to comply with RFC821.  This method is thread
 /// safe.
 /// </summary>
 public void ProcessConnection(Socket socket)
 {
     _Context = new SmtpContext(socket);
     _Log.Debug("Sending welcome message.");
     SendWelcomeMessage(_Context);
     _Log.Debug("Welcome message sent.");
     _Log.Debug("Processing Commands.");
     ProcessCommands(_Context);
     _Log.Debug("Done processing Commands.");
 }
예제 #5
0
 /// <summary>
 /// ProcessConnection handles a connected TCP Client
 /// and performs all necessary interaction with this
 /// client to comply with RFC821.  This method is thread
 /// safe.
 /// </summary>
 public void ProcessConnection(Socket socket)
 {
     this.context = new SmtpContext(socket);
     this.log.Debug("Sending welcome message.");
     this.SendWelcomeMessage(this.context);
     this.log.Debug("Welcome message sent.");
     this.log.Debug("Processing Commands.");
     this.ProcessCommands(this.context);
     this.log.Debug("Done processing Commands.");
 }
예제 #6
0
 /// <summary>
 /// Reset the connection state.
 /// </summary>
 private void Rset(SmtpContext context)
 {
     if (context.LastCommand != -1)
     {
         // Dump the message and reset the context.
         context.Reset();
         context.WriteLine(MESSAGE_OK);
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #7
0
        private void Data(SmtpContext context)
        {
            context.WriteLine(MESSAGE_START_DATA);

            RawSmtpMessage rawSmtpMessage = context.Message;

            IPEndPoint    clientEndPoint = (IPEndPoint)context.Socket.RemoteEndPoint;
            StringBuilder header         = new StringBuilder();

            header.Append(string.Format("Received: from ({0} [{1}])", context.ClientDomain, clientEndPoint.Address));
            header.Append("\r\n");
            header.Append("     " + System.DateTime.Now);
            header.Append("\r\n");

            rawSmtpMessage.Data.Append(header.ToString());

            header.Length = 0;

            string line = context.ReadLine();

            while (!line.Equals("."))
            {
                rawSmtpMessage.Data.Append(line);
                rawSmtpMessage.Data.Append("\r\n");
                line = context.ReadLine();
            }

            // Spool the message
            lock (this.smtpMessageStore)
            {
                SmtpMessage smtpMessage = new SmtpMessage(rawSmtpMessage);
                if (this.smtpMessageStore != null)
                {
                    this.smtpMessageStore.Add(smtpMessage);
                }

                if (this.MessageReceived != null)
                {
                    this.MessageReceived(this, new MessageReceivedArgs(smtpMessage));
                }
            }

            context.WriteLine(MESSAGE_OK);

            // Reset the connection.
            context.Reset();
        }
예제 #8
0
 /// <summary>
 /// Handles the HELO command.
 /// </summary>
 private void Helo(SmtpContext context, string[] inputs)
 {
     if (context.LastCommand == -1)
     {
         if (inputs.Length == 2)
         {
             context.ClientDomain = inputs[1];
             context.LastCommand  = COMMAND_HELO;
             context.WriteLine(this.HeloResponse);
         }
         else
         {
             context.WriteLine(MESSAGE_INVALID_ARGUMENT_COUNT);
         }
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #9
0
        /// <summary>
        /// Handle the RCPT TO:&lt;address&gt; command.
        /// </summary>
        private void Rcpt(SmtpContext context, string argument)
        {
            if (context.LastCommand == COMMAND_MAIL || context.LastCommand == COMMAND_RCPT)
            {
                string address = ParseAddress(argument);
                if (address != null)
                {
                    try
                    {
                        //EmailAddress emailAddress = new EmailAddress(address);

                        // Check to make sure we want to accept this message.
                        //if (recipientFilter.AcceptRecipient(context, emailAddress))
                        //{
                        EmailAddress emailAddress = new EmailAddress(address);
                        context.Message.AddToAddress(emailAddress);
                        context.LastCommand = COMMAND_RCPT;
                        context.WriteLine(MESSAGE_OK);
                        //}
                        //else
                        //{
                        //    context.WriteLine(MESSAGE_UNKNOWN_USER);
                        //    if (log.IsDebugEnabled) log.Debug(String.Format("Connection {0}: RcptTo address: {1} rejected.  Did not pass Address Filter.", context.ConnectionId, address));
                        //}
                    }
                    catch
                    {
                        context.WriteLine(MESSAGE_INVALID_ADDRESS);
                    }
                }
                else
                {
                    context.WriteLine(MESSAGE_INVALID_ADDRESS);
                }
            }
            else
            {
                context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
            }
        }
예제 #10
0
        /// <summary>
        /// Handles the command input from the client.  This
        /// message returns when the client issues the quit command.
        /// </summary>
        private void ProcessCommands(SmtpContext context)
        {
            bool isRunning = true;
            String inputLine;

            // Loop until the client quits.
            while (isRunning)
            {
                try
                {
                    inputLine = context.ReadLine();
                    if (inputLine == null)
                    {
                        isRunning = false;
                        context.WriteLine(MESSAGE_GOODBYE);
                        context.Close();
                        continue;
                    }

                    String[] inputs = inputLine.Split(" ".ToCharArray());

                    switch (inputs[0].ToLower())
                    {
                        case "helo":
                            Helo(context, inputs);
                            break;
                        case "rset":
                            Rset(context);
                            break;
                        case "noop":
                            context.WriteLine(MESSAGE_OK);
                            break;
                        case "quit":
                            isRunning = false;
                            context.WriteLine(MESSAGE_GOODBYE);
                            context.Close();
                            break;
                        case "mail":
                            if (inputs[1].ToLower().StartsWith("from"))
                            {
                                Mail(context, inputLine.Substring(inputLine.IndexOf(" ")));
                                break;
                            }
                            context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                            break;
                        case "rcpt":
                            if (inputs[1].ToLower().StartsWith("to"))
                            {
                                Rcpt(context, inputLine.Substring(inputLine.IndexOf(" ")));
                                break;
                            }
                            context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                            break;
                        case "data":
                            Data(context);
                            break;
                        default:
                            context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                            break;
                    }
                }
                catch (Exception ex)
                {
                    SocketException sx = ex as SocketException;

                    if (sx != null && sx.ErrorCode == 10060)
                        context.WriteLine(MESSAGE_GOODBYE);
                    //else
                    //    context.WriteLine(MESSAGE_SYSTEM_ERROR);

                    isRunning = false;
                    context.Socket.Dispose();
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Handles the command input from the client.  This
        /// message returns when the client issues the quit command.
        /// </summary>
        private void ProcessCommands(SmtpContext context)
        {
            bool   isRunning = true;
            string inputLine;

            // Loop until the client quits.
            while (isRunning)
            {
                try
                {
                    inputLine = context.ReadLine();
                    if (inputLine == null)
                    {
                        isRunning = false;
                        context.WriteLine(MESSAGE_GOODBYE);
                        context.Close();
                        continue;
                    }

                    string[] inputs = inputLine.Split(" ".ToCharArray());

                    switch (inputs[0].ToLower())
                    {
                    case "helo":
                        this.Helo(context, inputs);
                        break;

                    case "ehlo":
                        context.WriteLine("250-{inputs[1]}");
                        context.WriteLine("250 AUTH PLAIN");
                        context.LastCommand = COMMAND_HELO;
                        break;

                    case "rset":
                        this.Rset(context);
                        break;

                    case "noop":
                        context.WriteLine(MESSAGE_OK);
                        break;

                    case "quit":
                        isRunning = false;
                        context.WriteLine(MESSAGE_GOODBYE);
                        context.Close();
                        break;

                    case "mail":
                        if (inputs[1].ToLower().StartsWith("from"))
                        {
                            this.Mail(context, inputLine.Substring(inputLine.IndexOf(" ")));
                            break;
                        }

                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;

                    case "rcpt":
                        if (inputs[1].ToLower().StartsWith("to"))
                        {
                            this.Rcpt(context, inputLine.Substring(inputLine.IndexOf(" ")));
                            break;
                        }

                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;

                    case "data":
                        this.Data(context);
                        break;

                    case "auth":
                        context.WriteLine("235 Authentication successful.");
                        break;

                    default:
                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    SocketException sx = ex as SocketException;

                    if (sx != null && sx.ErrorCode == 10060)
                    {
                        context.WriteLine(MESSAGE_GOODBYE);
                    }

                    // else
                    //    context.WriteLine(MESSAGE_SYSTEM_ERROR);

                    isRunning = false;
                    context.Socket.Dispose();
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Sends the welcome greeting to the client.
 /// </summary>
 private void SendWelcomeMessage(SmtpContext context)
 {
     context.WriteLine(WelcomeMessage);
 }
예제 #13
0
 /// <summary>
 /// Reset the connection state.
 /// </summary>
 private void Rset(SmtpContext context)
 {
     if (context.LastCommand != -1)
     {
         // Dump the message and reset the context.
         context.Reset();
         context.WriteLine(MESSAGE_OK);
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #14
0
        /// <summary>
        /// Handles the command input from the client.  This
        /// message returns when the client issues the quit command.
        /// </summary>
        private void ProcessCommands(SmtpContext context)
        {
            bool   isRunning = true;
            String inputLine;

            // Loop until the client quits.
            while (isRunning)
            {
                try
                {
                    inputLine = context.ReadLine();
                    if (inputLine == null)
                    {
                        isRunning = false;
                        context.Close();
                        continue;
                    }

                    String[] inputs = inputLine.Split(" ".ToCharArray());

                    switch (inputs[0].ToLower())
                    {
                    case "helo":
                        Helo(context, inputs);
                        break;

                    case "rset":
                        Rset(context);
                        break;

                    case "noop":
                        context.WriteLine(MESSAGE_OK);
                        break;

                    case "quit":
                        isRunning = false;
                        context.WriteLine(MESSAGE_GOODBYE);
                        context.Close();
                        break;

                    case "mail":
                        if (inputs[1].ToLower().StartsWith("from"))
                        {
                            Mail(context, inputLine.Substring(inputLine.IndexOf(" ")));
                            break;
                        }
                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;

                    case "rcpt":
                        if (inputs[1].ToLower().StartsWith("to"))
                        {
                            Rcpt(context, inputLine.Substring(inputLine.IndexOf(" ")));
                            break;
                        }
                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;

                    case "data":
                        Data(context);
                        break;

                    default:
                        context.WriteLine(MESSAGE_UNKNOWN_COMMAND);
                        break;
                    }
                }
                catch
                {
                    context.WriteLine(MESSAGE_SYSTEM_ERROR);
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Handle the MAIL FROM:&lt;address&gt; command.
        /// </summary>
        private void Mail(SmtpContext context, string argument)
        {
            bool addressValid = false;
            if (context.LastCommand == COMMAND_HELO)
            {
                string address = ParseAddress(argument);
                if (address != null)
                {
                    try
                    {
                        EmailAddress emailAddress = new EmailAddress(address);
                        context.Message.FromAddress = emailAddress;
                        context.LastCommand = COMMAND_MAIL;
                        addressValid = true;
                        context.WriteLine(MESSAGE_OK);
                    }
                    catch
                    {
                        // This is fine, just fall through.
                    }
                }

                // If the address is invalid, inform the client.
                if (!addressValid)
                {
                    context.WriteLine(MESSAGE_INVALID_ADDRESS);
                }
            }
            else
            {
                context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
            }
        }
예제 #16
0
 /// <summary>
 /// Handles the HELO command.
 /// </summary>
 private void Helo(SmtpContext context, String[] inputs)
 {
     if (context.LastCommand == -1)
     {
         if (inputs.Length == 2)
         {
             context.ClientDomain = inputs[1];
             context.LastCommand = COMMAND_HELO;
             context.WriteLine(HeloResponse);
         }
         else
         {
             context.WriteLine(MESSAGE_INVALID_ARGUMENT_COUNT);
         }
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #17
0
        private void Data(SmtpContext context)
        {
            context.WriteLine(MESSAGE_START_DATA);

            SmtpMessage message = context.Message;
            IPEndPoint clientEndPoint = (IPEndPoint)context.Socket.RemoteEndPoint;
            StringBuilder header = new StringBuilder();
            header.Append(String.Format("Received: from ({0} [{1}])", context.ClientDomain, clientEndPoint.Address));
            header.Append("\r\n");
            header.Append("     " + System.DateTime.Now);
            header.Append("\r\n");

            message.AddData(header.ToString());

            header.Length = 0;

            String line = context.ReadLine();
            while (!line.Equals("."))
            {
                message.AddData(line);
                message.AddData("\r\n");
                line = context.ReadLine();
            }

            // Spool the message
            lock (smtpMessageStore)
                smtpMessageStore.Add(message);

            context.WriteLine(MESSAGE_OK);

            // Reset the connection.
            context.Reset();
        }
예제 #18
0
 /// <summary>
 /// ProcessConnection handles a connected TCP Client
 /// and performs all necessary interaction with this
 /// client to comply with RFC821.  This method is thread 
 /// safe.
 /// </summary>
 public void ProcessConnection(Socket socket)
 {
     context = new SmtpContext(socket);
     log.Debug("Sending welcome message.");
     SendWelcomeMessage(context);
     log.Debug("Welcome message sent.");
     log.Debug("Processing Commands.");
     ProcessCommands(context);
     log.Debug("Done processing Commands.");
 }
예제 #19
0
 /// <summary>
 /// Handle the RCPT TO:&lt;address&gt; command.
 /// </summary>
 private void Rcpt(SmtpContext context, string argument)
 {
     if (context.LastCommand == COMMAND_MAIL || context.LastCommand == COMMAND_RCPT)
     {
         string address = this.ParseAddress(argument);
         if (address != null)
         {
             try
             {
                 EmailAddress emailAddress = new EmailAddress(address);
                 context.Message.AddRecipient(emailAddress);
                 context.LastCommand = COMMAND_RCPT;
                 context.WriteLine(MESSAGE_OK);
             }
             catch
             {
                 context.WriteLine(MESSAGE_INVALID_ADDRESS);
             }
         }
         else
         {
             context.WriteLine(MESSAGE_INVALID_ADDRESS);
         }
     }
     else
     {
         context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
     }
 }
예제 #20
0
        private void Data(SmtpContext context)
        {
            context.WriteLine(MESSAGE_START_DATA);

            RawSmtpMessage rawSmtpMessage = context.Message;

            IPEndPoint clientEndPoint = (IPEndPoint)context.Socket.RemoteEndPoint;
            StringBuilder header = new StringBuilder();
            header.Append(string.Format("Received: from ({0} [{1}])", context.ClientDomain, clientEndPoint.Address));
            header.Append("\r\n");
            header.Append("     " + System.DateTime.Now);
            header.Append("\r\n");

            rawSmtpMessage.Data.Append(header.ToString());

            header.Length = 0;

            string line = context.ReadLine();
            while (!line.Equals("."))
            {
                rawSmtpMessage.Data.Append(line);
                rawSmtpMessage.Data.Append("\r\n");
                line = context.ReadLine();
            }

            // Spool the message
            lock (this.smtpMessageStore)
            {
                SmtpMessage smtpMessage = new SmtpMessage(rawSmtpMessage);
                if (this.smtpMessageStore != null)
                {
                    this.smtpMessageStore.Add(smtpMessage);
                }

                if (this.MessageReceived != null)
                {
                    this.MessageReceived(this, new MessageReceivedArgs(smtpMessage));
                }
            }

            context.WriteLine(MESSAGE_OK);

            // Reset the connection.
            context.Reset();
        }
예제 #21
0
 /// <summary>
 /// Sends the welcome greeting to the client.
 /// </summary>
 private void SendWelcomeMessage(SmtpContext context)
 {
     context.WriteLine(this.WelcomeMessage);
 }
예제 #22
0
        /// <summary>
        /// Handle the RCPT TO:&lt;address&gt; command.
        /// </summary>
        private void Rcpt(SmtpContext context, string argument)
        {
            if (context.LastCommand == COMMAND_MAIL || context.LastCommand == COMMAND_RCPT)
            {
                string address = ParseAddress(argument);
                if (address != null)
                {
                    try
                    {
                        //EmailAddress emailAddress = new EmailAddress(address);

                        // Check to make sure we want to accept this message.
                        //if (recipientFilter.AcceptRecipient(context, emailAddress))
                        //{
                        EmailAddress emailAddress = new EmailAddress(address);
                        context.Message.AddToAddress(emailAddress);
                        context.LastCommand = COMMAND_RCPT;
                        context.WriteLine(MESSAGE_OK);
                        //}
                        //else
                        //{
                        //    context.WriteLine(MESSAGE_UNKNOWN_USER);
                        //    if (log.IsDebugEnabled) log.Debug(String.Format("Connection {0}: RcptTo address: {1} rejected.  Did not pass Address Filter.", context.ConnectionId, address));
                        //}
                    }
                    catch
                    {
                        context.WriteLine(MESSAGE_INVALID_ADDRESS);
                    }
                }
                else
                {
                    context.WriteLine(MESSAGE_INVALID_ADDRESS);
                }
            }
            else
            {
                context.WriteLine(MESSAGE_INVALID_COMMAND_ORDER);
            }
        }