예제 #1
0
        /// <summary>
        /// Signs the given mail item using the provided signer. The mailItem object will be updated so that it includes the signature.
        /// </summary>
        /// <param name="domainSigner">The domain and its signer</param>
        /// <param name="mailItem">The mail item to sign</param>
        /// <returns></returns>
        public void SignMessage(DomainElementSigner domainSigner, MailItem mailItem)
        {
            using (Stream stream = mailItem.GetMimeReadStream())
            {
                stream.Seek(0, SeekOrigin.Begin);

                Logger.LogDebug("Parsing the MimeMessage");
                MimeMessage message = MimeMessage.Load(stream, true);

                Logger.LogDebug("Signing the message");
                lock (settingsMutex)
                {
                    message.Sign(domainSigner.Signer, eligibleHeaders, headerCanonicalization, bodyCanonicalization);
                }
                var value = message.Headers[HeaderId.DkimSignature];
                Logger.LogDebug("Got signing header: " + value);

                // we first need to create a memory stream, because if WriteTo is called with mailItem Stream directly, it throws an exception somehow.
                MemoryStream memoryOutputStream = new MemoryStream();
                message.WriteTo(FormatOptions.Default, memoryOutputStream);
                memoryOutputStream.Seek(0, SeekOrigin.Begin);

                using (Stream outputStream = mailItem.GetMimeWriteStream())
                {
                    memoryOutputStream.WriteTo(outputStream);
                    outputStream.Close();
                }

                stream.Close();
            }
        }
