Пример #1
0
        private async Task SendEhlo(SmtpSender sender, Connection connection, CancellationToken cancellationToken)
        {
            sender.RequestText = $"{SmtpCommandNames.EHLO} {ClientHostname}";

            await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

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

            sender.ValidateReply();
        }
Пример #2
0
 public ConnectionAuth(Connection connection, SmtpSender sender, NetworkCredential credentials)
 {
     _connection  = connection;
     _sender      = sender;
     _credentials = credentials;
 }
Пример #3
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="callback">The callback.</param>
        /// <param name="cancellationToken">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,
            RemoteCertificateValidationCallback?callback = null,
            CancellationToken cancellationToken          = default)
        {
            if (sessionStates == null)
            {
                throw new ArgumentNullException(nameof(sessionStates));
            }

            using var tcpClient = new TcpClient();
            await tcpClient.ConnectAsync(Host, Port, cancellationToken).ConfigureAwait(false);

            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(cancellationToken).ConfigureAwait(false);

                // EHLO 1
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

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

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();

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

                // EHLO 2
                await SendEhlo(sender, connection, cancellationToken).ConfigureAwait(false);

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

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

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

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

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }

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

                        await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        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, cancellationToken).ConfigureAwait(false);

                        if (!dataTerminator.EndsWith(SmtpDefinitions.SmtpDataCommandTerminator, StringComparison.OrdinalIgnoreCase))
                        {
                            await connection.WriteTextAsync(SmtpDefinitions.SmtpDataCommandTerminator, cancellationToken).ConfigureAwait(false);
                        }

                        sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                        sender.ValidateReply();
                    }
                }

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

                    await connection.WriteLineAsync(sender.RequestText, cancellationToken).ConfigureAwait(false);

                    sender.ReplyText = await connection.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    sender.ValidateReply();
                }
            }
            catch (Exception ex)
            {
                throw new SmtpException($"Could not send email - Session ID {sessionId}. {ex.Message}\r\n    Last Request: {sender.RequestText}\r\n    Last Reply: {sender.ReplyText}");
            }
        }