コード例 #1
0
 /// <summary>
 /// Create session manager
 /// </summary>
 /// <param name="clientConfig"></param>
 /// <param name="identity"></param>
 /// <param name="logger"></param>
 public DefaultSessionManager(IClientServicesConfig clientConfig,
                              IIdentity identity, ILogger logger)
 {
     _clientConfig = clientConfig;
     _logger       = logger;
     _identity     = identity;
     _lock         = new SemaphoreSlim(1, 1);
 }
コード例 #2
0
 /// <summary>
 /// Create client host services
 /// </summary>
 /// <param name="clientConfig"></param>
 /// <param name="logger"></param>
 /// <param name="maxOpTimeout"></param>
 public ClientServices(ILogger logger, IClientServicesConfig clientConfig,
                       TimeSpan?maxOpTimeout = null)
 {
     _logger = logger ??
               throw new ArgumentNullException(nameof(logger));
     _clientConfig = clientConfig ??
                     throw new ArgumentNullException(nameof(clientConfig));
     _maxOpTimeout = maxOpTimeout;
     _appConfig    = _clientConfig.ToApplicationConfigurationAsync(true, VerifyCertificate).Result;
     // Create discovery config and client certificate
     _timer = new Timer(_ => OnTimer(), null, kEvictionCheck, Timeout.InfiniteTimeSpan);
 }
コード例 #3
0
 /// <summary>
 /// Create client host services
 /// </summary>
 /// <param name="clientConfig"></param>
 /// <param name="logger"></param>
 /// <param name="identity"></param>
 /// <param name="maxOpTimeout"></param>
 public ClientServices(ILogger logger, IClientServicesConfig clientConfig,
                       IIdentity identity = null, TimeSpan?maxOpTimeout = null)
 {
     _logger = logger ??
               throw new ArgumentNullException(nameof(logger));
     _clientConfig = clientConfig ??
                     throw new ArgumentNullException(nameof(clientConfig));
     _identity     = identity;
     _maxOpTimeout = maxOpTimeout;
     // Create discovery config and client certificate
     _timer = new Timer(_ => OnTimer(), null, kEvictionCheck, Timeout.InfiniteTimeSpan);
 }
コード例 #4
0
 /// <summary>
 /// Create converter
 /// </summary>
 /// <param name="logger"></param>
 /// <param name="serializer"></param>
 /// <param name="engineConfig"></param>
 /// <param name="clientConfig"></param>
 /// <param name="cryptoProvider"></param>
 public PublishedNodesJobConverter(
     ILogger logger,
     IJsonSerializer serializer,
     IEngineConfiguration engineConfig,
     IClientServicesConfig clientConfig,
     ISecureElement cryptoProvider = null)
 {
     _engineConfig   = engineConfig ?? throw new ArgumentNullException(nameof(engineConfig));
     _clientConfig   = clientConfig ?? throw new ArgumentNullException(nameof(clientConfig));
     _cryptoProvider = cryptoProvider;
     _serializer     = serializer ?? throw new ArgumentNullException(nameof(serializer));
     _logger         = logger ?? throw new ArgumentNullException(nameof(logger));
 }
コード例 #5
0
        /// <summary>
        /// Create session manager
        /// </summary>
        /// <param name="clientConfig"></param>
        /// <param name="identity"></param>
        /// <param name="logger"></param>
        public DefaultSessionManager(IClientServicesConfig clientConfig,
                                     IIdentity identity, ILogger logger)
        {
            _clientConfig             = clientConfig;
            _logger                   = logger;
            _identity                 = identity;
            _applicationConfiguration = _clientConfig.
                                        ToApplicationConfigurationAsync(_identity, true, OnValidate).Result;
            _endpointConfiguration = _clientConfig.ToEndpointConfiguration();

            _lock   = new SemaphoreSlim(1, 1);
            _cts    = new CancellationTokenSource();
            _runner = Task.Run(() => RunAsync(_cts.Token));
        }
