/// <summary> /// To simplify inbound mail sending, SMTP Server allows you to drop new messages into a pickup folder /// You don't need to use SmtpClient or some other SMTP client /// </summary> public void SendFailure(OutgoingMessage envelope, string pickupFolder, DirectAddressCollection recipients) { if (string.IsNullOrEmpty(pickupFolder)) { throw new ArgumentException("value null or empty", "pickupFolder"); } if (recipients.IsNullOrEmpty()) { return; } if (recipients != null && envelope.UsingDeliveryStatus) { DSNMessage notification = this.ProduceFailure(envelope, recipients); string filePath = Path.Combine(pickupFolder, Extensions.CreateUniqueFileName()); notification.Save(filePath); } //Or maybe // // m_router.Route(message, envelope, routedRecipients); // // This would avoid loopback encrypt/decrypt... // // ISmtpMessage message // MessageEnvelope envelope // DirectAddressCollection routedRecipients, but would use DSN in-reply-to: // }
public void TestIncomingBasic() { Message message = LoadMessage("simple.eml"); DirectAddressCollection rcpto = new DirectAddressCollection( new DirectAddress[] { new DirectAddress("*****@*****.**"), new DirectAddress("*****@*****.**") } ); IncomingMessage incoming = new IncomingMessage(message, rcpto, new DirectAddress("*****@*****.**")); Assert.True(incoming.Recipients.Count == 2); DirectAddressCollection routingRecipients = incoming.GetRecipientsInRoutingHeaders(); Assert.True(routingRecipients.Count == 1); Assert.False(incoming.AreAddressesInRoutingHeaders(rcpto)); incoming.Recipients.Remove(x => MimeStandard.Equals(x.Address, "*****@*****.**")); Assert.True(incoming.AreAddressesInRoutingHeaders(rcpto)); message.ToValue = "*****@*****.**"; incoming = new IncomingMessage(message, rcpto, new DirectAddress("*****@*****.**")); Assert.False(incoming.AreAddressesInRoutingHeaders(rcpto)); message.ToValue = "*****@*****.**"; incoming = new IncomingMessage(message, rcpto, new DirectAddress("*****@*****.**")); Assert.False(incoming.AreAddressesInRoutingHeaders(rcpto)); }
public void RemoveRecipients() { MessageEnvelope envelope = new MessageEnvelope(TestMessage); DirectAddressCollection toRemove = new DirectAddressCollection(); toRemove.Add(new DirectAddress("<*****@*****.**>")); toRemove.Add(new DirectAddress("<*****@*****.**>")); toRemove.Add(new DirectAddress("<*****@*****.**>")); toRemove.Add(new DirectAddress("<*****@*****.**>")); Assert.DoesNotThrow(() => envelope.RemoveFromRoutingHeaders(toRemove)); string outputText = null; Assert.DoesNotThrow(() => outputText = envelope.SerializeMessage()); Message outputMessage = Message.Load(outputText); Assert.True(outputMessage.Bcc == null); this.CheckHeaderRaw(outputMessage.Cc, 2); this.CheckCollection(outputMessage.Cc, new string[] {"*****@*****.**", "*****@*****.**"}, new string[] {"*****@*****.**>", "*****@*****.**"}); this.CheckHeaderRaw(outputMessage.To, 1); this.CheckCollection(outputMessage.To, new string[] { "*****@*****.**"}, new string[] { "*****@*****.**"}); }
public void TestBasicAdddressCollectionCreate() { DirectAddressCollection coll = new DirectAddressCollection(); Assert.False(coll.IsTrusted()); Assert.Equal<string>("", coll.ToString()); Assert.False(coll.IsTrusted(TrustEnforcementStatus.Failed)); Assert.True(coll.GetCertificates().Count == 0); Assert.True(coll.Certificates.Count() == 0); Assert.True(coll.GetUntrusted().Count() == 0); Assert.True(coll.GetTrusted().Count() == 0); Assert.DoesNotThrow(() => coll.RemoveUntrusted()); }
/// <summary> /// Ensure that domain recipients are KNOWN - i.e. registered with the Config System /// If not, remove them. /// </summary> /// <param name="message"></param> void VerifyDomainRecipientsRegistered(IncomingMessage message) { message.EnsureRecipientsCategorizedByDomain(this.SecurityAgent.Domains); if (!message.HasDomainRecipients) { throw new AgentException(AgentError.NoRecipients); } DirectAddressCollection recipients = message.DomainRecipients; if (this.Settings.MaxIncomingDomainRecipients > 0 && recipients.Count > this.Settings.MaxIncomingDomainRecipients) { throw new AgentException(AgentError.MaxDomainRecipients); } if (!m_settings.HasAddressManager) { // Address validation is turned off return; } Address[] resolved = m_configService.GetAddresses(recipients); if (resolved.IsNullOrEmpty()) { throw new AgentException(AgentError.NoDomainRecipients); } // Remove any addresses that could not be resolved // Yes, this is currently n^2, but given the typical # of addresses, cost should be insignificant int i = 0; while (i < recipients.Count) { DirectAddress recipient = recipients[i]; int iAddress = Array.FindIndex <Address>(resolved, x => x.Match(recipient)); if (iAddress >= 0) { ++i; // Found recipient.Tag = resolved[iAddress]; } else { recipients.RemoveAt(i); } } }
DirectAddressCollection BasicCollection() { string[] addrStrings = new string[] { "*****@*****.**", "\"Franklin Roosevelt\" <*****@*****.**>", "sean+o'*****@*****.**" }; IEnumerable <DirectAddress> addrs = addrStrings.Select(a => new DirectAddress(a)); DirectAddressCollection coll = new DirectAddressCollection(); coll.Add(addrs); coll[0].Status = TrustEnforcementStatus.Failed; coll[1].Status = TrustEnforcementStatus.Unknown; coll[2].Status = TrustEnforcementStatus.Success; return(coll); }
internal Address[] GetAddresses(DirectAddressCollection addresses) { Debug.Assert(m_settings.HasAddressManager); string[] emailAddresses = ( from address in addresses select address.Address ).ToArray(); using (AddressManagerClient client = CreateAddressManagerClient()) { if (AddressDomainSearchEnabled(m_settings.AddressManager)) { return client.GetAddressesOrDomain(emailAddresses, EntityStatus.Enabled); } return client.GetAddresses(emailAddresses, EntityStatus.Enabled); } }
/// <summary> /// To simplify outbound mail sending, SMTP Server allows you to drop new messages into a pickup folder /// You don't need to use SmtpClient or some other SMTP client /// </summary> public void Send(IncomingMessage envelope, string pickupFolder, DirectAddressCollection senders, MDNStandard.NotificationType notificationType) { if (string.IsNullOrEmpty(pickupFolder)) { throw new ArgumentException("value null or empty", "pickupFolder"); } if (senders.IsNullOrEmpty()) { return; } foreach (NotificationMessage notification in this.Produce(envelope, senders.AsMailAddresses(), notificationType)) { string filePath = Path.Combine(pickupFolder, Extensions.CreateUniqueFileName()); notification.Save(filePath); } }
internal Address[] GetAddresses(DirectAddressCollection addresses) { Debug.Assert(m_settings.HasAddressManager); string[] emailAddresses = ( from address in addresses select address.Address ).ToArray(); using (AddressManagerClient client = CreateAddressManagerClient()) { if (AddressDomainSearchEnabled(m_settings.AddressManager)) { return(client.GetAddressesOrDomain(emailAddresses, EntityStatus.Enabled)); } return(client.GetAddresses(emailAddresses, EntityStatus.Enabled)); } }
MessageEnvelope CreateEnvelope(CDO.Message message) { DirectAddressCollection recipientAddresses = null; DirectAddress senderAddress = null; MessageEnvelope envelope; string messageText = message.GetMessageText(); if (this.ExtractEnvelopeFields(message, ref recipientAddresses, ref senderAddress)) { envelope = new MessageEnvelope(messageText, recipientAddresses, senderAddress); } else { envelope = new MessageEnvelope(messageText); } return(envelope); }
string CollectNoCertInformation(DirectAddressCollection recipients) { if (recipients.IsNullOrEmpty()) { return(string.Empty); } StringBuilder builder = new StringBuilder(); foreach (DirectAddress recipient in recipients) { if (!recipient.HasCertificates) { builder.Append(recipient.Address).Append(';'); } } return(builder.ToString()); }
protected static void MockPublicCerts(DirectAddressCollection recipients, Mock <ICertificateResolver> mockDnsResolver) { foreach (var recipient in recipients) { string address = recipient.Address; string host = new MailAddress(address).Host; mockDnsResolver.Setup( reslover => reslover.GetCertificates(It.Is <MailAddress>(adrs => adrs.Address.Equals( new MailAddress(address).Address , StringComparison.OrdinalIgnoreCase)))) .Returns(TestCertificates.AllPublicCerts.Where((x) => { return (x.MatchEmailNameOrName(address) || x.MatchDnsName(host)); } )); } }
public void TestUntrusted() { // // This should be accepted because the envelope is what we look at // MessageEnvelope envelope = new MessageEnvelope(BadMessage, DirectAddressCollection.ParseSmtpServerEnvelope("*****@*****.**"), new DirectAddress("*****@*****.**") ); Assert.DoesNotThrow(() => m_agent.SecurityAgent.ProcessOutgoing(envelope)); envelope = new MessageEnvelope(string.Format(TestMessage, Guid.NewGuid()), DirectAddressCollection.ParseSmtpServerEnvelope("*****@*****.**"), new DirectAddress("*****@*****.**")); // // This SHOULD throw an exception // Assert.Throws <OutgoingAgentException>(() => m_agent.SecurityAgent.ProcessOutgoing(envelope)); }
void CheckCollection(Header header, string[] contains, string[] doesNotContain) { Assert.True(header != null); DirectAddressCollection collection = null; Assert.DoesNotThrow(() => collection = DirectAddressCollection.Parse(header.Value)); if (!contains.IsNullOrEmpty()) { foreach (string addr in contains) { Assert.True(collection.Contains(addr)); } } if (!doesNotContain.IsNullOrEmpty()) { foreach (string addr in doesNotContain) { Assert.True(!collection.Contains(addr)); } } }
// // A CDO Message could be arriving via the SMTP server, or could have been constructed manually // The one created by SMTP has envelope information // Returns false if no envelope info is available. We have to look within message headers in that case // bool ExtractEnvelopeFields(CDO.Message message, ref DirectAddressCollection recipientAddresses, ref DirectAddress senderAddress) { if (!this.HasEnvelope) { // // No envelope // return(false); } recipientAddresses = null; senderAddress = null; string sender = message.GetEnvelopeSender(); if (string.IsNullOrEmpty(sender)) { throw new SmtpAgentException(SmtpAgentError.NoSenderInEnvelope); } // // In SMTP Server, the MAIL TO (sender) in the envelope can be empty if the message is from the server postmaster // The actual postmaster address is found in the message itself // if (Health.Direct.SmtpAgent.Extensions.IsSenderLocalPostmaster(sender)) { return(false); } string recipients = message.GetEnvelopeRecipients(); if (string.IsNullOrEmpty(recipients)) { throw new SmtpAgentException(SmtpAgentError.NoRecipientsInEnvelope); } recipientAddresses = DirectAddressCollection.ParseSmtpServerEnvelope(recipients); senderAddress = new DirectAddress(sender); return(true); }
void Route(ISmtpMessage message, DirectAddressCollection recipients, DirectAddressCollection routedRecipients) { Dictionary <string, Route> matchedRoutes = new Dictionary <string, Route>(StringComparer.OrdinalIgnoreCase); int i = 0; // // First, find all routes that match // We'll remove recipients that were routed from the recipients list so // SMTP server does not itself try to deliver to them // while (i < recipients.Count) { DirectAddress recipient = recipients[i]; Address address = recipient.Tag as Address; if (address != null) { Route route = this[address.Type]; if (route != null) { matchedRoutes[address.Type] = route; recipients.RemoveAt(i); if (routedRecipients != null) { recipient.Tag = route.AddressType; // Reference for failed delivery routedRecipients.Add(recipient); // Add the routed recipient to the list } continue; } } ++i; } if (matchedRoutes.Count == 0) { return; } this.Route(message, matchedRoutes.Values); }
/// <summary> /// To simplify inbound mail sending, SMTP Server allows you to drop new messages into a pickup folder /// You don't need to use SmtpClient or some other SMTP client /// </summary> public void SendFailure(OutgoingMessage envelope, string pickupFolder) { if (string.IsNullOrEmpty(pickupFolder)) { throw new ArgumentException("value null or empty", "pickupFolder"); } DirectAddressCollection recipients = envelope.RejectedRecipients; if (recipients.IsNullOrEmpty()) { return; } if (recipients != null && envelope.UsingDeliveryStatus) { DSNMessage notification = this.ProduceFailure(envelope, recipients); string filePath = Path.Combine(pickupFolder, Extensions.CreateUniqueFileName()); notification.Save(filePath); } }
/// <summary> /// Decrypts and verifies trust in a signed and encrypted RFC 5322 formatted message, providing a sender and recipient addresses. /// The provided sender and recipient addresses will be used instead of the header information in the <c>messageText</c>. /// </summary> /// <param name="messageText"> /// An RFC 5322 formatted message string. /// </param> /// <param name="recipients"> /// A <see cref="DirectAddressCollection"/> instance representing recipient addresses. /// </param> /// <param name="sender"> /// An <see cref="DirectAddress"/> instance representing the sender address /// </param> /// <returns> /// An <see cref="IncomingMessage"/> instance with the trust verified decrypted and verified message. /// </returns> public IncomingMessage ProcessIncoming(string messageText, DirectAddressCollection recipients, DirectAddress sender) { IncomingMessage message = new IncomingMessage(messageText, recipients, sender); return this.ProcessIncoming(message); }
/// <summary> /// Creates an instance from a <see cref="Message"/> and explicitly assigned sender and receivers, which take precendence over what may be /// in the message headers. /// </summary> /// <param name="message">The <see cref="Message"/> this envelopes</param> /// <param name="recipients">The <see cref="DirectAddressCollection"/> of reciepients; takes precedence over the <c>To:</c> header</param> /// <param name="sender">The <see cref="DirectAddress"/> of the sender - typically the MAIL FROM in SMTP; takes precendence over the <c>From:</c> header.</param> public MessageEnvelope(Message message, DirectAddressCollection recipients, DirectAddress sender) { this.Message = message; this.Recipients = recipients; this.Sender = sender; this.NotifyTo = GetDispostionNotifyTo(message); }
internal virtual void CategorizeRecipientsByTrust(TrustEnforcementStatus minTrustStatus) { m_rejectedRecipients = DirectAddressCollection.Create(Recipients.GetUntrusted(minTrustStatus)); if (this.HasRecipients) { this.Recipients.RemoveUntrusted(minTrustStatus); } if (this.HasDomainRecipients) { this.DomainRecipients.RemoveUntrusted(minTrustStatus); } }
public void SetRcptTo(DirectAddressCollection recipients) { if (recipients == null) { throw new ArgumentNullException("recipients"); } if (this.HasEnvelope) { m_message.SetEnvelopeRecipients(recipients.ToMailAddressCollection()); } }
void SendDeliveryStatus(IEnumerable<Route> router, IncomingMessage envelope, DirectAddressCollection routedRecipients) { if (envelope.Message.IsMDN() || envelope.Message.IsDSN()) { return; } DirectAddressCollection undeliveredRecipients = new DirectAddressCollection(); foreach (var route in router) { if (route.FailedDelivery) { foreach (var routedRecipient in routedRecipients) { if(route.AddressType == routedRecipient.Tag as string) { undeliveredRecipients.Add(routedRecipient); } } } } try { m_notifications.SendFailure(envelope, m_settings.InternalMessage.PickupFolder, undeliveredRecipients); } catch (Exception ex) { Logger.Error("While sending un-secured DSN {0}", ex.Message); } }
public void TestParseAddressCollection(string addressList, int expectedCount) { DirectAddressCollection coll = DirectAddressCollection.Parse(addressList); Assert.Equal <int>(expectedCount, coll.Count); }
/// <summary> /// Generate external notification messages for failed final destination delivery /// </summary> /// <param name="envelope"></param> /// <param name="recipients">sending failure status for these message recipients</param> /// <returns>An DSNmessage</returns> public DSNMessage ProduceFailure(IncomingMessage envelope, DirectAddressCollection recipients) { if (envelope == null) { throw new ArgumentNullException("envelope"); } if (string.IsNullOrEmpty(m_settings.ProductName)) { throw new ArgumentException("reportingAgentName:AgentSettings:ProductName"); } DSNPerMessage perMessage = new DSNPerMessage(envelope.Sender.Host, envelope.Message.IDValue); // // Un-Deliverable recipients // List<DSNPerRecipient> dsnPerRecipients = envelope.CreatePerRecipientStatus(recipients.AsMailAddresses() , m_settings.Text, m_settings.AlwaysAck, DSNStandard.DSNAction.Failed, DSNStandard.DSNStatus.Permanent , DSNStandard.DSNStatus.DELIVERY_OTHER).ToList(); DSN dsn = new DSN(perMessage, dsnPerRecipients); //Configure and/or dynamic plus refactor //TODO: Split messages by domain. See envelope.Recipients[0] below. return envelope.Message.CreateStatusMessage(new MailAddress("Postmaster@" + envelope.Recipients[0].Host), dsn); }
/// <summary> /// Return a combined collection of all recipients in routing headers (to/cc/bcc) /// </summary> /// <returns>A collection of recipients</returns> public DirectAddressCollection GetRecipientsInRoutingHeaders() { DirectAddressCollection addresses = new DirectAddressCollection(); if (this.To != null) { addresses.Add(this.To); } if (this.Cc != null) { addresses.Add(this.Cc); } if (this.Bcc != null) { addresses.Add(this.Bcc); } return addresses; }
public void SetRcptTo(DirectAddressCollection recipients) { throw new NotImplementedException(); }
/// <summary> /// Creates an instance from a <see cref="Message"/> instance, with explicitly assigned raw message, recipients and sender, /// which take precendece over what may be in the message object or text. /// </summary> /// <param name="message">The <see cref="Message"/> this envelopes</param> /// <param name="recipients">The <see cref="DirectAddressCollection"/> of reciepients; takes precedence over the <c>To:</c> header</param> /// <param name="sender">The <see cref="DirectAddress"/> of the sender; takes precendence over the <c>From:</c> header.</param> /// <param name="rawMessage">The RFC 5322 message string to use ae the raw message for this instance.</param> protected MessageEnvelope(Message message, string rawMessage, DirectAddressCollection recipients, DirectAddress sender) : this(message, recipients, sender) { this.RawMessage = rawMessage; }
/// <summary> /// Creates an instance from an RFC 5322 message string and explicitly assigned sender and receivers, which take precendence over what may be /// in the message headers. /// </summary> /// <param name="messageText">The RFC 5322 message string to intialize this envelope from. Stored as <c>RawMessage</c></param> /// <param name="recipients">The <see cref="DirectAddressCollection"/> of reciepients; takes precedence over the <c>To:</c> header</param> /// <param name="sender">The <see cref="DirectAddress"/> of the sender - typically the MAIL FROM in SMTP; takes precendence over the <c>From:</c> header.</param> public MessageEnvelope(string messageText, DirectAddressCollection recipients, DirectAddress sender) : this(MimeSerializer.Default.Deserialize<Message>(messageText), recipients, sender) { this.RawMessage = messageText; }
string CollectNoCertInformation(DirectAddressCollection recipients) { if (recipients.IsNullOrEmpty()) { return string.Empty; } StringBuilder builder = new StringBuilder(); foreach(DirectAddress recipient in recipients) { if (!recipient.HasCertificates) { builder.Append(recipient.Address).Append(';'); } } return builder.ToString(); }
/// <summary> /// Encrypts, verifies recipient trust, and signs an RFC 5322 formatted message /// The provided sender and recipient addresses will be used instead of the header information in the <c>messageText</c>. /// </summary> /// <param name="messageText"> /// An RFC 5322 formatted message string /// </param> /// <param name="recipients"> /// An <see cref="DirectAddressCollection"/> instance specifying message recipients. /// </param> /// <param name="sender"> /// An <see cref="DirectAddress"/> instance specifying message sender /// </param> /// <returns> /// An <see cref="OutgoingMessage"/> instance containing the encrypted and trust verified message. /// </returns> public OutgoingMessage ProcessOutgoing(string messageText, DirectAddressCollection recipients, DirectAddress sender) { OutgoingMessage message = new OutgoingMessage(this.WrapMessage(messageText), recipients, sender); return this.ProcessOutgoing(message); }
/// <summary> /// Generate internal notification messages (if any) for this outgoing message /// </summary> /// <param name="envelope"></param> /// <param name="recipients">sending failure status for these message recipients</param> /// <returns>An DSNmessage</returns> public DSNMessage ProduceFailure(OutgoingMessage envelope, DirectAddressCollection recipients) { if (envelope == null) { throw new ArgumentNullException("envelope"); } if (string.IsNullOrEmpty(m_settings.ProductName)) { throw new ArgumentException("reportingAgentName:AgentSettings:ProductName"); } DSNPerMessage perMessage = new DSNPerMessage(envelope.Sender.Host, envelope.Message.IDValue); // // Un-Secured recipients // List<DSNPerRecipient> dsnPerRecipients = envelope.CreatePerRecipientStatus(recipients.UnResolvedCertificates().AsMailAddresses() , m_settings.Text, m_settings.AlwaysAck, DSNStandard.DSNAction.Failed, DSNStandard.DSNStatus.Permanent , DSNStandard.DSNStatus.UNSECURED_STATUS).ToList(); // // Un-Trusted recipients // dsnPerRecipients.AddRange(envelope.CreatePerRecipientStatus(recipients.ResolvedCertificates().AsMailAddresses() , m_settings.Text, m_settings.AlwaysAck, DSNStandard.DSNAction.Failed, DSNStandard.DSNStatus.Permanent , DSNStandard.DSNStatus.UNTRUSTED_STATUS).ToList()); DSN dsn = new DSN(perMessage, dsnPerRecipients); //Configure and/or dynamic plus refactor return envelope.Message.CreateStatusMessage(new MailAddress("Postmaster@" + envelope.Sender.Host), dsn); }
/// <summary> /// Find <c>DirectAddress</c>s without Certificates /// </summary> /// <param name="addresses"></param> /// <returns></returns> public static DirectAddressCollection UnResolvedCertificates(this DirectAddressCollection addresses) { DirectAddressCollection unsecured = new DirectAddressCollection(); foreach (DirectAddress addr in addresses) { if ( ! addr.ResolvedCertificates) { unsecured.Add(addr); } } return unsecured; }
void PostProcessIncoming(ISmtpMessage message, IncomingMessage envelope) { this.CopyMessage(message, m_settings.Incoming); if (envelope.HasDomainRecipients) { DirectAddressCollection routedRecipients = new DirectAddressCollection(); m_router.Route(message, envelope, routedRecipients); this.SendNotifications(envelope, routedRecipients); SendDeliveryStatus(m_router, envelope, routedRecipients); } // // Any recipients that were handled by routes are no longer in the DomainRecipients collection (removed) // Smtp Server should continue process any domain recipients whose delivery were NOT handled by routes // if (m_settings.Incoming.EnableRelay && envelope.HasDomainRecipients) { this.SendNotifications(envelope, envelope.DomainRecipients); // // We only want the incoming message sent to trusted domain recipients // We are not allowing arbitrary relay // message.SetRcptTo(envelope.DomainRecipients); m_diagnostics.LogEnvelopeHeaders(message); } else { // // SMTP Server need not proceed with delivery because we already routed the message to all domain recipients // message.Abort(); } }
/// <summary> /// Remove addresses from Routing headers /// </summary> /// <param name="addresses"><see cref="DirectAddressCollection"/> containing addresses to remove</param> public void RemoveFromRoutingHeaders(DirectAddressCollection addresses) { this.UpdateRoutingHeaders(addresses); }
protected virtual void SendNotifications(IncomingMessage envelope, DirectAddressCollection senders) { if (!m_settings.InternalMessage.HasPickupFolder || !m_settings.Notifications.AutoResponse) { return; } // // Its ok if we fail on sending notifications - that should never cause us to not // deliver the message // try { if(envelope.Message.IsMDN() || envelope.Message.IsDSN()) { return; } m_notifications.Send(envelope, m_settings.InternalMessage.PickupFolder, senders, MDNStandard.NotificationType.Processed); if(m_settings.Notifications.GatewayIsDestination && envelope.Message.IsTimelyAndReliable()) { m_notifications.Send(envelope, m_settings.InternalMessage.PickupFolder, senders, MDNStandard.NotificationType.Dispatched); } } catch (Exception ex) { Logger.Error("While sending notification {0}", ex.ToString()); } }
public void ToHeaderNull() { DirectAddressCollection addresses = new DirectAddressCollection(); Header header = null; Assert.DoesNotThrow(() => header = addresses.ToHeader(MailStandard.Headers.To)); Assert.True(header == null); }
internal void UpdateRoutingHeaders(DirectAddressCollection rejectedRecipients) { if (rejectedRecipients.IsNullOrEmpty()) { return; } this.UpdateRecipientHeader(To, MailStandard.Headers.To, rejectedRecipients); this.UpdateRecipientHeader(Cc, MailStandard.Headers.Cc, rejectedRecipients); this.UpdateRecipientHeader(Bcc, MailStandard.Headers.Bcc, rejectedRecipients); }
void UpdateRecipientHeader(DirectAddressCollection recipients, string headerName, IEnumerable<DirectAddress> rejectedRecipients) { if (recipients != null) { recipients.Remove(rejectedRecipients); this.Message.Headers[headerName] = recipients.ToHeader(headerName); } }
/// <summary> /// Categorize recipients as follows: /// - are they in the local domain or are they external /// </summary> /// <param name="domains"></param> internal void CategorizeRecipientsByDomain(AgentDomains domains) { DirectAddressCollection recipients = Recipients; DirectAddressCollection domainRecipients = null; MailAddressCollection otherRecipients = null; for (int i = 0, count = recipients.Count; i < count; ++i) { DirectAddress address = recipients[i]; if (domains.IsManaged(address)) { if (domainRecipients == null) { domainRecipients = new DirectAddressCollection(); } domainRecipients.Add(address); } else { if (otherRecipients == null) { otherRecipients = new MailAddressCollection(); } otherRecipients.Add(address); } } this.DomainRecipients = domainRecipients; this.OtherRecipients = otherRecipients; }
internal MessageEnvelope(MessageEnvelope envelope) { m_agent = envelope.m_agent; this.RawMessage = envelope.RawMessage; m_message = envelope.m_message; if (envelope.m_recipients != null) { m_recipients = new DirectAddressCollection {envelope.m_recipients}; } m_sender = envelope.m_sender; m_notifyTo = envelope.m_notifyTo; }
// // A CDO Message could be arriving via the SMTP server, or could have been constructed manually // The one created by SMTP has envelope information // Returns false if no envelope info is available. We have to look within message headers in that case // bool ExtractEnvelopeFields(CDO.Message message, ref DirectAddressCollection recipientAddresses, ref DirectAddress senderAddress) { if (!this.HasEnvelope) { // // No envelope // return false; } recipientAddresses = null; senderAddress = null; string sender = message.GetEnvelopeSender(); if (string.IsNullOrEmpty(sender)) { throw new SmtpAgentException(SmtpAgentError.NoSenderInEnvelope); } // // In SMTP Server, the MAIL TO (sender) in the envelope can be empty if the message is from the server postmaster // The actual postmaster address is found in the message itself // if (Health.Direct.SmtpAgent.Extensions.IsSenderLocalPostmaster(sender)) { return false; } string recipients = message.GetEnvelopeRecipients(); if (string.IsNullOrEmpty(recipients)) { throw new SmtpAgentException(SmtpAgentError.NoRecipientsInEnvelope); } recipientAddresses = DirectAddressCollection.ParseSmtpServerEnvelope(recipients); senderAddress = new DirectAddress(sender); return true; }
void SendDeliveryStatus(IEnumerable <Route> router, IncomingMessage envelope, DirectAddressCollection routedRecipients) { if (envelope.Message.IsMDN() || envelope.Message.IsDSN()) { return; } DirectAddressCollection undeliveredRecipients = new DirectAddressCollection(); foreach (var route in router) { if (route.FailedDelivery) { foreach (var routedRecipient in routedRecipients) { if (route.AddressType == routedRecipient.Tag as string) { undeliveredRecipients.Add(routedRecipient); } } } } try { m_notifications.SendFailure(envelope, m_settings.InternalMessage.PickupFolder, undeliveredRecipients); } catch (Exception ex) { Logger.Error("While sending un-secured DSN {0}", ex.Message); } }
// // Release buffers // internal void Clear() { RawMessage = null; m_message = null; m_sender = null; m_to = null; m_cc = null; m_bcc = null; m_recipients = null; m_rejectedRecipients = null; }