예제 #2
0
        /// <summary>
        /// Signs the given mail item, if possible, according to the DKIM standard.
        /// </summary>
        /// <param name="mailItem">The mail item that is to be signed, if possible.</param>
        private void SignMailItem(MailItem mailItem)
        {
            // If the mail item is a "system message" then it will be read-only here,
            // and we can't sign it. Additionally, if the message has a "TnefPart",
            // then it is in a proprietary format used by Outlook and Exchange Server,
            // which means we shouldn't bother signing it.
            if (!mailItem.Message.IsSystemMessage && mailItem.Message.TnefPart == null)
            {
                /* Check if DKIM is defined for the current domain */
                DomainElement domain = null;
                foreach (DomainElement e in domainSettings)
                {
                    if (mailItem.FromAddress.DomainPart
                        .ToUpperInvariant()
                        .Contains(e.getDomain().ToUpperInvariant()))
                    {
                        domain = e;
                    }
                }

                /* If domain was found in define domain configuration, we just do nothing */
                if (domain != null)
                {
                    using (var inputStream = mailItem.GetMimeReadStream())
                    {
                        string dkim = this.dkimSigner.CanSign(domain, inputStream);

                        if (dkim.Length != 0)
                        {
                            Logger.LogInformation("Signing mail with header: " + dkim);

                            inputStream.Seek(0, SeekOrigin.Begin);
                            byte[] inputBuffer = ReadFully(inputStream);
                            inputStream.Close();

                            using (var outputStream = mailItem.GetMimeWriteStream())
                            {
                                try
                                {
                                    this.dkimSigner.Sign(inputBuffer, outputStream, dkim);
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogError("Signing went terribly wrong: " + ex.ToString());
                                }

                                outputStream.Close();
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Signs the given mail item, if possible, according to the DKIM standard.
        /// </summary>
        /// <param name="mailItem">The mail item that is to be signed, if possible.</param>
        private void SignMailItem(MailItem mailItem)
        {
            // If the mail item is a "system message" then it will be read-only here,
            // and we can't sign it. Additionally, if the message has a "TnefPart",
            // then it is in a proprietary format used by Outlook and Exchange Server,
            // which means we shouldn't bother signing it.

            if (!mailItem.Message.IsSystemMessage &&
                mailItem.Message.TnefPart == null)
            {
                using (var inputStream = mailItem.GetMimeReadStream())
                {
                    string dkim = this.dkimSigner.CanSign(inputStream);

                    if (dkim.Length != 0)
                    {
                        Logger.LogInformation("Signing mail with header: " + dkim);

                        inputStream.Seek(0, SeekOrigin.Begin);
                        byte[] inputBuffer = ReadFully(inputStream);
                        inputStream.Close();

                        using (var outputStream = mailItem.GetMimeWriteStream())
                        {
                            try
                            {
                                this.dkimSigner.Sign(inputBuffer, outputStream, dkim);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError("Signing went terribly wrong: " + ex.ToString());
                            }

                            outputStream.Close();
                        }

                    }
                }
            }
        }
        /// <summary>
        /// Signs the given mail item, if possible, according to the DKIM standard.
        /// </summary>
        /// <param name="mailItem">The mail item that is to be signed, if possible.</param>
        private void SignMailItem(MailItem mailItem)
        {
            // If the mail item is a "system message" then it will be read-only here,
            // and we can't sign it. Additionally, if the message has a "TnefPart",
            // then it is in a proprietary format used by Outlook and Exchange Server,
            // which means we shouldn't bother signing it.

            if (!mailItem.Message.IsSystemMessage &&
                mailItem.Message.TnefPart == null)
            {
                using (var inputStream = mailItem.GetMimeReadStream())
                {
                    string dkim = this.dkimSigner.CanSign(inputStream);

                    if (dkim.Length != 0)
                    {
                        string source = this.dkimSigner.SourceMessage(inputStream);

                        inputStream.Close();

                        Logger.LogInformation("Signing mail with header: " + dkim);

                        using (var outputStream = mailItem.GetMimeWriteStream())
                        {
                            try
                            {
                                this.dkimSigner.Sign(source, outputStream, dkim);
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError("Signing went terribly wrong: " + ex.ToString());
                            }

                            outputStream.Close();
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Signs the given mail item using the provided signer. The mailItem object will be updated so that it includes the signature.
        /// </summary>
        /// <param name="domainSigner">The domain and its signer</param>
        /// <param name="mailItem">The mail item to sign</param>
        /// <returns></returns>
        public void SignMessage(DomainElementSigner domainSigner, MailItem mailItem)
        {
            // MailItem.GetMimeWriteStream() internally uses
            // Microsoft.Exchange.Data.Mime.MimeDocument.GetLoadStream(), which may reformat the
            // message using different formatting than is originally read from
            // MailItem.GetMimeReadStream().  To prevent these formatting changes from invalidating
            // the DKIM signature, we must read then write then re-read the message to ensure that
            // any formatting changes are made before we sign the message.
            using (MemoryStream memStream = new MemoryStream())
            {
                using (Stream inputStream = mailItem.GetMimeReadStream())
                {
                    inputStream.Seek(0, SeekOrigin.Begin);
#if EX_2007_SP3 || EX_2010 || EX_2010_SP1 || EX_2010_SP2 || EX_2010_SP3
                    byte[] buffer = new byte[16 * 1024];
                    int    size;
                    while ((size = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        memStream.Write(buffer, 0, size);
                    }
#else
                    inputStream.CopyTo(memStream);
#endif
                }
                memStream.Seek(0, SeekOrigin.Begin);
                using (Stream outputStream = mailItem.GetMimeWriteStream())
                {
                    memStream.WriteTo(outputStream);
                }
            }

            using (Stream inputStream = mailItem.GetMimeReadStream())
            {
                inputStream.Seek(0, SeekOrigin.Begin);
                Logger.LogDebug("Parsing the MimeMessage");
                MimeMessage message = MimeMessage.Load(inputStream, true);
                // 'inputStream' cannot be disposed until we are done with 'message'

                Logger.LogDebug("Signing the message");
                lock (settingsMutex)
                {
                    message.Sign(domainSigner.Signer, eligibleHeaders, headerCanonicalization, bodyCanonicalization);
                }
                var value = message.Headers[HeaderId.DkimSignature];
                Logger.LogDebug("Got signing header: " + value);

                // The Stream returned by mailItem.GetMimeWriteStream() will throw an exception if
                // Stream.Write() is called after Stream.Flush() has been called, but
                // MimeMessage.WriteTo(FormatOptions, Stream) may call Stream.Flush() before the full
                // message has been written.  To avoid exceptions we must buffer the message in a
                // MemoryStream.
                using (MemoryStream memStream = new MemoryStream())
                {
                    message.WriteTo(FormatOptions.Default, memStream);
                    memStream.Seek(0, SeekOrigin.Begin);
                    using (Stream outputStream = mailItem.GetMimeWriteStream())
                    {
                        memStream.WriteTo(outputStream);
                    }
                }
            }
        }
 public EmailItem(MailItem mailItem)
     : this(mailItem, mailItem.Message, mailItem.FromAddress, mailItem.GetMimeReadStream())
 {
 }
예제 #7
0
        /// <summary>
        /// Signs the given mail item using the provided signer. The mailItem object will be updated so that it includes the signature.
        /// </summary>
        /// <param name="domainSigner">The domain and its signer</param>
        /// <param name="mailItem">The mail item to sign</param>
        /// <returns></returns>
        public void SignMessage(DomainElementSigner domainSigner, MailItem mailItem)
        {
            if (disposed)
                throw new ObjectDisposedException("DkimSigner");

            using (Stream stream = mailItem.GetMimeReadStream())
            {
                stream.Seek(0, SeekOrigin.Begin);
                
                Logger.LogDebug("Parsing the MimeMessage");
                MimeMessage message = MimeMessage.Load(stream, true);

                Logger.LogDebug("Signing the message");
                lock (settingsMutex)
                {
                    message.Sign(domainSigner.Signer, eligibleHeaders, headerCanonicalization, bodyCanonicalization);
                }
                var value = message.Headers[HeaderId.DkimSignature];
                Logger.LogDebug("Got signing header: " + value);

                // we first need to create a memory stream, because if WriteTo is called with mailItem Stream directly, it throws an exception somehow.
                MemoryStream memoryOutputStream = new MemoryStream();
                message.WriteTo(FormatOptions.Default, memoryOutputStream);
                memoryOutputStream.Seek(0, SeekOrigin.Begin);

                using (Stream outputStream = mailItem.GetMimeWriteStream())
                {
                    memoryOutputStream.WriteTo(outputStream);
                    outputStream.Close();
                }

                stream.Close();
            }
        }
 public EmailItem(MailItem mailItem)
     : this(mailItem, mailItem.Message, mailItem.FromAddress, mailItem.GetMimeReadStream())
 {
 }
        /// <summary>
        /// Signs the given mail item, if possible, according to the DKIM standard.
        /// </summary>
        /// <param name="mailItem">The mail item that is to be signed, if possible.</param>
        private void SignMailItem(MailItem mailItem)
        {
            // If the mail item is a "system message" then it will be read-only here,
            // and we can't sign it. Additionally, if the message has a "TnefPart",
            // then it is in a proprietary format used by Outlook and Exchange Server,
            // which means we shouldn't bother signing it.
            if (!mailItem.Message.IsSystemMessage && mailItem.Message.TnefPart == null)
            {
                /* Check if we have a valid From address */
                if (!mailItem.FromAddress.IsValid || mailItem.FromAddress.DomainPart == null)
                {
                    Logger.LogWarning("Invalid from address: '" + mailItem.FromAddress + "'. Not signing email.");
                    return;
                }

                /* If domain was found in define domain configuration */
                if (this.dkimSigner.GetDomains().ContainsKey(mailItem.FromAddress.DomainPart))
                {
                    DomainElement domain = this.dkimSigner.GetDomains()[mailItem.FromAddress.DomainPart];

                    using (Stream stream = mailItem.GetMimeReadStream())
                    {
                        Logger.LogDebug("Domain found: '"+domain.Domain+"'. I'll sign the message.");
                        string dkim = this.dkimSigner.CanSign(domain, stream);

                        if (dkim.Length != 0)
                        {
                            Logger.LogInformation("Signing mail with header: " + dkim);

                            stream.Seek(0, SeekOrigin.Begin);
                            byte[] inputBuffer = ReadFully(stream);
                            stream.Close();

                            using (Stream outputStream = mailItem.GetMimeWriteStream())
                            {
                                try
                                {
                                    this.dkimSigner.Sign(inputBuffer, outputStream, dkim);
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogError("Signing went terribly wrong: " + ex.ToString());
                                }

                                outputStream.Close();
                            }
                        } else {
                            Logger.LogDebug("Got empty signing header. Something went wrong...");
                        }

                    }
                } else {
                    Logger.LogDebug("No entry found in config for domain '" + mailItem.FromAddress.DomainPart + "'");
                }
            }
            else
                Logger.LogDebug("Message is a System message or of TNEF format. Not signing.");
        }
        /// <summary>
        /// Signs the given mail item, if possible, according to the DKIM standard.
        /// </summary>
        /// <param name="mailItem">The mail item that is to be signed, if possible.</param>
        private void SignMailItem(MailItem mailItem)
        {
            // If the mail item is a "system message" then it will be read-only here,
            // and we can't sign it. Additionally, if the message has a "TnefPart",
            // then it is in a proprietary format used by Outlook and Exchange Server,
            // which means we shouldn't bother signing it.
            if (!mailItem.Message.IsSystemMessage && mailItem.Message.TnefPart == null)
            {
                 /* Check if DKIM is defined for the current domain */
                DomainElement domain = null;
                foreach (DomainElement e in domainSettings)
                {
                    if (mailItem.FromAddress.DomainPart
                                            .ToUpperInvariant()
                                            .Contains(e.getDomain().ToUpperInvariant()))
                        domain = e;
                }

                /* If domain was found in define domain configuration, we just do nothing */
                if (domain != null)
                {
                    using (var inputStream = mailItem.GetMimeReadStream())
                    {
                        string dkim = this.dkimSigner.CanSign(domain, inputStream);

                        if (dkim.Length != 0)
                        {
                            Logger.LogInformation("Signing mail with header: " + dkim);

                            inputStream.Seek(0, SeekOrigin.Begin);
                            byte[] inputBuffer = ReadFully(inputStream);
                            inputStream.Close();

                            using (var outputStream = mailItem.GetMimeWriteStream())
                            {
                                try
                                {
                                    this.dkimSigner.Sign(inputBuffer, outputStream, dkim);
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogError("Signing went terribly wrong: " + ex.ToString());
                                }

                                outputStream.Close();
                            }
                        }
                    }
                }
            }
        }