using Microsoft.Exchange.Data.Mime; using Microsoft.Exchange.Data.Transport; using Microsoft.Exchange.Data.Transport.Email; using Microsoft.Exchange.Data.Transport.Routing; using System; namespace ITSwapShop { public class TransportAgent : RoutingAgent { private bool DoNotProcess = false; private SmtpServer server; public TransportAgent(SmtpServer server) { this.server = server; base.OnSubmittedMessage += new SubmittedMessageEventHandler(this.TransportAgent_OnSubmittedMessage); base.OnResolvedMessage += new ResolvedMessageEventHandler(this.TransportAgent_OnResolvedMessage); } private void TransportAgent_OnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { string from = e.MailItem.FromAddress.ToString(); string domain = e.MailItem.FromAddress.DomainPart; string msgId = e.MailItem.Message.MessageId; try { MimeDocument mimeDoc = e.MailItem.Message.MimeDocument; HeaderList headers = mimeDoc.RootPart.Headers; Header findHeader = headers.FindFirst("X-ITSwapShop"); bool isFromLocal = this.TransportAgent_IsLocalDomain(from, domain, msgId); bool isOof = e.MailItem.Message.MapiMessageClass.StartsWith("IPM.Note.Rules.OofTemplate", StringComparison.CurrentCultureIgnoreCase); if (isFromLocal && findHeader == null) { MimeNode lastChild = headers.LastChild; TextHeader newHeader = new TextHeader("X-ITSwapShop", DateTime.Now.ToString()); headers.InsertBefore(newHeader, lastChild); foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { Logging.Report(msgId, "Inserted header for " + from + " to " + recp.Address.ToString(), Logging.ReportType.Information); } } else { if (isOof) { EnvelopeRecipient recp = e.MailItem.Recipients[0]; bool delete = this.TransportAgent_AnalyzeOof(domain, recp.Address.DomainPart, msgId); if (delete) { Logging.Report(msgId, string.Concat(new string[] { "Message from ", from, " to ", recp.Address.ToString(), " found to be Oof. Deleted" }), Logging.ReportType.Information); source.Delete(); this.DoNotProcess = true; } } else { this.DoNotProcess = true; } } } catch (Exception ex) { Logging.Report(msgId, ex.ToString(), Logging.ReportType.Error); } } private void TransportAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs e) { if (!this.DoNotProcess) { string from = e.MailItem.FromAddress.ToString(); string domain = e.MailItem.FromAddress.DomainPart; string msgId = e.MailItem.Message.MessageId; try { bool isFromInternal = this.TransportAgent_IsLocalDomain(from, domain, msgId); Header header = e.MailItem.Message.RootPart.Headers.FindFirst("X-ITSwapShop"); if (isFromInternal) { foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { if (!recp.Address.DomainPart.Equals(domain, StringComparison.CurrentCultureIgnoreCase)) { this.TransportAgent_RouteOverride(source, recp, e.MailItem.Message); } else { Logging.Report(msgId, "Recipient " + recp.Address.ToString() + " is in same organization. Not overriding.", Logging.ReportType.Information); } } } else { Logging.Report(msgId, "From address is not internal: " + e.MailItem.FromAddress.ToString(), Logging.ReportType.Information); } } catch (Exception ex) { Logging.Report(msgId, ex.ToString(), Logging.ReportType.Error); } } } private void TransportAgent_RouteOverride(ResolvedMessageEventSource source, EnvelopeRecipient recipient, EmailMessage msg) { try { RoutingDomain routingDomain = new RoutingDomain("itswapshopfake.biz"); DeliveryQueueDomain deliveryQueue = DeliveryQueueDomain.UseOverrideDomain; RoutingOverride routingOverride = new RoutingOverride(routingDomain, deliveryQueue); source.SetRoutingOverride(recipient, routingOverride); Logging.Report(msg.MessageId, "Override default route for " + recipient.Address.ToString(), Logging.ReportType.Information); } catch (Exception ex) { Logging.Report(msg.MessageId, ex.ToString(), Logging.ReportType.Error); } } private bool TransportAgent_IsLocalDomain(string emailAddr, string domainPart, string messageId) { bool isLocal = false; try { if (!string.IsNullOrEmpty(emailAddr) && !string.IsNullOrEmpty(domainPart)) { AcceptedDomainCollection adc = this.server.AcceptedDomains; foreach (AcceptedDomain ad in adc) { if (domainPart.Equals(ad.NameSpecification, StringComparison.CurrentCultureIgnoreCase)) { isLocal = true; break; } } } } catch (Exception ex) { Logging.Report(messageId, ex.ToString(), Logging.ReportType.Error); } return isLocal; } private bool TransportAgent_AnalyzeOof(string fromDomain, string toDomain, string messageId) { bool deleteOof = false; fromDomain = ((fromDomain == null) ? "" : fromDomain); bool result; try { if (fromDomain.Equals(toDomain, StringComparison.CurrentCultureIgnoreCase)) { result = deleteOof; return result; } AcceptedDomainCollection adc = this.server.AcceptedDomains; foreach (AcceptedDomain ad in adc) { if (toDomain.Equals(ad.NameSpecification, StringComparison.CurrentCultureIgnoreCase)) { deleteOof = true; break; } } } catch (Exception ex) { Logging.Report(messageId, ex.ToString(), Logging.ReportType.Error); } result = deleteOof; return result; } } }