/// <summary>
        /// Initializes various settings based on configuration.
        /// </summary>
        private void Initialize()
        {
            // Load the signing algorithm.
            try
            {
                this.algorithm = (DkimAlgorithmKind)Enum.Parse(
                    typeof(DkimAlgorithmKind),
                    Properties.Settings.Default.Algorithm,
                    true);
            }
            catch (Exception ex)
            {
                throw new ConfigurationErrorsException(
                    Resources.DkimSigningRoutingAgentFactory_BadAlgorithmConfig,
                    ex);
            }

            // Load the list of headers to sign in each message.
            var unparsedHeaders = Properties.Settings.Default.HeadersToSign;
            if (unparsedHeaders != null)
            {
                this.headersToSign = unparsedHeaders
                    .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            }

            try
            {
                XmlDocument xmlDoc = new XmlDocument(); //* create an xml document object.
                xmlDoc.Load(this.GetType().Assembly.Location + ".config"); //* load the XML document from the specified file.
                XmlNodeList domainInfoList = xmlDoc.GetElementsByTagName("domainInfo");
                if (domainInfoList == null || domainInfoList.Count != 1)
                {
                    Logger.LogError("There is an error in your configuration file. domainInfo couldn't be initialized properly.");
                    return;
                }
                XmlNode domainInfo = domainInfoList.Item(0);

                domainSettings = new List<DomainElement>();

                foreach (XmlNode n in domainInfo.ChildNodes)
                {
                    DomainElement e = new DomainElement();
                    e.Domain = n.Attributes["Domain"].Value;
                    e.Selector = n.Attributes["Selector"].Value;
                    e.PrivateKeyFile = n.Attributes["PrivateKeyFile"].Value;
                    if (e.initElement(Path.GetDirectoryName(this.GetType().Assembly.Location)))
                        domainSettings.Add(e);
                }
                if (domainSettings.Count == 0)
                {
                    Logger.LogWarning("No domain configuration found. DKIM will do nothing.");
                }
            }
            catch (Exception e)
            {
                Logger.LogError("Couldn't load config: " + e.ToString());
            }
            Logger.LogInformation("Exchange DKIM started. Algorithm: " + algorithm.ToString() + " Number of domains: " + domainSettings.Count);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultDkimSigner"/> class.
        /// </summary>
        /// <param name="signatureKind">The signature kind to use.</param>
        /// <param name="headersToSign">The headers to be signed. If null, only the From header will be signed.</param>
        /// <param name="selector">The domain containing the public key TXT record.</param>
        /// <param name="domain">The DNS selector.</param>
        /// <param name="encodedKey">The PEM-encoded key.</param>
        public DefaultDkimSigner(
            DkimAlgorithmKind signatureKind,
            IEnumerable<string> headersToSign,
            string selector,
            string domain,
            string encodedKey)
        {
            if (encodedKey == null ||
                encodedKey.Trim().Length == 0)
            {
                throw new ArgumentNullException("encodedKey");
            }

            if (selector == null ||
                selector.Trim().Length == 0)
            {
                throw new ArgumentNullException("selector");
            }

            if (domain == null ||
                domain.Trim().Length == 0)
            {
                throw new ArgumentNullException("domain");
            }

            this.cryptoProvider = CryptHelper.GetProviderFromPemEncodedRsaPrivateKey(encodedKey);
            this.domain = domain;
            this.selector = selector;

            switch (signatureKind)
            {
                case DkimAlgorithmKind.RsaSha1:
                    this.hashAlgorithm = new SHA1CryptoServiceProvider();
                    this.hashAlgorithmCryptoCode = "SHA1";
                    this.hashAlgorithmDkimCode = "rsa-sha1";
                    break;
                case DkimAlgorithmKind.RsaSha256:
                    this.hashAlgorithm = new SHA256CryptoServiceProvider();
                    this.hashAlgorithmCryptoCode = "SHA256";
                    this.hashAlgorithmDkimCode = "rsa-sha256";
                    break;
                default:
                    throw new ArgumentOutOfRangeException("signatureKind");
            }

            this.eligibleHeaders = new HashSet<string>();

            if (headersToSign != null)
            {
                foreach (var headerToSign in headersToSign)
                {
                    this.eligibleHeaders.Add(headerToSign.Trim());
                }
            }

            // The From header must always be signed according to the
            // DKIM specification.
            this.eligibleHeaders.Add("From");
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultDkimSigner"/> class.
        /// </summary>
        /// <param name="signatureKind">The signature kind to use.</param>
        /// <param name="headersToSign">The headers to be signed. If null, only the From header will be signed.</param>
        /// <param name="selector">The domain containing the public key TXT record.</param>
        /// <param name="domain">The DNS selector.</param>
        /// <param name="encodedKey">The PEM-encoded key.</param>
        public DefaultDkimSigner(
            DkimAlgorithmKind signatureKind,
            DkimCanonicalizationKind headerCanonicalizationKind,
            DkimCanonicalizationKind bodyCanonicalizationKind,
            IEnumerable<string> headersToSign,
            List<DomainElement> domainSettings)
        {
            this.domainSettings = domainSettings;

            switch (signatureKind)
            {
                case DkimAlgorithmKind.RsaSha1:
                    this.hashAlgorithm = new SHA1CryptoServiceProvider();
                    this.hashAlgorithmCryptoCode = "SHA1";
                    this.hashAlgorithmDkimCode = "rsa-sha1";
                    break;
                case DkimAlgorithmKind.RsaSha256:
                    this.hashAlgorithm = new SHA256CryptoServiceProvider();
                    this.hashAlgorithmCryptoCode = "SHA256";
                    this.hashAlgorithmDkimCode = "rsa-sha256";
                    break;
                default:
                    throw new ArgumentOutOfRangeException("signatureKind");
            }

            this.headerCanonicalization = headerCanonicalizationKind;

            this.bodyCanonicalization = bodyCanonicalizationKind;

            this.eligibleHeaders = new HashSet<string>();

            if (headersToSign != null)
            {
                foreach (var headerToSign in headersToSign)
                {
                    this.eligibleHeaders.Add(headerToSign.Trim());
                }
            }

            // The From header must always be signed according to the
            // DKIM specification.
            this.eligibleHeaders.Add("From");
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DkimSigner"/> class.
        /// </summary>
        /// <param name="signatureKind">The signature kind to use.</param>
        /// <param name="headersToSign">The headers to be signed. If null, only the From header will be signed.</param>
        /// <param name="selector">The domain containing the public key TXT record.</param>
        /// <param name="domain">The DNS selector.</param>
        /// <param name="encodedKey">The PEM-encoded key.</param>
        public DkimSigner(
            DkimAlgorithmKind signatureKind,
            DkimCanonicalizationKind headerCanonicalizationKind,
            DkimCanonicalizationKind bodyCanonicalizationKind,
            IEnumerable <string> headersToSign)
        {
            switch (signatureKind)
            {
            case DkimAlgorithmKind.RsaSha1:
                this.hashAlgorithm           = new SHA1CryptoServiceProvider();
                this.hashAlgorithmCryptoCode = "SHA1";
                this.hashAlgorithmDkimCode   = "rsa-sha1";
                break;

            case DkimAlgorithmKind.RsaSha256:
                this.hashAlgorithm           = new SHA256CryptoServiceProvider();
                this.hashAlgorithmCryptoCode = "SHA256";
                this.hashAlgorithmDkimCode   = "rsa-sha256";
                break;

            default:
                throw new ArgumentOutOfRangeException("signatureKind");
            }

            this.headerCanonicalization = headerCanonicalizationKind;
            this.bodyCanonicalization   = bodyCanonicalizationKind;

            this.eligibleHeaders = new HashSet <string>();
            if (headersToSign != null)
            {
                foreach (var headerToSign in headersToSign)
                {
                    this.eligibleHeaders.Add(headerToSign.Trim());
                }
            }

            // The From header must always be signed according to the
            // DKIM specification.
            this.eligibleHeaders.Add("From");
        }
Esempio n. 5
0
        /// <summary>
        /// Load the config file
        /// </summary>
        /// <param name="filename">Xml file name</param>
        /// <returns>The object created from the xml file</returns>
        public bool Load(string filename)
        {
            if (File.Exists(filename))
            {
                using (Stream stream = File.OpenRead(filename))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(Settings));
                    Settings settings = serializer.Deserialize(stream) as Settings;

                    this.Loglevel = settings.Loglevel;
                    this.SigningAlgorithm = settings.SigningAlgorithm;
                    this.HeaderCanonicalization = settings.HeaderCanonicalization;
                    this.BodyCanonicalization = settings.BodyCanonicalization;
                    this.HeadersToSign = settings.HeadersToSign;
                    this.Domains = settings.Domains;

                    return true;
                }
            }

            return false;
        }
Esempio n. 6
0
        /// <summary>
        /// Load the current configuration for Exchange DkimSigner from the registry
        /// </summary>
        private void LoadDkimSignerConfig()
        {
            if (RegistryHelper.Open(@"Software\Exchange DkimSigner") != null)
            {
                // Load the log level.
                int logLevel = 0;
                try
                {
                    string temp = RegistryHelper.Read("LogLevel", @"Software\Exchange DkimSigner");

                    if (temp != null)
                    {
                        logLevel = Convert.ToInt32(RegistryHelper.Read("LogLevel", @"Software\Exchange DkimSigner"));
                    }
                }
                catch (FormatException) {}
                catch (OverflowException) {}

                if (logLevel == 1)
                {
                    this.cbLogLevel.Text = "Error";
                }
                else if (logLevel == 2)
                {
                    this.cbLogLevel.Text = "Warning";
                }
                else if (logLevel == 3)
                {
                    this.cbLogLevel.Text = "Information";
                }
                else
                {
                    this.cbLogLevel.Text = "Information";
                    MessageBox.Show(Resources.MainWindows_BadLogLevel);
                }

                // Load the signing algorithm.
                try
                {
                    DkimAlgorithmKind signingAlgorithm = (DkimAlgorithmKind)Enum.Parse(typeof(DkimAlgorithmKind), RegistryHelper.Read("Algorithm", @"Software\Exchange DkimSigner\DKIM"), true);

                    if (signingAlgorithm == DkimAlgorithmKind.RsaSha1)
                    {
                        this.rbRsaSha1.Checked = true;
                    }
                    else
                    {
                        this.rbRsaSha256.Checked = true;
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show(Resources.MainWindows_BadDkimAlgorithmConfig);
                }

                // Load the header canonicalization algorithm.
                try
                {
                    DkimCanonicalizationKind headerCanonicalization = (DkimCanonicalizationKind)Enum.Parse(typeof(DkimCanonicalizationKind), RegistryHelper.Read("HeaderCanonicalization", @"Software\Exchange DkimSigner\DKIM"), true);

                    if (headerCanonicalization == DkimCanonicalizationKind.Simple)
                    {
                        this.rbSimpleHeaderCanonicalization.Checked = true;
                    }
                    else
                    {
                        this.rbRelaxedHeaderCanonicalization.Checked = true;
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show(Resources.MainWindows_BadDkimCanonicalizationHeaderConfig);
                }

                // Load the body canonicalization algorithm.
                try
                {
                    DkimCanonicalizationKind bodyCanonicalization = (DkimCanonicalizationKind)Enum.Parse(typeof(DkimCanonicalizationKind), RegistryHelper.Read("BodyCanonicalization", @"Software\Exchange DkimSigner\DKIM"), true);

                    if (bodyCanonicalization == DkimCanonicalizationKind.Simple)
                    {
                        this.rbSimpleBodyCanonicalization.Checked = true;
                    }
                    else
                    {
                        this.rbRelaxedBodyCanonicalization.Checked = true;
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show(Resources.MainWindows_BadDkimCanonicalizationBodyConfig);
                }

                // Load the list of headers to sign in each message.
                string unparsedHeaders = RegistryHelper.Read("HeadersToSign", @"Software\Exchange DkimSigner\DKIM");
                if (unparsedHeaders != null)
                {
                    this.txtHeaderToSign.Text = unparsedHeaders;
                }

                // Load the list of domains
                string[] domainNames = RegistryHelper.GetSubKeyName(@"Software\Exchange DkimSigner\Domain");
                if (domainNames != null)
                {
                    int i = 0;
                    foreach (string domainName in domainNames)
                    {
                        string selector       = RegistryHelper.Read("Selector", @"Software\Exchange DkimSigner\Domain\" + domainName);
                        string privateKeyFile = RegistryHelper.Read("PrivateKeyFile", @"Software\Exchange DkimSigner\Domain\" + domainName);

                        this.dgvDomainConfiguration.Rows.Add(domainName,
                                                             selector,
                                                             privateKeyFile);

                        attachments[i++] = File.ReadAllBytes(DKIM_SIGNER_PATH + @"\keys\" + privateKeyFile);
                    }

                    this.dgvDomainConfiguration.Rows[0].Selected = true;
                }
            }
        }
        /// <summary>
        /// Initializes various settings based on configuration.
        /// </summary>
        private void Initialize()
        {
            // Load the signing algorithm.
            try
            {
                this.algorithm = (DkimAlgorithmKind)Enum.Parse(
                    typeof(DkimAlgorithmKind),
                    Properties.Settings.Default.Algorithm,
                    true);
            }
            catch (Exception ex)
            {
                throw new ConfigurationErrorsException(
                          Resources.DkimSigningRoutingAgentFactory_BadAlgorithmConfig,
                          ex);
            }

            // Load the list of headers to sign in each message.
            var unparsedHeaders = Properties.Settings.Default.HeadersToSign;

            if (unparsedHeaders != null)
            {
                this.headersToSign = unparsedHeaders
                                     .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            }

            try
            {
                XmlDocument xmlDoc = new XmlDocument();                    //* create an xml document object.
                xmlDoc.Load(this.GetType().Assembly.Location + ".config"); //* load the XML document from the specified file.
                XmlNodeList domainInfoList = xmlDoc.GetElementsByTagName("domainInfo");
                if (domainInfoList == null || domainInfoList.Count != 1)
                {
                    Logger.LogError("There is an error in your configuration file. domainInfo couldn't be initialized properly.");
                    return;
                }
                XmlNode domainInfo = domainInfoList.Item(0);

                domainSettings = new List <DomainElement>();

                foreach (XmlNode n in domainInfo.ChildNodes)
                {
                    DomainElement e = new DomainElement();
                    e.Domain         = n.Attributes["Domain"].Value;
                    e.Selector       = n.Attributes["Selector"].Value;
                    e.PrivateKeyFile = n.Attributes["PrivateKeyFile"].Value;
                    if (e.initElement(Path.GetDirectoryName(this.GetType().Assembly.Location)))
                    {
                        domainSettings.Add(e);
                    }
                }
                if (domainSettings.Count == 0)
                {
                    Logger.LogWarning("No domain configuration found. DKIM will do nothing.");
                }
            }
            catch (Exception e)
            {
                Logger.LogError("Couldn't load config: " + e.ToString());
            }
            Logger.LogInformation("Exchange DKIM started. Algorithm: " + algorithm.ToString() + " Number of domains: " + domainSettings.Count);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultDkimSigner"/> class.
        /// </summary>
        /// <param name="signatureKind">The signature kind to use.</param>
        /// <param name="headersToSign">The headers to be signed. If null, only the From header will be signed.</param>
        /// <param name="selector">The domain containing the public key TXT record.</param>
        /// <param name="domain">The DNS selector.</param>
        /// <param name="encodedKey">The PEM-encoded key.</param>
        public DefaultDkimSigner(
            DkimAlgorithmKind signatureKind,
            IEnumerable <string> headersToSign,
            string selector,
            string domain,
            string encodedKey)
        {
            if (encodedKey == null ||
                encodedKey.Trim().Length == 0)
            {
                throw new ArgumentNullException("encodedKey");
            }

            if (selector == null ||
                selector.Trim().Length == 0)
            {
                throw new ArgumentNullException("selector");
            }

            if (domain == null ||
                domain.Trim().Length == 0)
            {
                throw new ArgumentNullException("domain");
            }

            this.cryptoProvider = CryptHelper.GetProviderFromPemEncodedRsaPrivateKey(encodedKey);
            this.domain         = domain;
            this.selector       = selector;

            switch (signatureKind)
            {
            case DkimAlgorithmKind.RsaSha1:
                this.hashAlgorithm           = new SHA1CryptoServiceProvider();
                this.hashAlgorithmCryptoCode = "SHA1";
                this.hashAlgorithmDkimCode   = "rsa-sha1";
                break;

            case DkimAlgorithmKind.RsaSha256:
                this.hashAlgorithm           = new SHA256CryptoServiceProvider();
                this.hashAlgorithmCryptoCode = "SHA256";
                this.hashAlgorithmDkimCode   = "rsa-sha256";
                break;

            default:
                throw new ArgumentOutOfRangeException("signatureKind");
            }

            this.eligibleHeaders = new HashSet <string>();

            if (headersToSign != null)
            {
                foreach (var headerToSign in headersToSign)
                {
                    this.eligibleHeaders.Add(headerToSign.Trim());
                }
            }

            // The From header must always be signed according to the
            // DKIM specification.
            this.eligibleHeaders.Add("From");
        }
Esempio n. 9
0
        /// <summary>
        /// Initializes various settings based on configuration.
        /// </summary>
        private void Initialize()
        {
            if (RegistryHelper.Open(@"Exchange DkimSigner") != null)
            {
                DkimAlgorithmKind        signingAlgorithm       = DkimAlgorithmKind.RsaSha1;
                DkimCanonicalizationKind headerCanonicalization = DkimCanonicalizationKind.Simple;
                DkimCanonicalizationKind bodyCanonicalization   = DkimCanonicalizationKind.Simple;
                IEnumerable <string>     headersToSign          = null;

                // Load the log level.
                DkimSigningRoutingAgentFactory.logLevel = 0;
                try
                {
                    string temp = RegistryHelper.Read("LogLevel", @"Exchange DkimSigner");

                    if (temp != null)
                    {
                        DkimSigningRoutingAgentFactory.logLevel = Convert.ToInt32(temp);
                    }
                }
                catch (FormatException) { }
                catch (OverflowException) { }

                if (logLevel == 0)
                {
                    throw new ConfigurationErrorsException(Resources.DkimSigningRoutingAgentFactory_BadLogLevel);
                }

                // Load the signing algorithm.
                try
                {
                    signingAlgorithm = (DkimAlgorithmKind)Enum.Parse(typeof(DkimAlgorithmKind), RegistryHelper.Read("Algorithm", @"Exchange DkimSigner\DKIM"), true);
                }
                catch (Exception ex)
                {
                    throw new ConfigurationErrorsException(Resources.DkimSigningRoutingAgentFactory_BadDkimAlgorithmConfig, ex);
                }

                // Load the header canonicalization algorithm.
                try
                {
                    headerCanonicalization = (DkimCanonicalizationKind)Enum.Parse(typeof(DkimCanonicalizationKind), RegistryHelper.Read("HeaderCanonicalization", @"Exchange DkimSigner\DKIM"), true);
                }
                catch (Exception ex)
                {
                    throw new ConfigurationErrorsException(Resources.DkimSigningRoutingAgentFactory_BadDkimCanonicalizationHeaderConfig, ex);
                }

                // Load the body canonicalization algorithm.
                try
                {
                    bodyCanonicalization = (DkimCanonicalizationKind)Enum.Parse(typeof(DkimCanonicalizationKind), RegistryHelper.Read("BodyCanonicalization", @"Exchange DkimSigner\DKIM"), true);
                }
                catch (Exception ex)
                {
                    throw new ConfigurationErrorsException(Resources.DkimSigningRoutingAgentFactory_BadDkimCanonicalizationBodyConfig, ex);
                }

                // Load the list of headers to sign in each message.
                string unparsedHeaders = RegistryHelper.Read("HeadersToSign", @"Exchange DkimSigner\DKIM");
                if (unparsedHeaders != null)
                {
                    headersToSign = unparsedHeaders.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                }

                // Load the list of domains
                domainSettings = new List <DomainElement>();
                string[] domainNames = RegistryHelper.GetSubKeyName(@"Exchange DkimSigner\Domain");
                if (domainNames != null)
                {
                    foreach (string domainName in domainNames)
                    {
                        string selector       = RegistryHelper.Read("Selector", @"Exchange DkimSigner\Domain\" + domainName);
                        string privateKeyFile = RegistryHelper.Read("PrivateKeyFile", @"Exchange DkimSigner\Domain\" + domainName);

                        DomainElement domainElement = new DomainElement(domainName,
                                                                        selector,
                                                                        privateKeyFile);

                        if (domainElement.initElement(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)))
                        {
                            domainSettings.Add(domainElement);
                        }
                    }
                }

                this.dkimSigner = new DkimSigner(signingAlgorithm,
                                                 headerCanonicalization,
                                                 bodyCanonicalization,
                                                 headersToSign);

                Logger.LogInformation("Exchange DKIM started. Signing Algorithm: " + signingAlgorithm.ToString() + ", Canonicalization Header Algorithm: " + headerCanonicalization.ToString() + ", Canonicalization Header Algorithm: " + bodyCanonicalization.ToString() + ", Number of domains: " + domainSettings.Count);
            }
            else
            {
                throw new ConfigurationErrorsException(Resources.DkimSigningRoutingAgentFactory_BadDkimConfig);
            }
        }