コード例 #6
0
        /// <summary>
        /// Create client host services
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="configuration"></param>
        /// <param name="maxOpTimeout"></param>
        public ClientServices(ILogger logger, IClientServicesConfig configuration,
                              TimeSpan?maxOpTimeout = null)
        {
            _logger = logger ??
                      throw new ArgumentNullException(nameof(logger));
            _configuration = configuration ??
                             throw new ArgumentNullException(nameof(configuration));
            _maxOpTimeout = maxOpTimeout;

            // Create discovery config and client certificate
            _opcApplicationConfig = CreateApplicationConfiguration(
                TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(2));
            InitApplicationSecurityAsync().Wait();

            _timer = new Timer(_ => OnTimer(), null, kEvictionCheck, Timeout.InfiniteTimeSpan);
        }
コード例 #7
0
        /// <summary>
        /// Create application configuration
        /// </summary>
        /// <param name="opcConfig"></param>
        /// <param name="identity"></param>
        /// <param name="createSelfSignedCertIfNone"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public static async Task <ApplicationConfiguration> ToApplicationConfigurationAsync(
            this IClientServicesConfig opcConfig, IIdentity identity, bool createSelfSignedCertIfNone,
            CertificateValidationEventHandler handler)
        {
            if (string.IsNullOrWhiteSpace(opcConfig.ApplicationName))
            {
                throw new ArgumentNullException(nameof(opcConfig.ApplicationName));
            }

            // wait with the configuration until network is up
            for (var retry = 0; retry < 3; retry++)
            {
                if (NetworkInterface.GetIsNetworkAvailable())
                {
                    break;
                }
                else
                {
                    await Task.Delay(3000);
                }
            }

            var applicationConfiguration = new ApplicationConfiguration {
                ApplicationName      = opcConfig.ApplicationName,
                ProductUri           = opcConfig.ProductUri,
                ApplicationType      = ApplicationType.Client,
                TransportQuotas      = opcConfig.ToTransportQuotas(),
                CertificateValidator = new CertificateValidator(),
                ClientConfiguration  = new ClientConfiguration(),
                ServerConfiguration  = new ServerConfiguration()
            };

            try {
                await Retry.WithLinearBackoff(null, new CancellationToken(),
                                              async() => {
                    //  try to resolve the hostname
                    var hostname = !string.IsNullOrWhiteSpace(identity?.Gateway) ?
                                   identity.Gateway : !string.IsNullOrWhiteSpace(identity?.DeviceId) ?
                                   identity.DeviceId : Utils.GetHostName();
                    var alternateBaseAddresses = new List <string>();
                    try {
                        alternateBaseAddresses.Add($"urn://{hostname}");
                        var hostEntry = Dns.GetHostEntry(hostname);
                        if (hostEntry != null)
                        {
                            alternateBaseAddresses.Add($"urn://{hostEntry.HostName}");
                            foreach (var alias in hostEntry.Aliases)
                            {
                                alternateBaseAddresses.Add($"urn://{alias}");
                            }
                            foreach (var ip in hostEntry.AddressList)
                            {
                                // only ad IPV4 addresses
                                switch (ip.AddressFamily)
                                {
                                case AddressFamily.InterNetwork:
                                    alternateBaseAddresses.Add($"urn://{ip}");
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                    catch { }

                    applicationConfiguration.ApplicationUri =
                        opcConfig.ApplicationUri.Replace("urn:localhost", $"urn:{hostname}");
                    applicationConfiguration.SecurityConfiguration =
                        opcConfig.ToSecurityConfiguration(hostname);
                    applicationConfiguration.ServerConfiguration.AlternateBaseAddresses =
                        alternateBaseAddresses.ToArray();
                    await applicationConfiguration.Validate(applicationConfiguration.ApplicationType);
                    var application       = new ApplicationInstance(applicationConfiguration);
                    var hasAppCertificate = await application.CheckApplicationInstanceCertificate(true,
                                                                                                  CertificateFactory.DefaultKeySize);
                    if (!hasAppCertificate)
                    {
                        throw new InvalidConfigurationException("OPC UA application certificate invalid");
                    }

                    applicationConfiguration.CertificateValidator.CertificateValidation += handler;
                    await applicationConfiguration.CertificateValidator
                    .Update(applicationConfiguration.SecurityConfiguration);
                },
                                              e => true, 5);
            }
            catch (Exception e) {
                throw new InvalidConfigurationException("OPC UA configuration not valid", e);
            }
            return(applicationConfiguration);
        }
コード例 #8
0
 /// <summary>
 /// Create configuration
 /// </summary>
 /// <param name="application"></param>
 /// <param name="configuration"></param>
 public SecurityConfig(IClientServicesConfig application, IConfiguration configuration) :
     base(configuration)
 {
     _application = application ?? throw new ArgumentNullException(nameof(application));
 }
コード例 #9
0
        /// <summary>
        /// Create application configuration
        /// </summary>
        /// <param name="opcConfig"></param>
        /// <param name="handler"></param>
        /// <param name="createSelfSignedCertIfNone"></param>
        /// <returns></returns>
        public static async Task <ApplicationConfiguration> ToApplicationConfigurationAsync(
            this IClientServicesConfig opcConfig, bool createSelfSignedCertIfNone,
            CertificateValidationEventHandler handler)
        {
            if (string.IsNullOrWhiteSpace(opcConfig.ApplicationName))
            {
                throw new ArgumentNullException(nameof(opcConfig.ApplicationName));
            }

            var applicationConfiguration = new ApplicationConfiguration {
                ApplicationName       = opcConfig.ApplicationName,
                ApplicationUri        = opcConfig.ApplicationUri,
                ProductUri            = opcConfig.ProductUri,
                ApplicationType       = ApplicationType.Client,
                TransportQuotas       = opcConfig.ToTransportQuotas(),
                SecurityConfiguration = opcConfig.ToSecurityConfiguration(),
                ClientConfiguration   = new ClientConfiguration(),
                CertificateValidator  = new CertificateValidator()
            };

            applicationConfiguration.CertificateValidator.CertificateValidation += handler;

            var configuredSubject = applicationConfiguration.SecurityConfiguration
                                    .ApplicationCertificate.SubjectName;

            applicationConfiguration.SecurityConfiguration.ApplicationCertificate.SubjectName =
                applicationConfiguration.ApplicationName;
            await applicationConfiguration.CertificateValidator
            .Update(applicationConfiguration.SecurityConfiguration);

            // use existing certificate, if present
            var certificate = applicationConfiguration.SecurityConfiguration
                              .ApplicationCertificate.Certificate;

            // create a self signed certificate if there is none
            if (certificate == null && createSelfSignedCertIfNone)
            {
                certificate = CertificateFactory.CreateCertificate(
                    applicationConfiguration.SecurityConfiguration
                    .ApplicationCertificate.StoreType,
                    applicationConfiguration.SecurityConfiguration
                    .ApplicationCertificate.StorePath,
                    null,
                    applicationConfiguration.ApplicationUri,
                    applicationConfiguration.ApplicationName,
                    configuredSubject,
                    null,
                    CertificateFactory.defaultKeySize,
                    DateTime.UtcNow - TimeSpan.FromDays(1),
                    CertificateFactory.defaultLifeTime,
                    CertificateFactory.defaultHashSize
                    );

                if (certificate == null)
                {
                    throw new Exception(
                              "OPC UA application certificate can not be created! Cannot continue without it!");
                }

                applicationConfiguration.SecurityConfiguration
                .ApplicationCertificate.Certificate = certificate;
                try {
                    // copy the certificate *public key only* into the trusted certificates list
                    using (ICertificateStore trustedStore = applicationConfiguration
                                                            .SecurityConfiguration.TrustedPeerCertificates.OpenStore()) {
                        using (var publicKey = new X509Certificate2(certificate.RawData)) {
                            trustedStore.Add(publicKey.YieldReturn());
                        }
                    }
                }
                catch { }
                // update security information
                await applicationConfiguration.CertificateValidator.UpdateCertificate(
                    applicationConfiguration.SecurityConfiguration);
            }

            applicationConfiguration.ApplicationUri = Utils.GetApplicationUriFromCertificate(certificate);
            return(applicationConfiguration);
        }
コード例 #10
0
        /// <summary>
        /// Build the opc ua stack application configuration
        /// </summary>
        public static async Task <ApplicationConfiguration> BuildApplicationConfigurationAsync(
            this IClientServicesConfig opcConfig,
            IIdentity identity,
            CertificateValidationEventHandler handler,
            ILogger logger)
        {
            if (string.IsNullOrWhiteSpace(opcConfig.ApplicationName))
            {
                throw new ArgumentNullException(nameof(opcConfig.ApplicationName));
            }

            // wait with the configuration until network is up
            for (var retry = 0; retry < 3; retry++)
            {
                if (NetworkInterface.GetIsNetworkAvailable())
                {
                    break;
                }
                else
                {
                    await Task.Delay(3000);
                }
            }

            var appInstance = new ApplicationInstance {
                ApplicationName = opcConfig.ApplicationName,
                ApplicationType = ApplicationType.Client,
            };

            try {
                await Retry.WithLinearBackoff(null, new CancellationToken(),
                                              async() => {
                    //  try to resolve the hostname
                    var hostname = !string.IsNullOrWhiteSpace(identity?.Gateway)
                            ? identity.Gateway
                            : !string.IsNullOrWhiteSpace(identity?.DeviceId)
                                ? identity.DeviceId
                                : Utils.GetHostName();

                    var appBuilder = appInstance
                                     .Build(
                        opcConfig.ApplicationUri.Replace("urn:localhost", $"urn:{hostname}"),
                        opcConfig.ProductUri)
                                     .SetTransportQuotas(opcConfig.ToTransportQuotas())
                                     .AsClient();

                    var appConfig = await opcConfig
                                    .BuildSecurityConfiguration(
                        appBuilder,
                        appInstance.ApplicationConfiguration,
                        hostname)
                                    .ConfigureAwait(false);

                    appConfig.CertificateValidator.CertificateValidation += handler;
                    var ownCertificate = appConfig.SecurityConfiguration.ApplicationCertificate.Certificate;

                    if (ownCertificate == null)
                    {
                        logger.Information("No application own certificate found. Creating a self-signed " +
                                           "own certificate valid since yesterday for {defaultLifeTime} months, with a " +
                                           "{defaultKeySize} bit key and {defaultHashSize} bit hash.",
                                           CertificateFactory.DefaultLifeTime,
                                           CertificateFactory.DefaultKeySize,
                                           CertificateFactory.DefaultHashSize);
                    }
                    else
                    {
                        logger.Information("Own certificate Subject '{subject}' (thumbprint: {thumbprint}) loaded.",
                                           ownCertificate.Subject, ownCertificate.Thumbprint);
                    }

                    var hasAppCertificate = await appInstance
                                            .CheckApplicationInstanceCertificate(
                        true,
                        CertificateFactory.DefaultKeySize,
                        CertificateFactory.DefaultLifeTime)
                                            .ConfigureAwait(false);

                    if (!hasAppCertificate ||
                        appConfig.SecurityConfiguration.ApplicationCertificate.Certificate == null)
                    {
                        logger.Error("Failed to load or create application own certificate.");
                        throw new InvalidConfigurationException("OPC UA application own certificate invalid");
                    }

                    if (ownCertificate == null)
                    {
                        ownCertificate = appConfig.SecurityConfiguration.ApplicationCertificate.Certificate;
                        logger.Information("Own certificate Subject '{subject}' (thumbprint: {thumbprint}) created.",
                                           ownCertificate.Subject, ownCertificate.Thumbprint);
                    }

                    await ShowCertificateStoreInformationAsync(appConfig, logger)
                    .ConfigureAwait(false);
                },
                                              e => true, 5);
            }
            catch (Exception e) {
                throw new InvalidConfigurationException("OPC UA configuration not valid", e);
            }
            return(appInstance.ApplicationConfiguration);
        }