Esempio n. 1
0
 public ConnectionAuth(Connection connection, SmtpSender sender, NetworkCredential credentials)
 {
     _connection  = connection;
     _sender      = sender;
     _credentials = credentials;
 }
Esempio n. 2
0
        /// <summary>
        /// Sends an array of email messages using a session state object.
        /// Credentials, Enable SSL and Client Hostname are NOT taken from the state object but
        /// rather from the properties of this class.
        /// </summary>
        /// <param name="sessionStates">The session states.</param>
        /// <param name="sessionId">The session identifier.</param>
        /// <param name="ct">The cancellation token.</param>
        /// <returns>
        /// A task that represents the asynchronous of send email operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">sessionStates.</exception>
        /// <exception cref="SecurityException">Could not upgrade the channel to SSL.</exception>
        /// <exception cref="SmtpException">Defines an SMTP Exceptions class.</exception>
        public async Task SendMailAsync(
            IEnumerable <SmtpSessionState> sessionStates,
            string sessionId     = null,
            CancellationToken ct = default)
        {
            if (sessionStates == null)
            {
                throw new ArgumentNullException(nameof(sessionStates));
            }

            using (var tcpClient = new TcpClient())
            {
                await tcpClient.ConnectAsync(Host, Port);

                using (var connection = new Connection(tcpClient, Encoding.UTF8, "\r\n", true, 1000))
                {
                    var sender = new SmtpSender(sessionId);

                    try
                    {
                        // Read the greeting message
                        sender.ReplyText = await connection.ReadLineAsync(ct);

                        // EHLO 1
                        sender.RequestText = $"{SmtpCommandNames.EHLO} {ClientHostname}";

                        await connection.WriteLineAsync(sender.RequestText, ct);

                        do
                        {
                            sender.ReplyText = await connection.ReadLineAsync(ct);
                        }while (!sender.IsReplyOk);

                        sender.ValidateReply();

                        // STARTTLS
                        if (EnableSsl)
                        {
                            sender.RequestText = $"{SmtpCommandNames.STARTTLS}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            sender.ReplyText = await connection.ReadLineAsync(ct);

                            sender.ValidateReply();

                            if (await connection.UpgradeToSecureAsClientAsync() == false)
                            {
                                throw new SecurityException("Could not upgrade the channel to SSL.");
                            }
                        }

                        {
                            // EHLO 2
                            sender.RequestText = $"{SmtpCommandNames.EHLO} {ClientHostname}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            do
                            {
                                sender.ReplyText = await connection.ReadLineAsync(ct);
                            }while (!sender.IsReplyOk);

                            sender.ValidateReply();
                        }

                        // AUTH
                        if (Credentials != null)
                        {
                            var auth = new ConnectionAuth(connection, sender, Credentials);
                            await auth.AuthenticateAsync(ct);
                        }

                        foreach (var sessionState in sessionStates)
                        {
                            {
                                // MAIL FROM
                                sender.RequestText = $"{SmtpCommandNames.MAIL} FROM:<{sessionState.SenderAddress}>";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            // RCPT TO
                            foreach (var recipient in sessionState.Recipients)
                            {
                                sender.RequestText = $"{SmtpCommandNames.RCPT} TO:<{recipient}>";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            {
                                // DATA
                                sender.RequestText = $"{SmtpCommandNames.DATA}";

                                await connection.WriteLineAsync(sender.RequestText, ct);

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }

                            {
                                // CONTENT
                                var dataTerminator = sessionState.DataBuffer
                                                     .Skip(sessionState.DataBuffer.Count - 5)
                                                     .ToText();

                                sender.RequestText = $"Buffer ({sessionState.DataBuffer.Count} bytes)";

                                await connection.WriteDataAsync(sessionState.DataBuffer.ToArray(), true, ct);

                                if (dataTerminator.EndsWith(SmtpDefinitions.SmtpDataCommandTerminator) == false)
                                {
                                    await connection.WriteTextAsync(SmtpDefinitions.SmtpDataCommandTerminator, ct);
                                }

                                sender.ReplyText = await connection.ReadLineAsync(ct);

                                sender.ValidateReply();
                            }
                        }

                        {
                            // QUIT
                            sender.RequestText = $"{SmtpCommandNames.QUIT}";

                            await connection.WriteLineAsync(sender.RequestText, ct);

                            sender.ReplyText = await connection.ReadLineAsync(ct);

                            sender.ValidateReply();
                        }
                    }
                    catch (Exception ex)
                    {
                        var errorMessage =
                            $"Could not send email. {ex.Message}\r\n    Last Request: {sender.RequestText}\r\n    Last Reply: {sender.ReplyText}";
                        errorMessage.Error(typeof(SmtpClient).FullName, sessionId);

                        throw new SmtpException(errorMessage);
                    }
                }
            }
        }