コード例 #1
0
 /// <summary>
 /// Sends the welcome greeting to the client.
 /// </summary>
 private void SendWelcomeMessage(SMTPContext context)
 {
     context.WriteLine(WelcomeMessage);
 }
コード例 #2
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;

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

                    Log.DebugFormat(Resources.Log_ProcessCommands_ProcessCommands_Read_0, inputLine);
                    String[] inputs = inputLine.Split(" ".ToCharArray());

                    var messageUnknownCommand = Resources.Protocol_MESSAGE_UNKNOWN_COMMAND_500_Command_Unrecognized;
                    switch (inputs[0].ToLower())
                    {
                        case "helo":
                            Helo(context, inputs);
                            break;
                        case "rset":
                            Rset(context);
                            break;
                        case "noop":
                            context.WriteLine(Resources.Protocol_MESSAGE_OK_250_OK);
                            break;
                        case "quit":
                            isRunning = false;
                            context.WriteLine(Resources.Protocol_MESSAGE_GOODBYE_221_Goodbye);
                            context.Close();
                            break;
                        case "mail":
                            if (inputs[1].ToLower().StartsWith("from"))
                            {
                                Mail(context, inputLine.Substring(inputLine.IndexOf(" ", StringComparison.Ordinal)));
                                break;
                            }
                            context.WriteLine(messageUnknownCommand);
                            break;
                        case "rcpt":
                            if (inputs[1].ToLower().StartsWith("to"))
                            {
                                Rcpt(context, inputLine.Substring(inputLine.IndexOf(" ", StringComparison.Ordinal)));
                                break;
                            }
                            context.WriteLine(messageUnknownCommand);
                            break;
                        case "data":
                            Data(context);
                            break;
                        default:
                            context.WriteLine(messageUnknownCommand);
                            break;
                    }
                }
                catch (Exception exception)
                {
                    Log.ErrorFormat(
                        Resources.Log_ProcessCommands_Connection_0_Exception_occured_while_processing_commands_1,
                        context.ConnectionId, exception, exception);
                    context.WriteLine(Resources.Protocol_MESSAGE_SYSTEM_ERROR_554_Transaction_failed);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Handle the RCPT TO:&lt;address&gt; command.
        /// </summary>
        private void Rcpt(SMTPContext context, string argument)
        {
            if (context.LastCommand == CommandMail || context.LastCommand == CommandRcpt)
            {
                string address = ParseAddress(argument);
                var messageInvalidAddress = Resources.Protocol_MESSAGE_INVALID_ADDRESS_451_Address_is_invalid;
                if (address != null)
                {
                    try
                    {
                        var emailAddress = new MailAddress(address);

                        // Check to make sure we want to accept this message.
                        if (_recipientFilter.AcceptRecipient(context, emailAddress))
                        {
                            context.Message.AddToAddress(emailAddress);
                            context.LastCommand = CommandRcpt;
                            context.WriteLine(Resources.Protocol_MESSAGE_OK_250_OK);
                            if (Log.IsDebugEnabled)
                                Log.DebugFormat(Resources.Log_Connection_0_RcptTo_address_1_accepted,
                                                context.ConnectionId, address);
                        }
                        else
                        {
                            context.WriteLine(Resources.Protocol_MESSAGE_UNKNOWN_USER_550_User_does_not_exist);
                            if (Log.IsDebugEnabled)
                                Log.DebugFormat(
                                    Resources.Log_Connection_0_RcptTo_address_1_rejected_Did_not_pass_Address_Filter,
                                    context.ConnectionId, address);
                        }
                    }
                    catch (FormatException)
                    {
                        if (Log.IsDebugEnabled)
                            Log.DebugFormat(
                                Resources.Log_Connection_0_RcptTo_argument_1_rejected_Should_be_from_username_domain_com,
                                context.ConnectionId, argument);
                        context.WriteLine(messageInvalidAddress);
                    }
                }
                else
                {
                    if (Log.IsDebugEnabled)
                        Log.DebugFormat(
                            Resources.Log_Connection_0_RcptTo_argument_1_rejected_Should_be_from_username_domain_com,
                            context.ConnectionId, argument);
                    context.WriteLine(messageInvalidAddress);
                }
            }
            else
            {
                context.WriteLine(Resources.Protocol_MESSAGE_INVALID_COMMAND_ORDER_503_Command_not_allowed_here);
            }
        }
コード例 #4
0
 /// <summary>
 /// Handles the HELO command.
 /// </summary>
 private void Helo(SMTPContext context, IList<string> inputs)
 {
     if (context.LastCommand == -1)
     {
         if (inputs.Count == 2)
         {
             context.ClientDomain = inputs[1];
             context.LastCommand = CommandHelo;
             context.WriteLine(HeloResponse);
         }
         else
         {
             context.WriteLine(Resources.Protocol_MESSAGE_INVALID_ARGUMENT_COUNT__501_Incorrect_number_of_arguments);
         }
     }
     else
     {
         context.WriteLine(Resources.Protocol_MESSAGE_INVALID_COMMAND_ORDER_503_Command_not_allowed_here);
     }
 }
コード例 #5
0
        private void Data(SMTPContext context)
        {
            context.WriteLine(Resources.Protocol_MESSAGE_START_DATA__354_Start_mail_input_end_with_CRLF_CRLF);

            SMTPMessage message = context.Message;
            var clientEndPoint = (IPEndPoint)context.Socket.RemoteEndPoint;
            var header = new StringBuilder();
            header.AppendFormat(Resources.EMAIL_Received_from_0_0_1, context.ClientDomain, clientEndPoint.Address);
            header.AppendLine();
            header.AppendFormat(Resources.EMAIL_by_0_Eric_Daugherty_s_C_Email_Server, _domain);
            header.AppendLine();
            header.Append("     " + DateTime.Now);
            header.AppendLine();

            message.AddData(header.ToString());

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

            // Spool the message
            _messageSpool.SpoolMessage(message);
            context.WriteLine(Resources.Protocol_MESSAGE_OK_250_OK);

            // Reset the connection.
            context.Reset();
        }
コード例 #6
0
 /// <summary>
 /// Reset the connection state.
 /// </summary>
 private static void Rset(SMTPContext context)
 {
     if (context.LastCommand != -1)
     {
         // Dump the message and reset the context.
         context.Reset();
         context.WriteLine(Resources.Protocol_MESSAGE_OK_250_OK);
     }
     else
     {
         context.WriteLine(Resources.Protocol_MESSAGE_INVALID_COMMAND_ORDER_503_Command_not_allowed_here);
     }
 }
コード例 #7
0
        /// <summary>
        /// Handle the MAIL FROM:&lt;address&gt; command.
        /// </summary>
        private static void Mail(SMTPContext context, string argument)
        {
            bool addressValid = false;
            if (context.LastCommand == CommandHelo)
            {
                string address = ParseAddress(argument);
                if (address != null)
                {
                    try
                    {
                        var emailAddress = new MailAddress(address);
                        context.Message.FromAddress = emailAddress;
                        context.LastCommand = CommandMail;
                        addressValid = true;
                        context.WriteLine(Resources.Protocol_MESSAGE_OK_250_OK);
                        if (Log.IsDebugEnabled)
                            Log.DebugFormat(Resources.Log_Mail_Connection_0_MailFrom_address_1_accepted,
                                            context.ConnectionId, address);
                    }
                    catch (FormatException ex)
                    {
                        Log.Warn(Resources.Log_Invalid_E_Mail_address_detected, ex);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(Resources.Log_Unknown_exception_occured, ex);
                    }
                }

                // If the address is invalid, inform the client.
                if (!addressValid)
                {
                    if (Log.IsDebugEnabled)
                        Log.DebugFormat(
                            Resources.Log_Connection_0_MailFrom_argument_1_rejected_Should_be_from_username_domain_com,
                            context.ConnectionId, argument);
                    context.WriteLine(Resources.Protocol_MESSAGE_INVALID_ADDRESS_451_Address_is_invalid);
                }
            }
            else
            {
                context.WriteLine(Resources.Protocol_MESSAGE_INVALID_COMMAND_ORDER_503_Command_not_allowed_here);
            }
        }
コード例 #8
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)
        {
            long currentConnectionId;
            // Really only need to lock on the long, but that is not
            // allowed.  Is there a better way to do this?
            lock (this)
            {
                currentConnectionId = _connectionId++;
            }

            using (SMTPContext context = new SMTPContext(currentConnectionId, socket))
            {
                try
                {
                    SendWelcomeMessage(context);

                    ProcessCommands(context);
                }
                catch (Exception exception)
                {
                    Log.ErrorFormat(
                        Resources.Log_ProcessConnection_Connection_0_Error_1,
                        context.ConnectionId,
                        exception);
                }
            }
        }