/// <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:
            //
            
            
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
 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[] { "*****@*****.**"});
                          
 }
Beispiel #4
0
 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());
 }
Beispiel #5
0
        /// <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);
                }
            }
        }
Beispiel #6
0
        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);
     }
 }
Beispiel #9
0
        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));
            }
        }
Beispiel #10
0
        /// <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);
            }
        }
Beispiel #11
0
        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());
        }
Beispiel #13
0
 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));
         }
                                                        ));
     }
 }
Beispiel #14
0
        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));
                }
            }
        }
Beispiel #16
0
        //
        // 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);
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        /// <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);
            }
        }
Beispiel #19
0
 /// <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);                    
 }
Beispiel #20
0
 /// <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);
 }
Beispiel #21
0
 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);
     }
 }
Beispiel #22
0
 public void SetRcptTo(DirectAddressCollection recipients)
 {
     if (recipients == null)
     {
         throw new ArgumentNullException("recipients");
     }
     
     if (this.HasEnvelope)
     {
         m_message.SetEnvelopeRecipients(recipients.ToMailAddressCollection());
     }
 }
Beispiel #23
0
        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);
            }
        }
Beispiel #24
0
        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);

        }
Beispiel #26
0
 /// <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;
 }
Beispiel #27
0
 public void SetRcptTo(DirectAddressCollection recipients)
 {
     throw new NotImplementedException();
 }
Beispiel #28
0
 /// <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;
 }
Beispiel #29
0
 /// <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;
 }
Beispiel #30
0
 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();
 }
Beispiel #31
0
 /// <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);

        }
Beispiel #33
0
 /// <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;
 }
Beispiel #34
0
        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();
            }
        }
Beispiel #35
0
 public void SetRcptTo(DirectAddressCollection recipients)
 {
     throw new NotImplementedException();
 }
Beispiel #36
0
 /// <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);
 }
Beispiel #37
0
        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);
 }
Beispiel #39
0
        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);
        }
Beispiel #40
0
 void UpdateRecipientHeader(DirectAddressCollection recipients, string headerName, IEnumerable<DirectAddress> rejectedRecipients)
 {
     if (recipients != null) 
     {
         recipients.Remove(rejectedRecipients);
         this.Message.Headers[headerName] = recipients.ToHeader(headerName);
     }
 }
Beispiel #41
0
        /// <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;
        }
Beispiel #42
0
 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;
 }
Beispiel #43
0
        //
        // 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;
        }
Beispiel #44
0
        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);
            }
        }
Beispiel #45
0
 //
 // 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;
 }