/// <summary> /// Invoked when the application is launched normally by the end user. Other entry points /// will be used such as when the application is launched to open a specific file. /// </summary> /// <param name="e">Details about the launch request and process.</param> protected override async void OnLaunched(LaunchActivatedEventArgs e) { ApplicationInstance.MessageDlg = new ApplicationMessageDlg(); ApplicationInstance application = new ApplicationInstance(); application.ApplicationName = "UA Sample Client"; application.ApplicationType = ApplicationType.ClientAndServer; application.ConfigSectionName = "Opc.Ua.SampleClient"; // set empty page for MessageDlg Window.Current.Content = new ClientPage(); // Ensure the current window is active Window.Current.Activate(); try { // load the application configuration. await application.LoadApplicationConfiguration(false); // allow UA servers to use the same certificate for HTTPS validation. ApplicationInstance.SetUaValidationForHttps(application.ApplicationConfiguration.CertificateValidator); // run the application interactively. Window.Current.Content = new ClientPage(application.ApplicationConfiguration.CreateMessageContext(), application, null, application.ApplicationConfiguration); // Ensure the current window is active Window.Current.Activate(); } catch (ServiceResultException ex) { Utils.Trace("ServiceResultException:" + ex.Message); MessageDlg dialog = new MessageDlg("Client not started. Exit.\r\n" + ex.Message); await dialog.ShowAsync(); Application.Current.Exit(); return; } try { // check the application certificate. await application.CheckApplicationInstanceCertificate(false, 0); // start the server. await application.Start(new SampleServer()); } catch (ServiceResultException ex) { Utils.Trace("ServiceResultException:" + ex.Message); MessageDlg dialog = new MessageDlg("Client ok but Server has not started.\r\n" + ex.Message); await dialog.ShowAsync(); } }
/// <summary> /// Invoked when the application is launched normally by the end user. Other entry points /// will be used such as when the application is launched to open a specific file. /// </summary> /// <param name="e">Details about the launch request and process.</param> protected override async void OnLaunched(LaunchActivatedEventArgs e) { ApplicationInstance.MessageDlg = new ApplicationMessageDlg(); ApplicationInstance application = new ApplicationInstance(); application.ApplicationName = "UA Sample Client"; application.ApplicationType = ApplicationType.ClientAndServer; application.ConfigSectionName = "Opc.Ua.SampleClient"; // helper to let Opc.Ua Utils find the localFolder in the environment StorageFolder localFolder = ApplicationData.Current.LocalFolder; Utils.DefaultLocalFolder = localFolder.Path; // set empty page for MessageDlg Window.Current.Content = new ClientPage(); // Ensure the current window is active Window.Current.Activate(); // Allow the current window to activate since the stack initialization below can take some time // and the app can be terminated by the runtime if this takes too long await Task.Delay(1); try { // load the application configuration. await application.LoadApplicationConfiguration(false); // check the application certificate. await application.CheckApplicationInstanceCertificate(false, 0); // run the application interactively. Window.Current.Content = new ClientPage(application.ApplicationConfiguration.CreateMessageContext(), application, null, application.ApplicationConfiguration); // start the server. await application.Start(new SampleServer()); } catch (Exception ex) { Utils.Trace("Exception:" + ex.Message); MessageDlg dialog = new MessageDlg(ex.Message); await dialog.ShowAsync(); Application.Current.Exit(); } }
/// <summary> /// Invoked when the application is launched normally by the end user. Other entry points /// will be used such as when the application is launched to open a specific file. /// </summary> /// <param name="e">Details about the launch request and process.</param> protected override async void OnLaunched(LaunchActivatedEventArgs args) { ApplicationInstance.MessageDlg = new ApplicationMessageDlg(); ApplicationInstance application = new ApplicationInstance(); application.ApplicationName = "UA Sample Server"; application.ApplicationType = ApplicationType.Server; application.ConfigSectionName = "Opc.Ua.SampleServer"; // set empty page for MessageDlg Window.Current.Content = new ServerPage(); // Ensure the current window is active Window.Current.Activate(); try { // load the application configuration. await application.LoadApplicationConfiguration(false); // This call registers the certificate with HTTP.SYS // It must be called once after installation if the HTTPS endpoint is enabled. // HttpAccessRule.SetHttpsCertificate(c.SecurityConfiguration.ApplicationCertificate.Find(true), 51212, false); // check the application certificate. await application.CheckApplicationInstanceCertificate(false, 0); // start the server. await application.Start(new Opc.Ua.Sample.SampleServer()); // run the application interactively. Window.Current.Content = new ServerPage(application); // Ensure the current window is active Window.Current.Activate(); } catch (ServiceResultException ex) { Utils.Trace("ServiceResultException:" + ex.Message); MessageDlg dialog = new MessageDlg("Server not started. Exit.\r\n"+ex.Message); await dialog.ShowAsync(); Application.Current.Exit(); } }
async void ExceptionMessageDlg(string message) { await Dispatcher.RunAsync( CoreDispatcherPriority.Normal, async () => { MessageDlg dialog = new MessageDlg(message); await dialog.ShowAsync(); }); }
/// <summary> /// Provides a user defined method. /// </summary> protected virtual async void DoTest(Session session) { MessageDlg dialog = new MessageDlg("A handy place to put test code."); await dialog.ShowAsync(); }
async void Window_PageClosing(object sender, RoutedEventArgs e) { if (m_masterPage == null && m_pages.Count > 0) { MessageDlg dialog = new MessageDlg("Close all sessions?", MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { return; } } BrowseCTRL.Clear(); for (int ii = 0; ii < m_pages.Count; ii++) { if (Object.ReferenceEquals(m_pages[ii], sender)) { m_pages.RemoveAt(ii); break; } } }
private async void EndpointCB_KeyDown(object sender, KeyRoutedEventArgs e) { try { if (e.Key == VirtualKey.Delete) { // ignore "New" if (m_selectedIndex == 0) return; ConfiguredEndpoint endpoint = SelectedEndpoint; MessageDlg dialog = new MessageDlg( "Delete Endpoint?\r\n" + endpoint.EndpointUrl, MessageDlgButton.Yes, MessageDlgButton.No); if (await dialog.ShowAsync() == MessageDlgButton.Yes) { int oldIndex = m_selectedIndex; m_endpoints.Remove(endpoint); EndpointCB.Items.Remove(endpoint); if (oldIndex > 0) { EndpointCB.SelectedIndex = m_selectedIndex = oldIndex-1; } // raise notification. if (m_EndpointsChanged != null) { m_EndpointsChanged(this, null); } } } } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); } }
private async void OkBTN_Click(object sender, EventArgs e) { NodeId viewId = null; try { viewId = NodeId.Parse(ViewIdTB.Text); } catch (Exception) { MessageDlg dialog = new MessageDlg("Please enter a valid node id for the view id."); await dialog.ShowAsync(); } try { ViewDescription view = null; if (!NodeId.IsNull(viewId) || ((bool)ViewTimestampCK.IsChecked || (bool)ViewVersionCK.IsChecked)) { view = new ViewDescription(); view.ViewId = viewId; view.Timestamp = DateTime.MinValue; view.ViewVersion = 0; if ((bool)ViewTimestampCK.IsChecked && (ViewTimestampDP.Date > ViewTimestampDP.MinYear)) { view.Timestamp = Convert.ToDateTime(ViewTimestampDP.Date); } if ((bool)ViewVersionCK.IsChecked) { view.ViewVersion = (uint)ViewVersionNC.Value; } } m_browser.View = view; m_browser.MaxReferencesReturned = (uint)MaxReferencesReturnedNC.Value; m_browser.BrowseDirection = (BrowseDirection)BrowseDirectionCB.SelectedItem; m_browser.NodeClassMask = (int)NodeClass.View | (int)NodeClass.Object; m_browser.ReferenceTypeId = ReferenceTypeCTRL.SelectedTypeId; m_browser.IncludeSubtypes = (bool)IncludeSubtypesCK.IsChecked; m_browser.NodeClassMask = 0; int nodeClassMask = 0; foreach (NodeClass nodeClass in NodeClassList.Items) { nodeClassMask |= (int)nodeClass; } m_browser.NodeClassMask = nodeClassMask; } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); } }
private async void BrowseBTN_Click(object sender, EventArgs e) { try { Browser browser = new Browser(m_browser.Session); browser.BrowseDirection = BrowseDirection.Forward; browser.NodeClassMask = (int)NodeClass.View | (int)NodeClass.Object; browser.ReferenceTypeId = ReferenceTypeIds.Organizes; browser.IncludeSubtypes = true; ReferenceDescription reference = new SelectNodeDlg().ShowDialog(browser, Objects.ViewsFolder); if (reference != null) { if (reference.NodeClass != NodeClass.View) { MessageDlg dialog = new MessageDlg("Please select a valid view node id."); await dialog.ShowAsync(); return; } ViewIdTB.Text = Utils.Format("{0}", reference.NodeId); } } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); } }
/// <summary> /// Creates an application instance certificate if one does not already exist. /// </summary> public static async Task<X509Certificate2> CheckApplicationInstanceCertificate( ApplicationConfiguration configuration, ushort keySize, bool interactive, bool updateFile) { // create a default certificate if none is specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { id = new CertificateIdentifier(); id.StoreType = Utils.DefaultStoreType; id.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; id.SubjectName = configuration.ApplicationName; } bool createNewCertificate = false; IList<string> serverDomainNames = configuration.GetServerDomainNames(); // check for private key. X509Certificate2 certificate = await id.Find(true); if (certificate == null) { // check if config file has wrong thumprint. if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint)) { CertificateIdentifier id2 = new CertificateIdentifier(); id2.StoreType = id.StoreType; id2.StorePath = id.StorePath; id2.SubjectName = id.SubjectName; id = id2; certificate = await id2.Find(true); if (certificate != null) { string message = Utils.Format( "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?", id.SubjectName); if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { certificate = null; } } } } // check if private key is missing. if (certificate == null) { certificate = await id.Find(false); if (certificate != null) { string message = Utils.Format( "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?", id.SubjectName); if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { certificate = null; } } } } // check domains. if (certificate != null) { IList<string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate); for (int ii = 0; ii < serverDomainNames.Count; ii++) { if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii])) { continue; } if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0) { // check computer name. string computerName = Utils.GetHostName(); if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName)) { continue; } } string message = Utils.Format( "The server is configured to use domain '{0}' which does not appear in the certificate. Create new certificate?", serverDomainNames[ii]); createNewCertificate = true; if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { createNewCertificate = false; continue; } } Utils.Trace(message); break; } if (!createNewCertificate) { // check if key size matches. if (keySize == certificate.GetRSAPublicKey().KeySize) { await AddToTrustedStore(configuration, certificate); return certificate; } } } // prompt user. if (interactive) { if (!createNewCertificate) { MessageDlg dialog = new MessageDlg("Application does not have an instance certificate.\n Create one automatically?", MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { return null; } } } // delete existing certificate. if (certificate != null) { await DeleteApplicationInstanceCertificate(configuration); } // add the localhost. if (serverDomainNames.Count == 0) { serverDomainNames.Add(Utils.GetHostName()); } certificate = await Opc.Ua.CertificateFactory.CreateCertificate( id.StoreType, id.StorePath, configuration.ApplicationUri, configuration.ApplicationName, null, serverDomainNames, keySize, 300); id.Certificate = certificate; await AddToTrustedStore(configuration, certificate); if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath)) { configuration.SaveToFile(configuration.SourceFilePath); } await configuration.CertificateValidator.Update(configuration.SecurityConfiguration); return await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null); } return certificate; }
/// <summary> /// Does any configuration checks before starting up. /// </summary> public static async Task<ApplicationConfiguration> LoadConfiguration( string configSectionName, ApplicationType applicationType, string defaultConfigFile, bool interactive) { // get the location of the config file. string filePath = ApplicationConfiguration.GetFilePathFromAppConfig(configSectionName); if (filePath == null || !System.IO.File.Exists(filePath)) { filePath = Utils.GetAbsoluteFilePath(defaultConfigFile, false, false, false); } try { // load the configuration file. ApplicationConfiguration configuration = await ApplicationConfiguration.Load(new System.IO.FileInfo(filePath), applicationType, null); if (configuration == null) { return null; } return configuration; } catch (Exception e) { // warn user. if (interactive) { StringBuilder message = new StringBuilder(); message.Append("Could not load configuration file.\r\n"); message.Append(filePath); message.Append("\r\n"); message.Append("\r\n"); message.Append(e.Message); MessageDlg dialog = new MessageDlg(message.ToString()); await dialog.ShowAsync(); Utils.Trace(e, "Could not load configuration file. {0}", filePath); } return null; } }
/// <summary> /// Handles a certificate validation error. /// </summary> /// <param name="caller">The caller's text is used as the caption of the <see cref="MessageBox"/> shown to provide details about the error.</param> /// <param name="validator">The validator (not used).</param> /// <param name="e">The <see cref="Opc.Ua.CertificateValidationEventArgs"/> instance event arguments provided when a certificate validation error occurs.</param> public static async Task HandleCertificateValidationError(Page caller, CertificateValidator validator, CertificateValidationEventArgs e) { StringBuilder buffer = new StringBuilder(); buffer.AppendFormat("Certificate could not validated: {0}\r\n\r\n", e.Error.StatusCode); buffer.AppendFormat("Subject: {0}\r\n", e.Certificate.Subject); buffer.AppendFormat("Issuer: {0}\r\n", (e.Certificate.Subject == e.Certificate.Issuer) ? "Self-signed" : e.Certificate.Issuer); buffer.AppendFormat("Thumbprint: {0}\r\n\r\n", e.Certificate.Thumbprint); buffer.AppendFormat("Accept anyways?"); MessageDlg dialog = new MessageDlg(buffer.ToString(), MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result == MessageDlgButton.Yes) { e.Accept = true; } }
/// <summary> /// Creates an application instance certificate if one does not already exist. /// </summary> public static async Task <X509Certificate2> CheckApplicationInstanceCertificate( ApplicationConfiguration configuration, ushort keySize, bool interactive, bool updateFile) { // create a default certificate if none is specified. CertificateIdentifier id = configuration.SecurityConfiguration.ApplicationCertificate; if (id == null) { id = new CertificateIdentifier(); id.StoreType = Utils.DefaultStoreType; id.StorePath = ApplicationData.Current.LocalFolder.Path + "\\OPC Foundation\\CertificateStores\\MachineDefault"; id.SubjectName = configuration.ApplicationName; } bool createNewCertificate = false; IList <string> serverDomainNames = configuration.GetServerDomainNames(); // check for private key. X509Certificate2 certificate = await id.Find(true); if (certificate == null) { // check if config file has wrong thumprint. if (!String.IsNullOrEmpty(id.SubjectName) && !String.IsNullOrEmpty(id.Thumbprint)) { CertificateIdentifier id2 = new CertificateIdentifier(); id2.StoreType = id.StoreType; id2.StorePath = id.StorePath; id2.SubjectName = id.SubjectName; id = id2; certificate = await id2.Find(true); if (certificate != null) { string message = Utils.Format( "Matching certificate with SubjectName={0} found but with a different thumbprint. Use certificate?", id.SubjectName); if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { certificate = null; } } } } // check if private key is missing. if (certificate == null) { certificate = await id.Find(false); if (certificate != null) { string message = Utils.Format( "Matching certificate with SubjectName={0} found but without a private key. Create a new certificate?", id.SubjectName); if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { certificate = null; } } } } // check domains. if (certificate != null) { IList <string> certificateDomainNames = Utils.GetDomainsFromCertficate(certificate); for (int ii = 0; ii < serverDomainNames.Count; ii++) { if (Utils.FindStringIgnoreCase(certificateDomainNames, serverDomainNames[ii])) { continue; } if (String.Compare(serverDomainNames[ii], "localhost", StringComparison.OrdinalIgnoreCase) == 0) { // check computer name. string computerName = Utils.GetHostName(); if (Utils.FindStringIgnoreCase(certificateDomainNames, computerName)) { continue; } } string message = Utils.Format( "The server is configured to use domain '{0}' which does not appear in the certificate. Create new certificate?", serverDomainNames[ii]); createNewCertificate = true; if (interactive) { MessageDlg dialog = new MessageDlg(message, MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { createNewCertificate = false; continue; } } Utils.Trace(message); break; } if (!createNewCertificate) { // check if key size matches. if (keySize == certificate.GetRSAPublicKey().KeySize) { await AddToTrustedStore(configuration, certificate); return(certificate); } } } // prompt user. if (interactive) { if (!createNewCertificate) { MessageDlg dialog = new MessageDlg("Application does not have an instance certificate.\n Create one automatically?", MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { return(null); } } } // delete existing certificate. if (certificate != null) { await DeleteApplicationInstanceCertificate(configuration); } // add the localhost. if (serverDomainNames.Count == 0) { serverDomainNames.Add(Utils.GetHostName()); } certificate = await Opc.Ua.CertificateFactory.CreateCertificate( id.StoreType, id.StorePath, configuration.ApplicationUri, configuration.ApplicationName, null, serverDomainNames, keySize, 300); id.Certificate = certificate; await AddToTrustedStore(configuration, certificate); if (updateFile && !String.IsNullOrEmpty(configuration.SourceFilePath)) { configuration.SaveToFile(configuration.SourceFilePath); } await configuration.CertificateValidator.Update(configuration.SecurityConfiguration); return(await configuration.SecurityConfiguration.ApplicationCertificate.LoadPrivateKey(null)); } return(certificate); }
private async void UserIdentityBTN_Click(object sender, RoutedEventArgs e) { try { UserTokenItem currentItem = new UserTokenItem(UserTokenType.Anonymous); if (UserTokenTypeCB.SelectedIndex != -1) { currentItem = (UserTokenItem)UserTokenTypeCB.SelectedItem; } UserIdentityToken identity = null; m_userIdentities.TryGetValue(currentItem.ToString(), out identity); switch (currentItem.Policy.TokenType) { case UserTokenType.UserName: { UserNameIdentityToken userNameToken = identity as UserNameIdentityToken; if (userNameToken == null) { userNameToken = new UserNameIdentityToken(); } if (new UsernameTokenDlg().ShowDialog(userNameToken)) { userNameToken.PolicyId = currentItem.Policy.PolicyId; m_userIdentities[currentItem.ToString()] = userNameToken; UserIdentityTB.Text = userNameToken.UserName; } break; } default: { MessageDlg dialog = new MessageDlg("User token type not supported at this time."); await dialog.ShowAsync(); break; } } } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); } }
private async void OkBTN_Click(object sender, RoutedEventArgs e) { try { // check that discover has completed. if (!m_discoverySucceeded) { MessageDlg dialog = new MessageDlg("Endpoint information may be out of date because the discovery process has not completed. Continue anyway?", MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { return; } } EndpointConfiguration configuration = m_endpointConfiguration; if (configuration == null) { configuration = EndpointConfiguration.Create(m_configuration); } if (m_currentDescription == null) { m_currentDescription = CreateDescriptionFromSelections(); } // the discovery endpoint should always be on the same machine as the server. // if there is a mismatch it is likely because the server has multiple addresses // and was not configured to return the current address to the client. // The code automatically updates the domain in the url. Uri endpointUrl = Utils.ParseUri(m_currentDescription.EndpointUrl); if (m_discoverySucceeded) { if (!Utils.AreDomainsEqual(endpointUrl, m_discoveryUrl)) { UriBuilder url = new UriBuilder(endpointUrl); url.Host = m_discoveryUrl.DnsSafeHost; if (url.Scheme == m_discoveryUrl.Scheme) { url.Port = m_discoveryUrl.Port; } endpointUrl = url.Uri; m_currentDescription.EndpointUrl = endpointUrl.ToString(); } } // set the encoding. Encoding encoding = (Encoding)EncodingCB.SelectedItem; configuration.UseBinaryEncoding = encoding != Encoding.Xml; if (m_endpoint == null) { m_endpoint = new ConfiguredEndpoint(null, m_currentDescription, configuration); } else { m_endpoint.Update(m_currentDescription); m_endpoint.Update(configuration); } // set the user token policy. m_endpoint.SelectedUserTokenPolicyIndex = FindBestUserTokenPolicy(m_currentDescription); // update the user identity. UserTokenItem userTokenItem = (UserTokenItem)UserTokenTypeCB.SelectedItem; UserIdentityToken userIdentity = null; if (!m_userIdentities.TryGetValue(userTokenItem.ToString(), out userIdentity)) { userIdentity = null; } m_endpoint.UserIdentity = userIdentity; } catch (Exception exception) { GuiUtils.HandleException(String.Empty, GuiUtils.CallerName(), exception); } dialogPopup.IsOpen = false; }
/// <summary> /// Asks for confirmation before expanding a long list. /// </summary> private async Task<bool> PromptOnLongList(int length) { if (length < 256) { return true; } MessageDlg dialog = new MessageDlg("It may take a long time to display the list are you sure you want to continue?", MessageDlgButton.Yes, MessageDlgButton.No); MessageDlgButton result = await dialog.ShowAsync(); if (result != MessageDlgButton.Yes) { return true; } return false; }