Exemple #1
0
        public Task <MailSentStatus> Send(EMailEnvelop EMailEnvelop,
                                          Byte NumberOfRetries = 3,
                                          Boolean AutoStart    = true)
        {
            var SendMailTask = new Task <MailSentStatus>(() => {
                lock (this) {
                    switch (Connect())
                    {
                    case Sockets.TCP.TCPConnectResult.InvalidDomainName:
                        return(MailSentStatus.failed);

                    case Sockets.TCP.TCPConnectResult.NoIPAddressFound:
                        return(MailSentStatus.failed);

                    case Sockets.TCP.TCPConnectResult.UnknownError:
                        return(MailSentStatus.failed);

                    case Sockets.TCP.TCPConnectResult.Ok:

                        // 220 mail.ahzf.de ESMTP Postfix (Debian/GNU)
                        var LoginResponse = this.ReadSMTPResponse();
                        if (LoginResponse.StatusCode != SMTPStatusCode.ServiceReady)
                        {
                            throw new SMTPClientException("SMTP login error: " + LoginResponse.ToString());
                        }

                        switch (LoginResponse.StatusCode)
                        {
                        case SMTPStatusCode.ServiceReady:

                            #region Send EHLO

                            var EHLOResponses = SendCommandAndWaits("EHLO " + LocalDomain);

                            // 250-mail.ahzf.de
                            // 250-PIPELINING
                            // 250-SIZE 30720000
                            // 250-VRFY
                            // 250-ETRN
                            // 250-STARTTLS
                            // 250-AUTH LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-AUTH=LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-ENHANCEDSTATUSCODES
                            // 250-8BITMIME
                            // 250 DSN

                            if (EHLOResponses.Any(v => v.StatusCode != SMTPStatusCode.Ok))
                            {
                                var Error = EHLOResponses.Where(v => v.StatusCode != SMTPStatusCode.Ok).
                                            FirstOrDefault();

                                if (Error.StatusCode != SMTPStatusCode.Ok)
                                {
                                    throw new SMTPClientException("SMTP EHLO command error: " + Error.ToString());
                                }
                            }

                            #endregion

                            #region Check for STARTTLS

                            if (UseTLS == TLSUsage.STARTTLS)
                            {
                                if (EHLOResponses.Any(v => v.Response == "STARTTLS"))
                                {
                                    var StartTLSResponse = SendCommandAndWait("STARTTLS");

                                    if (StartTLSResponse.StatusCode == SMTPStatusCode.ServiceReady)
                                    {
                                        EnableTLS();
                                    }
                                }

                                else
                                {
                                    throw new Exception("TLS is not supported by the SMTP server!");
                                }

                                // Send EHLO again in order to get the new list of supported extensions!
                                EHLOResponses = SendCommandAndWaits("EHLO " + LocalDomain);
                            }

                            #endregion

                            #region Analyze EHLO responses and set SMTP capabilities

                            // 250-mail.ahzf.de
                            // 250-PIPELINING
                            // 250-SIZE 30720000
                            // 250-VRFY
                            // 250-ETRN
                            // 250-STARTTLS
                            // 250-AUTH LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-AUTH=LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-ENHANCEDSTATUSCODES
                            // 250-8BITMIME
                            // 250 DSN

                            var MailServerName = EHLOResponses.FirstOrDefault();

                            EHLOResponses.Skip(1).ForEach(v => {
                                #region PIPELINING

                                if (v.Response == "PIPELINING")
                                {
                                    Capabilities |= SmtpCapabilities.Pipelining;
                                }

                                #endregion

                                #region SIZE

                                else if (v.Response.StartsWith("SIZE "))
                                {
                                    Capabilities |= SmtpCapabilities.Size;

                                    if (!UInt64.TryParse(v.Response.Substring(5), out _MaxMailSize))
                                    {
                                        throw new Exception("Invalid SIZE capability!");
                                    }
                                }

                                #endregion

                                //   else if (v.Response == "VRFY")
                                //       Capabilities |= SmtpCapabilities.;

                                //   else if (v.Response == "ETRN")
                                //       Capabilities |= SmtpCapabilities.;

                                #region STARTTLS

                                if (v.Response == "STARTTLS")
                                {
                                    Capabilities |= SmtpCapabilities.StartTLS;
                                }

                                #endregion

                                #region AUTH

                                else if (v.Response.StartsWith("AUTH "))
                                {
                                    Capabilities |= SmtpCapabilities.Authentication;

                                    SMTPAuthMethods ParsedAuthMethod;
                                    var AuthType    = v.Response.Substring(4, 1);
                                    var AuthMethods = v.Response.Substring(5).Split(' ');

                                    // GMail: "AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN"
                                    foreach (var AuthMethod in AuthMethods)
                                    {
                                        if (Enum.TryParse <SMTPAuthMethods>(AuthMethod.Replace('-', '_'), true, out ParsedAuthMethod))
                                        {
                                            if (AuthType == " ")
                                            {
                                                _AuthMethods |= ParsedAuthMethod;
                                            }
                                        }
                                        else
                                        {
                                            _UnknownAuthMethods.Add(AuthMethod);
                                        }
                                    }
                                }

                                #endregion

                                #region ENHANCEDSTATUSCODES

                                if (v.Response == "ENHANCEDSTATUSCODES")
                                {
                                    Capabilities |= SmtpCapabilities.EnhancedStatusCodes;
                                }

                                #endregion

                                #region 8BITMIME

                                if (v.Response == "8BITMIME")
                                {
                                    Capabilities |= SmtpCapabilities.EightBitMime;
                                }

                                #endregion

                                #region DSN

                                if (v.Response == "DSN")
                                {
                                    Capabilities |= SmtpCapabilities.Dsn;
                                }

                                #endregion

                                #region BINARYMIME

                                if (v.Response == "BINARYMIME")
                                {
                                    Capabilities |= SmtpCapabilities.BinaryMime;
                                }

                                #endregion

                                #region CHUNKING

                                if (v.Response == "CHUNKING")
                                {
                                    Capabilities |= SmtpCapabilities.Chunking;
                                }

                                #endregion

                                #region UTF8

                                if (v.Response == "UTF8")
                                {
                                    Capabilities |= SmtpCapabilities.UTF8;
                                }

                                #endregion
                            });

                            #endregion

                            #region Auth PLAIN...

                            if (_AuthMethods.HasFlag(SMTPAuthMethods.PLAIN))
                            {
                                var AuthPLAINResponse = SendCommandAndWait("AUTH PLAIN " +
                                                                           Convert.ToBase64String(ByteZero.
                                                                                                  Concat(_Login.ToUTF8Bytes()).
                                                                                                  Concat(ByteZero).
                                                                                                  Concat(_Password.ToUTF8Bytes()).
                                                                                                  ToArray()));
                            }

                            #endregion

                            #region ...or Auth LOGIN...

                            else if (_AuthMethods.HasFlag(SMTPAuthMethods.LOGIN))
                            {
                                var AuthLOGIN1Response = SendCommandAndWait("AUTH LOGIN");
                                var AuthLOGIN2Response = SendCommandAndWait(Convert.ToBase64String(_Login.ToUTF8Bytes()));
                                var AuthLOGIN3Response = SendCommandAndWait(Convert.ToBase64String(_Password.ToUTF8Bytes()));
                            }

                            #endregion

                            #region ...or AUTH CRAM-MD5

                            else if (_AuthMethods.HasFlag(SMTPAuthMethods.CRAM_MD5))
                            {
                                var AuthCRAMMD5Response = SendCommandAndWait("AUTH CRAM-MD5");

                                if (AuthCRAMMD5Response.StatusCode == SMTPStatusCode.AuthenticationChallenge)
                                {
                                    var aa = Ext2.CRAM_MD5("<*****@*****.**>",
                                                           "tim", "tanstaaftanstaaf");
                                    var a2 = Convert.ToBase64String(aa) == "dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw";


                                    var bb = Ext2.CRAM_MD5("<*****@*****.**>",
                                                           "alice", "wonderland");
                                    var b2 = Convert.ToBase64String(bb) == "YWxpY2UgNjRiMmE0M2MxZjZlZDY4MDZhOTgwOTE0ZTIzZTc1ZjA=";

                                    var cc = Ext2.CRAM_MD5("<*****@*****.**>", "ahzf", "ahzf2305!");

                                    var zz = Ext2.CRAM_MD5(Convert.FromBase64String(AuthCRAMMD5Response.Response).ToUTF8String(),
                                                           _Login, _Password);

                                    var AuthPLAINResponse = SendCommandAndWait(Convert.ToBase64String(zz));
                                }
                            }

                            #endregion

                            #region MAIL FROM:

                            foreach (var MailFrom in EMailEnvelop.MailFrom)
                            {
                                // MAIL FROM:<*****@*****.**>
                                /// 250 2.1.0 Ok
                                var MailFromCommand = "MAIL FROM: <" + MailFrom.Address.ToString() + ">";

                                if (Capabilities.HasFlag(SmtpCapabilities.EightBitMime))
                                {
                                    MailFromCommand += " BODY=8BITMIME";
                                }
                                else if (Capabilities.HasFlag(SmtpCapabilities.BinaryMime))
                                {
                                    MailFromCommand += " BODY=BINARYMIME";
                                }

                                var _MailFromResponse = SendCommandAndWait(MailFromCommand);
                                if (_MailFromResponse.StatusCode != SMTPStatusCode.Ok)
                                {
                                    throw new SMTPClientException("SMTP MAIL FROM command error: " + _MailFromResponse.ToString());
                                }
                            }

                            #endregion

                            #region RCPT TO(s):

                            // RCPT TO:<*****@*****.**>
                            /// 250 2.1.5 Ok
                            EMailEnvelop.RcptTo.ForEach(Rcpt => {
                                var _RcptToResponse = SendCommandAndWait("RCPT TO: <" + Rcpt.Address.ToString() + ">");

                                switch (_RcptToResponse.StatusCode)
                                {
                                case SMTPStatusCode.UserNotLocalWillForward:
                                case SMTPStatusCode.Ok:
                                    break;

                                case SMTPStatusCode.UserNotLocalTryAlternatePath:
                                case SMTPStatusCode.MailboxNameNotAllowed:
                                case SMTPStatusCode.MailboxUnavailable:
                                case SMTPStatusCode.MailboxBusy:
                                //    throw new SmtpCommandException(SmtpErrorCode.RecipientNotAccepted, _RcptToResponse.StatusCode, mailbox, _RcptToResponse.Response);

                                case SMTPStatusCode.AuthenticationRequired:
                                    throw new UnauthorizedAccessException(_RcptToResponse.Response);

                                    //default:
                                    //    throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, _RcptToResponse.StatusCode, _RcptToResponse.Response);
                                }

                                //Debug.WriteLine(_RcptToResponse);
                            });

                            #endregion

                            #region Mail DATA

                            // The encoded MIME text lines must not be longer than 76 characters!

                            /// 354 End data with <CR><LF>.<CR><LF>
                            var _DataResponse = SendCommandAndWait("DATA");
                            if (_DataResponse.StatusCode != SMTPStatusCode.StartMailInput)
                            {
                                throw new SMTPClientException("SMTP DATA command error: " + _DataResponse.ToString());
                            }

                            // Send e-mail headers...
                            if (EMailEnvelop.Mail != null)
                            {
                                EMailEnvelop.Mail.
                                Header.
                                Select(header => header.Key + ": " + header.Value).
                                ForEach(line => SendCommand(line));

                                //SendCommand("Message-Id: <" + (EMailEnvelop.Mail.MessageId != null
                                //                                    ? EMailEnvelop.Mail.MessageId.ToString()
                                //                                    : GenerateMessageId(EMailEnvelop.Mail, RemoteHost).ToString()) + ">");

                                SendCommand("");

                                // Send e-mail body(parts)...
                                //if (EMailEnvelop.Mail.MailBody != null)
                                //{
                                EMailEnvelop.Mail.Body.ToText(false).ForEach(line => SendCommand(line));
                                SendCommand("");
                                //}
                            }

                            else if (EMailEnvelop.Mail.ToText != null)
                            {
                                EMailEnvelop.Mail.ToText.ForEach(line => SendCommand(line));
                                SendCommand("");
                            }

                            #endregion

                            #region End-of-DATA

                            /// .
                            /// 250 2.0.0 Ok: queued as 83398728027
                            var _FinishedResponse = SendCommandAndWait(".");
                            if (_FinishedResponse.StatusCode != SMTPStatusCode.Ok)
                            {
                                throw new SMTPClientException("SMTP DATA '.' command error: " + _FinishedResponse.ToString());
                            }

                            #endregion

                            #region QUIT

                            /// QUIT
                            /// 221 2.0.0 Bye
                            var _QuitResponse = SendCommandAndWait("QUIT");
                            if (_QuitResponse.StatusCode != SMTPStatusCode.ServiceClosingTransmissionChannel)
                            {
                                throw new SMTPClientException("SMTP QUIT command error: " + _QuitResponse.ToString());
                            }

                            #endregion

                            break;
                        }

                        return(MailSentStatus.ok);

                    default:
                        return(MailSentStatus.failed);
                    }
                }
            });

            if (AutoStart)
            {
                SendMailTask.Start();
            }

            return(SendMailTask);
        }
