public async Task AuthenticateAsync(CancellationToken ct) { _sender.RequestText = $"{SmtpCommandNames.AUTH} {SmtpDefinitions.SmtpAuthMethods.Login} {Convert.ToBase64String(Encoding.UTF8.GetBytes(_credentials.UserName))}"; await _connection.WriteLineAsync(_sender.RequestText, ct); _sender.ReplyText = await _connection.ReadLineAsync(ct); _sender.ValidateReply(); _sender.RequestText = Convert.ToBase64String(Encoding.UTF8.GetBytes(_credentials.Password)); await _connection.WriteLineAsync(_sender.RequestText, ct); _sender.ReplyText = await _connection.ReadLineAsync(ct); _sender.ValidateReply(); }
/// <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); } } } }