/// <summary> /// Initializes a new instance of the <see cref="DkimSigningRoutingAgentFactory"/> class. /// </summary> public DkimSigningRoutingAgentFactory() { Logger.LogDebug("Initializing DkimSigner Service"); /*Logger.LogDebug("Waiting for debugger"); while (!System.Diagnostics.Debugger.IsAttached) System.Threading.Thread.Sleep(100); Logger.LogDebug("Debugger connected");*/ Settings config = new Settings(); config.InitHeadersToSign(); dkimSigner = new DkimSigner(); LoadSettings(); WatchSettings(); }
/// <summary> /// Load the settings from the settings.xml file and apply the new settings to the dkimSigner instance. /// </summary> private void LoadSettings() { Settings config = new Settings(); config.InitHeadersToSign(); string assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (assemblyDir != null && config.Load(Path.Combine(assemblyDir, "settings.xml"))) { dkimSigner.UpdateSettings(config); Logger.LogLevel = config.Loglevel; Logger.LogInformation("Exchange DKIM settings loaded: " + config.SigningAlgorithm + ", Canonicalization Header Algorithm: " + config.HeaderCanonicalization + ", Canonicalization Body Algorithm: " + config.BodyCanonicalization + ", Number of domains: " + dkimSigner.GetDomains().Count); } else { Logger.LogError("Couldn't load the settings file.\n"); } }
public void UpdateSettings(Settings config) { lock (settingsMutex) { // Load the list of domains domains.Clear(); DkimSignatureAlgorithm signatureAlgorithm; switch (config.SigningAlgorithm) { case DkimAlgorithmKind.RsaSha1: signatureAlgorithm = DkimSignatureAlgorithm.RsaSha1; break; case DkimAlgorithmKind.RsaSha256: signatureAlgorithm = DkimSignatureAlgorithm.RsaSha256; break; default: // ReSharper disable once NotResolvedInText throw new ArgumentOutOfRangeException("config.SigningAlgorithm"); } foreach (DomainElement domainElement in config.Domains) { string privateKey = domainElement.PrivateKeyPathAbsolute( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); if (String.IsNullOrEmpty(privateKey) || !File.Exists(privateKey)) { Logger.LogError("The private key for domain " + domainElement.Domain + " wasn't found: " + privateKey + ". Ignoring domain."); } //check if the private key can be parsed try { KeyHelper.ParseKeyPair(privateKey); } catch (Exception ex) { Logger.LogError("Couldn't load private key for domain " + domainElement.Domain + ": " + ex.Message); continue; } MimeKit.Cryptography.DkimSigner signer; try { AsymmetricKeyParameter key = KeyHelper.ParsePrivateKey(privateKey); signer = new MimeKit.Cryptography.DkimSigner(key, domainElement.Domain, domainElement.Selector) { SignatureAlgorithm = signatureAlgorithm }; } catch (Exception ex) { Logger.LogError("Could not initialize MimeKit DkimSigner for domain " + domainElement.Domain + ": " + ex.Message); continue; } domains.Add(domainElement.Domain, new DomainElementSigner(domainElement, signer)); } headerCanonicalization = config.HeaderCanonicalization == DkimCanonicalizationKind.Relaxed ? DkimCanonicalizationAlgorithm.Relaxed : DkimCanonicalizationAlgorithm.Simple; bodyCanonicalization = config.BodyCanonicalization == DkimCanonicalizationKind.Relaxed ? DkimCanonicalizationAlgorithm.Relaxed : DkimCanonicalizationAlgorithm.Simple; List<HeaderId> headerList = new List<HeaderId>(); foreach (string headerToSign in config.HeadersToSign) { HeaderId headerId; #if EX_2007_SP3 || EX_2010 || EX_2010_SP1 || EX_2010_SP2 || EX_2010_SP3 if (!TryParseHeader(headerToSign, out headerId)) #else if (!Enum.TryParse(headerToSign, true, out headerId)) #endif { Logger.LogWarning("Invalid value for header to sign: '" + headerToSign + "'. This header will be ignored."); } headerList.Add(headerId); } // The From header must always be signed according to the // DKIM specification. if (!headerList.Contains(HeaderId.From)) { headerList.Add(HeaderId.From); } eligibleHeaders = headerList.ToArray(); } }
/// <summary> /// Load the current configuration for Exchange DkimSigner from the registry /// </summary> private void LoadDkimSignerConfig() { oConfig = new Settings(); oConfig.InitHeadersToSign(); if (!oConfig.Load(Path.Combine(Constants.DkimSignerPath, "settings.xml"))) { ShowMessageBox("Settings error", "Couldn't load the settings file.\n Setting it to default values.", MessageBoxButtons.OK, MessageBoxIcon.Information); } // // Log level // switch (oConfig.Loglevel) { case 1: cbLogLevel.Text = "Error"; break; case 2: cbLogLevel.Text = "Warning"; break; case 3: cbLogLevel.Text = "Information"; break; case 4: cbLogLevel.Text = "Debug"; break; default: cbLogLevel.Text = "Information"; ShowMessageBox("Information", "The log level is invalid. Set to default: Information.", MessageBoxButtons.OK, MessageBoxIcon.Information); break; } // // Algorithm and Canonicalization // rbRsaSha1.Checked = (oConfig.SigningAlgorithm == DkimAlgorithmKind.RsaSha1); rbRsaSha256.Checked = (oConfig.SigningAlgorithm == DkimAlgorithmKind.RsaSha256); rbSimpleHeaderCanonicalization.Checked = (oConfig.HeaderCanonicalization == DkimCanonicalizationKind.Simple); rbRelaxedHeaderCanonicalization.Checked = (oConfig.HeaderCanonicalization == DkimCanonicalizationKind.Relaxed); rbSimpleBodyCanonicalization.Checked = (oConfig.BodyCanonicalization == DkimCanonicalizationKind.Simple); rbRelaxedBodyCanonicalization.Checked = (oConfig.BodyCanonicalization == DkimCanonicalizationKind.Relaxed); // // Headers to sign // lbxHeadersToSign.Items.Clear(); foreach (string sItem in oConfig.HeadersToSign) { lbxHeadersToSign.Items.Add(sItem); } // // Domain // DomainElement oCurrentDomain = null; if (lbxDomains.SelectedItem != null) { oCurrentDomain = (DomainElement)lbxDomains.SelectedItem; } lbxDomains.Items.Clear(); foreach (DomainElement oConfigDomain in oConfig.Domains) { lbxDomains.Items.Add(oConfigDomain); } if (oCurrentDomain != null) { lbxDomains.SelectedItem = oCurrentDomain; } bDataUpdated = false; }
public void TestInitHeadersToSign() { Settings config = new Settings(); config.InitHeadersToSign(); Assert.AreEqual(new[] { "From", "Subject", "To", "Date", "Message-ID" }, config.HeadersToSign); }