Exemple #2
0
        public Task<MailSentStatus> Send(EMailEnvelop  EMailEnvelop,
                                         Byte          NumberOfRetries  = 3,
                                         Boolean       AutoStart        = true)
        {
            var SendMailTask = new Task<MailSentStatus>(() => {

                lock (this) {

                switch (Connect())
                {

                    case Sockets.TCP.TCPConnectResult.InvalidDomainName:
                        return MailSentStatus.failed;

                    case Sockets.TCP.TCPConnectResult.NoIPAddressFound:
                        return MailSentStatus.failed;

                    case Sockets.TCP.TCPConnectResult.UnknownError:
                        return MailSentStatus.failed;

                    case Sockets.TCP.TCPConnectResult.Ok:

                        // 220 mail.ahzf.de ESMTP Postfix (Debian/GNU)
                        var LoginResponse = this.ReadSMTPResponse();
                        if (LoginResponse.StatusCode != SMTPStatusCode.ServiceReady)
                            throw new SMTPClientException("SMTP login error: " + LoginResponse.ToString());

                        switch (LoginResponse.StatusCode)
                        {

                            case SMTPStatusCode.ServiceReady:

                            #region Send EHLO

                            var EHLOResponses = SendCommandAndWaits("EHLO " + LocalDomain);

                            // 250-mail.ahzf.de
                            // 250-PIPELINING
                            // 250-SIZE 30720000
                            // 250-VRFY
                            // 250-ETRN
                            // 250-STARTTLS
                            // 250-AUTH LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-AUTH=LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-ENHANCEDSTATUSCODES
                            // 250-8BITMIME
                            // 250 DSN

                            if (EHLOResponses.Any(v => v.StatusCode != SMTPStatusCode.Ok))
                            {

                                var Error = EHLOResponses.Where(v => v.StatusCode != SMTPStatusCode.Ok).
                                                          FirstOrDefault();

                                if (Error.StatusCode != SMTPStatusCode.Ok)
                                    throw new SMTPClientException("SMTP EHLO command error: " + Error.ToString());

                            }

                            #endregion

                            #region Check for STARTTLS

                            if (UseTLS == TLSUsage.STARTTLS)
                            {

                                if (EHLOResponses.Any(v => v.Response == "STARTTLS"))
                                {

                                    var StartTLSResponse = SendCommandAndWait("STARTTLS");

                                    if (StartTLSResponse.StatusCode == SMTPStatusCode.ServiceReady)
                                        EnableTLS();

                                }

                                else
                                    throw new Exception("TLS is not supported by the SMTP server!");

                                // Send EHLO again in order to get the new list of supported extensions!
                                EHLOResponses = SendCommandAndWaits("EHLO " + LocalDomain);

                            }

                            #endregion

                            #region Analyze EHLO responses and set SMTP capabilities

                            // 250-mail.ahzf.de
                            // 250-PIPELINING
                            // 250-SIZE 30720000
                            // 250-VRFY
                            // 250-ETRN
                            // 250-STARTTLS
                            // 250-AUTH LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-AUTH=LOGIN DIGEST-MD5 PLAIN CRAM-MD5
                            // 250-ENHANCEDSTATUSCODES
                            // 250-8BITMIME
                            // 250 DSN

                            var MailServerName = EHLOResponses.FirstOrDefault();

                            EHLOResponses.Skip(1).ForEach(v => {

                                #region PIPELINING

                                if      (v.Response == "PIPELINING")
                                    Capabilities |= SmtpCapabilities.Pipelining;

                                #endregion

                                #region SIZE

                                else if (v.Response.StartsWith("SIZE "))
                                {

                                    Capabilities |= SmtpCapabilities.Size;

                                    if (!UInt64.TryParse(v.Response.Substring(5), out _MaxMailSize))
                                        throw new Exception("Invalid SIZE capability!");

                                }

                                #endregion

                             //   else if (v.Response == "VRFY")
                             //       Capabilities |= SmtpCapabilities.;

                             //   else if (v.Response == "ETRN")
                             //       Capabilities |= SmtpCapabilities.;

                                #region STARTTLS

                                if (v.Response == "STARTTLS")
                                    Capabilities |= SmtpCapabilities.StartTLS;

                                #endregion

                                #region AUTH

                                else if (v.Response.StartsWith("AUTH "))
                                {

                                    Capabilities |= SmtpCapabilities.Authentication;

                                    SMTPAuthMethods ParsedAuthMethod;
                                    var AuthType            = v.Response.Substring(4, 1);
                                    var AuthMethods         = v.Response.Substring(5).Split(' ');

                                    // GMail: "AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN"
                                    foreach (var AuthMethod in AuthMethods)
                                    {

                                        if (Enum.TryParse<SMTPAuthMethods>(AuthMethod.Replace('-', '_'), true, out ParsedAuthMethod))
                                        {
                                            if (AuthType == " ")
                                                _AuthMethods |= ParsedAuthMethod;
                                        }
                                        else
                                            _UnknownAuthMethods.Add(AuthMethod);

                                    }

                                }

                                #endregion

                                #region ENHANCEDSTATUSCODES

                                if (v.Response == "ENHANCEDSTATUSCODES")
                                    Capabilities |= SmtpCapabilities.EnhancedStatusCodes;

                                #endregion

                                #region 8BITMIME

                                if (v.Response == "8BITMIME")
                                    Capabilities |= SmtpCapabilities.EightBitMime;

                                #endregion

                                #region DSN

                                if (v.Response == "DSN")
                                    Capabilities |= SmtpCapabilities.Dsn;

                                #endregion

                                #region BINARYMIME

                                if (v.Response == "BINARYMIME")
                                    Capabilities |= SmtpCapabilities.BinaryMime;

                                #endregion

                                #region CHUNKING

                                if (v.Response == "CHUNKING")
                                    Capabilities |= SmtpCapabilities.Chunking;

                                #endregion

                                #region UTF8

                                if (v.Response == "UTF8")
                                    Capabilities |= SmtpCapabilities.UTF8;

                                #endregion

                            });

                            #endregion

                            #region Auth PLAIN...

                            if (_AuthMethods.HasFlag(SMTPAuthMethods.PLAIN))
                            {

                                var AuthPLAINResponse  = SendCommandAndWait("AUTH PLAIN " +
                                                                            Convert.ToBase64String(ByteZero.
                                                                                                   Concat(_Login.   ToUTF8Bytes()).
                                                                                                   Concat(ByteZero).
                                                                                                   Concat(_Password.ToUTF8Bytes()).
                                                                                                   ToArray()));

                            }

                            #endregion

                            #region ...or Auth LOGIN...

                            else if (_AuthMethods.HasFlag(SMTPAuthMethods.LOGIN))
                            {

                                var AuthLOGIN1Response  = SendCommandAndWait("AUTH LOGIN");
                                var AuthLOGIN2Response  = SendCommandAndWait(Convert.ToBase64String(_Login.   ToUTF8Bytes()));
                                var AuthLOGIN3Response  = SendCommandAndWait(Convert.ToBase64String(_Password.ToUTF8Bytes()));

                            }

                            #endregion

                            #region ...or AUTH CRAM-MD5

                            else if (_AuthMethods.HasFlag(SMTPAuthMethods.CRAM_MD5))
                            {

                                var AuthCRAMMD5Response = SendCommandAndWait("AUTH CRAM-MD5");

                                if (AuthCRAMMD5Response.StatusCode == SMTPStatusCode.AuthenticationChallenge)
                                {

                                    var aa = Ext2.CRAM_MD5("<*****@*****.**>",
                                                           "tim", "tanstaaftanstaaf");
                                    var a2 = Convert.ToBase64String(aa) == "dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw";

                                    var bb = Ext2.CRAM_MD5("<*****@*****.**>",
                                                           "alice", "wonderland");
                                    var b2 = Convert.ToBase64String(bb) == "YWxpY2UgNjRiMmE0M2MxZjZlZDY4MDZhOTgwOTE0ZTIzZTc1ZjA=";

                                    var cc = Ext2.CRAM_MD5("<*****@*****.**>", "ahzf", "ahzf2305!");

                                    var zz = Ext2.CRAM_MD5(Convert.FromBase64String(AuthCRAMMD5Response.Response).ToUTF8String(),
                                                           _Login, _Password);

                                    var AuthPLAINResponse = SendCommandAndWait(Convert.ToBase64String(zz));

                                }

                            }

                            #endregion

                            #region MAIL FROM:

                            foreach (var MailFrom in EMailEnvelop.MailFrom)
                            {

                                // MAIL FROM:<*****@*****.**>
                                /// 250 2.1.0 Ok
                                var MailFromCommand = "MAIL FROM: <" + MailFrom.Address.ToString() + ">";

                                if      (Capabilities.HasFlag(SmtpCapabilities.EightBitMime))
                                    MailFromCommand += " BODY=8BITMIME";
                                else if (Capabilities.HasFlag(SmtpCapabilities.BinaryMime))
                                    MailFromCommand += " BODY=BINARYMIME";

                                var _MailFromResponse = SendCommandAndWait(MailFromCommand);
                                if (_MailFromResponse.StatusCode != SMTPStatusCode.Ok)
                                    throw new SMTPClientException("SMTP MAIL FROM command error: " + _MailFromResponse.ToString());

                            }

                            #endregion

                            #region RCPT TO(s):

                            // RCPT TO:<*****@*****.**>
                            /// 250 2.1.5 Ok
                            EMailEnvelop.RcptTo.ForEach(Rcpt => {

                                var _RcptToResponse = SendCommandAndWait("RCPT TO: <" + Rcpt.Address.ToString() + ">");

                                switch (_RcptToResponse.StatusCode)
                                {

                                    case SMTPStatusCode.UserNotLocalWillForward:
                                    case SMTPStatusCode.Ok:
                                        break;

                                    case SMTPStatusCode.UserNotLocalTryAlternatePath:
                                    case SMTPStatusCode.MailboxNameNotAllowed:
                                    case SMTPStatusCode.MailboxUnavailable:
                                    case SMTPStatusCode.MailboxBusy:
                                    //    throw new SmtpCommandException(SmtpErrorCode.RecipientNotAccepted, _RcptToResponse.StatusCode, mailbox, _RcptToResponse.Response);

                                    case SMTPStatusCode.AuthenticationRequired:
                                        throw new UnauthorizedAccessException(_RcptToResponse.Response);

                                    //default:
                                    //    throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, _RcptToResponse.StatusCode, _RcptToResponse.Response);

                                }

                                //Debug.WriteLine(_RcptToResponse);

                            });

                            #endregion

                            #region Mail DATA

                            // The encoded MIME text lines must not be longer than 76 characters!

                            /// 354 End data with <CR><LF>.<CR><LF>
                            var _DataResponse = SendCommandAndWait("DATA");
                            if (_DataResponse.StatusCode != SMTPStatusCode.StartMailInput)
                                throw new SMTPClientException("SMTP DATA command error: " + _DataResponse.ToString());

                            // Send e-mail headers...
                            if (EMailEnvelop.Mail != null)
                            {

                                EMailEnvelop.Mail.
                                             Header.
                                             Select(header => header.Key + ": " + header.Value).
                                             ForEach(line => SendCommand(line));

                                //SendCommand("Message-Id: <" + (EMailEnvelop.Mail.MessageId != null
                                //                                    ? EMailEnvelop.Mail.MessageId.ToString()
                                //                                    : GenerateMessageId(EMailEnvelop.Mail, RemoteHost).ToString()) + ">");

                                SendCommand("");

                                // Send e-mail body(parts)...
                                //if (EMailEnvelop.Mail.MailBody != null)
                                //{
                                    EMailEnvelop.Mail.Body.ToText(false).ForEach(line => SendCommand(line));
                                    SendCommand("");
                                //}

                            }

                            else if (EMailEnvelop.Mail.ToText != null)
                            {
                                EMailEnvelop.Mail.ToText.ForEach(line => SendCommand(line));
                                SendCommand("");
                            }

                            #endregion

                            #region End-of-DATA

                            /// .
                            /// 250 2.0.0 Ok: queued as 83398728027
                            var _FinishedResponse = SendCommandAndWait(".");
                            if (_FinishedResponse.StatusCode != SMTPStatusCode.Ok)
                                throw new SMTPClientException("SMTP DATA '.' command error: " + _FinishedResponse.ToString());

                            #endregion

                            #region QUIT

                            /// QUIT
                            /// 221 2.0.0 Bye
                            var _QuitResponse     = SendCommandAndWait("QUIT");
                            if (_QuitResponse.StatusCode != SMTPStatusCode.ServiceClosingTransmissionChannel)
                                throw new SMTPClientException("SMTP QUIT command error: " + _QuitResponse.ToString());

                            #endregion

                            break;

                        }

                        return MailSentStatus.ok;

                    default:
                        return MailSentStatus.failed;

                }}

            });

            if (AutoStart)
                SendMailTask.Start();

            return SendMailTask;
        }