// Copyright (c) 2011 rubicon IT GmbH using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Mime; using System.Net.Mail; using log4net; using System.Security.Cryptography.X509Certificates; using System.Net.Security; namespace bsmd.email { public class BSMDMail : IDisposable { private readonly SmtpClient client; private static readonly ILog log = LogManager.GetLogger(typeof(BSMDMail)); internal BSMDMail() { this.client = new SmtpClient(); NetworkCredential basicCredential = new NetworkCredential(Properties.Settings.Default.SMTPUser, Properties.Settings.Default.SMTPPassword); // setup up the host, increase the timeout to 5 minutes this.client.Host = Properties.Settings.Default.SMTPServer; this.client.UseDefaultCredentials = false; this.client.Credentials = basicCredential; this.client.Timeout = (60 * 5 * 1000); this.client.EnableSsl = false; // evil workaround for invalid BSMD E-Mail certificate! ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; } /// /// Synchrones Senden einer E-Mail /// internal void Send(MailMessage message) { try { this.client.Send(message); log.InfoFormat("Email sending to {0} successful.", message.To.ToString()); } catch (SmtpException smtpException) { log.ErrorFormat("SMTP error while sending e-mail:{0}", smtpException.Message); } catch (Exception ex) { log.ErrorFormat("other error while sending e-mail:{0}", ex.Message); } } /// /// sendet eine E-Mail mit Attachments (jetzt asynchron) /// /// Betreffzeile /// Liste von Dateien die angehängt werden sollen public static void SendNSWReportWithAttachments(string subject, List filenameList, string recipient) { BSMDMail mailer = new BSMDMail(); MailMessage message = new MailMessage(); MailAddress fromAddress = new MailAddress(Properties.Settings.Default.Sender); message.From = fromAddress; message.Subject = string.Format(subject); message.IsBodyHtml = false; message.Body = "see attachment"; // wenn recipient leer ist, geht es an die Recipientliste if ((recipient == null) || (recipient.Length == 0)) { foreach (string defaultRecipient in Properties.Settings.Default.Recipient) { message.To.Add(defaultRecipient); } } else { message.To.Add(recipient); // message.CC.Add(Properties.Settings.Default.AdminEmail); foreach (string extraRecipient in Properties.Settings.Default.Recipient) { if(!extraRecipient.Equals(recipient, StringComparison.OrdinalIgnoreCase)) message.CC.Add(extraRecipient); } } foreach (string filename in filenameList) { Attachment attachment = new Attachment(filename, MediaTypeNames.Application.Octet); ContentDisposition disposition = attachment.ContentDisposition; disposition.CreationDate = File.GetCreationTime(filename); disposition.ModificationDate = File.GetLastWriteTime(filename); disposition.ReadDate = File.GetLastAccessTime(filename); disposition.FileName = Path.GetFileName(filename); disposition.Size = new FileInfo(filename).Length; disposition.DispositionType = DispositionTypeNames.Attachment; message.Attachments.Add(attachment); } // mailer.Send(message); /* mailer.client.SendCompleted += (s, e) => { log.InfoFormat("{0} email send completed", subject); mailer.Dispose(); message.Dispose(); }; */ try { // Umgestellt auf synchron, da sonst die gesendeten Elemente nicht gelöscht werden können.. mailer.Send(message); // mailer.client.SendAsync(message, null); } catch (SmtpException smtpException) { log.ErrorFormat("SMTP error while sending e-mail:{0}", smtpException.Message); } catch (Exception ex) { log.ErrorFormat("other error while sending e-mail:{0}", ex.Message); } } public static void SendSystemInfo(string subject, string body, string recipient) { using (BSMDMail mailer = new BSMDMail()) { if (recipient.Equals(Properties.Settings.Default.POP3User, StringComparison.OrdinalIgnoreCase)) { log.Warn("system info recipient is pop3 user, skipping send to avoid loops"); return; } MailMessage message = new MailMessage(); MailAddress fromAddress = new MailAddress(Properties.Settings.Default.Sender); message.From = fromAddress; message.Subject = subject; message.IsBodyHtml = false; message.Body = body; message.To.Add(recipient); MailAddress adminAddress = new MailAddress(Properties.Settings.Default.AdminEmail); message.CC.Add(adminAddress); try { mailer.Send(message); } catch (SmtpException smtpException) { log.ErrorFormat("SMTP error while sending e-mail:{0}", smtpException.Message); } catch (Exception ex) { log.ErrorFormat("other error while sending e-mail:{0}", ex.Message); } } } public static void SendSystemInfoAsync(string subject, string body, string recipient) { BSMDMail mailer = new BSMDMail(); MailMessage message = new MailMessage(); MailAddress fromAddress = new MailAddress(Properties.Settings.Default.Sender); message.From = fromAddress; message.Subject = subject; message.IsBodyHtml = false; message.Body = body; MailAddress adminAddress = new MailAddress(Properties.Settings.Default.AdminEmail); if (recipient != null) { message.To.Add(recipient); message.CC.Add(adminAddress); } else { message.To.Add(adminAddress); } // http://stackoverflow.com/questions/7276375/what-are-best-practices-for-using-smtpclient-sendasync-and-dispose-under-net-4 // asynchron schicken und wenn's erledigt ist gleich disposen (wichtig!) mailer.client.SendCompleted += (s, e) => { log.InfoFormat("system info email async send to {0} completed", recipient); mailer.Dispose(); message.Dispose(); }; try { mailer.client.SendAsync(message, null); } catch (SmtpException smtpException) { log.ErrorFormat("SMTP error while sending e-mail:{0}", smtpException.Message); } catch (Exception ex) { log.ErrorFormat("other error while sending e-mail:{0}", ex.Message); } } public void Dispose() { this.client.Dispose(); } } }