Ejemplo n.º 1
0
        private void EditMI_Click(object sender, EventArgs e)
        {
            try
            {
                FileSystemAccessRule  fileSystemRule  = SelectedTag as FileSystemAccessRule;
                ApplicationAccessRule applicationRule = SelectedTag as ApplicationAccessRule;

                if (fileSystemRule == null && applicationRule == null)
                {
                    return;
                }

                if (fileSystemRule != null)
                {
                    applicationRule                   = new ApplicationAccessRule();
                    applicationRule.RuleType          = ApplicationAccessRule.Convert(fileSystemRule.AccessControlType);
                    applicationRule.Right             = GetEffectiveRight(fileSystemRule);
                    applicationRule.IdentityReference = fileSystemRule.IdentityReference;
                }

                if (!new AccessRuleDlg().ShowDialog(applicationRule))
                {
                    return;
                }

                UpdateItem(ItemsLV.SelectedItems[0], applicationRule);
                AdjustColumns();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public bool ShowDialog(ApplicationAccessRule accessRule)
        {
            AccessTypeCB.SelectedItem = accessRule.RuleType;
            IdentityNameTB.Text = accessRule.IdentityName;
            m_identity = accessRule.IdentityReference;

            if (m_identity == null)
            {
                AccountInfo account = AccountInfo.Create(IdentityNameTB.Text);

                if (account != null)
                {
                    m_identity = account.GetIdentityReference();
                }
            }

            if (accessRule.Right != ApplicationAccessRight.None)
            {
                AccessRightCB.SelectedItem = accessRule.Right;
            }

            if (ShowDialog() != DialogResult.OK)
            {
                return false;
            }
                    
            accessRule.RuleType = (AccessControlType)AccessTypeCB.SelectedItem;
            accessRule.Right = (ApplicationAccessRight)AccessRightCB.SelectedItem;
            accessRule.IdentityReference = m_identity;

            return true;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Updates an item in the control.
        /// </summary>
        protected override void UpdateItem(ListViewItem listItem, object item)
        {
            FileSystemAccessRule  fileSystemRule  = item as FileSystemAccessRule;
            ApplicationAccessRule applicationRule = item as ApplicationAccessRule;

            if (fileSystemRule == null && applicationRule == null)
            {
                base.UpdateItem(listItem, item);
                return;
            }

            if (fileSystemRule != null)
            {
                listItem.SubItems[0].Text = fileSystemRule.AccessControlType.ToString();
                listItem.SubItems[1].Text = fileSystemRule.IdentityReference.Value;
                listItem.SubItems[2].Text = GetEffectiveRight(fileSystemRule).ToString();
                listItem.SubItems[3].Text = GetRightsForFile(fileSystemRule.FileSystemRights);
                listItem.SubItems[4].Text = (fileSystemRule.IsInherited)?"Yes":"No";
                listItem.ImageKey         = (fileSystemRule.AccessControlType == System.Security.AccessControl.AccessControlType.Allow) ? GuiUtils.Icons.Users : GuiUtils.Icons.UsersRedCross;
            }

            if (applicationRule != null)
            {
                listItem.SubItems[0].Text = applicationRule.RuleType.ToString();
                listItem.SubItems[1].Text = applicationRule.IdentityName;
                listItem.SubItems[2].Text = applicationRule.Right.ToString();
                listItem.SubItems[3].Text = null;
                listItem.SubItems[4].Text = null;
                listItem.ImageKey         = (applicationRule.RuleType == AccessControlType.Allow) ? GuiUtils.Icons.Users : GuiUtils.Icons.UsersRedCross;
            }

            listItem.Tag = item;
        }
        /// <summary>
        /// Gets the log file directory and ensures it is writeable.
        /// </summary>
        public static string GetLogFileDirectory()
        {
            // try the program data directory.
            string logFileDirectory = ApplicationData.Current.LocalFolder.Path;

            logFileDirectory += "\\OPC Foundation\\Logs";

            try
            {
                // create the directory.
                if (!Directory.Exists(logFileDirectory))
                {
                    Directory.CreateDirectory(logFileDirectory);
                }

                // ensure everyone has write access to it.
                List <ApplicationAccessRule> rules = new List <ApplicationAccessRule>();

                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Users;
                rule.Right        = ApplicationAccessRight.Configure;
                rule.RuleType     = AccessControlType.Allow;

                rules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.NetworkService;
                rule.Right        = ApplicationAccessRight.Configure;
                rule.RuleType     = AccessControlType.Allow;

                rules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.LocalService;
                rule.Right        = ApplicationAccessRight.Configure;
                rule.RuleType     = AccessControlType.Allow;

                rules.Add(rule);

                ApplicationAccessRule.SetAccessRules(logFileDirectory, rules, false);
            }
            catch (Exception)
            {
                // try the MyDocuments directory instead.
                logFileDirectory  = ApplicationData.Current.LocalFolder.Path;
                logFileDirectory += "OPC Foundation\\Logs";

                if (!Directory.Exists(logFileDirectory))
                {
                    Directory.CreateDirectory(logFileDirectory);
                }
            }

            return(logFileDirectory);
        }
        /// <summary>
        /// Gets the log file directory and ensures it is writeable.
        /// </summary>
        public static string GetLogFileDirectory()
        {
            // try the program data directory.
            string logFileDirectory = ApplicationData.Current.LocalFolder.Path;
            logFileDirectory += "\\OPC Foundation\\Logs";

            try
            {
                // create the directory.
                if (!Directory.Exists(logFileDirectory))
                {
                    Directory.CreateDirectory(logFileDirectory);
                }

                // ensure everyone has write access to it.
                List<ApplicationAccessRule> rules = new List<ApplicationAccessRule>();

                ApplicationAccessRule rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.Users;
                rule.Right = ApplicationAccessRight.Configure;
                rule.RuleType = AccessControlType.Allow;

                rules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.NetworkService;
                rule.Right = ApplicationAccessRight.Configure;
                rule.RuleType = AccessControlType.Allow;

                rules.Add(rule);

                rule = new ApplicationAccessRule();

                rule.IdentityName = WellKnownSids.LocalService;
                rule.Right = ApplicationAccessRight.Configure;
                rule.RuleType = AccessControlType.Allow;

                rules.Add(rule);

                ApplicationAccessRule.SetAccessRules(logFileDirectory, rules, false);
            }
            catch (Exception)
            {
                // try the MyDocuments directory instead.
                logFileDirectory = ApplicationData.Current.LocalFolder.Path;
                logFileDirectory += "OPC Foundation\\Logs";

                if (!Directory.Exists(logFileDirectory))
                {
                    Directory.CreateDirectory(logFileDirectory);
                }
            }

            return logFileDirectory;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Extracts the access rules from the SDDL string.
        /// </summary>
        private static void ParseSddl(string url, string sddl, List <HttpAccessRule> accessRules)
        {
            IList <AccessControlEntity> entities = AccessControlEntity.Parse(sddl);

            for (int ii = 0; ii < entities.Count; ii++)
            {
                AccessControlEntity entity = entities[ii];

                if (entity.AccessType != "A")
                {
                    continue;
                }

                ApplicationAccessRight rights = ApplicationAccessRight.None;

                switch (entity.Rights)
                {
                case "GA":
                case "GXGW":
                case "GWGX":
                {
                    rights = ApplicationAccessRight.Configure;
                    break;
                }

                case "GX":
                {
                    rights = ApplicationAccessRight.Run;
                    break;
                }
                }

                if (rights == ApplicationAccessRight.None)
                {
                    continue;
                }

                string accountName = ApplicationAccessRule.SidToAccountName(entity.AccountSid);

                if (String.IsNullOrEmpty(accountName))
                {
                    continue;
                }

                HttpAccessRule rule = new HttpAccessRule();

                rule.UrlPrefix    = url;
                rule.Right        = rights;
                rule.IdentityName = accountName;

                accessRules.Add(rule);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Enables the menu items based on the current selection.
        /// </summary>
        protected override void EnableMenuItems(ListViewItem clickedItem)
        {
            base.EnableMenuItems(clickedItem);

            NewMI.Enabled = true;

            FileSystemAccessRule  fileSystemRule  = SelectedTag as FileSystemAccessRule;
            ApplicationAccessRule applicationRule = SelectedTag as ApplicationAccessRule;

            if (fileSystemRule != null || applicationRule != null)
            {
                EditMI.Enabled   = true;
                DeleteMI.Enabled = true;
            }
        }
Ejemplo n.º 8
0
        private void DeleteMI_Click(object sender, EventArgs e)
        {
            try
            {
                FileSystemAccessRule  fileSystemRule  = SelectedTag as FileSystemAccessRule;
                ApplicationAccessRule applicationRule = SelectedTag as ApplicationAccessRule;

                if (fileSystemRule == null && applicationRule == null)
                {
                    return;
                }

                ItemsLV.SelectedItems[0].Remove();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sets the application access rules for the specified URL (replaces the hostname with a wildcard).
        /// </summary>
        public static void SetAccessRules(Uri url, IList <ApplicationAccessRule> accessRules, bool replaceExisting)
        {
            StringBuilder wildcard = new StringBuilder();

            wildcard.Append(url.Scheme);
            wildcard.Append("://+:");
            wildcard.Append(url.Port);
            wildcard.Append(url.PathAndQuery);

            List <HttpAccessRule> httpRules = new List <HttpAccessRule>();

            foreach (ApplicationAccessRule accessRule in accessRules)
            {
                // urls do not support deny rules.
                if (accessRule.RuleType == AccessControlType.Deny)
                {
                    continue;
                }

                string identityName = accessRule.IdentityName;

                if (accessRule.IdentityName.StartsWith("S-"))
                {
                    identityName = ApplicationAccessRule.SidToAccountName(accessRule.IdentityName);

                    if (identityName == null)
                    {
                        Utils.Trace("Could not translate SID: {0}", accessRule.IdentityName);
                        continue;
                    }
                }

                HttpAccessRule httpRule = new HttpAccessRule();

                httpRule.Right        = accessRule.Right;
                httpRule.IdentityName = identityName;

                httpRules.Add(httpRule);
            }

            SetAccessRules(wildcard.ToString(), httpRules, replaceExisting);
        }
Ejemplo n.º 10
0
        private void NewMI_Click(object sender, EventArgs e)
        {
            try
            {
                ApplicationAccessRule accessRule = new ApplicationAccessRule();

                accessRule.RuleType = AccessControlType.Allow;
                accessRule.Right    = ApplicationAccessRight.Run;

                if (!new AccessRuleDlg().ShowDialog(accessRule))
                {
                    return;
                }

                AddItem(accessRule);
                AdjustColumns();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Extracts the access rules from the SDDL string.
        /// </summary>
        private static string FormatSddl(IList <HttpAccessRule> accessRules)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("D:");

            for (int ii = 0; ii < accessRules.Count; ii++)
            {
                builder.Append("(");  // start of ACE
                builder.Append("A;"); // access type
                builder.Append(";");  // flags

                switch (accessRules[ii].Right)
                {
                case ApplicationAccessRight.Configure:
                {
                    builder.Append("GXGW;");      // rights
                    break;
                }

                case ApplicationAccessRight.Run:
                case ApplicationAccessRight.Update:
                {
                    builder.Append("GX;");      // rights
                    break;
                }
                }

                builder.Append(";"); // object guid
                builder.Append(";"); // inherited object guid

                string sid = ApplicationAccessRule.AccountNameToSid(accessRules[ii].IdentityName);
                builder.Append(sid);

                builder.Append(')'); // end of ace.
            }

            return(builder.ToString());
        }
        /// <summary>
        /// Updates the access permissions for the certificate store.
        /// </summary>
        private static void SetCertificatePermissions(
            Opc.Ua.Security.SecuredApplication application,
            CertificateIdentifier id,
            IList <ApplicationAccessRule> accessRules,
            bool replaceExisting)
        {
            if (id == null || accessRules == null || accessRules.Count == 0)
            {
                return;
            }

            try
            {
                using (ICertificateStore store = id.OpenStore())
                {
                    if (store.SupportsCertificateAccessControl)
                    {
                        store.SetAccessRules(id.Thumbprint, accessRules, replaceExisting);
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace("Could not set permissions for certificate store: {0}. Error={1}", id, 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);
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Returns the rules in the control.
        /// </summary>
        public IList <ApplicationAccessRule> GetAccessRules()
        {
            if (ItemsLV.Items.Count == 1)
            {
                if (ItemsLV.Items[0].Text == Instructions)
                {
                    return(new ApplicationAccessRule[0]);
                }
            }

            List <ApplicationAccessRule> rules = new List <ApplicationAccessRule>();

            for (int ii = 0; ii < ItemsLV.Items.Count; ii++)
            {
                ApplicationAccessRule applicationRule = ItemsLV.Items[ii].Tag as ApplicationAccessRule;

                if (applicationRule != null)
                {
                    rules.Add(applicationRule);
                    continue;
                }

                FileSystemAccessRule fileSystemRule = ItemsLV.Items[ii].Tag as FileSystemAccessRule;

                if (fileSystemRule != null)
                {
                    applicationRule                   = new ApplicationAccessRule();
                    applicationRule.RuleType          = ApplicationAccessRule.Convert(fileSystemRule.AccessControlType);
                    applicationRule.Right             = GetEffectiveRight(fileSystemRule);
                    applicationRule.IdentityReference = fileSystemRule.IdentityReference;
                    rules.Add(applicationRule);
                    continue;
                }
            }

            return(rules.ToArray());
        }
        /// <summary>
        /// Gets the access rules to use for the application.
        /// </summary>
        private List<ApplicationAccessRule> GetAccessRules()
        {
            List<ApplicationAccessRule> rules = new List<ApplicationAccessRule>();

            // check for rules specified in the installer configuration.
            bool hasAdmin = false;

            if (InstallConfig.AccessRules != null)
            {
                for (int ii = 0; ii < InstallConfig.AccessRules.Count; ii++)
                {
                    ApplicationAccessRule rule = InstallConfig.AccessRules[ii];

                    if (rule.Right == ApplicationAccessRight.Configure && rule.RuleType == AccessControlType.Allow)
                    {
                        hasAdmin = true;
                        break;
                    }
                }

                rules = InstallConfig.AccessRules;
            }

            // provide some default rules.
            if (rules.Count == 0)
            {
                // give user run access.
                ApplicationAccessRule rule = new ApplicationAccessRule();
                rule.RuleType = AccessControlType.Allow;
                rule.Right = ApplicationAccessRight.Run;
                rule.IdentityName = WellKnownSids.Users;
                rules.Add(rule);

                // ensure service can access.
                if (InstallConfig.InstallAsService)
                {
                    rule = new ApplicationAccessRule();
                    rule.RuleType = AccessControlType.Allow;
                    rule.Right = ApplicationAccessRight.Run;
                    rule.IdentityName = WellKnownSids.NetworkService;
                    rules.Add(rule);

                    rule = new ApplicationAccessRule();
                    rule.RuleType = AccessControlType.Allow;
                    rule.Right = ApplicationAccessRight.Run;
                    rule.IdentityName = WellKnownSids.LocalService;
                    rules.Add(rule);
                }               
            }

            // ensure someone can change the configuration later.
            if (!hasAdmin)
            {
                ApplicationAccessRule rule = new ApplicationAccessRule();
                rule.RuleType = AccessControlType.Allow;
                rule.Right = ApplicationAccessRight.Configure;
                rule.IdentityName = WellKnownSids.Administrators;
                rules.Add(rule);
            }

            return rules;
        }
Ejemplo n.º 15
0
        /// <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>
        /// 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);
                    }
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Returns the rules in the control.
        /// </summary>
        public IList<ApplicationAccessRule> GetAccessRules()
        {
            if (ItemsLV.Items.Count == 1)
            {
                if (ItemsLV.Items[0].Text == Instructions)
                {
                    return new ApplicationAccessRule[0];
                }
            }

            List<ApplicationAccessRule> rules = new List<ApplicationAccessRule>();

            for (int ii = 0; ii < ItemsLV.Items.Count; ii++)
            {
                ApplicationAccessRule applicationRule = ItemsLV.Items[ii].Tag as ApplicationAccessRule;

                if (applicationRule != null)
                {
                    rules.Add(applicationRule);
                    continue;
                }

                FileSystemAccessRule fileSystemRule = ItemsLV.Items[ii].Tag as FileSystemAccessRule;

                if (fileSystemRule != null)
                {
                    applicationRule = new ApplicationAccessRule();
                    applicationRule.RuleType = ApplicationAccessRule.Convert(fileSystemRule.AccessControlType);
                    applicationRule.Right = GetEffectiveRight(fileSystemRule);
                    applicationRule.IdentityReference = fileSystemRule.IdentityReference;
                    rules.Add(applicationRule);
                    continue;
                }
            }

            return rules.ToArray();
        }
Ejemplo n.º 18
0
        private void NewMI_Click(object sender, EventArgs e)
        {            
            try
            {
                ApplicationAccessRule accessRule = new ApplicationAccessRule();

                accessRule.RuleType = AccessControlType.Allow;
                accessRule.Right = ApplicationAccessRight.Run;

                if (!new AccessRuleDlg().ShowDialog(accessRule))
                {
                    return;
                }

                AddItem(accessRule);
                AdjustColumns();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
Ejemplo n.º 19
0
        private void EditMI_Click(object sender, EventArgs e)
        {            
            try
            {
                FileSystemAccessRule fileSystemRule = SelectedTag as FileSystemAccessRule;
                ApplicationAccessRule applicationRule = SelectedTag as ApplicationAccessRule;

                if (fileSystemRule == null && applicationRule == null)
                {
                    return;
                }

                if (fileSystemRule != null)
                {
                    applicationRule = new ApplicationAccessRule();
                    applicationRule.RuleType = ApplicationAccessRule.Convert(fileSystemRule.AccessControlType);
                    applicationRule.Right = GetEffectiveRight(fileSystemRule);
                    applicationRule.IdentityReference = fileSystemRule.IdentityReference;
                }

                if (!new AccessRuleDlg().ShowDialog(applicationRule))
                {
                    return;
                }

                UpdateItem(ItemsLV.SelectedItems[0], applicationRule);
                AdjustColumns();
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <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);
                    }
                }
            }

            
        }