Пример #1
0
        /// <summary>
        /// Check for untrusted certificates and only accept them if the user has accepted them
        /// </summary>
        private void CertificateValidator_CertificateValidation(CertificateValidator validator, CertificateValidationEventArgs e)
        {
            if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted)
            {
                // Session is not accessible from here so we need to iterate through all key-value-pairs
                foreach (KeyValuePair <string, OpcSessionCacheData> pair in OpcSessionCache.ToArray())
                {
                    // try processing each entry
                    try
                    {
                        string hostName = pair.Value.EndpointURL.Substring("opc.tcp://".Length);
                        if (hostName.Contains(":"))
                        {
                            hostName = hostName.Substring(0, hostName.IndexOf(':'));
                        }

                        // Look up by cert thumbprint
                        if (string.Equals(pair.Value.CertThumbprint, e.Certificate.Thumbprint, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // check if the current session user has confirmed trust
                            if (pair.Value.Trusted)
                            {
                                // In this case, we accept the cert
                                e.Accept = true;
                                break;
                            }
                        }

                        // Update our cache data
                        if (e.Certificate.Subject.Contains(hostName))
                        {
                            OpcSessionCacheData newValue = new OpcSessionCacheData
                            {
                                OPCSession     = pair.Value.OPCSession,
                                EndpointURL    = pair.Value.EndpointURL,
                                Trusted        = pair.Value.Trusted,
                                CertThumbprint = e.Certificate.Thumbprint
                            };
                            OpcSessionCache.TryUpdate(pair.Key, newValue, pair.Value);
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        // do nothing
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Establishes an OPC UA session to the given OPC UA server with implicit trust.
        /// </summary>
        public async Task <Session> GetSessionWithImplicitTrust(string sessionID, string appUri)
        {
            // Try to connect to Server
            Session session = null;

            try
            {
                session = await GetSessionAsync(sessionID, appUri);
            }
            catch (ServiceResultException exception)
                when((exception.InnerResult != null) &&
                     (exception.InnerResult.StatusCode == StatusCodes.BadCertificateUntrusted))
                {
                    // Check that there is a session already in our cache data
                    OpcSessionCacheData entry;

                    if (OpcSessionCache.TryGetValue(sessionID, out entry))
                    {
                        if (string.Equals(entry.EndpointURL, appUri, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // We always trust the Server for which we have generated the URL ourselves
                            OpcSessionCacheData newValue = new OpcSessionCacheData
                            {
                                CertThumbprint = entry.CertThumbprint,
                                OPCSession     = entry.OPCSession,
                                EndpointURL    = entry.EndpointURL,
                                Trusted        = true
                            };
                            OpcSessionCache.TryUpdate(sessionID, newValue, entry);

                            // try again
                            session = await GetSessionAsync(sessionID, appUri);
                        }
                    }
                }
            catch (ServiceResultException exception)
                when((exception.InnerResult != null) &&
                     (exception.InnerResult.StatusCode != StatusCodes.BadCertificateUntrusted))
                {
                    // any other reason than untrusted certificate
                    Trace.TraceError($"ServiceResultException occured: '{exception.InnerException.Message}'");
                    throw;
                }

            return(session);
        }
Пример #3
0
        /// <summary>
        /// Checks if there is an active OPC UA session for the provided browser session. If the persisted OPC UA session does not exist,
        /// a new OPC UA session to the given endpoint URL is established.
        /// </summary>
        public async Task <Session> GetSessionAsync(string sessionID, string endpointURL)
        {
            if (string.IsNullOrEmpty(sessionID) || string.IsNullOrEmpty(endpointURL))
            {
                return(null);
            }

            OpcSessionCacheData entry;

            if (OpcSessionCache.TryGetValue(sessionID, out entry))
            {
                if (entry.OPCSession != null)
                {
                    if (entry.OPCSession.Connected)
                    {
                        return(entry.OPCSession);
                    }

                    try
                    {
                        entry.OPCSession.Close(500);
                    }
                    catch
                    {
                    }
                    entry.OPCSession = null;
                }
            }
            else
            {
                // create a new entry
                OpcSessionCacheData newEntry = new OpcSessionCacheData {
                    EndpointURL = endpointURL
                };
                OpcSessionCache.TryAdd(sessionID, newEntry);
            }

            Uri endpointURI = new Uri(endpointURL);
            EndpointDescriptionCollection endpointCollection    = DiscoverEndpoints(_configuration, endpointURI, 10);
            EndpointDescription           selectedEndpoint      = SelectUaTcpEndpoint(endpointCollection);
            EndpointConfiguration         endpointConfiguration = EndpointConfiguration.Create(_configuration);
            ConfiguredEndpoint            endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);

            endpoint.Update(selectedEndpoint);

            // Check if we have a cached endpoint with the same URL and use that one instead
            foreach (ConfiguredEndpoint cachedEndpoint in OpcCachedEndpoints)
            {
                if (cachedEndpoint.EndpointUrl.AbsoluteUri.Equals(endpointURL, StringComparison.InvariantCultureIgnoreCase))
                {
                    endpoint = cachedEndpoint;
                    break;
                }
            }

            Session session = await Session.Create(
                _configuration,
                endpoint,
                true,
                false,
                sessionID,
                60000,
                new UserIdentity(new AnonymousIdentityToken()),
                null);

            if (session != null)
            {
                session.KeepAlive += new KeepAliveEventHandler(StandardClient_KeepAlive);

                // Update our cache data
                if (OpcSessionCache.TryGetValue(sessionID, out entry))
                {
                    if (string.Equals(entry.EndpointURL, endpointURL, StringComparison.InvariantCultureIgnoreCase))
                    {
                        OpcSessionCacheData newValue = new OpcSessionCacheData
                        {
                            CertThumbprint = entry.CertThumbprint,
                            EndpointURL    = entry.EndpointURL,
                            Trusted        = entry.Trusted,
                            OPCSession     = session
                        };
                        OpcSessionCache.TryUpdate(sessionID, newValue, entry);
                    }
                }
            }

            return(session);
        }