/// <summary> /// Authenticates a socket client using plain authentication. /// </summary> /// <returns>True if the client was successfully authenticated. False otherwise.</returns> private async Task <bool> AuthenticateByPlainAsync() { if (!IsConnected) { return(false); } SmtpResponse response = await Socket.Send("Auth Plain"); if (!response.ContainsStatus(SmtpCode.WaitingForAuthentication)) { return(false); } string lineAuthentication = string.Format("{0}\0{0}\0{1}", Username, Password); SmtpResponse responseAuth = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(lineAuthentication))); if (!responseAuth.ContainsStatus(SmtpCode.AuthenticationSuccessful)) { return(false); } return(true); }
/// <summary> /// Connects to the server. /// </summary> /// <returns>True for successful connection. False otherwise.</returns> private async Task <bool> ConnectAsync() { try { if (IsConnected) { Socket.Dispose(); IsConnected = false; } Socket = new SmtpSocket(Server, Port, SSL); SmtpResponse response = await Socket.EstablishConnection(); if (response.ContainsStatus(SmtpCode.ServiceReady)) { IsConnected = true; return(true); } } catch { return(false); } return(false); }
/// <summary> /// Authenticates a socket client using login authentication. /// </summary> /// <returns>True if the client was successfully authenticated. False otherwise.</returns> private async Task <bool> AuthenticateByLoginAsync() { if (!IsConnected) { return(false); } SmtpResponse response = await Socket.Send("Auth Login"); if (!response.ContainsStatus(SmtpCode.WaitingForAuthentication)) { return(false); } SmtpResponse responseUsername = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(Username))); if (!responseUsername.ContainsStatus(SmtpCode.WaitingForAuthentication)) { return(false); } SmtpResponse responsePassword = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(Password))); if (!responsePassword.ContainsStatus(SmtpCode.AuthenticationSuccessful)) { return(false); } return(true); }
/// <summary> /// Connects to the server. /// </summary> /// <returns>True for successful connection. False otherwise.</returns> public async Task <bool> Connect() { try { if (IsConnected) { Socket.Close(); IsConnected = false; } Socket = new SmtpSocket(Server, Port, SSL, Username, Password); SmtpResponse response = await Socket.EstablishConnection(); if (response.Contains(SmtpCode.ServiceReady)) { IsConnected = true; return(true); } } catch { return(false); } return(false); }
/// <summary> /// Sends the specified email message. /// </summary> /// <param name="message">The email message.</param> /// <returns>True if the email was sent successfully. False otherwise.</returns> public async Task <bool> SendMail(SmtpMessage message) { if (!IsConnected) { await Connect(); } if (!IsConnected) { throw new Exception("Can't connect to the SMTP server."); } if (!IsAuthenticated) { await Authenticate(); } SmtpResponse response = await Socket.Send(string.Format("Mail From:<{0}>", message.From.EmailAddress)); if (!response.Contains(SmtpCode.RequestedMailActionCompleted)) { return(false); } foreach (MailBox to in message.To) { SmtpResponse responseTo = await Socket.Send(String.Format("Rcpt To:<{0}>", to.EmailAddress)); if (!responseTo.Contains(SmtpCode.RequestedMailActionCompleted)) { break; } } SmtpResponse responseData = await Socket.Send(String.Format("Data")); if (!responseData.Contains(SmtpCode.StartMailInput)) { return(false); } SmtpResponse repsonseMessage = await Socket.Send(await message.CreateMessageBody()); if (!repsonseMessage.Contains(SmtpCode.RequestedMailActionCompleted)) { return(false); } SmtpResponse responseQuit = await Socket.Send("Quit"); if (!responseQuit.Contains(SmtpCode.ServiceClosingTransmissionChannel)) { return(false); } return(true); }
/// <summary> /// Authenticates a socket client using the specified Username and Password. /// </summary> /// <returns>True if the client was successfully authenticated. False otherwise.</returns> private async Task <bool> AuthenticateAsync() { if (!IsConnected) { return(false); } // get the type of auth SmtpResponse response = await Socket.Send("EHLO " + Server); if (response.ContainsMessage("STARTTLS")) { SmtpResponse responseSSL = await Socket.Send("STARTTLS"); if (responseSSL.ContainsStatus(SmtpCode.ServiceReady)) { await Socket.UpgradeToSslAsync(); return(await AuthenticateAsync()); } } if (response.ContainsMessage("AUTH")) { if (response.ContainsMessage("LOGIN")) { IsAuthenticated = await AuthenticateByLoginAsync(); } else if (response.ContainsMessage("PLAIN")) { IsAuthenticated = await AuthenticateByPlainAsync(); } } else { await Socket.Send("EHLO " + Server); IsAuthenticated = true; } return(IsAuthenticated); }
/// <summary> /// Authenticates a socket client using the specified Username and Password. /// </summary> /// <returns>True if the client was successfully authenticated. False otherwise.</returns> public async Task <bool> Authenticate() { if (!IsConnected) { throw new Exception("Client is not connected"); } // get the type of auth SmtpResponse response = await Socket.Send("EHLO " + Server); if (response.Contains("STARTTLS")) { SmtpResponse responseSSL = await Socket.Send("STARTTLS"); if (responseSSL.Contains(SmtpCode.ServiceReady)) { await Socket.UpgradeToSslAsync(); return(await Authenticate()); } } if (response.Contains("AUTH")) { if (response.Contains("LOGIN")) { IsAuthenticated = await AuthenticateByLogin(); } else if (response.Contains("PLAIN")) { IsAuthenticated = await AuthenticateByPlain(); } } else { await Socket.Send("EHLO " + Server); IsAuthenticated = true; } return(IsAuthenticated); }
private async Task <SmtpResponse> GetResponse(string from) { SmtpResponse response = new SmtpResponse(); bool isStartingLine = true; StringBuilder stringBuilder = null; int charLen = 3; Boolean endOfStream = false; SmtpCode code = SmtpCode.None; string codeStr = string.Empty; try { stringBuilder = new StringBuilder(); while (!endOfStream) { // There is a Strange beahvior when the bufferLength is exactly the same size as the inputStream await _reader.LoadAsync(BUFFER_LENGTH); charLen = Math.Min((int)_reader.UnconsumedBufferLength, BUFFER_LENGTH); if (charLen == 0) { endOfStream = true; break; } // If charLen < bufferLength, it's end of stream if (charLen < BUFFER_LENGTH) { endOfStream = true; } // get the current position int charPos = 0; // Read the buffer byte[] buffer = new byte[charLen]; _reader.ReadBytes(buffer); do { // get the character char chr = (char)buffer[charPos]; // if it's starting point, we can read the first 3 chars. if (isStartingLine) { codeStr += chr; // Get the code if (codeStr.Length == 3) { int codeInt; if (int.TryParse(codeStr, out codeInt)) { code = (SmtpCode)codeInt; } // next isStartingLine = false; } } else if (chr == '\r' || chr == '\n') { // Advance 1 byte to get the '\n' if not at the end of the buffer if (chr == '\r' && charPos < (charLen - 1)) { charPos++; chr = (char)buffer[charPos]; } if (chr == '\n') { KeyValuePair <SmtpCode, String> r = new KeyValuePair <SmtpCode, string> (code, stringBuilder.ToString()); response.Values.Add(r); Debug.WriteLine("{0}{1}", ((int)code).ToString(), stringBuilder.ToString()); stringBuilder = new StringBuilder(); code = SmtpCode.None; codeStr = string.Empty; isStartingLine = true; } } else { stringBuilder.Append(chr); } charPos++; } while (charPos < charLen); } } catch { throw; } return(response); }
private async Task<SmtpResponse> GetResponse(string from) { SmtpResponse response = new SmtpResponse(); bool isStartingLine = true; StringBuilder stringBuilder = null; int charLen = 3; Boolean endOfStream = false; SmtpCode code = SmtpCode.None; string codeStr = string.Empty; try { stringBuilder = new StringBuilder(); while (!endOfStream) { // There is a Strange beahvior when the bufferLength is exactly the same size as the inputStream await _reader.LoadAsync(BUFFER_LENGTH); charLen = Math.Min((int)_reader.UnconsumedBufferLength, BUFFER_LENGTH); if (charLen == 0) { endOfStream = true; break; } // If charLen < bufferLength, it's end of stream if (charLen < BUFFER_LENGTH) endOfStream = true; // get the current position int charPos = 0; // Read the buffer byte[] buffer = new byte[charLen]; _reader.ReadBytes(buffer); do { // get the character char chr = (char)buffer[charPos]; // if it's starting point, we can read the first 3 chars. if (isStartingLine) { codeStr += chr; // Get the code if (codeStr.Length == 3) { int codeInt; if (int.TryParse(codeStr, out codeInt)) code = (SmtpCode)codeInt; // next isStartingLine = false; } } else if (chr == '\r' || chr == '\n') { // Advance 1 byte to get the '\n' if not at the end of the buffer if (chr == '\r' && charPos < (charLen - 1)) { charPos++; chr = (char)buffer[charPos]; } if (chr == '\n') { KeyValuePair<SmtpCode, String> r = new KeyValuePair<SmtpCode, string> (code, stringBuilder.ToString()); response.Values.Add(r); Debug.WriteLine("{0}{1}", ((int)code).ToString(), stringBuilder.ToString()); stringBuilder = new StringBuilder(); code = SmtpCode.None; codeStr = string.Empty; isStartingLine = true; } } else { stringBuilder.Append(chr); } charPos++; } while (charPos < charLen); } } catch { throw; } return response; }
/// <summary> /// Sends the specified email message. /// </summary> /// <param name="message">The email message.</param> /// <returns>True if the email was sent successfully. False otherwise.</returns> public async Task <SmtpResult> SendMailAsync(EmailMessage message) { if (!IsConnected) { await ConnectAsync(); } if (!IsConnected) { return(SmtpResult.ConnectionFailed); } if (!IsAuthenticated) { await AuthenticateAsync(); } if (!IsAuthenticated) { return(SmtpResult.AuthenticationFailed); } SmtpResponse response = message.Sender != null && message.Sender.Address.Length != 0 ? await Socket.Send(string.Format("Mail From:<{0}>", message.Sender.Address)) : await Socket.Send(string.Format("Mail From:<{0}>", Username)); if (!response.ContainsStatus(SmtpCode.RequestedMailActionCompleted)) { return(SmtpResult.CouldNotCreateMail); } foreach (EmailRecipient to in message.To) { SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address)); if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted)) { break; } } foreach (EmailRecipient to in message.CC) { SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address)); if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted)) { break; } } foreach (EmailRecipient to in message.Bcc) { SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address)); if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted)) { break; } } SmtpResponse responseData = await Socket.Send(string.Format("Data")); if (!responseData.ContainsStatus(SmtpCode.StartMailInput)) { return(SmtpResult.CouldNotCreateMail); } SmtpResponse repsonseMessage = await Socket.Send(await BuildSmtpMailInput(message)); if (!repsonseMessage.ContainsStatus(SmtpCode.RequestedMailActionCompleted)) { return(SmtpResult.CouldNotCreateMail); } SmtpResponse responseQuit = await Socket.Send("Quit"); if (!responseQuit.ContainsStatus(SmtpCode.ServiceClosingTransmissionChannel)) { return(SmtpResult.CouldNotCloseTransmissionChannel); } return(SmtpResult.OK); }