/// <summary> /// Installs the service. /// </summary> /// <param name="silent">if set to <c>true</c> no dialogs such be displayed.</param> /// <param name="args">Additional arguments provided on the command line.</param> protected virtual void Install(bool silent, Dictionary<string, string> args) { Utils.Trace(Utils.TraceMasks.Information, "Installing application."); // check the configuration. string filePath = Utils.GetAbsoluteFilePath(InstallConfig.ConfigurationFile, true, false, false); if (filePath == null) { Utils.Trace("WARNING: Could not load config file specified in the installation configuration: {0}", InstallConfig.ConfigurationFile); filePath = ApplicationConfiguration.GetFilePathFromAppConfig(ConfigSectionName); InstallConfig.ConfigurationFile = filePath; } ApplicationConfiguration configuration = LoadAppConfig(silent, filePath, Opc.Ua.Security.SecuredApplication.FromApplicationType(InstallConfig.ApplicationType), ConfigurationType, false); if (configuration == null) { return; } // update the configuration. UpdateAppConfigWithInstallConfig(configuration); ApplicationConfiguration = configuration; // update configuration with information form the install config. // check the certificate. X509Certificate2 certificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true); if (certificate != null) { if (!silent) { if (!CheckApplicationInstanceCertificate(configuration, certificate, silent, InstallConfig.MinimumKeySize)) { certificate = null; } } } // create a new certificate. if (certificate == null) { certificate = CreateApplicationInstanceCertificate(configuration, InstallConfig.MinimumKeySize, InstallConfig.LifeTimeInMonths); } // ensure the certificate is trusted. AddToTrustedStore(configuration, certificate); // add to discovery server. if (configuration.ApplicationType == ApplicationType.Server || configuration.ApplicationType == ApplicationType.ClientAndServer) { try { AddToDiscoveryServerTrustList(certificate, null, null, configuration.SecurityConfiguration.TrustedPeerCertificates); } catch (Exception e) { Utils.Trace(e, "Could not add certificate to LDS trust list."); } } // configure the firewall. if (InstallConfig.ConfigureFirewall) { ConfigureFirewall(configuration, silent, false); } // configure HTTP access. ConfigureHttpAccess(configuration, false); // configure access to the executable, the configuration file and the private key. ConfigureFileAccess(configuration); // update configuration file. ConfigUtils.UpdateConfigurationLocation(InstallConfig.ExecutableFile, InstallConfig.ConfigurationFile); try { // ensure the RawData does not get serialized. certificate = configuration.SecurityConfiguration.ApplicationCertificate.Certificate; configuration.SecurityConfiguration.ApplicationCertificate.Certificate = null; configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = certificate.Subject; configuration.SecurityConfiguration.ApplicationCertificate.Thumbprint = certificate.Thumbprint; configuration.SaveToFile(configuration.SourceFilePath); // restore the configuration. configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate; } catch (Exception e) { Utils.Trace(e, "Could not save configuration file. FilePath={0}", configuration.SourceFilePath); } if (!NoGdsAgentAdmin) { try { // install the GDS agent configuration file string agentPath = Utils.GetAbsoluteDirectoryPath("%CommonApplicationData%\\OPC Foundation\\GDS\\Applications", false, false, true); if (agentPath != null) { Opc.Ua.Security.SecuredApplication export = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configuration.SourceFilePath); export.ExecutableFile = InstallConfig.ExecutableFile; DataContractSerializer serializer = new DataContractSerializer(typeof(Opc.Ua.Security.SecuredApplication)); using (FileStream ostrm = File.Open(agentPath + "\\" + configuration.ApplicationName + ".xml", FileMode.Create)) { serializer.WriteObject(ostrm, export); Utils.Trace(Utils.TraceMasks.Information, "Created GDS agent configuration file."); } } } catch (Exception e) { Utils.Trace(Utils.TraceMasks.Error, "Could not create GDS agent configuration file: {0}", e.Message); } } // install the service. if (InstallConfig.InstallAsService) { Utils.Trace(Utils.TraceMasks.Information, "Installing service '{0}'.", InstallConfig.ApplicationName); OnBeforeInstallService(); bool start = true; bool result = Opc.Ua.Configuration.ServiceInstaller.InstallService( Application.ExecutablePath, InstallConfig.ApplicationName, configuration.ApplicationName, InstallConfig.ServiceDescription, InstallConfig.ServiceStartMode, InstallConfig.ServiceUserName, InstallConfig.ServicePassword, ref start); if (!result) { throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "Could not install service."); } Utils.Trace(Utils.TraceMasks.Information, "Service '{0}' installed as {1}.", InstallConfig.ApplicationName, InstallConfig.ServiceStartMode); } }
/// <summary> /// Uninstalls a UA application. /// </summary> public static async Task UninstallApplication(InstalledApplication application) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); if (configurationFile != null) { // load the current configuration. Opc.Ua.Security.SecuredApplication security = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // delete the application certificates. if (application.DeleteCertificatesOnUninstall) { CertificateIdentifier id = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(security.ApplicationCertificate); // delete public key from trusted peers certificate store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(security.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2Collection peerCertificates = await store.FindByThumbprint(id.Thumbprint); if (peerCertificates.Count > 0) { await store.Delete(peerCertificates[0].Thumbprint); } } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // delete private key from application certificate store. try { using (ICertificateStore store = id.OpenStore()) { await store.Delete(id.Thumbprint); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // permentently delete any UA defined stores if they are now empty. try { WindowsCertificateStore store = new WindowsCertificateStore(); await store.Open("LocalMachine\\UA Applications"); X509Certificate2Collection collection = await store.Enumerate(); if (collection.Count == 0) { store.PermanentlyDeleteStore(); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } } // remove the permissions for the HTTP endpoints used by the application. if (application.BaseAddresses != null && application.BaseAddresses.Count > 0) { List <ApplicationAccessRule> noRules = new List <ApplicationAccessRule>(); for (int ii = 0; ii < application.BaseAddresses.Count; ii++) { Uri url = Utils.ParseUri(application.BaseAddresses[ii]); if (url != null) { try { HttpAccessRule.SetAccessRules(url, noRules, true); Utils.Trace("Removed HTTP access rules for URL: {0}", url); } catch (Exception e) { Utils.Trace("Could not remove HTTP access rules for URL: {0}. Error={1}", url, e.Message); } } } } } }
/// <summary> /// Adds the application certificate to the discovery server trust list. /// </summary> public static void AddToDiscoveryServerTrustList( X509Certificate2 certificate, string oldThumbprint, IList<X509Certificate2> issuers, CertificateStoreIdentifier trustedCertificateStore) { Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to discovery server trust list."); try { string configurationPath = Utils.GetAbsoluteFilePath(@"%CommonApplicationData%\OPC Foundation\Config\Opc.Ua.DiscoveryServer.Config.xml", true, false, false); if (configurationPath == null) { throw new ServiceResultException("Could not find the discovery server configuration file. Please confirm that it is installed."); } Opc.Ua.Security.SecuredApplication ldsConfiguration = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationPath); CertificateStoreIdentifier csid = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(ldsConfiguration.TrustedCertificateStore); AddApplicationCertificateToStore(csid, certificate, oldThumbprint); if (issuers != null && ldsConfiguration.IssuerCertificateStore != null) { csid = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(ldsConfiguration.IssuerCertificateStore); AddIssuerCertificatesToStore(csid, issuers); } CertificateIdentifier cid = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(ldsConfiguration.ApplicationCertificate); X509Certificate2 ldsCertificate = cid.Find(false); // add LDS certificate to application trust list. if (ldsCertificate != null && trustedCertificateStore != null) { AddApplicationCertificateToStore(csid, ldsCertificate, null); } } catch (Exception e) { Utils.Trace(e, "Could not add certificate to discovery server trust list."); } }
/// <summary> /// Installs the service. /// </summary> /// <param name="silent">if set to <c>true</c> no dialogs such be displayed.</param> /// <param name="args">Additional arguments provided on the command line.</param> protected virtual async Task Install(bool silent, Dictionary<string, string> args) { Utils.Trace(Utils.TraceMasks.Information, "Installing application."); // check the configuration. string filePath = Utils.GetAbsoluteFilePath(InstallConfig.ConfigurationFile, true, false, false); if (filePath == null) { Utils.Trace("WARNING: Could not load config file specified in the installation configuration: {0}", InstallConfig.ConfigurationFile); filePath = ApplicationConfiguration.GetFilePathFromAppConfig(ConfigSectionName); InstallConfig.ConfigurationFile = filePath; } ApplicationConfiguration configuration = await LoadAppConfig(silent, filePath, Opc.Ua.Security.SecuredApplication.FromApplicationType(InstallConfig.ApplicationType), ConfigurationType, false); if (configuration == null) { return; } // update the configuration. await UpdateAppConfigWithInstallConfig(configuration); ApplicationConfiguration = configuration; // update configuration with information form the install config. // check the certificate. X509Certificate2 certificate = await configuration.SecurityConfiguration.ApplicationCertificate.Find(true); if (certificate != null) { if (!silent) { bool result = await CheckApplicationInstanceCertificate(configuration, certificate, silent, InstallConfig.MinimumKeySize); if (!result) { certificate = null; } } } if (certificate == null) { // create a new certificate. certificate = await CreateApplicationInstanceCertificate(configuration, InstallConfig.MinimumKeySize, InstallConfig.LifeTimeInMonths); } else { // ensure the certificate is trusted. await AddToTrustedStore(configuration, certificate); } // add to discovery server. if (configuration.ApplicationType == ApplicationType.Server || configuration.ApplicationType == ApplicationType.ClientAndServer) { try { await AddToDiscoveryServerTrustList(certificate, null, null, configuration.SecurityConfiguration.TrustedPeerCertificates); } catch (Exception e) { Utils.Trace(e, "Could not add certificate to LDS trust list."); } } // configure access to the executable, the configuration file and the private key. await ConfigureFileAccess(configuration); // update configuration file. ConfigUtils.UpdateConfigurationLocation(InstallConfig.ExecutableFile, InstallConfig.ConfigurationFile); try { // ensure the RawData does not get serialized. certificate = configuration.SecurityConfiguration.ApplicationCertificate.Certificate; configuration.SecurityConfiguration.ApplicationCertificate.Certificate = null; configuration.SecurityConfiguration.ApplicationCertificate.SubjectName = certificate.Subject; configuration.SecurityConfiguration.ApplicationCertificate.Thumbprint = certificate.Thumbprint; configuration.SaveToFile(configuration.SourceFilePath); // restore the configuration. configuration.SecurityConfiguration.ApplicationCertificate.Certificate = certificate; } catch (Exception e) { Utils.Trace(e, "Could not save configuration file. FilePath={0}", configuration.SourceFilePath); } if (!NoGdsAgentAdmin) { try { // install the GDS agent configuration file string agentPath = Utils.GetAbsoluteDirectoryPath( Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "OPC Foundation" + Path.DirectorySeparatorChar + "GDS" + Path.DirectorySeparatorChar + "Applications", false, false, true); if (agentPath != null) { Opc.Ua.Security.SecuredApplication export = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configuration.SourceFilePath); export.ExecutableFile = InstallConfig.ExecutableFile; DataContractSerializer serializer = new DataContractSerializer(typeof(Opc.Ua.Security.SecuredApplication)); using (FileStream ostrm = File.Open(agentPath + Path.DirectorySeparatorChar + configuration.ApplicationName + ".xml", FileMode.Create)) { serializer.WriteObject(ostrm, export); Utils.Trace(Utils.TraceMasks.Information, "Created GDS agent configuration file."); } } } catch (Exception e) { Utils.Trace(Utils.TraceMasks.Error, "Could not create GDS agent configuration file: {0}", e.Message); } } }
/// <summary> /// Installs a UA application. /// </summary> public static async Task InstallApplication( InstalledApplication application, bool autostart, bool configureFirewall) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length - 4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); // create a new file if one does not exist. bool useExisting = true; if (configurationFile == null) { configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, true, true); useExisting = false; } // create the default configuration file. if (useExisting) { try { Opc.Ua.Security.SecuredApplication existingSettings = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // copy current settings application.ApplicationType = existingSettings.ApplicationType; application.BaseAddresses = existingSettings.BaseAddresses; application.ApplicationCertificate = existingSettings.ApplicationCertificate; application.ApplicationName = existingSettings.ApplicationName; application.ProductName = existingSettings.ProductName; application.RejectedCertificatesStore = existingSettings.RejectedCertificatesStore; application.TrustedCertificateStore = existingSettings.TrustedCertificateStore; application.TrustedCertificates = existingSettings.TrustedCertificates; application.IssuerCertificateStore = existingSettings.IssuerCertificateStore; application.IssuerCertificates = application.IssuerCertificates; application.UseDefaultCertificateStores = false; } catch (Exception e) { useExisting = false; Utils.Trace("WARNING. Existing configuration file could not be loaded: {0}.\r\nReplacing with default: {1}", e.Message, configurationFile); File.Copy(configurationFile, configurationFile + ".bak", true); } } // create the configuration file from the default. if (!useExisting) { try { string installationFile = Utils.Format( "{0}\\Install\\{1}.Config.xml", executableFileInfo.Directory.Parent.FullName, applicationName); if (!File.Exists(installationFile)) { Utils.Trace("Could not find default configuation at: {0}", installationFile); } File.Copy(installationFile, configurationFile, true); Utils.Trace("File.Copy({0}, {1})", installationFile, configurationFile); } catch (Exception e) { Utils.Trace("Could not copy default configuation to: {0}. Error={1}.", configurationFile, e.Message); } } // create a default application name. if (String.IsNullOrEmpty(application.ApplicationName)) { application.ApplicationName = applicationName; } // create a default product name. if (String.IsNullOrEmpty(application.ProductName)) { application.ProductName = application.ApplicationName; } // create a default uri. if (String.IsNullOrEmpty(application.ApplicationUri)) { application.ApplicationUri = Utils.Format("http://localhost/{0}/{1}", applicationName, Guid.NewGuid()); } // make the uri specify the local machine. application.ApplicationUri = Utils.ReplaceLocalhost(application.ApplicationUri); // set a default application store. if (application.ApplicationCertificate == null) { application.ApplicationCertificate = new Opc.Ua.Security.CertificateIdentifier(); application.ApplicationCertificate.StoreType = Utils.DefaultStoreType; application.ApplicationCertificate.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } if (application.UseDefaultCertificateStores) { if (application.IssuerCertificateStore == null) { application.IssuerCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.IssuerCertificateStore.StoreType = Utils.DefaultStoreType; application.IssuerCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } if (application.TrustedCertificateStore == null) { application.TrustedCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.TrustedCertificateStore.StoreType = Utils.DefaultStoreType; application.TrustedCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } try { Utils.GetAbsoluteDirectoryPath(application.TrustedCertificateStore.StorePath, true, true, true); } catch (Exception e) { Utils.Trace("Could not access the machine directory: {0} '{1}'", application.RejectedCertificatesStore.StorePath, e); } if (application.RejectedCertificatesStore == null) { application.RejectedCertificatesStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.RejectedCertificatesStore.StoreType = CertificateStoreType.Directory; application.RejectedCertificatesStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\RejectedCertificates"; StringBuilder buffer = new StringBuilder(); buffer.Append(ApplicationData.Current.LocalFolder.Path); buffer.Append("\\OPC Foundation"); buffer.Append("\\RejectedCertificates"); string folderPath = buffer.ToString(); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } } // check for valid certificate (discard invalid certificates). CertificateIdentifier applicationCertificate = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(application.ApplicationCertificate); X509Certificate2 certificate = await applicationCertificate.Find(true); if (certificate == null) { certificate = await applicationCertificate.Find(false); if (certificate != null) { Utils.Trace( "Found existing certificate but it does not have a private key: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } else { Utils.Trace( "Existing certificate could not be found: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } } // check if no certificate exists. if (certificate == null) { certificate = await CreateCertificateForApplication(application); } // ensure the application certificate is in the trusted peers store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2Collection peerCertificates = await store.FindByThumbprint(certificate.Thumbprint); if (peerCertificates.Count == 0) { await store.Add(new X509Certificate2(certificate.RawData)); } } } catch (Exception e) { Utils.Trace( "Could not add certificate '{0}' to trusted peer store '{1}'. Error={2}", certificate.Subject, application.TrustedCertificateStore, e.Message); } // update configuration file location. UpdateConfigurationLocation(executableFile, configurationFile); // update configuration file. new Opc.Ua.Security.SecurityConfigurationManager().WriteConfiguration(configurationFile, application); ApplicationAccessRuleCollection accessRules = application.AccessRules; bool noRulesDefined = application.AccessRules == null || application.AccessRules.Count == 0; // add the default access rules. if (noRulesDefined) { ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Administrators; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Configure; accessRules.Add(rule); rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Users; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Update; accessRules.Add(rule); } // ensure the service account has priviledges. if (application.InstallAsService) { // check if a specific account is assigned. AccountInfo accountInfo = null; if (!String.IsNullOrEmpty(application.ServiceUserName)) { accountInfo = AccountInfo.Create(application.ServiceUserName); } // choose a built-in service account. if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.NetworkService); if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.LocalSystem); } } ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = accountInfo.ToString(); rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Run; accessRules.Add(rule); } // set the permissions for the HTTP endpoints used by the application. if (configureFirewall && application.BaseAddresses != null && application.BaseAddresses.Count > 0) { for (int ii = 0; ii < application.BaseAddresses.Count; ii++) { Uri url = Utils.ParseUri(application.BaseAddresses[ii]); if (url != null) { try { HttpAccessRule.SetAccessRules(url, accessRules, true); Utils.Trace("Added HTTP access rules for URL: {0}", url); } catch (Exception e) { Utils.Trace("Could not set HTTP access rules for URL: {0}. Error={1}", url, e.Message); for (int jj = 0; jj < accessRules.Count; jj++) { ApplicationAccessRule rule = accessRules[jj]; Utils.Trace( (int)Utils.TraceMasks.Error, "IdentityName={0}, Right={1}, RuleType={2}", rule.IdentityName, rule.Right, rule.RuleType); } } } } } // set permissions on the local certificate store. SetCertificatePermissions( application, applicationCertificate, accessRules, false); // set permissions on the local certificate store. if (application.RejectedCertificatesStore != null) { // need to grant full control to certificates in the RejectedCertificatesStore. foreach (ApplicationAccessRule rule in accessRules) { if (rule.RuleType == AccessControlType.Allow) { rule.Right = ApplicationAccessRight.Configure; } } CertificateStoreIdentifier rejectedCertificates = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.RejectedCertificatesStore); using (ICertificateStore store = rejectedCertificates.OpenStore()) { if (store.SupportsAccessControl) { store.SetAccessRules(accessRules, false); } } } }
/// <summary> /// Adds the application certificate to the discovery server trust list. /// </summary> public static async Task AddToDiscoveryServerTrustList( X509Certificate2 certificate, string oldThumbprint, IList<X509Certificate2> issuers, CertificateStoreIdentifier trustedCertificateStore) { Utils.Trace(Utils.TraceMasks.Information, "Adding certificate to discovery server trust list."); try { string configurationPath = Utils.GetAbsoluteFilePath(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "OPC Foundation" + Path.DirectorySeparatorChar + "Config" + Path.DirectorySeparatorChar + "Opc.Ua.DiscoveryServer.Config.xml", true, false, false); if (configurationPath == null) { Utils.Trace("Could not find the discovery server configuration file. Please confirm that it is installed."); } else { Opc.Ua.Security.SecuredApplication ldsConfiguration = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationPath); CertificateStoreIdentifier csid = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(ldsConfiguration.TrustedCertificateStore); await AddApplicationCertificateToStore(csid, certificate, oldThumbprint); if (issuers != null && ldsConfiguration.IssuerCertificateStore != null) { csid = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(ldsConfiguration.IssuerCertificateStore); AddIssuerCertificatesToStore(csid, issuers); } CertificateIdentifier cid = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(ldsConfiguration.ApplicationCertificate); X509Certificate2 ldsCertificate = await cid.Find(false); // add LDS certificate to application trust list. if (ldsCertificate != null && trustedCertificateStore != null) { await AddApplicationCertificateToStore(csid, ldsCertificate, null); } } } catch (Exception e) { Utils.Trace(e, "Could not add certificate to discovery server trust list."); } }
/// <summary> /// Uninstalls a UA application. /// </summary> public static async Task UninstallApplication(InstalledApplication application) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length-4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); if (configurationFile != null) { // load the current configuration. Opc.Ua.Security.SecuredApplication security = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // delete the application certificates. if (application.DeleteCertificatesOnUninstall) { CertificateIdentifier id = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(security.ApplicationCertificate); // delete public key from trusted peers certificate store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(security.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2Collection peerCertificates = await store.FindByThumbprint(id.Thumbprint); if (peerCertificates.Count > 0) { await store.Delete(peerCertificates[0].Thumbprint); } } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // delete private key from application certificate store. try { using (ICertificateStore store = id.OpenStore()) { await store.Delete(id.Thumbprint); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // permentently delete any UA defined stores if they are now empty. try { WindowsCertificateStore store = new WindowsCertificateStore(); await store.Open("LocalMachine\\UA Applications"); X509Certificate2Collection collection = await store.Enumerate(); if (collection.Count == 0) { store.PermanentlyDeleteStore(); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } } } }
/// <summary> /// Installs a UA application. /// </summary> public static async Task InstallApplication( InstalledApplication application, bool autostart, bool configureFirewall) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length-4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); // create a new file if one does not exist. bool useExisting = true; if (configurationFile == null) { configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, true, true); useExisting = false; } // create the default configuration file. if (useExisting) { try { Opc.Ua.Security.SecuredApplication existingSettings = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // copy current settings application.ApplicationType = existingSettings.ApplicationType; application.BaseAddresses = existingSettings.BaseAddresses; application.ApplicationCertificate = existingSettings.ApplicationCertificate; application.ApplicationName = existingSettings.ApplicationName; application.ProductName = existingSettings.ProductName; application.RejectedCertificatesStore = existingSettings.RejectedCertificatesStore; application.TrustedCertificateStore = existingSettings.TrustedCertificateStore; application.TrustedCertificates = existingSettings.TrustedCertificates; application.IssuerCertificateStore = existingSettings.IssuerCertificateStore; application.IssuerCertificates = application.IssuerCertificates; application.UseDefaultCertificateStores = false; } catch (Exception e) { useExisting = false; Utils.Trace("WARNING. Existing configuration file could not be loaded: {0}.\r\nReplacing with default: {1}", e.Message, configurationFile); File.Copy(configurationFile, configurationFile + ".bak", true); } } // create the configuration file from the default. if (!useExisting) { try { string installationFile = Utils.Format( "{0}\\Install\\{1}.Config.xml", executableFileInfo.Directory.Parent.FullName, applicationName); if (!File.Exists(installationFile)) { Utils.Trace("Could not find default configuation at: {0}", installationFile); } File.Copy(installationFile, configurationFile, true); Utils.Trace("File.Copy({0}, {1})", installationFile, configurationFile); } catch (Exception e) { Utils.Trace("Could not copy default configuation to: {0}. Error={1}.", configurationFile, e.Message); } } // create a default application name. if (String.IsNullOrEmpty(application.ApplicationName)) { application.ApplicationName = applicationName; } // create a default product name. if (String.IsNullOrEmpty(application.ProductName)) { application.ProductName = application.ApplicationName; } // create a default uri. if (String.IsNullOrEmpty(application.ApplicationUri)) { application.ApplicationUri = Utils.Format("http://localhost/{0}/{1}", applicationName, Guid.NewGuid()); } // make the uri specify the local machine. application.ApplicationUri = Utils.ReplaceLocalhost(application.ApplicationUri); // set a default application store. if (application.ApplicationCertificate == null) { application.ApplicationCertificate = new Opc.Ua.Security.CertificateIdentifier(); application.ApplicationCertificate.StoreType = Utils.DefaultStoreType; application.ApplicationCertificate.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } if (application.UseDefaultCertificateStores) { if (application.IssuerCertificateStore == null) { application.IssuerCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.IssuerCertificateStore.StoreType = Utils.DefaultStoreType; application.IssuerCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } if (application.TrustedCertificateStore == null) { application.TrustedCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.TrustedCertificateStore.StoreType = Utils.DefaultStoreType; application.TrustedCertificateStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; } try { Utils.GetAbsoluteDirectoryPath(application.TrustedCertificateStore.StorePath, true, true, true); } catch (Exception e) { Utils.Trace("Could not access the machine directory: {0} '{1}'", application.RejectedCertificatesStore.StorePath, e); } if (application.RejectedCertificatesStore == null) { application.RejectedCertificatesStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.RejectedCertificatesStore.StoreType = CertificateStoreType.Directory; application.RejectedCertificatesStore.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\RejectedCertificates"; StringBuilder buffer = new StringBuilder(); buffer.Append(ApplicationData.Current.LocalFolder.Path); buffer.Append("\\OPC Foundation"); buffer.Append("\\RejectedCertificates"); string folderPath = buffer.ToString(); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } } // check for valid certificate (discard invalid certificates). CertificateIdentifier applicationCertificate = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(application.ApplicationCertificate); X509Certificate2 certificate = await applicationCertificate.Find(true); if (certificate == null) { certificate = await applicationCertificate.Find(false); if (certificate != null) { Utils.Trace( "Found existing certificate but it does not have a private key: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } else { Utils.Trace( "Existing certificate could not be found: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } } // check if no certificate exists. if (certificate == null) { certificate = await CreateCertificateForApplication(application); } // ensure the application certificate is in the trusted peers store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2Collection peerCertificates = await store.FindByThumbprint(certificate.Thumbprint); if (peerCertificates.Count == 0) { await store.Add(new X509Certificate2(certificate.RawData)); } } } catch (Exception e) { Utils.Trace( "Could not add certificate '{0}' to trusted peer store '{1}'. Error={2}", certificate.Subject, application.TrustedCertificateStore, e.Message); } // update configuration file location. UpdateConfigurationLocation(executableFile, configurationFile); // update configuration file. new Opc.Ua.Security.SecurityConfigurationManager().WriteConfiguration(configurationFile, application); ApplicationAccessRuleCollection accessRules = application.AccessRules; bool noRulesDefined = application.AccessRules == null || application.AccessRules.Count == 0; // add the default access rules. if (noRulesDefined) { ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Administrators; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Configure; accessRules.Add(rule); rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Users; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Update; accessRules.Add(rule); } // ensure the service account has priviledges. if (application.InstallAsService) { // check if a specific account is assigned. AccountInfo accountInfo = null; if (!String.IsNullOrEmpty(application.ServiceUserName)) { accountInfo = AccountInfo.Create(application.ServiceUserName); } // choose a built-in service account. if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.NetworkService); if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.LocalSystem); } } ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = accountInfo.ToString(); rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Run; accessRules.Add(rule); } // set permissions on the local certificate store. SetCertificatePermissions( application, applicationCertificate, accessRules, false); // set permissions on the local certificate store. if (application.RejectedCertificatesStore != null) { // need to grant full control to certificates in the RejectedCertificatesStore. foreach (ApplicationAccessRule rule in accessRules) { if (rule.RuleType == AccessControlType.Allow) { rule.Right = ApplicationAccessRight.Configure; } } CertificateStoreIdentifier rejectedCertificates = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.RejectedCertificatesStore); using (ICertificateStore store = rejectedCertificates.OpenStore()) { if (store.SupportsAccessControl) { store.SetAccessRules(accessRules, false); } } } }
/// <summary> /// Installs a UA application. /// </summary> public static void InstallApplication( InstalledApplication application, bool autostart, bool configureFirewall) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length-4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); // create a new file if one does not exist. bool useExisting = true; if (configurationFile == null) { configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, true, true); useExisting = false; } // create the default configuration file. if (useExisting) { try { Opc.Ua.Security.SecuredApplication existingSettings = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // copy current settings application.ApplicationType = existingSettings.ApplicationType; application.BaseAddresses = existingSettings.BaseAddresses; application.ApplicationCertificate = existingSettings.ApplicationCertificate; application.ApplicationName = existingSettings.ApplicationName; application.ProductName = existingSettings.ProductName; application.RejectedCertificatesStore = existingSettings.RejectedCertificatesStore; application.TrustedCertificateStore = existingSettings.TrustedCertificateStore; application.TrustedCertificates = existingSettings.TrustedCertificates; application.IssuerCertificateStore = existingSettings.IssuerCertificateStore; application.IssuerCertificates = application.IssuerCertificates; application.UseDefaultCertificateStores = false; } catch (Exception e) { useExisting = false; Utils.Trace("WARNING. Existing configuration file could not be loaded: {0}.\r\nReplacing with default: {1}", e.Message, configurationFile); File.Copy(configurationFile, configurationFile + ".bak", true); } } // create the configuration file from the default. if (!useExisting) { try { string installationFile = Utils.Format( "{0}\\Install\\{1}.Config.xml", executableFileInfo.Directory.Parent.FullName, applicationName); if (!File.Exists(installationFile)) { Utils.Trace("Could not find default configuation at: {0}", installationFile); } File.Copy(installationFile, configurationFile, true); Utils.Trace("File.Copy({0}, {1})", installationFile, configurationFile); } catch (Exception e) { Utils.Trace("Could not copy default configuation to: {0}. Error={1}.", configurationFile, e.Message); } } // create a default application name. if (String.IsNullOrEmpty(application.ApplicationName)) { application.ApplicationName = applicationName; } // create a default product name. if (String.IsNullOrEmpty(application.ProductName)) { application.ProductName = application.ApplicationName; } // create a default uri. if (String.IsNullOrEmpty(application.ApplicationUri)) { application.ApplicationUri = Utils.Format("http://localhost/{0}/{1}", applicationName, Guid.NewGuid()); } // make the uri specify the local machine. application.ApplicationUri = Utils.ReplaceLocalhost(application.ApplicationUri); // set a default application store. if (application.ApplicationCertificate == null) { application.ApplicationCertificate = new Opc.Ua.Security.CertificateIdentifier(); application.ApplicationCertificate.StoreType = Utils.DefaultStoreType; application.ApplicationCertificate.StorePath = Utils.DefaultStorePath; } if (application.UseDefaultCertificateStores) { if (application.IssuerCertificateStore == null) { application.IssuerCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.IssuerCertificateStore.StoreType = Utils.DefaultStoreType; application.IssuerCertificateStore.StorePath = Utils.DefaultStorePath; } if (application.TrustedCertificateStore == null) { application.TrustedCertificateStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.TrustedCertificateStore.StoreType = Utils.DefaultStoreType; application.TrustedCertificateStore.StorePath = Utils.DefaultStorePath; } try { Utils.GetAbsoluteDirectoryPath(application.TrustedCertificateStore.StorePath, true, true, true); } catch (Exception e) { Utils.Trace("Could not access the machine directory: {0} '{1}'", application.RejectedCertificatesStore.StorePath, e); } if (application.RejectedCertificatesStore == null) { application.RejectedCertificatesStore = new Opc.Ua.Security.CertificateStoreIdentifier(); application.RejectedCertificatesStore.StoreType = CertificateStoreType.Directory; application.RejectedCertificatesStore.StorePath = "%CommonApplicationData%\\OPC Foundation\\CertificateStores\\RejectedCertificates"; StringBuilder buffer = new StringBuilder(); buffer.Append(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); buffer.Append("\\OPC Foundation"); buffer.Append("\\RejectedCertificates"); string folderPath = buffer.ToString(); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } } // check for valid certificate (discard invalid certificates). CertificateIdentifier applicationCertificate = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(application.ApplicationCertificate); X509Certificate2 certificate = applicationCertificate.Find(true); if (certificate == null) { certificate = applicationCertificate.Find(false); if (certificate != null) { Utils.Trace( "Found existing certificate but it does not have a private key: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } else { Utils.Trace( "Existing certificate could not be found: Store={0}, Certificate={1}", application.ApplicationCertificate.StorePath, application.ApplicationCertificate); } } // check if no certificate exists. if (certificate == null) { certificate = CreateCertificateForApplication(application); } // ensure the application certificate is in the trusted peers store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2 peerCertificate = store.FindByThumbprint(certificate.Thumbprint); if (peerCertificate == null) { store.Add(new X509Certificate2(certificate.GetRawCertData())); } } } catch (Exception e) { Utils.Trace( "Could not add certificate '{0}' to trusted peer store '{1}'. Error={2}", certificate.Subject, application.TrustedCertificateStore, e.Message); } // locally register the certficate OIDs. if (application.LocallyRegisterOIDs) { try { LocallyRegisterCertificateOIDs(certificate); } catch (Exception e) { Utils.Trace( "Could not register OIDs used for certificate '{0}'. Error={1}", certificate.Subject, e.Message); } } // update configuration file location. UpdateConfigurationLocation(executableFile, configurationFile); // update configuration file. new Opc.Ua.Security.SecurityConfigurationManager().WriteConfiguration(configurationFile, application); // configure firewall. if (configureFirewall && application.ConfigureFirewall) { if (application.BaseAddresses != null && application.BaseAddresses.Count > 0) { try { SetFirewallAccess(application, executableFile); } catch (Exception e) { Utils.Trace("Could not set firewall access for executable: {0}. Error={1}", executableFile, e.Message); } } } ApplicationAccessRuleCollection accessRules = application.AccessRules; bool noRulesDefined = application.AccessRules == null || application.AccessRules.Count == 0; // add the default access rules. if (noRulesDefined) { ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Administrators; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Configure; accessRules.Add(rule); rule = new ApplicationAccessRule(); rule.IdentityName = WellKnownSids.Users; rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Update; accessRules.Add(rule); } // ensure the service account has priviledges. if (application.InstallAsService) { // check if a specific account is assigned. AccountInfo accountInfo = null; if (!String.IsNullOrEmpty(application.ServiceUserName)) { accountInfo = AccountInfo.Create(application.ServiceUserName); } // choose a built-in service account. if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.NetworkService); if (accountInfo == null) { accountInfo = AccountInfo.Create(WellKnownSids.LocalSystem); } } ApplicationAccessRule rule = new ApplicationAccessRule(); rule.IdentityName = accountInfo.ToString(); rule.RuleType = AccessControlType.Allow; rule.Right = ApplicationAccessRight.Run; accessRules.Add(rule); } // set the permissions for the HTTP endpoints used by the application. if (configureFirewall && application.BaseAddresses != null && application.BaseAddresses.Count > 0) { for (int ii = 0; ii < application.BaseAddresses.Count; ii++) { Uri url = Utils.ParseUri(application.BaseAddresses[ii]); if (url != null) { if (url.Scheme == Uri.UriSchemeHttp || url.Scheme == Uri.UriSchemeHttps) { try { HttpAccessRule.SetAccessRules(url, accessRules, true); Utils.Trace("Added HTTP access rules for URL: {0}", url); } catch (Exception e) { Utils.Trace("Could not set HTTP access rules for URL: {0}. Error={1}", url, e.Message); for (int jj = 0; jj < accessRules.Count; jj++) { ApplicationAccessRule rule = accessRules[jj]; Utils.Trace( (int)Utils.TraceMasks.Error, "IdentityName={0}, Right={1}, RuleType={2}", rule.IdentityName, rule.Right, rule.RuleType); } } } } } } // set permissions on the local certificate store. SetCertificatePermissions( application, applicationCertificate, accessRules, false); // set permissions on the local certificate store. if (application.RejectedCertificatesStore != null) { // need to grant full control to certificates in the RejectedCertificatesStore. foreach (ApplicationAccessRule rule in accessRules) { if (rule.RuleType == AccessControlType.Allow) { rule.Right = ApplicationAccessRight.Configure; } } CertificateStoreIdentifier rejectedCertificates = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(application.RejectedCertificatesStore); using (ICertificateStore store = rejectedCertificates.OpenStore()) { if (store.SupportsAccessControl) { store.SetAccessRules(accessRules, false); } } } // install as a service. if (application.InstallAsService) { ServiceInstaller.UnInstallService(application.ApplicationName); StartMode startMode = application.ServiceStartMode; if (!autostart) { startMode = StartMode.Manual; } bool start = true; bool result = ServiceInstaller.InstallService( executableFileInfo.FullName, application.ApplicationName, application.ApplicationName, application.ServiceDescription, startMode, application.ServiceUserName, application.ServicePassword, ref start); if (!result) { throw new ApplicationException("Could not install service."); } } }
/// <summary> /// Uninstalls a UA application. /// </summary> public static void UninstallApplication(InstalledApplication application) { // validate the executable file. string executableFile = Utils.GetAbsoluteFilePath(application.ExecutableFile, true, true, false); // get the default application name from the executable file. FileInfo executableFileInfo = new FileInfo(executableFile); string applicationName = executableFileInfo.Name.Substring(0, executableFileInfo.Name.Length-4); // choose a default configuration file. if (String.IsNullOrEmpty(application.ConfigurationFile)) { application.ConfigurationFile = Utils.Format( "{0}\\{1}.Config.xml", executableFileInfo.DirectoryName, applicationName); } // install as a service. if (application.InstallAsService) { ServiceInstaller.UnInstallService(application.ApplicationName); } // validate the configuration file. string configurationFile = Utils.GetAbsoluteFilePath(application.ConfigurationFile, true, false, false); if (configurationFile != null) { // load the current configuration. Opc.Ua.Security.SecuredApplication security = new Opc.Ua.Security.SecurityConfigurationManager().ReadConfiguration(configurationFile); // delete the application certificates. if (application.DeleteCertificatesOnUninstall) { CertificateIdentifier id = Opc.Ua.Security.SecuredApplication.FromCertificateIdentifier(security.ApplicationCertificate); // delete public key from trusted peers certificate store. try { CertificateStoreIdentifier certificateStore = Opc.Ua.Security.SecuredApplication.FromCertificateStoreIdentifier(security.TrustedCertificateStore); using (ICertificateStore store = certificateStore.OpenStore()) { X509Certificate2 peerCertificate = store.FindByThumbprint(id.Thumbprint); if (peerCertificate != null) { store.Delete(peerCertificate.Thumbprint); } } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // delete private key from application certificate store. try { using (ICertificateStore store = id.OpenStore()) { store.Delete(id.Thumbprint); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } // permentently delete any UA defined stores if they are now empty. try { WindowsCertificateStore store = new WindowsCertificateStore(); store.Open("LocalMachine\\UA Applications"); if (store.Enumerate().Count == 0) { store.PermanentlyDeleteStore(); } } catch (Exception e) { Utils.Trace("Could not delete certificate '{0}' from store. Error={1}", id, e.Message); } } // configure firewall. if (application.ConfigureFirewall) { if (security.BaseAddresses != null && security.BaseAddresses.Count > 0) { try { RemoveFirewallAccess(security, executableFile); } catch (Exception e) { Utils.Trace("Could not remove firewall access for executable: {0}. Error={1}", executableFile, e.Message); } } } // remove the permissions for the HTTP endpoints used by the application. if (application.BaseAddresses != null && application.BaseAddresses.Count > 0) { List<ApplicationAccessRule> noRules = new List<ApplicationAccessRule>(); for (int ii = 0; ii < application.BaseAddresses.Count; ii++) { Uri url = Utils.ParseUri(application.BaseAddresses[ii]); if (url != null) { if (url.Scheme == Uri.UriSchemeHttp || url.Scheme == Uri.UriSchemeHttps) { try { HttpAccessRule.SetAccessRules(url, noRules, true); Utils.Trace("Removed HTTP access rules for URL: {0}", url); } catch (Exception e) { Utils.Trace("Could not remove HTTP access rules for URL: {0}. Error={1}", url, e.Message); } } } } } } }