//////////////////////////////////////////////////////////////////// // Send Address To //////////////////////////////////////////////////////////////////// private void SendAddressTo ( string Type, List <SecureSmtpMailAddress> AddressList ) { // nothing to do if (AddressList.Count == 0) { return; } // build list StringBuilder List = new StringBuilder(); // send one address at a time foreach (SecureSmtpMailAddress MA in AddressList) { if (List.Length == 0) { // send first item of the list List.AppendFormat("{0}: {1} <{2}>", Type, SecureSmtpPart.Utf8Base64Encode(MA.DisplayName), MA.Address); } else { // append all others List.AppendFormat(",\r\n {0} <{1}>", SecureSmtpPart.Utf8Base64Encode(MA.DisplayName), MA.Address); } } // send the list SendDataLine(List.ToString()); return; }
/// <summary> /// Add child part to list of parts /// </summary> /// <param name="Part">Derived class from SecureSmtpPart</param> public void AddPart ( SecureSmtpPart Part ) { Children.Add(Part); return; }
//////////////////////////////////////////////////////////////////// // Send subject line to the server. //////////////////////////////////////////////////////////////////// /* * To encode a header using this technique you must use this format: * =?charset?encoding?encoded-text?= * And this is an example of its use: * =?utf-8?Q?hello?= * The encoding must be either B or Q, these mean base 64 and quoted-printable respectively. * You can read the RFC 1342 document for more information about how they work. * * // convert content string unicode to byte array * byte[] ContentBytes = Encoding.UTF8.GetBytes(ContentString); * string EncodedText = "=?utf-8?Q?" + QuotedPrintableEncode(ContentBytes) + "?="; */ private void SendSubjectLine ( string Text ) { #if DEBUG Debug.WriteLine("Subject: " + Text); #endif // test for unicode characters (not ascii) bool Unicode = false; foreach (char Chr in Text) { if (Chr > '~') { Unicode = true; break; } } // we need special encoding if (Unicode) { // convert content string unicode to byte array byte[] SubjectBytes = Encoding.UTF8.GetBytes(Text); string SubjectText = SecureSmtpPart.QuotedPrintableEncode(SubjectBytes, false); // send subject Writer.Write("Subject: =?utf-8?Q?"); Writer.Write(SubjectText); Writer.Write("?=\r\n"); } else { // send subject Writer.Write("Subject: "); Writer.Write(Text); Writer.Write("\r\n"); } return; }
/// <summary> /// Send the email message to the mail server /// </summary> /// <param name="Message">Email message</param> public void SendMail ( SecureSmtpMessage Message ) { try { if (string.IsNullOrWhiteSpace(Message.Subject)) { throw new ApplicationException("Email subject is missing"); } if (Message.From == null || string.IsNullOrWhiteSpace(Message.From.Address)) { throw new ApplicationException("From address is missing or in error"); } if (Message.To.Count == 0) { throw new ApplicationException("At least one mail to address is required"); } foreach (SecureSmtpMailAddress MA in Message.To) { if (string.IsNullOrWhiteSpace(MA.Address)) { throw new ApplicationException("To mail address address is missing"); } } foreach (SecureSmtpMailAddress MA in Message.Cc) { if (string.IsNullOrWhiteSpace(MA.Address)) { throw new ApplicationException("CC mail address address is missing"); } } foreach (SecureSmtpMailAddress MA in Message.Bcc) { if (string.IsNullOrWhiteSpace(MA.Address)) { throw new ApplicationException("To mail address address is missing"); } } // open connection OpenConnection(); // send host name and expect request completed 250 SendCommand("EHLO " + Host, SmtpReplyCode.RequestCompleted); // get supported authorization from last reply SupportedAuthorizations(); // plain text authentication method if (AuthMethod == Authentication.PlainText) { if ((SupportedAuth & AuthenticationMethod.PlainText) == 0) { throw new ApplicationException("Email server does not support plain text authorization"); } SendCommand("AUTH LOGIN", SmtpReplyCode.SendUserAndPassword); SendCommand(Convert.ToBase64String(Encoding.ASCII.GetBytes(UserName)), SmtpReplyCode.SendUserAndPassword); SendCommand(Convert.ToBase64String(Encoding.ASCII.GetBytes(UserPassword)), SmtpReplyCode.AuthenticationSuccessful); } // OAuth2 authentication method else { if ((SupportedAuth & AuthenticationMethod.XOAuth2) == 0) { throw new ApplicationException("Email server does not support XOAUTH2 authorization"); } string OAuth2Password = OAuth2.OAuth2Password(); string AuthStr = string.Format("user={0}\u0001auth=Bearer {1}\u0001\u0001", UserName, OAuth2Password); byte[] AuthBin = new byte[AuthStr.Length]; for (int x = 0; x < AuthStr.Length; x++) { AuthBin[x] = (byte)AuthStr[x]; } SendCommand("AUTH XOAUTH2 " + Convert.ToBase64String(AuthBin), SmtpReplyCode.AuthenticationSuccessful); } // from address SendCommand(string.Format("MAIL FROM: <{0}>", Message.From.Address), SmtpReplyCode.RequestCompleted); // send the addresses of all recipients SendRecipientAddress(Message.To); SendRecipientAddress(Message.Cc); SendRecipientAddress(Message.Bcc); // start data block SendCommand("DATA", SmtpReplyCode.StartInput); // send from SendDataLine(string.Format("From: {0} <{1}>", SecureSmtpPart.Utf8Base64Encode(Message.From.DisplayName), Message.From.Address)); // send to list SendAddressTo("To", Message.To); SendAddressTo("Cc", Message.Cc); // send subject SendSubjectLine(Message.Subject); // send date and time SendDataLine(string.Format("Date: {0:r}", DateTime.UtcNow)); // send mime vertion SendDataLine("MIME-Version: 1.0"); // send all data parts Message.RootPart.SendData(Writer); // data terminating dot SendCommand("\r\n.", SmtpReplyCode.RequestCompleted); // terminate connection SendCommand("QUIT", SmtpReplyCode.ClosingChannel); // dispose connection Dispose(); return; } catch (Exception Exp) { try { SendCommand("QUIT", SmtpReplyCode.IgnoreReply); } catch { } // dispose connection Dispose(); throw new Exception(Exp.Message, Exp); } }