Esempio n. 1
0
        /// <summary>
        /// Dns relay session constructor.
        /// </summary>
        /// <param name="server">Owner relay server.</param>
        /// <param name="realyItem">Relay item.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>server</b> or <b>realyItem</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        internal Relay_Session(Relay_Server server,Relay_QueueItem realyItem)
        {
            if(server == null){
                throw new ArgumentNullException("server");
            }
            if(realyItem == null){
                throw new ArgumentNullException("realyItem");
            }

            m_pServer    = server;
            m_pRelayItem = realyItem;

            m_SessionID         = Guid.NewGuid().ToString();
            m_SessionCreateTime = DateTime.Now;
            m_pTargets          = new List<Relay_Target>();
            m_pSmtpClient       = new SMTP_Client();
        }
Esempio n. 2
0
        /// <summary>
        /// Sends message by using specified smart host.
        /// </summary>
        /// <param name="localHost">Host name which is reported to SMTP server.</param>
        /// <param name="host">Host name or IP address.</param>
        /// <param name="port">Host port.</param>
        /// <param name="ssl">Specifies if connected via SSL.</param>
        /// <param name="userName">SMTP server user name. This value may be null, then authentication not used.</param>
        /// <param name="password">SMTP server password.</param>
        /// <param name="from">Sender email what is reported to SMTP server.</param>
        /// <param name="to">Recipients email addresses.</param>
        /// <param name="message">Raw message to send.</param>
        /// <exception cref="ArgumentNullException">Is raised when argument <b>host</b>,<b>from</b>,<b>to</b> or <b>stream</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the method arguments has invalid value.</exception>
        /// <exception cref="SMTP_ClientException">Is raised when SMTP server returns error.</exception>
        public static void QuickSendSmartHost(string localHost,string host,int port,bool ssl,string userName,string password,string from,string[] to,Stream message)
        {
            if(host == null){
                throw new ArgumentNullException("host");
            }
            if(host == ""){
                throw new ArgumentException("Argument 'host' value may not be empty.");
            }
            if(port < 1){
                throw new ArgumentException("Argument 'port' value must be >= 1.");
            }
            if(from == null){
                throw new ArgumentNullException("from");
            }
            if(from != "" && !SMTP_Utils.IsValidAddress(from)){
                throw new ArgumentException("Argument 'from' has invalid value.");
            }
            if(to == null){
                throw new ArgumentNullException("to");
            }
            if(to.Length == 0){
                throw new ArgumentException("Argument 'to' must contain at least 1 recipient.");
            }
            foreach(string t in to){
                if(!SMTP_Utils.IsValidAddress(t)){
                    throw new ArgumentException("Argument 'to' has invalid value '" + t + "'.");
                }
            }
            if(message == null){
                throw new ArgumentNullException("message");
            }

            using(SMTP_Client smtp = new SMTP_Client()){
                smtp.Connect(host,port,ssl);
                smtp.EhloHelo(localHost != null ? localHost : Dns.GetHostName());
                if(!string.IsNullOrEmpty(userName)){
                    smtp.Auth(smtp.AuthGetStrongestMethod(userName,password));
                }
                smtp.MailFrom(from,-1);
                foreach(string t in to){
                    smtp.RcptTo(t);
                }
                smtp.SendMessage(message);
            }
        }
