/* Copyright (c) 1996-2020 The OPC Foundation. All rights reserved. The source code in this file is covered under a dual-license scenario: - RCL: for OPC Foundation members in good-standing - GPL V2: everybody else RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/ GNU General Public License as published by the Free Software Foundation; version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2 This source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Security.Cryptography.X509Certificates; namespace Opc.Ua { #region ApplicationConfiguration /// /// Stores the configurable configuration information for a UA application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ApplicationConfiguration { #region Constructors /// /// The default constructor. /// public ApplicationConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_sourceFilePath = null; m_securityConfiguration = new SecurityConfiguration(); m_transportConfigurations = new TransportConfigurationCollection(); m_disableHiResClock = false; m_properties = new Dictionary(); m_certificateValidator = new CertificateValidator(); } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Public Properties /// /// Gets an object used to synchronize access to the properties dictionary. /// /// /// The object used to synchronize access to the properties dictionary. /// public object PropertiesLock => m_properties; /// /// Gets a dictionary used to save state associated with the application. /// /// /// The dictionary used to save state associated with the application. /// public IDictionary Properties => m_properties; #endregion #region Persistent Properties /// /// A descriptive name for the the application (not necessarily unique). /// /// The name of the application. [DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)] public string ApplicationName { get { return m_applicationName; } set { m_applicationName = value; } } /// /// A unique identifier for the application instance. /// /// The application URI. [DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)] public string ApplicationUri { get { return m_applicationUri; } set { m_applicationUri = value; } } /// /// A unique identifier for the product. /// /// The product URI. [DataMember(IsRequired = false, Order = 2)] public string ProductUri { get { return m_productUri; } set { m_productUri = value; } } /// /// The type of application. /// /// The type of the application. [DataMember(IsRequired = true, Order = 3)] public ApplicationType ApplicationType { get { return m_applicationType; } set { m_applicationType = value; } } /// /// The security configuration for the application. /// /// The security configuration. [DataMember(IsRequired = false, EmitDefaultValue = true, Order = 4)] public SecurityConfiguration SecurityConfiguration { get { return m_securityConfiguration; } set { m_securityConfiguration = value ?? new SecurityConfiguration(); } } /// /// The transport configuration for the application. /// /// The transport configurations. [DataMember(IsRequired = false, EmitDefaultValue = true, Order = 5)] public TransportConfigurationCollection TransportConfigurations { get { return m_transportConfigurations; } set { m_transportConfigurations = value ?? new TransportConfigurationCollection(); } } /// /// The quotas that are used at the transport layer. /// /// The transport quotas. [DataMember(IsRequired = false, EmitDefaultValue = true, Order = 6)] public TransportQuotas TransportQuotas { get { return m_transportQuotas; } set { m_transportQuotas = value; } } /// /// Additional configuration for server applications. /// /// The server configuration. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)] public ServerConfiguration ServerConfiguration { get { return m_serverConfiguration; } set { m_serverConfiguration = value; } } /// /// Additional configuration for client applications. /// /// The client configuration. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)] public ClientConfiguration ClientConfiguration { get { return m_clientConfiguration; } set { m_clientConfiguration = value; } } /// /// Additional configuration of the discovery server. /// /// The discovery server configuration. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)] public DiscoveryServerConfiguration DiscoveryServerConfiguration { get { return m_discoveryServerConfiguration; } set { m_discoveryServerConfiguration = value; } } /// /// A bucket to store additional application specific configuration data. /// /// The extensions. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)] public XmlElementCollection Extensions { get { return m_extensions; } set { m_extensions = value; } } /// /// Configuration of the trace and information about log file /// /// The trace configuration. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)] public TraceConfiguration TraceConfiguration { get { return m_traceConfiguration; } set { m_traceConfiguration = value; } } /// /// Disabling / enabling high resolution clock /// /// true if high resolution clock is disabled; otherwise, false. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)] public bool DisableHiResClock { get { return m_disableHiResClock; } set { m_disableHiResClock = value; } } #endregion #region Private Fields private string m_applicationName; private string m_applicationUri; private string m_productUri; private ApplicationType m_applicationType; private SecurityConfiguration m_securityConfiguration; private TransportConfigurationCollection m_transportConfigurations; private TransportQuotas m_transportQuotas; private ServerConfiguration m_serverConfiguration; private ClientConfiguration m_clientConfiguration; private DiscoveryServerConfiguration m_discoveryServerConfiguration; private TraceConfiguration m_traceConfiguration; private bool m_disableHiResClock; private XmlElementCollection m_extensions; private string m_sourceFilePath; private ServiceMessageContext m_messageContext; private CertificateValidator m_certificateValidator; private Dictionary m_properties; #endregion } #endregion #region TransportQuotas Class /// /// Specifies various limits that apply to the transport or secure channel layers. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class TransportQuotas { #region Constructors /// /// The default constructor. /// public TransportQuotas() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_operationTimeout = 120000; m_maxStringLength = 65535; m_maxByteStringLength = 65535; m_maxArrayLength = 65535; m_maxMessageSize = 1048576; m_maxBufferSize = 65535; m_channelLifetime = 600000; m_securityTokenLifetime = 3600000; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The default timeout to use when sending requests. /// /// The operation timeout. [DataMember(IsRequired = false, Order = 0)] public int OperationTimeout { get { return m_operationTimeout; } set { m_operationTimeout = value; } } /// /// The maximum length of string encoded in a message body. /// /// The max length of the string. [DataMember(IsRequired = false, Order = 1)] public int MaxStringLength { get { return m_maxStringLength; } set { m_maxStringLength = value; } } /// /// The maximum length of a byte string encoded in a message body. /// /// The max length of the byte string. [DataMember(IsRequired = false, Order = 2)] public int MaxByteStringLength { get { return m_maxByteStringLength; } set { m_maxByteStringLength = value; } } /// /// The maximum length of an array encoded in a message body. /// /// The max length of the array. [DataMember(IsRequired = false, Order = 3)] public int MaxArrayLength { get { return m_maxArrayLength; } set { m_maxArrayLength = value; } } /// /// The maximum length of a message body. /// /// The max size of the message. [DataMember(IsRequired = false, Order = 4)] public int MaxMessageSize { get { return m_maxMessageSize; } set { m_maxMessageSize = value; } } /// /// The maximum size of the buffer to use when sending messages. /// /// The max size of the buffer. [DataMember(IsRequired = false, Order = 5)] public int MaxBufferSize { get { return m_maxBufferSize; } set { m_maxBufferSize = value; } } /// /// The lifetime of a secure channel. /// /// The channel lifetime. [DataMember(IsRequired = false, Order = 6)] public int ChannelLifetime { get { return m_channelLifetime; } set { m_channelLifetime = value; } } /// /// The lifetime of a security token. /// /// The security token lifetime. [DataMember(IsRequired = false, Order = 7)] public int SecurityTokenLifetime { get { return m_securityTokenLifetime; } set { m_securityTokenLifetime = value; } } #endregion #region Private Fields private int m_operationTimeout; private int m_maxStringLength; private int m_maxByteStringLength; private int m_maxArrayLength; private int m_maxMessageSize; private int m_maxBufferSize; private int m_channelLifetime; private int m_securityTokenLifetime; #endregion } #endregion #region TraceConfiguration Class /// /// Specifies parameters used for tracing. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class TraceConfiguration { #region Constructors /// /// The default constructor. /// public TraceConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_outputFilePath = null; m_deleteOnLoad = false; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The output file used to log the trace information. /// /// The output file path. [DataMember(IsRequired = false, Order = 0)] public string OutputFilePath { get { return m_outputFilePath; } set { m_outputFilePath = value; } } /// /// Whether the existing log file should be deleted when the application configuration is loaded. /// /// true if existing log file should be deleted when the application configuration is loaded; otherwise, false. [DataMember(IsRequired = false, Order = 1)] public bool DeleteOnLoad { get { return m_deleteOnLoad; } set { m_deleteOnLoad = value; } } /// /// The masks used to select what is written to the output /// Masks supported by the trace feature: /// - Do not output any messages -None = 0x0; /// - Output error messages - Error = 0x1; /// - Output informational messages - Information = 0x2; /// - Output stack traces - StackTrace = 0x4; /// - Output basic messages for service calls - Service = 0x8; /// - Output detailed messages for service calls - ServiceDetail = 0x10; /// - Output basic messages for each operation - Operation = 0x20; /// - Output detailed messages for each operation - OperationDetail = 0x40; /// - Output messages related to application initialization or shutdown - StartStop = 0x80; /// - Output messages related to a call to an external system - ExternalSystem = 0x100; /// - Output messages related to security. - Security = 0x200; /// /// The trace masks. [DataMember(IsRequired = false, Order = 2)] public int TraceMasks { get { return m_traceMasks; } set { m_traceMasks = value; } } #endregion #region Private Fields private string m_outputFilePath; private bool m_deleteOnLoad; private int m_traceMasks; #endregion } #endregion #region TransportConfiguration Class /// /// Specifies the configuration information for a transport protocol /// /// /// Each application is allows to have one transport configure per protocol type. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class TransportConfiguration { #region Constructors /// /// The default constructor. /// public TransportConfiguration() { } /// /// The default constructor. /// /// The URL scheme. /// The type. public TransportConfiguration(string urlScheme, Type type) { m_uriScheme = urlScheme; m_typeName = type.AssemblyQualifiedName; } #endregion #region Persistent Properties /// /// The URL prefix used by the application (http, opc.tcp, net.tpc, etc.). /// /// The URI scheme. [DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)] public string UriScheme { get { return m_uriScheme; } set { m_uriScheme = value; } } /// /// The name of the class that defines the binding for the transport. /// /// The name of the type. /// /// This can be any instance of the System.ServiceModel.Channels.Binding class /// that implements these constructors: /// /// XxxBinding(EndpointDescription description, EndpointConfiguration configuration); /// XxxBinding(IList{EndpointDescription} descriptions, EndpointConfiguration configuration) /// XxxBinding(EndpointConfiguration configuration) /// [DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)] public string TypeName { get { return m_typeName; } set { m_typeName = value; } } #endregion #region Private Fields private string m_uriScheme; private string m_typeName; #endregion } #endregion #region TransportConfigurationCollection Class /// /// A collection of TransportConfiguration objects. /// [CollectionDataContract(Name = "ListOfTransportConfiguration", Namespace = Namespaces.OpcUaConfig, ItemName = "TransportConfiguration")] public partial class TransportConfigurationCollection : List { /// /// Initializes an empty collection. /// public TransportConfigurationCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public TransportConfigurationCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public TransportConfigurationCollection(int capacity) : base(capacity) { } } #endregion #region ServerSecurityPolicy Class /// /// A class that defines a group of sampling rates supported by the server. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ServerSecurityPolicy { #region Constructors /// /// The default constructor. /// public ServerSecurityPolicy() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_securityMode = MessageSecurityMode.SignAndEncrypt; m_securityPolicyUri = SecurityPolicies.Basic256Sha256; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Public Properties /// /// Calculates the security level, given the security mode and policy /// Invalid and none is discouraged /// Just signing is always weaker than any use of encryption /// public static byte CalculateSecurityLevel(MessageSecurityMode mode, string policyUri) { if ((mode == MessageSecurityMode.Invalid) || (mode == MessageSecurityMode.None)) { return 0; } byte result = 0; switch (policyUri) { case SecurityPolicies.Basic128Rsa15: result = 2; break; case SecurityPolicies.Basic256: result = 4; break; case SecurityPolicies.Basic256Sha256: result = 6; break; case SecurityPolicies.Aes128_Sha256_RsaOaep: result = 8; break; case SecurityPolicies.Aes256_Sha256_RsaPss: result = 10; break; case SecurityPolicies.None: default: return 0; } if (mode == MessageSecurityMode.SignAndEncrypt) { result += 100; } return result; } /// /// Specifies whether the messages are signed and encrypted or simply signed /// /// The security mode. [DataMember(IsRequired = false, Order = 1)] public MessageSecurityMode SecurityMode { get { return m_securityMode; } set { m_securityMode = value; } } /// /// The security policy to use. /// /// The security policy URI. [DataMember(IsRequired = false, Order = 2)] public string SecurityPolicyUri { get { return m_securityPolicyUri; } set { m_securityPolicyUri = value; } } #endregion #region Private Members private MessageSecurityMode m_securityMode; private string m_securityPolicyUri; #endregion } #endregion #region ServerSecurityPolicyCollection Class /// /// A collection of ServerSecurityPolicy objects. /// [CollectionDataContract(Name = "ListOfServerSecurityPolicy", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerSecurityPolicy")] public partial class ServerSecurityPolicyCollection : List { /// /// Initializes an empty collection. /// public ServerSecurityPolicyCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public ServerSecurityPolicyCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public ServerSecurityPolicyCollection(int capacity) : base(capacity) { } } #endregion #region SecurityConfiguration Class /// /// The security configuration for the application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class SecurityConfiguration { #region Constructors /// /// The default constructor. /// public SecurityConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_trustedIssuerCertificates = new CertificateTrustList(); m_trustedPeerCertificates = new CertificateTrustList(); m_nonceLength = 32; m_autoAcceptUntrustedCertificates = false; m_rejectSHA1SignedCertificates = true; m_rejectUnknownRevocationStatus = false; m_minCertificateKeySize = CertificateFactory.DefaultKeySize; m_addAppCertToTrustedStore = true; m_sendCertificateChain = false; m_suppressNonceValidationErrors = false; } /// /// Initializes the object during deserialization. /// [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The application instance certificate. /// /// The application certificate. /// /// This certificate must contain the application uri. /// For servers, URLs for each supported protocol must also be present. /// [DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)] public CertificateIdentifier ApplicationCertificate { get { return m_applicationCertificate; } set { m_applicationCertificate = value; } } /// /// The store containing any additional issuer certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] public CertificateTrustList TrustedIssuerCertificates { get { return m_trustedIssuerCertificates; } set { m_trustedIssuerCertificates = value ?? new CertificateTrustList(); } } /// /// The trusted certificate store. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)] public CertificateTrustList TrustedPeerCertificates { get { return m_trustedPeerCertificates; } set { m_trustedPeerCertificates = value ?? new CertificateTrustList(); } } /// /// The length of nonce in the CreateSession service. /// /// /// The length of nonce in the CreateSession service. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)] public int NonceLength { get { return m_nonceLength; } set { m_nonceLength = value; } } /// /// A store where invalid certificates can be placed for later review by the administrator. /// /// /// A store where invalid certificates can be placed for later review by the administrator. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)] public CertificateStoreIdentifier RejectedCertificateStore { get { return m_rejectedCertificateStore; } set { m_rejectedCertificateStore = value; } } /// /// Gets or sets a value indicating whether untrusted certificates should be automatically accepted. /// /// /// This flag can be set to by servers that allow anonymous clients or use user credentials for authentication. /// It can be set by clients that connect to URLs specified in configuration rather than with user entry. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)] public bool AutoAcceptUntrustedCertificates { get { return m_autoAcceptUntrustedCertificates; } set { m_autoAcceptUntrustedCertificates = value; } } /// /// Gets or sets a directory which contains files representing users roles. /// [DataMember(Order = 9)] public string UserRoleDirectory { get { return m_userRoleDirectory; } set { m_userRoleDirectory = value; } } /// /// Gets or sets a value indicating whether SHA-1 signed certificates are accepted. /// /// /// This flag can be set to false by servers that accept SHA-1 signed certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)] public bool RejectSHA1SignedCertificates { get { return m_rejectSHA1SignedCertificates; } set { m_rejectSHA1SignedCertificates = value; } } /// /// Gets or sets a value indicating whether certificates with unavailable revocation lists are not accepted. /// /// /// This flag can be set to true by servers that must have a revocation list for each CA (even if empty). /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)] public bool RejectUnknownRevocationStatus { get { return m_rejectUnknownRevocationStatus; } set { m_rejectUnknownRevocationStatus = value; } } /// /// Gets or sets a value indicating which minimum certificate key strength is accepted. /// /// /// This value can be set to 1024, 2048 or 4096 by servers /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)] public ushort MinimumCertificateKeySize { get { return m_minCertificateKeySize; } set { m_minCertificateKeySize = value; } } /// /// Gets or sets a value indicating whether the application cert should be copied to the trusted store. /// /// /// It is useful for client/server applications running on the same host and sharing the cert store to autotrust. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 13)] public bool AddAppCertToTrustedStore { get { return m_addAppCertToTrustedStore; } set { m_addAppCertToTrustedStore = value; } } /// /// Gets or sets a value indicating whether the application should send the complete certificate chain. /// /// /// If set to true the complete certificate chain will be sent for CA signed certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 14)] public bool SendCertificateChain { get { return m_sendCertificateChain; } set { m_sendCertificateChain = value; } } /// /// The store containing additional user issuer certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 15)] public CertificateTrustList UserIssuerCertificates { get { return m_userIssuerCertificates; } set { m_userIssuerCertificates = value; if (m_userIssuerCertificates == null) { m_userIssuerCertificates = new CertificateTrustList(); } } } /// /// The store containing trusted user certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 16)] public CertificateTrustList TrustedUserCertificates { get { return m_trustedUserCertificates; } set { m_trustedUserCertificates = value; if (m_trustedUserCertificates == null) { m_trustedUserCertificates = new CertificateTrustList(); } } } /// /// The store containing additional Https issuer certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 17)] public CertificateTrustList HttpsIssuerCertificates { get { return m_httpsIssuerCertificates; } set { m_httpsIssuerCertificates = value; if (m_httpsIssuerCertificates == null) { m_httpsIssuerCertificates = new CertificateTrustList(); } } } /// /// The store containing trusted Https certificates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 18)] public CertificateTrustList TrustedHttpsCertificates { get { return m_trustedHttpsCertificates; } set { m_trustedHttpsCertificates = value; if (m_trustedHttpsCertificates == null) { m_trustedHttpsCertificates = new CertificateTrustList(); } } } /// /// Gets or sets a value indicating whether the server nonce validation errors should be suppressed. /// /// /// Allows client interoperability with legacy servers which do not comply with the specification for nonce usage. /// If set to true the server nonce validation errors are suppressed. /// Please set this flag to true only in close and secured networks since it can cause security vulnerabilities. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 19)] public bool SuppressNonceValidationErrors { get { return m_suppressNonceValidationErrors; } set { m_suppressNonceValidationErrors = value; } } #endregion #region Private Fields private CertificateIdentifier m_applicationCertificate; private CertificateTrustList m_trustedIssuerCertificates; private CertificateTrustList m_trustedPeerCertificates; private CertificateTrustList m_httpsIssuerCertificates; private CertificateTrustList m_trustedHttpsCertificates; private CertificateTrustList m_userIssuerCertificates; private CertificateTrustList m_trustedUserCertificates; private int m_nonceLength; private CertificateStoreIdentifier m_rejectedCertificateStore; private bool m_autoAcceptUntrustedCertificates; private string m_userRoleDirectory; private bool m_rejectSHA1SignedCertificates; private bool m_rejectUnknownRevocationStatus; private ushort m_minCertificateKeySize; private bool m_addAppCertToTrustedStore; private bool m_sendCertificateChain; private bool m_suppressNonceValidationErrors; #endregion } #endregion #region SamplingRateGroup Class /// /// A class that defines a group of sampling rates supported by the server. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class SamplingRateGroup { #region Constructors /// /// The default constructor. /// public SamplingRateGroup() { Initialize(); } /// /// Creates a group with the specified settings. /// /// The start. /// The increment. /// The count. public SamplingRateGroup(int start, int increment, int count) { m_start = start; m_increment = increment; m_count = count; } /// /// Sets private members to default values. /// private void Initialize() { m_start = 1000; m_increment = 0; m_count = 0; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Public Properties /// /// The first sampling rate in the group (in milliseconds). /// /// The first sampling rate in the group (in milliseconds). [DataMember(IsRequired = false, Order = 1)] public double Start { get { return m_start; } set { m_start = value; } } /// /// The increment between sampling rates in the group (in milliseconds). /// /// The increment. /// /// An increment of 0 means the group only contains one sampling rate equal to the start. /// [DataMember(IsRequired = false, Order = 2)] public double Increment { get { return m_increment; } set { m_increment = value; } } /// /// The number of sampling rates in the group. /// /// The count. /// /// A count of 0 means there is no limit. /// [DataMember(IsRequired = false, Order = 3)] public int Count { get { return m_count; } set { m_count = value; } } #endregion #region Private Members private double m_start; private double m_increment; private int m_count; #endregion } #endregion #region SamplingRateGroupCollection Class /// /// A collection of SamplingRateGroup objects. /// [CollectionDataContract(Name = "ListOfSamplingRateGroup", Namespace = Namespaces.OpcUaConfig, ItemName = "SamplingRateGroup")] public partial class SamplingRateGroupCollection : List { /// /// Initializes an empty collection. /// public SamplingRateGroupCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public SamplingRateGroupCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public SamplingRateGroupCollection(int capacity) : base(capacity) { } } #endregion #region ServerBaseConfiguration Class /// /// Specifies the configuration for a server application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ServerBaseConfiguration { #region Constructors /// /// The default constructor. /// public ServerBaseConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_baseAddresses = new StringCollection(); m_alternateBaseAddresses = new StringCollection(); m_securityPolicies = new ServerSecurityPolicyCollection(); m_minRequestThreadCount = 10; m_maxRequestThreadCount = 100; m_maxQueuedRequestCount = 200; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); /// /// Remove unsupported security policies and expand wild cards. /// [OnDeserialized()] private void ValidateSecurityPolicyCollection(StreamingContext context) { var supportedPolicies = Opc.Ua.SecurityPolicies.GetDisplayNames(); var newPolicies = new ServerSecurityPolicyCollection(); foreach (var securityPolicy in m_securityPolicies) { if (String.IsNullOrWhiteSpace(securityPolicy.SecurityPolicyUri)) { // add wild card policies foreach (var policyUri in Opc.Ua.SecurityPolicies.GetDefaultUris()) { var newPolicy = new ServerSecurityPolicy() { SecurityMode = securityPolicy.SecurityMode, SecurityPolicyUri = policyUri }; if (newPolicies.Find(s => s.SecurityMode == newPolicy.SecurityMode && String.Compare(s.SecurityPolicyUri, newPolicy.SecurityPolicyUri) == 0 ) == null) { newPolicies.Add(newPolicy); } } } else { for (int i = 0; i < supportedPolicies.Length; i++) { if (securityPolicy.SecurityPolicyUri.Contains(supportedPolicies[i])) { if (newPolicies.Find(s => s.SecurityMode == securityPolicy.SecurityMode && String.Compare(s.SecurityPolicyUri, securityPolicy.SecurityPolicyUri) == 0 ) == null) { newPolicies.Add(securityPolicy); } break; } } } } m_securityPolicies = newPolicies; } #endregion #region Persistent Properties /// /// The base addresses for the server. /// /// The base addresses. /// /// The actually endpoints are constructed from the security policies. /// On one base address per supported transport protocol is allowed. /// [DataMember(IsRequired = false, Order = 0)] public StringCollection BaseAddresses { get { return m_baseAddresses; } set { m_baseAddresses = value; if (m_baseAddresses == null) { m_baseAddresses = new StringCollection(); } } } /// /// Gets or sets the alternate base addresses. /// /// The alternate base addresses. /// /// These addresses are used to specify alternate paths to ther via firewalls, proxies /// or similar network infrastructure. If these paths are specified in the configuration /// file then the server will use the domain of the URL used by the client to determine /// which, if any, or the alternate addresses to use instead of the primary addresses. /// [DataMember(IsRequired = false, Order = 1)] public StringCollection AlternateBaseAddresses { get { return m_alternateBaseAddresses; } set { m_alternateBaseAddresses = value; if (m_alternateBaseAddresses == null) { m_alternateBaseAddresses = new StringCollection(); } } } /// /// The security policies supported by the server. /// /// The security policies. /// /// An endpoint description is created for each combination of base address and security policy. /// [DataMember(IsRequired = false, Order = 2)] public ServerSecurityPolicyCollection SecurityPolicies { get { return m_securityPolicies; } set { m_securityPolicies = value; if (m_securityPolicies == null) { m_securityPolicies = new ServerSecurityPolicyCollection(); } } } /// /// Gets or sets the minimum number of threads assigned to processing requests. /// /// The minimum request thread count. [DataMember(IsRequired = false, Order = 3)] public int MinRequestThreadCount { get { return m_minRequestThreadCount; } set { m_minRequestThreadCount = value; } } /// /// Gets or sets the maximum number of threads assigned to processing requests. /// /// The maximum request thread count. [DataMember(IsRequired = false, Order = 4)] public int MaxRequestThreadCount { get { return m_maxRequestThreadCount; } set { m_maxRequestThreadCount = value; } } /// /// Gets or sets the maximum number of requests that will be queued waiting for a thread. /// /// The maximum queued request count. [DataMember(IsRequired = false, Order = 5)] public int MaxQueuedRequestCount { get { return m_maxQueuedRequestCount; } set { m_maxQueuedRequestCount = value; } } #endregion #region Private Members private StringCollection m_baseAddresses; private StringCollection m_alternateBaseAddresses; private ServerSecurityPolicyCollection m_securityPolicies; private int m_minRequestThreadCount; private int m_maxRequestThreadCount; private int m_maxQueuedRequestCount; #endregion } #endregion #region ServerConfiguration Class /// /// Specifies the configuration for a server application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ServerConfiguration : ServerBaseConfiguration { #region Constructors /// /// The default constructor. /// public ServerConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_userTokenPolicies = new UserTokenPolicyCollection(); m_diagnosticsEnabled = false; m_maxSessionCount = 100; m_maxSessionTimeout = 3600000; m_minSessionTimeout = 10000; m_maxBrowseContinuationPoints = 10; m_maxQueryContinuationPoints = 10; m_maxHistoryContinuationPoints = 100; m_maxRequestAge = 600000; m_minPublishingInterval = 100; m_maxPublishingInterval = 3600000; m_publishingResolution = 100; m_minSubscriptionLifetime = 10000; m_maxSubscriptionLifetime = 3600000; m_maxMessageQueueSize = 10; m_maxNotificationQueueSize = 100; m_maxNotificationsPerPublish = 100; m_minMetadataSamplingInterval = 1000; m_availableSamplingRates = new SamplingRateGroupCollection(); m_registrationEndpoint = null; m_maxRegistrationInterval = 30000; m_maxPublishRequestCount = 20; m_maxSubscriptionCount = 100; m_maxEventQueueSize = 10000; // see https://opcfoundation-onlineapplications.org/profilereporting/ for list of available profiles m_serverProfileArray = new string[] { "http://opcfoundation.org/UA-Profile/Server/StandardUA2017" }; m_shutdownDelay = 5; m_serverCapabilities = new string[] { "DA" }; m_supportedPrivateKeyFormats = new string[] { }; m_maxTrustListSize = 0; m_multicastDnsEnabled = false; } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public new void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The user tokens accepted by the server. /// /// The user token policies. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)] public UserTokenPolicyCollection UserTokenPolicies { get { return m_userTokenPolicies; } set { m_userTokenPolicies = value; if (m_userTokenPolicies == null) { m_userTokenPolicies = new UserTokenPolicyCollection(); } } } /// /// Whether diagnostics are enabled. /// /// true if diagnostic is enabled; otherwise, false. [DataMember(IsRequired = false, Order = 4)] public bool DiagnosticsEnabled { get { return m_diagnosticsEnabled; } set { m_diagnosticsEnabled = value; } } /// /// The maximum number of open sessions. /// /// The maximum session count. [DataMember(IsRequired = false, Order = 5)] public int MaxSessionCount { get { return m_maxSessionCount; } set { m_maxSessionCount = value; } } /// /// That minimum period of that a session is allowed to remain open without communication from the client (in milliseconds). /// /// The minimum session timeout. [DataMember(IsRequired = false, Order = 6)] public int MinSessionTimeout { get { return m_minSessionTimeout; } set { m_minSessionTimeout = value; } } /// /// That maximum period of that a session is allowed to remain open without communication from the client (in milliseconds). /// /// The maximum session timeout. [DataMember(IsRequired = false, Order = 7)] public int MaxSessionTimeout { get { return m_maxSessionTimeout; } set { m_maxSessionTimeout = value; } } /// /// The maximum number of continuation points used for Browse/BrowseNext operations. /// /// The maximum number of continuation points used for Browse/BrowseNext operations [DataMember(IsRequired = false, Order = 8)] public int MaxBrowseContinuationPoints { get { return m_maxBrowseContinuationPoints; } set { m_maxBrowseContinuationPoints = value; } } /// /// The maximum number of continuation points used for Query/QueryNext operations. /// /// The maximum number of query continuation points. [DataMember(IsRequired = false, Order = 9)] public int MaxQueryContinuationPoints { get { return m_maxQueryContinuationPoints; } set { m_maxQueryContinuationPoints = value; } } /// /// The maximum number of continuation points used for HistoryRead operations. /// /// The maximum number of history continuation points. [DataMember(IsRequired = false, Order = 10)] public int MaxHistoryContinuationPoints { get { return m_maxHistoryContinuationPoints; } set { m_maxHistoryContinuationPoints = value; } } /// /// The maximum age of an incoming request (old requests are rejected). /// /// The maximum age of an incoming request. [DataMember(IsRequired = false, Order = 11)] public int MaxRequestAge { get { return m_maxRequestAge; } set { m_maxRequestAge = value; } } /// /// The minimum publishing interval supported by the server (in milliseconds). /// /// The minimum publishing interval. [DataMember(IsRequired = false, Order = 12)] public int MinPublishingInterval { get { return m_minPublishingInterval; } set { m_minPublishingInterval = value; } } /// /// The maximum publishing interval supported by the server (in milliseconds). /// /// The maximum publishing interval. [DataMember(IsRequired = false, Order = 13)] public int MaxPublishingInterval { get { return m_maxPublishingInterval; } set { m_maxPublishingInterval = value; } } /// /// The minimum difference between supported publishing interval (in milliseconds). /// /// The publishing resolution. [DataMember(IsRequired = false, Order = 14)] public int PublishingResolution { get { return m_publishingResolution; } set { m_publishingResolution = value; } } /// /// How long the subscriptions will remain open without a publish from the client. /// /// The maximum subscription lifetime. [DataMember(IsRequired = false, Order = 15)] public int MaxSubscriptionLifetime { get { return m_maxSubscriptionLifetime; } set { m_maxSubscriptionLifetime = value; } } /// /// The maximum number of messages saved in the queue for each subscription. /// /// The maximum size of the message queue. [DataMember(IsRequired = false, Order = 16)] public int MaxMessageQueueSize { get { return m_maxMessageQueueSize; } set { m_maxMessageQueueSize = value; } } /// /// The maximum number of notificates saved in the queue for each monitored item. /// /// The maximum size of the notification queue. [DataMember(IsRequired = false, Order = 17)] public int MaxNotificationQueueSize { get { return m_maxNotificationQueueSize; } set { m_maxNotificationQueueSize = value; } } /// /// The maximum number of notifications per publish. /// /// The maximum number of notifications per publish. [DataMember(IsRequired = false, Order = 18)] public int MaxNotificationsPerPublish { get { return m_maxNotificationsPerPublish; } set { m_maxNotificationsPerPublish = value; } } /// /// The minimum sampling interval for metadata. /// /// The minimum sampling interval for metadata. [DataMember(IsRequired = false, Order = 19)] public int MinMetadataSamplingInterval { get { return m_minMetadataSamplingInterval; } set { m_minMetadataSamplingInterval = value; } } /// /// The available sampling rates. /// /// The available sampling rates. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 20)] public SamplingRateGroupCollection AvailableSamplingRates { get { return m_availableSamplingRates; } set { m_availableSamplingRates = value; } } /// /// The endpoint description for the registration endpoint. /// /// The registration endpoint. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 21)] public EndpointDescription RegistrationEndpoint { get { return m_registrationEndpoint; } set { m_registrationEndpoint = value; } } /// /// The maximum time between registration attempts (in milliseconds). /// /// The maximum time between registration attempts (in milliseconds). [DataMember(IsRequired = false, Order = 22)] public int MaxRegistrationInterval { get { return m_maxRegistrationInterval; } set { m_maxRegistrationInterval = value; } } /// /// The path to the file containing nodes persisted by the core node manager. /// /// The path to the file containing nodes persisted by the core node manager. [DataMember(IsRequired = false, Order = 23)] public string NodeManagerSaveFile { get { return m_nodeManagerSaveFile; } set { m_nodeManagerSaveFile = value; } } /// /// The minimum lifetime for a subscription. /// /// The minimum lifetime for a subscription. [DataMember(IsRequired = false, Order = 24)] public int MinSubscriptionLifetime { get { return m_minSubscriptionLifetime; } set { m_minSubscriptionLifetime = value; } } /// /// Gets or sets the max publish request count. /// /// The max publish request count. [DataMember(IsRequired = false, Order = 25)] public int MaxPublishRequestCount { get { return m_maxPublishRequestCount; } set { m_maxPublishRequestCount = value; } } /// /// Gets or sets the max subscription count. /// /// The max subscription count. [DataMember(IsRequired = false, Order = 26)] public int MaxSubscriptionCount { get { return m_maxSubscriptionCount; } set { m_maxSubscriptionCount = value; } } /// /// Gets or sets the max size of the event queue. /// /// The max size of the event queue. [DataMember(IsRequired = false, Order = 27)] public int MaxEventQueueSize { get { return m_maxEventQueueSize; } set { m_maxEventQueueSize = value; } } /// /// Gets or sets the server profile array. /// /// The array of server profiles. [DataMember(IsRequired = false, Order = 28)] public StringCollection ServerProfileArray { get { return m_serverProfileArray; } set { m_serverProfileArray = value; if (m_serverProfileArray == null) { m_serverProfileArray = new StringCollection(); } } } /// /// Gets or sets the server shutdown delay. /// /// The array of server profiles. [DataMember(IsRequired = false, Order = 29)] public int ShutdownDelay { get { return m_shutdownDelay; } set { m_shutdownDelay = value; } } /// /// Gets or sets the server capabilities. /// /// The array of server profiles. [DataMember(IsRequired = false, Order = 30)] public StringCollection ServerCapabilities { get { return m_serverCapabilities; } set { m_serverCapabilities = value; if (m_serverCapabilities == null) { m_serverCapabilities = new StringCollection(); } } } /// /// Gets or sets the supported private key format. /// /// The array of server profiles. [DataMember(IsRequired = false, Order = 31)] public StringCollection SupportedPrivateKeyFormats { get { return m_supportedPrivateKeyFormats; } set { m_supportedPrivateKeyFormats = value; if (m_supportedPrivateKeyFormats == null) { m_supportedPrivateKeyFormats = new StringCollection(); } } } /// /// Gets or sets the max size of the trust list. /// [DataMember(IsRequired = false, Order = 32)] public int MaxTrustListSize { get { return m_maxTrustListSize; } set { m_maxTrustListSize = value; } } /// /// Gets or sets if multicast DNS is enabled. /// [DataMember(IsRequired = false, Order = 33)] public bool MultiCastDnsEnabled { get { return m_multicastDnsEnabled; } set { m_multicastDnsEnabled = value; } } /// /// Gets or sets reverse connect server configuration. /// [DataMember(IsRequired = false, Order = 34)] public ReverseConnectServerConfiguration ReverseConnect { get { return m_reverseConnect; } set { m_reverseConnect = value; } } #endregion #region Private Members private UserTokenPolicyCollection m_userTokenPolicies; private bool m_diagnosticsEnabled; private int m_maxSessionCount; private int m_minSessionTimeout; private int m_maxSessionTimeout; private int m_maxBrowseContinuationPoints; private int m_maxQueryContinuationPoints; private int m_maxHistoryContinuationPoints; private int m_maxRequestAge; private int m_minPublishingInterval; private int m_maxPublishingInterval; private int m_publishingResolution; private int m_minSubscriptionLifetime; private int m_maxSubscriptionLifetime; private int m_maxMessageQueueSize; private int m_maxNotificationQueueSize; private int m_maxNotificationsPerPublish; private int m_minMetadataSamplingInterval; private SamplingRateGroupCollection m_availableSamplingRates; private EndpointDescription m_registrationEndpoint; private int m_maxRegistrationInterval; private string m_nodeManagerSaveFile; private int m_maxPublishRequestCount; private int m_maxSubscriptionCount; private int m_maxEventQueueSize; private StringCollection m_serverProfileArray; private int m_shutdownDelay; private StringCollection m_serverCapabilities; private StringCollection m_supportedPrivateKeyFormats; private int m_maxTrustListSize; private bool m_multicastDnsEnabled; private ReverseConnectServerConfiguration m_reverseConnect; #endregion } #endregion #region ReverseConnectServerConfiguration Class /// /// Stores the configuration of the reverse connections. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ReverseConnectServerConfiguration { #region Constructors /// /// The default constructor. /// public ReverseConnectServerConfiguration() { Initialize(); } /// /// Initializes the object during deserialization. /// [OnDeserializing] private void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { } #endregion #region Public Properties /// /// A collection of reverse connect clients. /// [DataMember(Order = 10)] public ReverseConnectClientCollection Clients { get; set; } /// /// The interval after which a new reverse connection is attempted. /// [DataMember(Order = 20)] public int ConnectInterval { get; set; } = 15000; /// /// The default timeout to wait for a response to a reverse connection. /// [DataMember(Order = 30)] public int ConnectTimeout { get; set; } = 30000; /// /// The timeout to wait to establish a new reverse /// connection after a rejected attempt. /// [DataMember(Order = 40)] public int RejectTimeout { get; set; } = 60000; #endregion } #endregion #region ReverseConnectClient Class /// /// Stores the configuration of the reverse connections. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ReverseConnectClient { #region Constructors /// /// The default constructor. /// public ReverseConnectClient() { Initialize(); } /// /// Initializes the object during deserialization. /// [OnDeserializing] private void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { Enabled = true; } #endregion #region Persistent Properties /// /// The endpoint Url of the reverse connect client endpoint. /// [DataMember(Order = 10)] public string EndpointUrl { get; set; } /// /// The timeout to wait for a response to a reverse connection. /// Overrides the default reverse connection setting. /// [DataMember(Order = 20)] public int Timeout { get; set; } /// /// The maximum count of active reverse connect sessions. /// 0 or undefined means unlimited number of sessions. /// 1 means a single connection is created at a time. /// n disables reverse hello once the total number of sessions /// in the server reaches n. /// [DataMember(Order = 30)] public int MaxSessionCount { get; set; } /// /// Specifies whether the sending of reverse connect attempts is enabled. /// [DataMember(Order = 40)] public bool Enabled { get; set; } = true; #endregion } #endregion #region ReverseConnectClientCollection Class /// /// A collection of reverse connect clients. /// [CollectionDataContract(Name = "ListOfReverseConnectClient", Namespace = Namespaces.OpcUaConfig, ItemName = "ReverseConnectClient")] public class ReverseConnectClientCollection : List { #region Constructors /// /// Initializes an empty collection. /// public ReverseConnectClientCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public ReverseConnectClientCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public ReverseConnectClientCollection(int capacity) : base(capacity) { } #endregion } #endregion #region ClientConfiguration Class /// /// The configuration for a client application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ClientConfiguration { #region Constructors /// /// The default constructor. /// public ClientConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_defaultSessionTimeout = 60000; m_minSubscriptionLifetime = 10000; m_wellKnownDiscoveryUrls = new StringCollection(); m_discoveryServers = new EndpointDescriptionCollection(); } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The default session timeout. /// /// The default session timeout. [DataMember(IsRequired = false, Order = 0)] public int DefaultSessionTimeout { get { return m_defaultSessionTimeout; } set { m_defaultSessionTimeout = value; } } /// /// The well known URLs for the local discovery servers. /// /// The well known discovery URLs. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)] public StringCollection WellKnownDiscoveryUrls { get { return m_wellKnownDiscoveryUrls; } set { m_wellKnownDiscoveryUrls = value; if (m_wellKnownDiscoveryUrls == null) { m_wellKnownDiscoveryUrls = new StringCollection(); } } } /// /// The endpoint descriptions for central discovery servers. /// /// The endpoint descriptions for central discovery servers. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] public EndpointDescriptionCollection DiscoveryServers { get { return m_discoveryServers; } set { m_discoveryServers = value; if (m_discoveryServers == null) { m_discoveryServers = new EndpointDescriptionCollection(); } } } /// /// The path to the file containing the cached endpoints. /// /// The path to the file containing the cached endpoints. [DataMember(IsRequired = false, Order = 3)] public string EndpointCacheFilePath { get { return m_endpointCacheFilePath; } set { m_endpointCacheFilePath = value; } } /// /// The minimum lifetime for a subscription. /// /// The minimum lifetime for a subscription. [DataMember(IsRequired = false, Order = 4)] public int MinSubscriptionLifetime { get { return m_minSubscriptionLifetime; } set { m_minSubscriptionLifetime = value; } } /// /// Gets or sets reverse connect Client configuration. /// [DataMember(IsRequired = false, Order = 5)] public ReverseConnectClientConfiguration ReverseConnect { get { return m_reverseConnect; } set { m_reverseConnect = value; } } #endregion #region Private Members private StringCollection m_wellKnownDiscoveryUrls; private EndpointDescriptionCollection m_discoveryServers; private int m_defaultSessionTimeout; private string m_endpointCacheFilePath; private int m_minSubscriptionLifetime; private ReverseConnectClientConfiguration m_reverseConnect; #endregion } #endregion #region ReverseConnectClientConfiguration Class /// /// Stores the configuration of the reverse connections. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ReverseConnectClientConfiguration { #region Constructors /// /// The default constructor. /// public ReverseConnectClientConfiguration() { Initialize(); } /// /// Initializes the object during deserialization. /// [OnDeserializing] private void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { } #endregion #region Public Properties /// /// A collection of reverse connect client endpoints. /// [DataMember(Order = 10, IsRequired = false)] public ReverseConnectClientEndpointCollection ClientEndpoints { get; set; } /// /// The time a reverse hello port is held open to wait for a /// reverse connection until the request is rejected. /// [DataMember(Order = 20, IsRequired = false)] public int HoldTime { get; set; } = 15000; /// /// The timeout to wait for a reverse hello message. /// [DataMember(Order = 30, IsRequired = false)] public int WaitTimeout { get; set; } = 20000; #endregion } #endregion #region ReverseConnectClientEndpoint Class /// /// Stores the configuration of the reverse connections. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ReverseConnectClientEndpoint { #region Constructors /// /// The default constructor. /// public ReverseConnectClientEndpoint() { Initialize(); } /// /// Initializes the object during deserialization. /// [OnDeserializing] private void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { } #endregion #region Persistent Properties /// /// The endpoint Url of a reverse connect client. /// [DataMember(Order = 1, IsRequired = false)] public string EndpointUrl { get; set; } #endregion } #endregion #region ReverseConnectClientEndpointCollection Class /// /// A collection of reverse connect client endpoints. /// [CollectionDataContract(Name = "ListOfReverseConnectClientEndpoint", Namespace = Namespaces.OpcUaConfig, ItemName = "ClientEndpoint")] public class ReverseConnectClientEndpointCollection : List { #region Constructors /// /// Initializes an empty collection. /// public ReverseConnectClientEndpointCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public ReverseConnectClientEndpointCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public ReverseConnectClientEndpointCollection(int capacity) : base(capacity) { } #endregion } #endregion #region DiscoveryServerConfiguration Class /// /// Specifies the configuration for a discovery server application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class DiscoveryServerConfiguration : ServerBaseConfiguration { #region Constructors /// /// The default constructor. /// public DiscoveryServerConfiguration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_serverNames = new LocalizedTextCollection(); m_serverRegistrations = new ServerRegistrationCollection(); } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public new void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The localized names for the discovery server. /// /// The server names. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] public LocalizedTextCollection ServerNames { get { return m_serverNames; } set { m_serverNames = value; if (m_serverNames == null) { m_serverNames = new LocalizedTextCollection(); } } } /// /// The path to the file containing servers saved by the discovery server. /// /// The discovery server cache file. [DataMember(IsRequired = false, Order = 3)] public string DiscoveryServerCacheFile { get { return m_discoveryServerCacheFile; } set { m_discoveryServerCacheFile = value; } } /// /// Gets or sets the server registrations associated with the discovery server. /// /// The server registrations. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)] public ServerRegistrationCollection ServerRegistrations { get { return m_serverRegistrations; } set { m_serverRegistrations = value; } } #endregion #region Private Members private LocalizedTextCollection m_serverNames; private string m_discoveryServerCacheFile; private ServerRegistrationCollection m_serverRegistrations; #endregion } #endregion #region ServerRegistration Class /// /// Specifies the configuration for a discovery server application. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public class ServerRegistration { #region Constructors /// /// The default constructor. /// public ServerRegistration() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() { m_applicationUri = null; m_alternateDiscoveryUrls = new StringCollection(); } /// /// Initializes the object during deserialization. /// /// The context. [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// Gets or sets the application URI of the server which the registration applies to. /// /// The application uri. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)] public string ApplicationUri { get { return m_applicationUri; } set { m_applicationUri = value; } } /// /// Gets or sets the alternate discovery urls. /// /// The alternate discovery urls. /// /// These addresses are used to specify alternate paths to ther via firewalls, proxies /// or similar network infrastructure. If these paths are specified in the configuration /// file then the server will use the domain of the URL used by the client to determine /// which, if any, or the alternate addresses to use instead of the primary addresses. /// /// In the ideal world the server would provide these URLs during registration but this /// table allows the administrator to provide the information to the disovery server /// directly without requiring a patch to the server. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] public StringCollection AlternateDiscoveryUrls { get { return m_alternateDiscoveryUrls; } set { m_alternateDiscoveryUrls = value; if (m_alternateDiscoveryUrls == null) { m_alternateDiscoveryUrls = new StringCollection(); } } } #endregion #region Private Members private string m_applicationUri; private StringCollection m_alternateDiscoveryUrls; #endregion } #endregion #region ServerRegistrationCollection Class /// /// A collection of AdditionalServerRegistrationInfo objects. /// [CollectionDataContract(Name = "ListOfServerRegistration", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerRegistration")] public partial class ServerRegistrationCollection : List { /// /// Initializes an empty collection. /// public ServerRegistrationCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection /// /// is null. /// public ServerRegistrationCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// /// The capacity. public ServerRegistrationCollection(int capacity) : base(capacity) { } } #endregion #region CertificateStoreIdentifier Class /// /// Describes a certificate store. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateStoreIdentifier { #region Persistent Properties /// /// The type of certificate store. /// /// /// If the StoreName is not empty, the CertificateStoreType.X509Store is returned, otherwise the StoreType is returned. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 0)] public string StoreType { get { if (!String.IsNullOrEmpty(m_storeName)) { return CertificateStoreType.X509Store; } return m_storeType; } set { m_storeType = value; } } /// /// The path that identifies the certificate store. /// /// /// If the StoreName is not empty and the StoreLocation is empty, the Utils.Format("LocalMachine\\{0}", m_storeName) is returned. /// If the StoreName is not empty and the StoreLocation is not empty, the Utils.Format("{1}\\{0}", m_storeName, m_storeLocation) is returned. /// If the StoreName is empty, the m_storePath is returned. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)] public string StorePath { get { if (!String.IsNullOrEmpty(m_storeName)) { if (String.IsNullOrEmpty(m_storeLocation)) { return Utils.Format("CurrentUser\\{0}", m_storeName); } return Utils.Format("{1}\\{0}", m_storeName, m_storeLocation); } return m_storePath; } set { m_storePath = value; if (!String.IsNullOrEmpty(m_storePath)) { if (String.IsNullOrEmpty(m_storeType)) { if (m_storePath.StartsWith("LocalMachine", StringComparison.CurrentCultureIgnoreCase) || m_storePath.StartsWith("CurrentUser", StringComparison.CurrentCultureIgnoreCase)) { m_storeType = CertificateStoreType.X509Store; } else { m_storeType = CertificateStoreType.Directory; } } } } } /// /// The name of the certifcate store that contains the trusted certficates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] [Obsolete("Use StoreType/StorePath instead")] public string StoreName { get { return m_storeName; } set { m_storeName = value; } } /// /// The location of the certifcate store that contains the trusted certficates. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)] [Obsolete("Use StoreType/StorePath instead")] public string StoreLocation { get { return m_storeLocation; } set { m_storeLocation = value; } } /// /// Options that can be used to suppress certificate validation errors. /// [DataMember(Name = "ValidationOptions", IsRequired = false, EmitDefaultValue = false, Order = 4)] private int XmlEncodedValidationOptions { get { return (int)m_validationOptions; } set { m_validationOptions = (CertificateValidationOptions)value; } } #endregion #region Private Fields private string m_storeType; private string m_storePath; private string m_storeLocation; private string m_storeName; private CertificateValidationOptions m_validationOptions; #endregion } #endregion #region CertificateTrustList Class [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateTrustList : CertificateStoreIdentifier { #region Constructors /// /// The default constructor. /// public CertificateTrustList() { Initialize(); } /// /// Sets private members to default values. /// private void Initialize() => m_trustedCertificates = new CertificateIdentifierCollection(); /// /// Initializes the object during deserialization. /// [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Persistent Properties /// /// The list of trusted certificates. /// /// /// The list of trusted certificates is set when TrustedCertificates is not a null value, otherwise new CertificateIdentifierCollection is set. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)] public CertificateIdentifierCollection TrustedCertificates { get { return m_trustedCertificates; } set { m_trustedCertificates = value; if (m_trustedCertificates == null) { m_trustedCertificates = new CertificateIdentifierCollection(); } } } #endregion #region Private Fields private CertificateIdentifierCollection m_trustedCertificates; #endregion } #endregion #region CertificateIdentifierCollection Class [CollectionDataContract(Name = "ListOfCertificateIdentifier", Namespace = Namespaces.OpcUaConfig, ItemName = "CertificateIdentifier")] public partial class CertificateIdentifierCollection : List { /// /// Initializes an empty collection. /// public CertificateIdentifierCollection() { } /// /// Initializes the collection from another collection. /// /// A collection of values to add to this new collection public CertificateIdentifierCollection(IEnumerable collection) : base(collection) { } /// /// Initializes the collection with the specified capacity. /// public CertificateIdentifierCollection(int capacity) : base(capacity) { } } #endregion #region CertificateIdentifier Class [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class CertificateIdentifier { #region Constructors /// /// The default constructor. /// public CertificateIdentifier() { Initialize(); } /// /// Initializes the identifier with the raw data from a certificate. /// public CertificateIdentifier(X509Certificate2 certificate) { Initialize(); m_certificate = certificate; } /// /// Initializes the identifier with the raw data from a certificate. /// public CertificateIdentifier(X509Certificate2 certificate, CertificateValidationOptions validationOptions) { Initialize(); m_certificate = certificate; m_validationOptions = validationOptions; } /// /// Initializes the identifier with the raw data from a certificate. /// public CertificateIdentifier(byte[] rawData) { Initialize(); m_certificate = CertificateFactory.Create(rawData, true); } /// /// Sets private members to default values. /// private void Initialize() { } /// /// Initializes the object during deserialization. /// [OnDeserializing()] public void Initialize(StreamingContext context) => Initialize(); #endregion #region Public Properties /// /// The type of certificate store. /// /// The type of the store - defined in the . [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 0)] public string StoreType { get { if (!String.IsNullOrEmpty(m_storeName)) { return CertificateStoreType.X509Store; } return m_storeType; } set { m_storeType = value; } } /// /// The path that identifies the certificate store. /// /// The store path in the form StoreName\\Store Location . [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)] public string StorePath { get { if (!String.IsNullOrEmpty(m_storeName)) { if (String.IsNullOrEmpty(m_storeLocation)) { return Utils.Format("LocalMachine\\{0}", m_storeName); } return Utils.Format("{1}\\{0}", m_storeName, m_storeLocation); } return m_storePath; } set { m_storePath = value; if (!String.IsNullOrEmpty(m_storePath)) { if (String.IsNullOrEmpty(m_storeType)) { if (m_storePath.StartsWith("LocalMachine", StringComparison.CurrentCultureIgnoreCase) || m_storePath.StartsWith("CurrentUser", StringComparison.CurrentCultureIgnoreCase)) { m_storeType = CertificateStoreType.X509Store; } else { m_storeType = CertificateStoreType.Directory; } } } } } /// /// The name of the store that contains the certificate. /// /// The name of the store. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)] [Obsolete("Use StoreType/StorePath instead")] public string StoreName { get { return m_storeName; } set { m_storeName = value; } } /// /// The location of the store that contains the certificate. /// /// The store location. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)] [Obsolete("Use StoreType/StorePath instead")] public string StoreLocation { get { return m_storeLocation; } set { m_storeLocation = value; } } /// /// The certificate's subject name - the distinguished name of an X509 certificate. /// /// /// The distinguished name of an X509 certificate acording to the Abstract Syntax Notation One (ASN.1) syntax. /// /// The subject field identifies the entity associated with the public key stored in the subject public /// key field. The subject name MAY be carried in the subject field and/or the subjectAltName extension. /// Where it is non-empty, the subject field MUST contain an X.500 distinguished name (DN). /// Name is defined by the following ASN.1 structures: /// Name ::= CHOICE {RDNSequence } /// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName /// RelativeDistinguishedName ::= SET OF AttributeTypeAndValue /// AttributeTypeAndValue ::= SEQUENCE {type AttributeType, value AttributeValue } /// AttributeType ::= OBJECT IDENTIFIER /// AttributeValue ::= ANY DEFINED BY AttributeType /// DirectoryString ::= CHOICE { /// teletexString TeletexString (SIZE (1..MAX)), /// printableString PrintableString (SIZE (1..MAX)), /// universalString UniversalString (SIZE (1..MAX)), /// utf8String UTF8String (SIZE (1..MAX)), /// bmpString BMPString (SIZE (1..MAX)) } /// The Name describes a hierarchical name composed of attributes, such as country name, and /// corresponding values, such as US. The type of the component AttributeValue is determined by /// the AttributeType; in general it will be a DirectoryString. /// String X.500 AttributeType: /// /// CN commonName /// L localityName /// ST stateOrProvinceName /// O organizationName /// OU organizationalUnitName /// C countryName /// STREET streetAddress /// DC domainComponent /// UID userid /// /// This notation is designed to be convenient for common forms of name. This section gives a few /// examples of distinguished names written using this notation. First is a name containing three relative /// distinguished names (RDNs): /// CN=Steve Kille,O=Isode Limited,C=GB /// /// RFC 3280 Internet X.509 Public Key Infrastructure, April 2002 /// RFC 2253 LADPv3 Distinguished Names, December 1997 /// /// /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)] public string SubjectName { get { if (m_certificate == null) { return m_subjectName; } return m_certificate.Subject; } set { if (m_certificate != null && !String.IsNullOrEmpty(value)) { if (m_certificate.Subject != value) { throw new ArgumentException("SubjectName does not match the SubjectName of the current certificate."); } } m_subjectName = value; } } /// /// The certificate's thumbprint. /// /// The thumbprint of a certificate.. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 5)] public string Thumbprint { get { if (m_certificate == null) { return m_thumbprint; } return m_certificate.Thumbprint; } set { if (m_certificate != null) { if (!String.IsNullOrEmpty(value) && m_certificate.Thumbprint != value) { throw new ArgumentException("Thumbprint does not match the thumbprint of the current certificate."); } } m_thumbprint = value; } } /// /// Gets the DER encoded certificate data or create emebeded in this instance certifcate using the DER encoded certificate data. /// /// A byte array containing the X.509 certificate data. [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)] public byte[] RawData { get { if (m_certificate == null) { return null; } return m_certificate.RawData; } set { if (value == null || value.Length == 0) { m_certificate = null; return; } m_certificate = CertificateFactory.Create(value, true); m_subjectName = m_certificate.Subject; m_thumbprint = m_certificate.Thumbprint; } } /// /// Gets or sets the XML encoded validation options - use to serialize the validation options. /// /// The XML encoded validation options. [DataMember(Name = "ValidationOptions", IsRequired = false, EmitDefaultValue = false, Order = 7)] private int XmlEncodedValidationOptions { get { return (int)m_validationOptions; } set { m_validationOptions = (CertificateValidationOptions)value; } } #endregion #region Private Fields private string m_storeType; private string m_storePath; private string m_storeLocation; private string m_storeName; private string m_subjectName; private string m_thumbprint; private X509Certificate2 m_certificate; private CertificateValidationOptions m_validationOptions; #endregion } #endregion #region ConfiguredEndpointCollection Class /// /// Stores a list of cached enpoints. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ConfiguredEndpointCollection { #region Constructors /// /// The default constructor. /// public ConfiguredEndpointCollection() { Initialize(); } /// /// Called by the .NET framework during deserialization. /// [OnDeserializing] public void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { m_knownHosts = new StringCollection(); m_discoveryUrls = new StringCollection(Utils.DiscoveryUrls); m_endpoints = new List(); m_defaultConfiguration = EndpointConfiguration.Create(); } #endregion #region Public Properties /// /// A list of known hosts that can be used for discovery. /// [DataMember(Name = "KnownHosts", IsRequired = false, Order = 1)] public StringCollection KnownHosts { get { return m_knownHosts; } set { if (value == null) { m_knownHosts = new StringCollection(); } else { m_knownHosts = value; } } } /// /// The default configuration to use when connecting to an endpoint. /// [DataMember(Name = "Endpoints", IsRequired = false, Order = 2)] public List Endpoints { get { return m_endpoints; } private set { if (value == null) { m_endpoints = new List(); } else { m_endpoints = value; } foreach (ConfiguredEndpoint endpoint in m_endpoints) { endpoint.Collection = this; } } } /// /// The URL of the UA TCP proxy server. /// [DataMember(Name = "TcpProxyUrl", EmitDefaultValue = false, Order = 3)] public Uri TcpProxyUrl { get { return m_tcpProxyUrl; } set { m_tcpProxyUrl = value; } } #endregion #region Private Fields private string m_filepath; private StringCollection m_knownHosts; private StringCollection m_discoveryUrls; private EndpointConfiguration m_defaultConfiguration; private List m_endpoints; private Uri m_tcpProxyUrl; #endregion } #endregion #region ConfiguredEndpoint Class /// /// Stores the configuration information for an endpoint. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] [KnownType(typeof(UserNameIdentityToken))] [KnownType(typeof(X509IdentityToken))] [KnownType(typeof(IssuedIdentityToken))] public partial class ConfiguredEndpoint { #region Constructors /// /// The default constructor. /// public ConfiguredEndpoint() { Initialize(); } /// /// Called by the .NET framework during deserialization. /// [OnDeserializing] public void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { m_collection = null; m_description = new EndpointDescription(); m_configuration = null; m_updateBeforeConnect = true; m_binaryEncodingSupport = BinaryEncodingSupport.Optional; m_selectedUserTokenPolicyIndex = 0; m_userIdentity = null; m_reverseConnect = null; } #endregion #region Public Properties /// /// The description for the endpoint. /// [DataMember(Name = "Endpoint", Order = 1, IsRequired = true)] public EndpointDescription Description { get { return m_description; } private set { if (value == null) { m_description = new EndpointDescription(); } else { m_description = value; } } } /// /// The configuration to use when connecting to an endpoint. /// [DataMember(Name = "Configuration", Order = 2, IsRequired = false)] public EndpointConfiguration Configuration { get { return m_configuration; } set { m_configuration = value; // copy default configuration if not already set. if (m_configuration == null) { if (m_collection != null) { Update(m_collection.DefaultConfiguration); } else { Update(EndpointConfiguration.Create()); } } } } /// /// Whether the endpoint information should be updated before connecting to the server. /// [DataMember(Name = "UpdateBeforeConnect", Order = 3, IsRequired = false)] public bool UpdateBeforeConnect { get { return m_updateBeforeConnect; } set { m_updateBeforeConnect = value; } } /// /// The user identity to use when connecting to the endpoint. /// [DataMember(Name = "BinaryEncodingSupport", Order = 4, IsRequired = false)] public BinaryEncodingSupport BinaryEncodingSupport { get { return m_binaryEncodingSupport; } set { m_binaryEncodingSupport = value; } } /// /// The user identity to use when connecting to the endpoint. /// [DataMember(Name = "SelectedUserTokenPolicy", Order = 5, IsRequired = false)] public int SelectedUserTokenPolicyIndex { get { return m_selectedUserTokenPolicyIndex; } set { m_selectedUserTokenPolicyIndex = value; } } /// /// The user identity to use when connecting to the endpoint. /// [DataMember(Name = "UserIdentity", Order = 6, IsRequired = false)] public UserIdentityToken UserIdentity { get { return m_userIdentity; } set { m_userIdentity = value; } } /// /// The reverse connect information. /// [DataMember(Name = "ReverseConnect", Order = 8, IsRequired = false)] public ReverseConnectEndpoint ReverseConnect { get { return m_reverseConnect; } set { m_reverseConnect = value; } } /// /// A bucket to store additional application specific configuration data. /// [DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)] public XmlElementCollection Extensions { get { return m_extensions; } set { m_extensions = value; } } #endregion #region Private Fields private ConfiguredEndpointCollection m_collection; private EndpointDescription m_description; private EndpointConfiguration m_configuration; private bool m_updateBeforeConnect; private BinaryEncodingSupport m_binaryEncodingSupport; private int m_selectedUserTokenPolicyIndex; private UserIdentityToken m_userIdentity; private ReverseConnectEndpoint m_reverseConnect; private XmlElementCollection m_extensions; #endregion } #endregion #region BinaryEncodingSupport Enumeration /// /// The type of binary encoding support allowed by a channel. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public enum BinaryEncodingSupport { /// /// The UA binary encoding may be used. /// [EnumMember()] Optional, /// /// The UA binary encoding must be used. /// [EnumMember()] Required, /// /// The UA binary encoding may not be used. /// [EnumMember()] None } #endregion #region ReverseConnectEndpoint Class /// /// Stores the reverse connect information for an endpoint. /// [DataContract(Namespace = Namespaces.OpcUaConfig)] public partial class ReverseConnectEndpoint { #region Constructors /// /// The default constructor. /// public ReverseConnectEndpoint() { Initialize(); } /// /// Called by the .NET framework during deserialization. /// [OnDeserializing] public void Initialize(StreamingContext context) => Initialize(); /// /// Sets private members to default values. /// private void Initialize() { m_enabled = false; m_serverUri = null; m_thumbprint = null; } #endregion #region Public Properties /// /// Whether reverse connect is enabled for the endpoint. /// [DataMember(Name = "Enabled", Order = 1, IsRequired = false)] public bool Enabled { get { return m_enabled; } set { m_enabled = value; } } /// /// The server Uri of the endpoint. /// [DataMember(Name = "ServerUri", Order = 2, IsRequired = false)] public string ServerUri { get { return m_serverUri; } set { m_serverUri = value; } } /// /// The thumbprint of the certificate which contains /// the server Uri. /// [DataMember(Name = "Thumbprint", Order = 3, IsRequired = false)] public string Thumbprint { get { return m_thumbprint; } set { m_thumbprint = value; } } #endregion #region Private Fields private bool m_enabled; private string m_serverUri; private string m_thumbprint; #endregion } #endregion }