MessageSignature FindTrustedSignature(IncomingMessage message, X509Certificate2Collection anchors) { DirectAddress sender = message.Sender; MessageSignatureCollection signatures = message.SenderSignatures; MessageSignature lastTrustedSignature = null; foreach (MessageSignature signature in signatures) { if (m_certChainValidator.IsTrustedCertificate(signature.Certificate, anchors) && signature.CheckSignature()) { if (!sender.HasCertificates) { // Can't really check thumbprints etc. So, this is about as good as its going to get return(signature); } if (signature.CheckThumbprint(sender)) { return(signature); } // // We'll save this guy, but keep looking for a signer whose thumbprint we can verify // If we can't find one, we'll use the last trusted signer we found.. and just mark the recipient's trust // enforcement status as Success_ThumbprintMismatch // lastTrustedSignature = signature; } } return(lastTrustedSignature); }
void FindSenderSignatures(IncomingMessage message) { message.SenderSignatures = null; DirectAddress sender = message.Sender; SignerInfoCollection allSigners = message.Signatures.SignerInfos; MessageSignatureCollection senderSignatures = null; bool match; foreach (SignerInfo signer in allSigners) { bool isOrgCertificate = false; match = signer.Certificate.MatchEmailNameOrName(sender.Address); if (!match) { match = signer.Certificate.MatchDnsOrEmailOrName(sender.Host); isOrgCertificate = match; } if (match) { senderSignatures = senderSignatures ?? new MessageSignatureCollection(); senderSignatures.Add(new MessageSignature(signer, isOrgCertificate)); } } message.SenderSignatures = senderSignatures; }
/// <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); }
/// <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 (domains.HsmEnabled(address)) { address.HsmEnabled = true; } 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; }
void BindAddresses(OutgoingMessage message) { // // Retrieving the sender's private certificate is requied for encryption // if (message.UseIncomingTrustAnchors) { message.Sender.TrustAnchors = m_trustAnchors.IncomingAnchors.GetCertificates(message.Sender); } else { message.Sender.TrustAnchors = m_trustAnchors.OutgoingAnchors.GetCertificates(message.Sender); } message.Sender.Certificates = this.ResolvePrivateCerts(message.Sender, true); // // Bind each recipient's certs // DirectAddressCollection recipients = message.Recipients; for (int i = 0, count = recipients.Count; i < count; ++i) { DirectAddress recipient = recipients[i]; X509Certificate2Collection certificates = this.ResolvePublicCerts(recipient, false); recipient.Certificates = certificates; if (certificates != null) { recipient.ResolvedCertificates = true; } } }
// // 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; }
ISmimeCryptographer ResolveOutgoingCryptographer(DirectAddress address) { if (address.HsmEnabled) { // Using HSM then you must install an HSM enabled Cryptographer return(m_cryptographer); } // return the encapsulated software based cryptographer return(m_cryptographer.DefaultCryptographer); }
internal Address GetAddress(DirectAddress address) { Debug.Assert(m_settings.HasAddressManager); using (AddressManagerClient client = CreateAddressManagerClient()) { if (AddressDomainSearchEnabled(m_settings.AddressManager)) { return client.GetAddressesOrDomain(address, EntityStatus.Enabled); } return client.GetAddress(address, EntityStatus.Enabled); } }
void BindAddresses(IncomingMessage message) { // // Bind each recpient's certs and trust settings // DirectAddressCollection recipients = message.DomainRecipients; for (int i = 0, count = recipients.Count; i < count; ++i) { DirectAddress recipient = recipients[i]; recipient.Certificates = this.ResolvePrivateCerts(recipient, m_encryptionEnabled); recipient.TrustAnchors = m_trustAnchors.IncomingAnchors.GetCertificates(recipient); } }
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; }
internal bool CheckThumbprint(DirectAddress messageSender) { if (m_thumbprintVerified == null) { if (messageSender.HasCertificates) { m_thumbprintVerified = (messageSender.Certificates.FindByThumbprint(this.Certificate.Thumbprint) != null); } else { m_thumbprintVerified = false; } } return(m_thumbprintVerified.Value); }
/// <summary> /// Enforces the trust model on an incoming message by marking /// the <c>Status</c> property of <see cref="DirectAddress"/> instances for the receivers /// </summary> /// <param name="message">The <see cref="IncomingMessage"/> to validate trust for.</param> /// <exception cref="AgentException">If this message has no signatures</exception> public void Enforce(IncomingMessage message) { if (message == null) { throw new ArgumentNullException("message"); } if (!message.HasSignatures) { throw new AgentException(AgentError.UnsignedMessage); } // // The message could have multiple signatures, including, possibly, some not by the sender // this.FindSenderSignatures(message); if (!message.HasSenderSignatures) { throw new AgentException(AgentError.MissingSenderSignature); } // // For each recipient, find at least one valid sender signature that the recipient trusts // DirectAddress sender = message.Sender; DirectAddressCollection recipients = message.DomainRecipients; foreach (DirectAddress recipient in recipients) { recipient.Status = TrustEnforcementStatus.Failed; // // First, find a signature that this recipient trusts // MessageSignature trustedSignature = this.FindTrustedSignature(message, recipient, recipient.TrustAnchors); if (trustedSignature != null) { recipient.Status = TrustEnforcementStatus.Success; // // Signature has already been verified by FindTrustedSignature! // } } }
/// <summary> /// Enforces the trust model on an outgoing message by marking /// the <c>Status</c> property of <see cref="DirectAddress"/> instances for the receivers /// </summary> /// <param name="message">The <see cref="OutgoingMessage"/> to validate trust for.</param> public void Enforce(OutgoingMessage message) { if (message == null) { throw new ArgumentNullException("message"); } DirectAddress sender = message.Sender; foreach (DirectAddress recipient in message.Recipients) { recipient.Status = TrustEnforcementStatus.Failed; // The recipient is trusted if we at least one certificate that the sender trusts. recipient.Certificates = this.FindTrustedCerts(recipient.Certificates, sender.TrustAnchors); if (recipient.HasCertificates) { recipient.Status = TrustEnforcementStatus.Success; } } }
bool DecryptSignedContent(IncomingMessage message, DirectAddress recipient, out SignedCms signatures, out MimeEntity payload) { signatures = null; payload = null; foreach (X509Certificate2 cert in m_certificateFilter.FilterEncryptionCertificates(recipient.Certificates)) { try { if (this.DecryptSignatures(message, cert, out signatures, out payload)) { // Decrypted and extracted signatures successfully return(true); } } catch (Exception ex) { this.Notify(message, ex); } } return(false); }
internal OutgoingMessage(Message message, string messageText, DirectAddressCollection recipients, DirectAddress sender) : base(message, recipients, sender) { }
/// <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); }
bool DecryptSignedContent(IncomingMessage message, DirectAddress recipient, out SignedCms signatures, out MimeEntity payload) { signatures = null; payload = null; foreach (X509Certificate2 cert in recipient.Certificates) { try { if (this.DecryptSignatures(message, cert, out signatures, out payload)) { // Decrypted and extracted signatures successfully return true; } } catch(Exception ex) { this.Notify(message, ex); } } return false; }
/// <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 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; }
/// <summary> /// Creates an instance from a <see cref="Message"/> instance, specifying recipients and sender. /// </summary> /// <param name="message"><see cref="Message"/> instance representing the message to be prepped for send.</param> /// <param name="recipients">An <see cref="DirectAddressCollection"/> of recipients, takes precedence over recipients in the message</param> /// <param name="rejectedRecipients">An <see cref="DirectAddressCollection"/> of rejected recipients</param> /// <param name="sender">Sender <see cref="DirectAddress"/>, takes precendence over the <c>To</c> field in the message.</param> /// <param name="usingDeliveryStatus">Indicate if message requests DeliveryStatus</param> public OutgoingMessage(Message message, DirectAddressCollection recipients, DirectAddressCollection rejectedRecipients, DirectAddress sender, bool usingDeliveryStatus) : base(message, recipients, rejectedRecipients, sender) { this.UsingDeliveryStatus = usingDeliveryStatus; }
/// <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 a <see cref="Message"/> instance, specifying recipients and sender. /// </summary> /// <param name="message"><see cref="Message"/> instance representing the message to be prepped for send.</param> /// <param name="recipients">An <see cref="DirectAddressCollection"/> of recipients, takes precedence over recipients in the message</param> /// <param name="sender">Sender <see cref="DirectAddress"/>, takes precendence over the <c>To</c> field in the message.</param> public OutgoingMessage(Message message, DirectAddressCollection recipients, DirectAddress sender) : base(message, recipients, sender) { }
internal bool CheckThumbprint(DirectAddress messageSender) { if (m_thumbprintVerified == null) { if (messageSender.HasCertificates) { m_thumbprintVerified = (messageSender.Certificates.FindByThumbprint(this.Certificate.Thumbprint) != null); } else { m_thumbprintVerified = false; } } return m_thumbprintVerified.Value; }
// // 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; }
/// <summary> /// Creates an instance from a <see cref="Message"/> instance, specifying recipients and sender. /// </summary> /// <param name="message"><see cref="Message"/> instance, signed and encrypted.</param> /// <param name="recipients">An <see cref="DirectAddress"/> of recipients, takes precedence over recipients in the message</param> /// <param name="sender">Sender <see cref="DirectAddressCollection"/>, takes precendence over the <c>To</c> field in the message.</param> public IncomingMessage(Message message, DirectAddressCollection recipients, DirectAddress sender) : base(message, recipients, sender) { }
/// <summary> /// Creates an instance from an RFC 5322 format message string., specifying recipients and sender. /// </summary> /// <param name="messageText">RFC 5322 message string, signed and encrypted.</param> /// <param name="recipients">An <see cref="DirectAddressCollection"/> of recipients, takes precedence over recipients in the message</param> /// <param name="sender">Sender <see cref="DirectAddress"/>, takes precendence over the <c>To</c> field in the message.</param> public IncomingMessage(string messageText, DirectAddressCollection recipients, DirectAddress sender) : base(messageText, recipients, sender) { }
/// <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)); }
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; }
/// <summary> /// Creates an instance from an RFC 5322 string, specifying recipients and sender. /// </summary> /// <param name="messageText">RFC 5322 message string to be prepped for send.</param> /// <param name="recipients">An <see cref="DirectAddressCollection"/> of recipients, takes precedence over recipients in the message</param> /// <param name="sender">Sender <see cref="DirectAddress"/>, takes precendence over the <c>To</c> field in the message.</param> public OutgoingMessage(string messageText, DirectAddressCollection recipients, DirectAddress sender) : base(messageText, recipients, sender) { }
// // 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; }
/// <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> /// 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 OutgoingMessage(Message message, string messageText, DirectAddressCollection recipients, DirectAddress sender) : base(message, recipients, sender) { }
/// <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 a <see cref="Message"/> instance, specifying recipients and sender. /// </summary> /// <param name="message"><see cref="Message"/> instance representing the message to be prepped for send.</param> /// <param name="recipients">An <see cref="DirectAddressCollection"/> of recipients, takes precedence over recipients in the message</param> /// <param name="rejectedRecipients">An <see cref="DirectAddressCollection"/> of rejected recipients</param> /// <param name="sender">Sender <see cref="DirectAddress"/>, takes precendence over the <c>To</c> field in the message.</param> /// <param name="usingDeliveryStatus">Indicate if message requests DeliveryStatus</param> public OutgoingMessage(Message message, DirectAddressCollection recipients, DirectAddressCollection rejectedRecipients, DirectAddress sender, bool usingDeliveryStatus) : base(message, recipients, rejectedRecipients, sender) { this.UsingDeliveryStatus = usingDeliveryStatus; }
/// <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; }