/// <summary> /// Default constructor. /// </summary> /// <param name="session">Owner SMTP server session.</param> /// <param name="from">MAIL FROM: value.</param> /// <param name="reply">SMTP server reply.</param> /// <exception cref="ArgumentNullException">Is raised when <b>session</b>, <b>from</b> or <b>reply</b> is null reference.</exception> public SMTP_e_MailFrom(SMTP_Session session,SMTP_MailFrom from,SMTP_Reply reply) { if(session == null){ throw new ArgumentNullException("session"); } if(from == null){ throw new ArgumentNullException("from"); } if(reply == null){ throw new ArgumentNullException("reply"); } m_pSession = session; m_pMailFrom = from; m_pReply = reply; }
/// <summary> /// Cleans up any resource being used. /// </summary> public override void Dispose() { if(this.IsDisposed){ return; } base.Dispose(); m_pAuthentications = null; m_EhloHost = null; m_pUser = null; m_pFrom = null; m_pTo = null; if(m_pMessageStream != null){ m_pMessageStream.Dispose(); m_pMessageStream = null; } }
/// <summary> /// Default constructor. /// </summary> /// <param name="session">Owner SMTP server session.</param> /// <param name="from">MAIL FROM: value.</param> /// <param name="reply">SMTP server reply.</param> /// <exception cref="ArgumentNullException">Is raised when <b>session</b>, <b>from</b> or <b>reply</b> is null reference.</exception> public SMTP_e_MailFrom(SMTP_Session session, SMTP_MailFrom from, SMTP_Reply reply) { if (session == null) { throw new ArgumentNullException("session"); } if (from == null) { throw new ArgumentNullException("from"); } if (reply == null) { throw new ArgumentNullException("reply"); } m_pSession = session; m_pMailFrom = from; m_pReply = reply; }
/// <summary> /// Raises <b>MailFrom</b> event. /// </summary> /// <param name="from">MAIL FROM: value.</param> /// <param name="reply">Default SMTP server reply.</param> /// <returns>Returns SMTP server reply what must be sent to the connected client.</returns> private SMTP_Reply OnMailFrom(SMTP_MailFrom from,SMTP_Reply reply) { if(this.MailFrom != null){ SMTP_e_MailFrom eArgs = new SMTP_e_MailFrom(this,from,reply); this.MailFrom(this,eArgs); return eArgs.Reply; } return reply; }
/// <summary> /// Does reset as specified in RFC 5321. /// </summary> private void Reset() { if(this.IsDisposed){ return; } m_pFrom = null; m_pTo.Clear(); m_pMessageStream = null; m_BDatReadedCount = 0; }
private void MAIL(string cmdText) { // RFC 5321 3.1. if(m_SessionRejected){ WriteLine("503 bad sequence of commands: Session rejected."); return; } // RFC 5321 4.1.4. if(string.IsNullOrEmpty(m_EhloHost)){ WriteLine("503 Bad sequence of commands: send EHLO/HELO first."); return; } // RFC 5321 4.1.4. if(m_pFrom != null){ WriteLine("503 Bad sequence of commands: nested MAIL command."); return; } // RFC 3030 BDAT. if(m_pMessageStream != null){ WriteLine("503 Bad sequence of commands: BDAT command is pending."); return; } if(this.Server.MaxTransactions != 0 && m_Transactions >= this.Server.MaxTransactions){ WriteLine("503 Bad sequence of commands: Maximum allowed mail transactions exceeded."); return; } /* RFC 5321 4.1.1.2. mail = "MAIL FROM:" Reverse-path [SP Mail-parameters] CRLF Mail-parameters = esmtp-param *(SP esmtp-param) esmtp-param = esmtp-keyword ["=" esmtp-value] esmtp-keyword = (ALPHA / DIGIT) *(ALPHA / DIGIT / "-") esmtp-value = 1*(%d33-60 / %d62-126) ; any CHAR excluding "=", SP, and control ; characters. If this string is an email address, ; i.e., a Mailbox, then the "xtext" syntax [32] SHOULD be used. Reverse-path = Path / "<>" Path = "<" [ A-d-l ":" ] Mailbox ">" 4.1.1.11. If the server SMTP does not recognize or cannot implement one or more of the parameters associated with a particular MAIL FROM or RCPT TO command, it will return code 555. */ if(cmdText.ToUpper().StartsWith("FROM:")){ // Remove FROM: from command text. cmdText = cmdText.Substring(5).Trim(); } else{ WriteLine("501 Syntax error, syntax: \"MAIL FROM:\" \"<\" address \">\" / \"<>\" [SP Mail-parameters] CRLF"); return; } string address = ""; int size = -1; string body = null; SMTP_DSN_Ret ret = SMTP_DSN_Ret.NotSpecified; string envID = null; // Mailbox not between <>. if(!cmdText.StartsWith("<") || cmdText.IndexOf('>') == -1){ WriteLine("501 Syntax error, syntax: \"MAIL FROM:\" \"<\" address \">\" / \"<>\" [SP Mail-parameters] CRLF"); return; } // Parse mailbox. else{ address = cmdText.Substring(1,cmdText.IndexOf('>') - 1).Trim(); cmdText = cmdText.Substring(cmdText.IndexOf('>') + 1).Trim(); } #region Parse parameters string[] parameters = string.IsNullOrEmpty(cmdText) ? new string[0] : cmdText.Split(' '); foreach(string parameter in parameters){ string[] name_value = parameter.Split(new char[]{'='},2); // SIZE if(this.Server.Extentions.Contains(SMTP_ServiceExtensions.SIZE) && name_value[0].ToUpper() == "SIZE"){ // RFC 1870. // size-value ::= 1*20DIGIT if(name_value.Length == 1){ WriteLine("501 Syntax error: SIZE parameter value must be specified."); return; } if(!int.TryParse(name_value[1],out size)){ WriteLine("501 Syntax error: SIZE parameter value must be integer."); return; } // Message size exceeds maximum allowed message size. if(size > this.Server.MaxMessageSize){ WriteLine("552 Message exceeds fixed maximum message size."); return; } } // BODY else if(this.Server.Extentions.Contains(SMTP_ServiceExtensions._8BITMIME) && name_value[0].ToUpper() == "BODY"){ // RFC 1652. // body-value ::= "7BIT" / "8BITMIME" / "BINARYMIME" // // BINARYMIME - defined in RFC 3030. if(name_value.Length == 1){ WriteLine("501 Syntax error: BODY parameter value must be specified."); return; } if(name_value[1].ToUpper() != "7BIT" && name_value[1].ToUpper() != "8BITMIME" && name_value[1].ToUpper() != "BINARYMIME"){ WriteLine("501 Syntax error: BODY parameter value must be \"7BIT\",\"8BITMIME\" or \"BINARYMIME\"."); return; } body = name_value[1].ToUpper(); } // RET else if(this.Server.Extentions.Contains(SMTP_ServiceExtensions.DSN) && name_value[0].ToUpper() == "RET"){ // RFC 3461 4.3. // ret-value = "FULL" / "HDRS" if(name_value.Length == 1){ WriteLine("501 Syntax error: RET parameter value must be specified."); return; } else if(name_value[1].ToUpper() != "FULL"){ ret = SMTP_DSN_Ret.FullMessage; } else if(name_value[1].ToUpper() != "HDRS"){ ret = SMTP_DSN_Ret.Headers; } else{ WriteLine("501 Syntax error: RET parameter value must be \"FULL\" or \"HDRS\"."); return; } } // ENVID else if(this.Server.Extentions.Contains(SMTP_ServiceExtensions.DSN) && name_value[0].ToUpper() == "ENVID"){ // RFC 3461 4.4. // envid-parameter = "ENVID=" xtext if(name_value.Length == 1){ WriteLine("501 Syntax error: ENVID parameter value must be specified."); return; } envID = name_value[1].ToUpper(); } // AUTH else if(name_value[0].ToUpper() == "AUTH"){ } // Unsupported parameter. else{ WriteLine("555 Unsupported parameter: " + parameter); return; } } #endregion SMTP_MailFrom from = new SMTP_MailFrom(address,size,body,ret,envID); SMTP_Reply reply = new SMTP_Reply(250,"OK."); reply = OnMailFrom(from,reply); // MAIL accepted. if(reply.ReplyCode < 300){ m_pFrom = from; m_Transactions++; } WriteLine(reply.ToString()); }