Esempio n. 3
0
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner SMTP client.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(SMTP_Client owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pSmtpClient = owner;

                SetState(AsyncOP_State.Active);

                try{
                    /* RFC 4954 4. The AUTH Command.

                        AUTH mechanism [initial-response]

                        Arguments:
                            mechanism: A string identifying a [SASL] authentication mechanism.

                            initial-response: An optional initial client response.  If
                            present, this response MUST be encoded as described in Section
                            4 of [BASE64] or contain a single character "=".
                    */

                    if(m_pSASL.SupportsInitialResponse){
                        byte[] buffer = Encoding.UTF8.GetBytes("AUTH " + m_pSASL.Name + " " + Convert.ToBase64String(m_pSASL.Continue(null)) + "\r\n");

                        // Log
                        m_pSmtpClient.LogAddWrite(buffer.Length,Encoding.UTF8.GetString(buffer).TrimEnd());

                        // Start command sending.
                        m_pSmtpClient.TcpStream.BeginWrite(buffer,0,buffer.Length,this.AuthCommandSendingCompleted,null);
                    }
                    else{
                        byte[] buffer = Encoding.UTF8.GetBytes("AUTH " + m_pSASL.Name + "\r\n");

                        // Log
                        m_pSmtpClient.LogAddWrite(buffer.Length,"AUTH " + m_pSASL.Name);

                        // Start command sending.
                        m_pSmtpClient.TcpStream.BeginWrite(buffer,0,buffer.Length,this.AuthCommandSendingCompleted,null);
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    m_pSmtpClient.LogAddException("Exception: " + x.Message,x);
                    SetState(AsyncOP_State.Completed);
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
Esempio n. 4
0
        /// <summary>
        /// Is called when RCPT command has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void RcptCommandCompleted(SMTP_Client.RcptToAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                else{
                    // Start sending message.
                    SMTP_Client.SendMessageAsyncOP sendMsgOP = new SMTP_Client.SendMessageAsyncOP(m_pRelayItem.MessageStream,false);
                    sendMsgOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.SendMessageAsyncOP> e){
                        MessageSendingCompleted(sendMsgOP);
                    };
                    if(!m_pSmtpClient.SendMessageAsync(sendMsgOP)){
                        MessageSendingCompleted(sendMsgOP);
                    }
                }
            }
            catch(Exception x){
                Dispose(x);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Is called when message sending has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void MessageSendingCompleted(SMTP_Client.SendMessageAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                // Message sent sucessfully.
                else{
                    Dispose(null);
                }
            }
            catch(Exception x){
                Dispose(x);
            }

            op.Dispose();
        }
