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(); }
/// <summary> /// Handle the MAIL FROM:<address> 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); } }
/// <summary> /// Handle the RCPT TO:<address> 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); } }
/// <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."); }
/// <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."); }
/// <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); } }
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(); }
/// <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); } }
/// <summary> /// Handle the RCPT TO:<address> 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); } }
/// <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(); } } }
/// <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(); } } }
/// <summary> /// Sends the welcome greeting to the client. /// </summary> private void SendWelcomeMessage(SmtpContext context) { context.WriteLine(WelcomeMessage); }
/// <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); } } }
/// <summary> /// Handle the MAIL FROM:<address> 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); } }
/// <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); } }
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(); }
/// <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."); }
/// <summary> /// Sends the welcome greeting to the client. /// </summary> private void SendWelcomeMessage(SmtpContext context) { context.WriteLine(this.WelcomeMessage); }