/// <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;
        }
Beispiel #2
0
        /// <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;
            }
        }
Beispiel #3
0
        /// <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;
        }
Beispiel #4
0
        /// <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;
        }
Beispiel #5
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());
        }