Esempio n. 6
0
        /// <summary>
        /// Is called when MAIL command has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void MailCommandCompleted(SMTP_Client.MailFromAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                else{
                    SMTP_Client.RcptToAsyncOP rcptOP = new SMTP_Client.RcptToAsyncOP(
                        this.To,
                        IsDsnSupported() ? m_pRelayItem.DSN_Notify : SMTP_DSN_Notify.NotSpecified,
                        IsDsnSupported() ? m_pRelayItem.OriginalRecipient : null
                    );
                    rcptOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.RcptToAsyncOP> e){
                        RcptCommandCompleted(rcptOP);
                    };
                    if(!m_pSmtpClient.RcptToAsync(rcptOP)){
                        RcptCommandCompleted(rcptOP);
                    }
                }
            }
            catch(Exception x){
                Dispose(x);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Is called when EHLO/HELO command has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void EhloCommandCompleted(SMTP_Client.EhloHeloAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                else{
                    // Start TLS requested, start switching to secure.
                    if(!m_pSmtpClient.IsSecureConnection && m_pActiveTarget.SslMode == SslMode.TLS){
                        SMTP_Client.StartTlsAsyncOP startTlsOP = new SMTP_Client.StartTlsAsyncOP(null);
                        startTlsOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.StartTlsAsyncOP> e){
                            StartTlsCommandCompleted(startTlsOP);
                        };
                        if(!m_pSmtpClient.StartTlsAsync(startTlsOP)){
                            StartTlsCommandCompleted(startTlsOP);
                        }
                    }
                    // Authentication requested, start authenticating.
                    else if(!string.IsNullOrEmpty(m_pActiveTarget.UserName)){
                        SMTP_Client.AuthAsyncOP authOP = new SMTP_Client.AuthAsyncOP(m_pSmtpClient.AuthGetStrongestMethod(m_pActiveTarget.UserName,m_pActiveTarget.Password));
                        authOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.AuthAsyncOP> e){
                            AuthCommandCompleted(authOP);
                        };
                        if(!m_pSmtpClient.AuthAsync(authOP)){
                            AuthCommandCompleted(authOP);
                        }
                    }
                    // Start MAIL command.
                    else{
                        long messageSize = -1;
                        try{
                            messageSize = m_pRelayItem.MessageStream.Length - m_pRelayItem.MessageStream.Position;
                        }
                        catch{
                            // Stream doesn't support seeking.
                        }

                        SMTP_Client.MailFromAsyncOP mailOP = new SMTP_Client.MailFromAsyncOP(
                            this.From,
                            messageSize,
                            IsDsnSupported() ? m_pRelayItem.DSN_Ret : SMTP_DSN_Ret.NotSpecified,
                            IsDsnSupported() ? m_pRelayItem.EnvelopeID : null
                        );
                        mailOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.MailFromAsyncOP> e){
                            MailCommandCompleted(mailOP);
                        };
                        if(!m_pSmtpClient.MailFromAsync(mailOP)){
                            MailCommandCompleted(mailOP);
                        }
                    }
                }
            }
            catch(Exception x){
                Dispose(x);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Is called when AUTH command has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void AuthCommandCompleted(SMTP_Client.AuthAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                else{
                    long messageSize = -1;
                    try{
                        messageSize = m_pRelayItem.MessageStream.Length - m_pRelayItem.MessageStream.Position;
                    }
                    catch{
                        // Stream doesn't support seeking.
                    }

                    SMTP_Client.MailFromAsyncOP mailOP = new SMTP_Client.MailFromAsyncOP(
                        this.From,
                        messageSize,
                        IsDsnSupported() ? m_pRelayItem.DSN_Ret : SMTP_DSN_Ret.NotSpecified,
                        IsDsnSupported() ? m_pRelayItem.EnvelopeID : null
                    );
                    mailOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.MailFromAsyncOP> e){
                        MailCommandCompleted(mailOP);
                    };
                    if(!m_pSmtpClient.MailFromAsync(mailOP)){
                        MailCommandCompleted(mailOP);
                    }
                }
            }
            catch(Exception x){
                Dispose(x);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Completes relay session and does clean up. This method is thread-safe.
        /// </summary>
        /// <param name="exception">Exception happened or null if relay completed successfully.</param>
        public void Dispose(Exception exception)
        {
            try{
                lock(this){
                    if(m_IsDisposed){
                        return;
                    }
                    try{
                        m_pServer.OnSessionCompleted(this,exception);
                    }
                    catch{
                    }
                    m_pServer.Sessions.Remove(this);
                    m_IsDisposed = true;

                    m_pLocalBindInfo = null;
                    m_pRelayItem = null;
                    m_pSmartHosts = null;
                    if(m_pSmtpClient != null){
                        m_pSmtpClient.Dispose();
                        m_pSmtpClient = null;
                    }
                    m_pTargets = null;
                    if(m_pActiveTarget != null){
                        m_pServer.RemoveIpUsage(m_pActiveTarget.Target.Address);
                        m_pActiveTarget = null;
                    }
                    m_pServer = null;
                }
            }
            catch(Exception x){
                if(m_pServer != null){
                    m_pServer.OnError(x);
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Is called when STARTTLS command has completed.
        /// </summary>
        /// <param name="op">Asynchronous operation.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        private void StartTlsCommandCompleted(SMTP_Client.StartTlsAsyncOP op)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            try{
                if(op.Error != null){
                    Dispose(op.Error);
                }
                else{
                    // Do EHLO/HELO.
                    SMTP_Client.EhloHeloAsyncOP ehloOP = new SMTP_Client.EhloHeloAsyncOP(null);
                    ehloOP.CompletedAsync += delegate(object s,EventArgs<SMTP_Client.EhloHeloAsyncOP> e){
                        EhloCommandCompleted(ehloOP);
                    };
                    if(!m_pSmtpClient.EhloHeloAsync(ehloOP)){
                        EhloCommandCompleted(ehloOP);
                    }
                }
            }
            catch(Exception x){
                Dispose(x);
            }
        }