// 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();
}
}
}