Files
Mapo-IOB-WIN/IOB-OPC-UA/Stack/Opc.Ua.Core/Schema/ApplicationConfiguration.cs
T
2021-03-25 18:25:25 +01:00

3396 lines
115 KiB
C#

/* 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
/// <summary>
/// Stores the configurable configuration information for a UA application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ApplicationConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ApplicationConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_sourceFilePath = null;
m_securityConfiguration = new SecurityConfiguration();
m_transportConfigurations = new TransportConfigurationCollection();
m_disableHiResClock = false;
m_properties = new Dictionary<string, object>();
m_certificateValidator = new CertificateValidator();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Public Properties
/// <summary>
/// Gets an object used to synchronize access to the properties dictionary.
/// </summary>
/// <value>
/// The object used to synchronize access to the properties dictionary.
/// </value>
public object PropertiesLock => m_properties;
/// <summary>
/// Gets a dictionary used to save state associated with the application.
/// </summary>
/// <value>
/// The dictionary used to save state associated with the application.
/// </value>
public IDictionary<string, object> Properties => m_properties;
#endregion
#region Persistent Properties
/// <summary>
/// A descriptive name for the the application (not necessarily unique).
/// </summary>
/// <value>The name of the application.</value>
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
public string ApplicationName
{
get { return m_applicationName; }
set { m_applicationName = value; }
}
/// <summary>
/// A unique identifier for the application instance.
/// </summary>
/// <value>The application URI.</value>
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 1)]
public string ApplicationUri
{
get { return m_applicationUri; }
set { m_applicationUri = value; }
}
/// <summary>
/// A unique identifier for the product.
/// </summary>
/// <value>The product URI.</value>
[DataMember(IsRequired = false, Order = 2)]
public string ProductUri
{
get { return m_productUri; }
set { m_productUri = value; }
}
/// <summary>
/// The type of application.
/// </summary>
/// <value>The type of the application.</value>
[DataMember(IsRequired = true, Order = 3)]
public ApplicationType ApplicationType
{
get { return m_applicationType; }
set { m_applicationType = value; }
}
/// <summary>
/// The security configuration for the application.
/// </summary>
/// <value>The security configuration.</value>
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 4)]
public SecurityConfiguration SecurityConfiguration
{
get
{
return m_securityConfiguration;
}
set
{
m_securityConfiguration = value ?? new SecurityConfiguration();
}
}
/// <summary>
/// The transport configuration for the application.
/// </summary>
/// <value>The transport configurations.</value>
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 5)]
public TransportConfigurationCollection TransportConfigurations
{
get
{
return m_transportConfigurations;
}
set
{
m_transportConfigurations = value ?? new TransportConfigurationCollection();
}
}
/// <summary>
/// The quotas that are used at the transport layer.
/// </summary>
/// <value>The transport quotas.</value>
[DataMember(IsRequired = false, EmitDefaultValue = true, Order = 6)]
public TransportQuotas TransportQuotas
{
get { return m_transportQuotas; }
set { m_transportQuotas = value; }
}
/// <summary>
/// Additional configuration for server applications.
/// </summary>
/// <value>The server configuration.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
public ServerConfiguration ServerConfiguration
{
get { return m_serverConfiguration; }
set { m_serverConfiguration = value; }
}
/// <summary>
/// Additional configuration for client applications.
/// </summary>
/// <value>The client configuration.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
public ClientConfiguration ClientConfiguration
{
get { return m_clientConfiguration; }
set { m_clientConfiguration = value; }
}
/// <summary>
/// Additional configuration of the discovery server.
/// </summary>
/// <value>The discovery server configuration.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 9)]
public DiscoveryServerConfiguration DiscoveryServerConfiguration
{
get { return m_discoveryServerConfiguration; }
set { m_discoveryServerConfiguration = value; }
}
/// <summary>
/// A bucket to store additional application specific configuration data.
/// </summary>
/// <value>The extensions.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
public XmlElementCollection Extensions
{
get { return m_extensions; }
set { m_extensions = value; }
}
/// <summary>
/// Configuration of the trace and information about log file
/// </summary>
/// <value>The trace configuration.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
public TraceConfiguration TraceConfiguration
{
get { return m_traceConfiguration; }
set { m_traceConfiguration = value; }
}
/// <summary>
/// Disabling / enabling high resolution clock
/// </summary>
/// <value><c>true</c> if high resolution clock is disabled; otherwise, <c>false</c>.</value>
[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<string, object> m_properties;
#endregion
}
#endregion
#region TransportQuotas Class
/// <summary>
/// Specifies various limits that apply to the transport or secure channel layers.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class TransportQuotas
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public TransportQuotas()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
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;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The default timeout to use when sending requests.
/// </summary>
/// <value>The operation timeout.</value>
[DataMember(IsRequired = false, Order = 0)]
public int OperationTimeout
{
get { return m_operationTimeout; }
set { m_operationTimeout = value; }
}
/// <summary>
/// The maximum length of string encoded in a message body.
/// </summary>
/// <value>The max length of the string.</value>
[DataMember(IsRequired = false, Order = 1)]
public int MaxStringLength
{
get { return m_maxStringLength; }
set { m_maxStringLength = value; }
}
/// <summary>
/// The maximum length of a byte string encoded in a message body.
/// </summary>
/// <value>The max length of the byte string.</value>
[DataMember(IsRequired = false, Order = 2)]
public int MaxByteStringLength
{
get { return m_maxByteStringLength; }
set { m_maxByteStringLength = value; }
}
/// <summary>
/// The maximum length of an array encoded in a message body.
/// </summary>
/// <value>The max length of the array.</value>
[DataMember(IsRequired = false, Order = 3)]
public int MaxArrayLength
{
get { return m_maxArrayLength; }
set { m_maxArrayLength = value; }
}
/// <summary>
/// The maximum length of a message body.
/// </summary>
/// <value>The max size of the message.</value>
[DataMember(IsRequired = false, Order = 4)]
public int MaxMessageSize
{
get { return m_maxMessageSize; }
set { m_maxMessageSize = value; }
}
/// <summary>
/// The maximum size of the buffer to use when sending messages.
/// </summary>
/// <value>The max size of the buffer.</value>
[DataMember(IsRequired = false, Order = 5)]
public int MaxBufferSize
{
get { return m_maxBufferSize; }
set { m_maxBufferSize = value; }
}
/// <summary>
/// The lifetime of a secure channel.
/// </summary>
/// <value>The channel lifetime.</value>
[DataMember(IsRequired = false, Order = 6)]
public int ChannelLifetime
{
get { return m_channelLifetime; }
set { m_channelLifetime = value; }
}
/// <summary>
/// The lifetime of a security token.
/// </summary>
/// <value>The security token lifetime.</value>
[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
/// <summary>
/// Specifies parameters used for tracing.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class TraceConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public TraceConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_outputFilePath = null;
m_deleteOnLoad = false;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The output file used to log the trace information.
/// </summary>
/// <value>The output file path.</value>
[DataMember(IsRequired = false, Order = 0)]
public string OutputFilePath
{
get { return m_outputFilePath; }
set { m_outputFilePath = value; }
}
/// <summary>
/// Whether the existing log file should be deleted when the application configuration is loaded.
/// </summary>
/// <value><c>true</c> if existing log file should be deleted when the application configuration is loaded; otherwise, <c>false</c>.</value>
[DataMember(IsRequired = false, Order = 1)]
public bool DeleteOnLoad
{
get { return m_deleteOnLoad; }
set { m_deleteOnLoad = value; }
}
/// <summary>
/// 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;
/// </summary>
/// <value>The trace masks.</value>
[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
/// <summary>
/// Specifies the configuration information for a transport protocol
/// </summary>
/// <remarks>
/// Each application is allows to have one transport configure per protocol type.
/// </remarks>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class TransportConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public TransportConfiguration()
{
}
/// <summary>
/// The default constructor.
/// </summary>
/// <param name="urlScheme">The URL scheme.</param>
/// <param name="type">The type.</param>
public TransportConfiguration(string urlScheme, Type type)
{
m_uriScheme = urlScheme;
m_typeName = type.AssemblyQualifiedName;
}
#endregion
#region Persistent Properties
/// <summary>
/// The URL prefix used by the application (http, opc.tcp, net.tpc, etc.).
/// </summary>
/// <value>The URI scheme.</value>
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
public string UriScheme
{
get { return m_uriScheme; }
set { m_uriScheme = value; }
}
/// <summary>
/// The name of the class that defines the binding for the transport.
/// </summary>
/// <value>The name of the type.</value>
/// <remarks>
/// 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)
/// </remarks>
[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
/// <summary>
/// A collection of TransportConfiguration objects.
/// </summary>
[CollectionDataContract(Name = "ListOfTransportConfiguration", Namespace = Namespaces.OpcUaConfig, ItemName = "TransportConfiguration")]
public partial class TransportConfigurationCollection : List<TransportConfiguration>
{
/// <summary>
/// Initializes an empty collection.
/// </summary>
public TransportConfigurationCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public TransportConfigurationCollection(IEnumerable<TransportConfiguration> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public TransportConfigurationCollection(int capacity) : base(capacity) { }
}
#endregion
#region ServerSecurityPolicy Class
/// <summary>
/// A class that defines a group of sampling rates supported by the server.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ServerSecurityPolicy
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ServerSecurityPolicy()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_securityMode = MessageSecurityMode.SignAndEncrypt;
m_securityPolicyUri = SecurityPolicies.Basic256Sha256;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Public Properties
/// <summary>
/// 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
/// </summary>
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;
}
/// <summary>
/// Specifies whether the messages are signed and encrypted or simply signed
/// </summary>
/// <value>The security mode.</value>
[DataMember(IsRequired = false, Order = 1)]
public MessageSecurityMode SecurityMode
{
get { return m_securityMode; }
set { m_securityMode = value; }
}
/// <summary>
/// The security policy to use.
/// </summary>
/// <value>The security policy URI.</value>
[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
/// <summary>
/// A collection of ServerSecurityPolicy objects.
/// </summary>
[CollectionDataContract(Name = "ListOfServerSecurityPolicy", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerSecurityPolicy")]
public partial class ServerSecurityPolicyCollection : List<ServerSecurityPolicy>
{
/// <summary>
/// Initializes an empty collection.
/// </summary>
public ServerSecurityPolicyCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public ServerSecurityPolicyCollection(IEnumerable<ServerSecurityPolicy> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public ServerSecurityPolicyCollection(int capacity) : base(capacity) { }
}
#endregion
#region SecurityConfiguration Class
/// <summary>
/// The security configuration for the application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class SecurityConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public SecurityConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
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;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The application instance certificate.
/// </summary>
/// <value>The application certificate.</value>
/// <remarks>
/// This certificate must contain the application uri.
/// For servers, URLs for each supported protocol must also be present.
/// </remarks>
[DataMember(IsRequired = true, EmitDefaultValue = false, Order = 0)]
public CertificateIdentifier ApplicationCertificate
{
get { return m_applicationCertificate; }
set { m_applicationCertificate = value; }
}
/// <summary>
/// The store containing any additional issuer certificates.
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
public CertificateTrustList TrustedIssuerCertificates
{
get
{
return m_trustedIssuerCertificates;
}
set
{
m_trustedIssuerCertificates = value ?? new CertificateTrustList();
}
}
/// <summary>
/// The trusted certificate store.
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 4)]
public CertificateTrustList TrustedPeerCertificates
{
get
{
return m_trustedPeerCertificates;
}
set
{
m_trustedPeerCertificates = value ?? new CertificateTrustList();
}
}
/// <summary>
/// The length of nonce in the CreateSession service.
/// </summary>
/// <value>
/// The length of nonce in the CreateSession service.
/// </value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 6)]
public int NonceLength
{
get { return m_nonceLength; }
set { m_nonceLength = value; }
}
/// <summary>
/// A store where invalid certificates can be placed for later review by the administrator.
/// </summary>
/// <value>
/// A store where invalid certificates can be placed for later review by the administrator.
/// </value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 7)]
public CertificateStoreIdentifier RejectedCertificateStore
{
get { return m_rejectedCertificateStore; }
set { m_rejectedCertificateStore = value; }
}
/// <summary>
/// Gets or sets a value indicating whether untrusted certificates should be automatically accepted.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 8)]
public bool AutoAcceptUntrustedCertificates
{
get { return m_autoAcceptUntrustedCertificates; }
set { m_autoAcceptUntrustedCertificates = value; }
}
/// <summary>
/// Gets or sets a directory which contains files representing users roles.
/// </summary>
[DataMember(Order = 9)]
public string UserRoleDirectory
{
get { return m_userRoleDirectory; }
set { m_userRoleDirectory = value; }
}
/// <summary>
/// Gets or sets a value indicating whether SHA-1 signed certificates are accepted.
/// </summary>
/// <remarks>
/// This flag can be set to false by servers that accept SHA-1 signed certificates.
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 10)]
public bool RejectSHA1SignedCertificates
{
get { return m_rejectSHA1SignedCertificates; }
set { m_rejectSHA1SignedCertificates = value; }
}
/// <summary>
/// Gets or sets a value indicating whether certificates with unavailable revocation lists are not accepted.
/// </summary>
/// <remarks>
/// This flag can be set to true by servers that must have a revocation list for each CA (even if empty).
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 11)]
public bool RejectUnknownRevocationStatus
{
get { return m_rejectUnknownRevocationStatus; }
set { m_rejectUnknownRevocationStatus = value; }
}
/// <summary>
/// Gets or sets a value indicating which minimum certificate key strength is accepted.
/// </summary>
/// <remarks>
/// This value can be set to 1024, 2048 or 4096 by servers
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 12)]
public ushort MinimumCertificateKeySize
{
get { return m_minCertificateKeySize; }
set { m_minCertificateKeySize = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the application cert should be copied to the trusted store.
/// </summary>
/// <remarks>
/// It is useful for client/server applications running on the same host and sharing the cert store to autotrust.
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 13)]
public bool AddAppCertToTrustedStore
{
get { return m_addAppCertToTrustedStore; }
set { m_addAppCertToTrustedStore = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the application should send the complete certificate chain.
/// </summary>
/// <remarks>
/// If set to true the complete certificate chain will be sent for CA signed certificates.
/// </remarks>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 14)]
public bool SendCertificateChain
{
get { return m_sendCertificateChain; }
set { m_sendCertificateChain = value; }
}
/// <summary>
/// The store containing additional user issuer certificates.
/// </summary>
[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();
}
}
}
/// <summary>
/// The store containing trusted user certificates.
/// </summary>
[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();
}
}
}
/// <summary>
/// The store containing additional Https issuer certificates.
/// </summary>
[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();
}
}
}
/// <summary>
/// The store containing trusted Https certificates.
/// </summary>
[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();
}
}
}
/// <summary>
/// Gets or sets a value indicating whether the server nonce validation errors should be suppressed.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[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
/// <summary>
/// A class that defines a group of sampling rates supported by the server.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class SamplingRateGroup
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public SamplingRateGroup()
{
Initialize();
}
/// <summary>
/// Creates a group with the specified settings.
/// </summary>
/// <param name="start">The start.</param>
/// <param name="increment">The increment.</param>
/// <param name="count">The count.</param>
public SamplingRateGroup(int start, int increment, int count)
{
m_start = start;
m_increment = increment;
m_count = count;
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_start = 1000;
m_increment = 0;
m_count = 0;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Public Properties
/// <summary>
/// The first sampling rate in the group (in milliseconds).
/// </summary>
/// <value>The first sampling rate in the group (in milliseconds).</value>
[DataMember(IsRequired = false, Order = 1)]
public double Start
{
get { return m_start; }
set { m_start = value; }
}
/// <summary>
/// The increment between sampling rates in the group (in milliseconds).
/// </summary>
/// <value>The increment.</value>
/// <remarks>
/// An increment of 0 means the group only contains one sampling rate equal to the start.
/// </remarks>
[DataMember(IsRequired = false, Order = 2)]
public double Increment
{
get { return m_increment; }
set { m_increment = value; }
}
/// <summary>
/// The number of sampling rates in the group.
/// </summary>
/// <value>The count.</value>
/// <remarks>
/// A count of 0 means there is no limit.
/// </remarks>
[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
/// <summary>
/// A collection of SamplingRateGroup objects.
/// </summary>
[CollectionDataContract(Name = "ListOfSamplingRateGroup", Namespace = Namespaces.OpcUaConfig, ItemName = "SamplingRateGroup")]
public partial class SamplingRateGroupCollection : List<SamplingRateGroup>
{
/// <summary>
/// Initializes an empty collection.
/// </summary>
public SamplingRateGroupCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public SamplingRateGroupCollection(IEnumerable<SamplingRateGroup> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public SamplingRateGroupCollection(int capacity) : base(capacity) { }
}
#endregion
#region ServerBaseConfiguration Class
/// <summary>
/// Specifies the configuration for a server application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ServerBaseConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ServerBaseConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_baseAddresses = new StringCollection();
m_alternateBaseAddresses = new StringCollection();
m_securityPolicies = new ServerSecurityPolicyCollection();
m_minRequestThreadCount = 10;
m_maxRequestThreadCount = 100;
m_maxQueuedRequestCount = 200;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Remove unsupported security policies and expand wild cards.
/// </summary>
[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
/// <summary>
/// The base addresses for the server.
/// </summary>
/// <value>The base addresses.</value>
/// <remarks>
/// The actually endpoints are constructed from the security policies.
/// On one base address per supported transport protocol is allowed.
/// </remarks>
[DataMember(IsRequired = false, Order = 0)]
public StringCollection BaseAddresses
{
get
{
return m_baseAddresses;
}
set
{
m_baseAddresses = value;
if (m_baseAddresses == null)
{
m_baseAddresses = new StringCollection();
}
}
}
/// <summary>
/// Gets or sets the alternate base addresses.
/// </summary>
/// <value>The alternate base addresses.</value>
/// <remarks>
/// 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.
/// </remarks>
[DataMember(IsRequired = false, Order = 1)]
public StringCollection AlternateBaseAddresses
{
get
{
return m_alternateBaseAddresses;
}
set
{
m_alternateBaseAddresses = value;
if (m_alternateBaseAddresses == null)
{
m_alternateBaseAddresses = new StringCollection();
}
}
}
/// <summary>
/// The security policies supported by the server.
/// </summary>
/// <value>The security policies.</value>
/// <remarks>
/// An endpoint description is created for each combination of base address and security policy.
/// </remarks>
[DataMember(IsRequired = false, Order = 2)]
public ServerSecurityPolicyCollection SecurityPolicies
{
get
{
return m_securityPolicies;
}
set
{
m_securityPolicies = value;
if (m_securityPolicies == null)
{
m_securityPolicies = new ServerSecurityPolicyCollection();
}
}
}
/// <summary>
/// Gets or sets the minimum number of threads assigned to processing requests.
/// </summary>
/// <value>The minimum request thread count.</value>
[DataMember(IsRequired = false, Order = 3)]
public int MinRequestThreadCount
{
get { return m_minRequestThreadCount; }
set { m_minRequestThreadCount = value; }
}
/// <summary>
/// Gets or sets the maximum number of threads assigned to processing requests.
/// </summary>
/// <value>The maximum request thread count.</value>
[DataMember(IsRequired = false, Order = 4)]
public int MaxRequestThreadCount
{
get { return m_maxRequestThreadCount; }
set { m_maxRequestThreadCount = value; }
}
/// <summary>
/// Gets or sets the maximum number of requests that will be queued waiting for a thread.
/// </summary>
/// <value>The maximum queued request count.</value>
[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
/// <summary>
/// Specifies the configuration for a server application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ServerConfiguration : ServerBaseConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ServerConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
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;
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public new void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The user tokens accepted by the server.
/// </summary>
/// <value>The user token policies.</value>
[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();
}
}
}
/// <summary>
/// Whether diagnostics are enabled.
/// </summary>
/// <value><c>true</c> if diagnostic is enabled; otherwise, <c>false</c>.</value>
[DataMember(IsRequired = false, Order = 4)]
public bool DiagnosticsEnabled
{
get { return m_diagnosticsEnabled; }
set { m_diagnosticsEnabled = value; }
}
/// <summary>
/// The maximum number of open sessions.
/// </summary>
/// <value>The maximum session count.</value>
[DataMember(IsRequired = false, Order = 5)]
public int MaxSessionCount
{
get { return m_maxSessionCount; }
set { m_maxSessionCount = value; }
}
/// <summary>
/// That minimum period of that a session is allowed to remain open without communication from the client (in milliseconds).
/// </summary>
/// <value>The minimum session timeout.</value>
[DataMember(IsRequired = false, Order = 6)]
public int MinSessionTimeout
{
get { return m_minSessionTimeout; }
set { m_minSessionTimeout = value; }
}
/// <summary>
/// That maximum period of that a session is allowed to remain open without communication from the client (in milliseconds).
/// </summary>
/// <value>The maximum session timeout.</value>
[DataMember(IsRequired = false, Order = 7)]
public int MaxSessionTimeout
{
get { return m_maxSessionTimeout; }
set { m_maxSessionTimeout = value; }
}
/// <summary>
/// The maximum number of continuation points used for Browse/BrowseNext operations.
/// </summary>
/// <value>The maximum number of continuation points used for Browse/BrowseNext operations</value>
[DataMember(IsRequired = false, Order = 8)]
public int MaxBrowseContinuationPoints
{
get { return m_maxBrowseContinuationPoints; }
set { m_maxBrowseContinuationPoints = value; }
}
/// <summary>
/// The maximum number of continuation points used for Query/QueryNext operations.
/// </summary>
/// <value>The maximum number of query continuation points.</value>
[DataMember(IsRequired = false, Order = 9)]
public int MaxQueryContinuationPoints
{
get { return m_maxQueryContinuationPoints; }
set { m_maxQueryContinuationPoints = value; }
}
/// <summary>
/// The maximum number of continuation points used for HistoryRead operations.
/// </summary>
/// <value>The maximum number of history continuation points.</value>
[DataMember(IsRequired = false, Order = 10)]
public int MaxHistoryContinuationPoints
{
get { return m_maxHistoryContinuationPoints; }
set { m_maxHistoryContinuationPoints = value; }
}
/// <summary>
/// The maximum age of an incoming request (old requests are rejected).
/// </summary>
/// <value>The maximum age of an incoming request.</value>
[DataMember(IsRequired = false, Order = 11)]
public int MaxRequestAge
{
get { return m_maxRequestAge; }
set { m_maxRequestAge = value; }
}
/// <summary>
/// The minimum publishing interval supported by the server (in milliseconds).
/// </summary>
/// <value>The minimum publishing interval.</value>
[DataMember(IsRequired = false, Order = 12)]
public int MinPublishingInterval
{
get { return m_minPublishingInterval; }
set { m_minPublishingInterval = value; }
}
/// <summary>
/// The maximum publishing interval supported by the server (in milliseconds).
/// </summary>
/// <value>The maximum publishing interval.</value>
[DataMember(IsRequired = false, Order = 13)]
public int MaxPublishingInterval
{
get { return m_maxPublishingInterval; }
set { m_maxPublishingInterval = value; }
}
/// <summary>
/// The minimum difference between supported publishing interval (in milliseconds).
/// </summary>
/// <value>The publishing resolution.</value>
[DataMember(IsRequired = false, Order = 14)]
public int PublishingResolution
{
get { return m_publishingResolution; }
set { m_publishingResolution = value; }
}
/// <summary>
/// How long the subscriptions will remain open without a publish from the client.
/// </summary>
/// <value>The maximum subscription lifetime.</value>
[DataMember(IsRequired = false, Order = 15)]
public int MaxSubscriptionLifetime
{
get { return m_maxSubscriptionLifetime; }
set { m_maxSubscriptionLifetime = value; }
}
/// <summary>
/// The maximum number of messages saved in the queue for each subscription.
/// </summary>
/// <value>The maximum size of the message queue.</value>
[DataMember(IsRequired = false, Order = 16)]
public int MaxMessageQueueSize
{
get { return m_maxMessageQueueSize; }
set { m_maxMessageQueueSize = value; }
}
/// <summary>
/// The maximum number of notificates saved in the queue for each monitored item.
/// </summary>
/// <value>The maximum size of the notification queue.</value>
[DataMember(IsRequired = false, Order = 17)]
public int MaxNotificationQueueSize
{
get { return m_maxNotificationQueueSize; }
set { m_maxNotificationQueueSize = value; }
}
/// <summary>
/// The maximum number of notifications per publish.
/// </summary>
/// <value>The maximum number of notifications per publish.</value>
[DataMember(IsRequired = false, Order = 18)]
public int MaxNotificationsPerPublish
{
get { return m_maxNotificationsPerPublish; }
set { m_maxNotificationsPerPublish = value; }
}
/// <summary>
/// The minimum sampling interval for metadata.
/// </summary>
/// <value>The minimum sampling interval for metadata.</value>
[DataMember(IsRequired = false, Order = 19)]
public int MinMetadataSamplingInterval
{
get { return m_minMetadataSamplingInterval; }
set { m_minMetadataSamplingInterval = value; }
}
/// <summary>
/// The available sampling rates.
/// </summary>
/// <value>The available sampling rates.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 20)]
public SamplingRateGroupCollection AvailableSamplingRates
{
get { return m_availableSamplingRates; }
set { m_availableSamplingRates = value; }
}
/// <summary>
/// The endpoint description for the registration endpoint.
/// </summary>
/// <value>The registration endpoint.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 21)]
public EndpointDescription RegistrationEndpoint
{
get { return m_registrationEndpoint; }
set { m_registrationEndpoint = value; }
}
/// <summary>
/// The maximum time between registration attempts (in milliseconds).
/// </summary>
/// <value>The maximum time between registration attempts (in milliseconds).</value>
[DataMember(IsRequired = false, Order = 22)]
public int MaxRegistrationInterval
{
get { return m_maxRegistrationInterval; }
set { m_maxRegistrationInterval = value; }
}
/// <summary>
/// The path to the file containing nodes persisted by the core node manager.
/// </summary>
/// <value>The path to the file containing nodes persisted by the core node manager.</value>
[DataMember(IsRequired = false, Order = 23)]
public string NodeManagerSaveFile
{
get { return m_nodeManagerSaveFile; }
set { m_nodeManagerSaveFile = value; }
}
/// <summary>
/// The minimum lifetime for a subscription.
/// </summary>
/// <value>The minimum lifetime for a subscription.</value>
[DataMember(IsRequired = false, Order = 24)]
public int MinSubscriptionLifetime
{
get { return m_minSubscriptionLifetime; }
set { m_minSubscriptionLifetime = value; }
}
/// <summary>
/// Gets or sets the max publish request count.
/// </summary>
/// <value>The max publish request count.</value>
[DataMember(IsRequired = false, Order = 25)]
public int MaxPublishRequestCount
{
get { return m_maxPublishRequestCount; }
set { m_maxPublishRequestCount = value; }
}
/// <summary>
/// Gets or sets the max subscription count.
/// </summary>
/// <value>The max subscription count.</value>
[DataMember(IsRequired = false, Order = 26)]
public int MaxSubscriptionCount
{
get { return m_maxSubscriptionCount; }
set { m_maxSubscriptionCount = value; }
}
/// <summary>
/// Gets or sets the max size of the event queue.
/// </summary>
/// <value>The max size of the event queue.</value>
[DataMember(IsRequired = false, Order = 27)]
public int MaxEventQueueSize
{
get { return m_maxEventQueueSize; }
set { m_maxEventQueueSize = value; }
}
/// <summary>
/// Gets or sets the server profile array.
/// </summary>
/// <value>The array of server profiles.</value>
[DataMember(IsRequired = false, Order = 28)]
public StringCollection ServerProfileArray
{
get { return m_serverProfileArray; }
set
{
m_serverProfileArray = value;
if (m_serverProfileArray == null)
{
m_serverProfileArray = new StringCollection();
}
}
}
/// <summary>
/// Gets or sets the server shutdown delay.
/// </summary>
/// <value>The array of server profiles.</value>
[DataMember(IsRequired = false, Order = 29)]
public int ShutdownDelay
{
get { return m_shutdownDelay; }
set
{
m_shutdownDelay = value;
}
}
/// <summary>
/// Gets or sets the server capabilities.
/// </summary>
/// <value>The array of server profiles.</value>
[DataMember(IsRequired = false, Order = 30)]
public StringCollection ServerCapabilities
{
get { return m_serverCapabilities; }
set
{
m_serverCapabilities = value;
if (m_serverCapabilities == null)
{
m_serverCapabilities = new StringCollection();
}
}
}
/// <summary>
/// Gets or sets the supported private key format.
/// </summary>
/// <value>The array of server profiles.</value>
[DataMember(IsRequired = false, Order = 31)]
public StringCollection SupportedPrivateKeyFormats
{
get { return m_supportedPrivateKeyFormats; }
set
{
m_supportedPrivateKeyFormats = value;
if (m_supportedPrivateKeyFormats == null)
{
m_supportedPrivateKeyFormats = new StringCollection();
}
}
}
/// <summary>
/// Gets or sets the max size of the trust list.
/// </summary>
[DataMember(IsRequired = false, Order = 32)]
public int MaxTrustListSize
{
get { return m_maxTrustListSize; }
set { m_maxTrustListSize = value; }
}
/// <summary>
/// Gets or sets if multicast DNS is enabled.
/// </summary>
[DataMember(IsRequired = false, Order = 33)]
public bool MultiCastDnsEnabled
{
get { return m_multicastDnsEnabled; }
set { m_multicastDnsEnabled = value; }
}
/// <summary>
/// Gets or sets reverse connect server configuration.
/// </summary>
[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
/// <summary>
/// Stores the configuration of the reverse connections.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectServerConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ReverseConnectServerConfiguration()
{
Initialize();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing]
private void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
}
#endregion
#region Public Properties
/// <summary>
/// A collection of reverse connect clients.
/// </summary>
[DataMember(Order = 10)]
public ReverseConnectClientCollection Clients { get; set; }
/// <summary>
/// The interval after which a new reverse connection is attempted.
/// </summary>
[DataMember(Order = 20)]
public int ConnectInterval { get; set; } = 15000;
/// <summary>
/// The default timeout to wait for a response to a reverse connection.
/// </summary>
[DataMember(Order = 30)]
public int ConnectTimeout { get; set; } = 30000;
/// <summary>
/// The timeout to wait to establish a new reverse
/// connection after a rejected attempt.
/// </summary>
[DataMember(Order = 40)]
public int RejectTimeout { get; set; } = 60000;
#endregion
}
#endregion
#region ReverseConnectClient Class
/// <summary>
/// Stores the configuration of the reverse connections.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClient
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ReverseConnectClient()
{
Initialize();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing]
private void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
Enabled = true;
}
#endregion
#region Persistent Properties
/// <summary>
/// The endpoint Url of the reverse connect client endpoint.
/// </summary>
[DataMember(Order = 10)]
public string EndpointUrl { get; set; }
/// <summary>
/// The timeout to wait for a response to a reverse connection.
/// Overrides the default reverse connection setting.
/// </summary>
[DataMember(Order = 20)]
public int Timeout { get; set; }
/// <summary>
/// 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.
/// </summary>
[DataMember(Order = 30)]
public int MaxSessionCount { get; set; }
/// <summary>
/// Specifies whether the sending of reverse connect attempts is enabled.
/// </summary>
[DataMember(Order = 40)]
public bool Enabled { get; set; } = true;
#endregion
}
#endregion
#region ReverseConnectClientCollection Class
/// <summary>
/// A collection of reverse connect clients.
/// </summary>
[CollectionDataContract(Name = "ListOfReverseConnectClient", Namespace = Namespaces.OpcUaConfig, ItemName = "ReverseConnectClient")]
public class ReverseConnectClientCollection : List<ReverseConnectClient>
{
#region Constructors
/// <summary>
/// Initializes an empty collection.
/// </summary>
public ReverseConnectClientCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public ReverseConnectClientCollection(IEnumerable<ReverseConnectClient> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public ReverseConnectClientCollection(int capacity) : base(capacity) { }
#endregion
}
#endregion
#region ClientConfiguration Class
/// <summary>
/// The configuration for a client application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ClientConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ClientConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_defaultSessionTimeout = 60000;
m_minSubscriptionLifetime = 10000;
m_wellKnownDiscoveryUrls = new StringCollection();
m_discoveryServers = new EndpointDescriptionCollection();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The default session timeout.
/// </summary>
/// <value>The default session timeout.</value>
[DataMember(IsRequired = false, Order = 0)]
public int DefaultSessionTimeout
{
get { return m_defaultSessionTimeout; }
set { m_defaultSessionTimeout = value; }
}
/// <summary>
/// The well known URLs for the local discovery servers.
/// </summary>
/// <value>The well known discovery URLs.</value>
[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();
}
}
}
/// <summary>
/// The endpoint descriptions for central discovery servers.
/// </summary>
/// <value>The endpoint descriptions for central discovery servers.</value>
[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();
}
}
}
/// <summary>
/// The path to the file containing the cached endpoints.
/// </summary>
/// <value>The path to the file containing the cached endpoints.</value>
[DataMember(IsRequired = false, Order = 3)]
public string EndpointCacheFilePath
{
get { return m_endpointCacheFilePath; }
set { m_endpointCacheFilePath = value; }
}
/// <summary>
/// The minimum lifetime for a subscription.
/// </summary>
/// <value>The minimum lifetime for a subscription.</value>
[DataMember(IsRequired = false, Order = 4)]
public int MinSubscriptionLifetime
{
get { return m_minSubscriptionLifetime; }
set { m_minSubscriptionLifetime = value; }
}
/// <summary>
/// Gets or sets reverse connect Client configuration.
/// </summary>
[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
/// <summary>
/// Stores the configuration of the reverse connections.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClientConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ReverseConnectClientConfiguration()
{
Initialize();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing]
private void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
}
#endregion
#region Public Properties
/// <summary>
/// A collection of reverse connect client endpoints.
/// </summary>
[DataMember(Order = 10, IsRequired = false)]
public ReverseConnectClientEndpointCollection ClientEndpoints { get; set; }
/// <summary>
/// The time a reverse hello port is held open to wait for a
/// reverse connection until the request is rejected.
/// </summary>
[DataMember(Order = 20, IsRequired = false)]
public int HoldTime { get; set; } = 15000;
/// <summary>
/// The timeout to wait for a reverse hello message.
/// </summary>
[DataMember(Order = 30, IsRequired = false)]
public int WaitTimeout { get; set; } = 20000;
#endregion
}
#endregion
#region ReverseConnectClientEndpoint Class
/// <summary>
/// Stores the configuration of the reverse connections.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ReverseConnectClientEndpoint
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ReverseConnectClientEndpoint()
{
Initialize();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing]
private void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
}
#endregion
#region Persistent Properties
/// <summary>
/// The endpoint Url of a reverse connect client.
/// </summary>
[DataMember(Order = 1, IsRequired = false)]
public string EndpointUrl { get; set; }
#endregion
}
#endregion
#region ReverseConnectClientEndpointCollection Class
/// <summary>
/// A collection of reverse connect client endpoints.
/// </summary>
[CollectionDataContract(Name = "ListOfReverseConnectClientEndpoint", Namespace = Namespaces.OpcUaConfig, ItemName = "ClientEndpoint")]
public class ReverseConnectClientEndpointCollection : List<ReverseConnectClientEndpoint>
{
#region Constructors
/// <summary>
/// Initializes an empty collection.
/// </summary>
public ReverseConnectClientEndpointCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public ReverseConnectClientEndpointCollection(IEnumerable<ReverseConnectClientEndpoint> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public ReverseConnectClientEndpointCollection(int capacity) : base(capacity) { }
#endregion
}
#endregion
#region DiscoveryServerConfiguration Class
/// <summary>
/// Specifies the configuration for a discovery server application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class DiscoveryServerConfiguration : ServerBaseConfiguration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public DiscoveryServerConfiguration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_serverNames = new LocalizedTextCollection();
m_serverRegistrations = new ServerRegistrationCollection();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public new void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The localized names for the discovery server.
/// </summary>
/// <value>The server names.</value>
[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();
}
}
}
/// <summary>
/// The path to the file containing servers saved by the discovery server.
/// </summary>
/// <value>The discovery server cache file.</value>
[DataMember(IsRequired = false, Order = 3)]
public string DiscoveryServerCacheFile
{
get { return m_discoveryServerCacheFile; }
set { m_discoveryServerCacheFile = value; }
}
/// <summary>
/// Gets or sets the server registrations associated with the discovery server.
/// </summary>
/// <value>The server registrations.</value>
[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
/// <summary>
/// Specifies the configuration for a discovery server application.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public class ServerRegistration
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ServerRegistration()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_applicationUri = null;
m_alternateDiscoveryUrls = new StringCollection();
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
/// <param name="context">The context.</param>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// Gets or sets the application URI of the server which the registration applies to.
/// </summary>
/// <value>The application uri.</value>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 1)]
public string ApplicationUri
{
get
{
return m_applicationUri;
}
set
{
m_applicationUri = value;
}
}
/// <summary>
/// Gets or sets the alternate discovery urls.
/// </summary>
/// <value>The alternate discovery urls.</value>
/// <remarks>
/// 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.
/// </remarks>
[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
/// <summary>
/// A collection of AdditionalServerRegistrationInfo objects.
/// </summary>
[CollectionDataContract(Name = "ListOfServerRegistration", Namespace = Namespaces.OpcUaConfig, ItemName = "ServerRegistration")]
public partial class ServerRegistrationCollection : List<ServerRegistration>
{
/// <summary>
/// Initializes an empty collection.
/// </summary>
public ServerRegistrationCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection"/> is null.
/// </exception>
public ServerRegistrationCollection(IEnumerable<ServerRegistration> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
/// <param name="capacity">The capacity.</param>
public ServerRegistrationCollection(int capacity) : base(capacity) { }
}
#endregion
#region CertificateStoreIdentifier Class
/// <summary>
/// Describes a certificate store.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class CertificateStoreIdentifier
{
#region Persistent Properties
/// <summary>
/// The type of certificate store.
/// </summary>
/// <value>
/// If the StoreName is not empty, the CertificateStoreType.X509Store is returned, otherwise the StoreType is returned.
/// </value>
[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;
}
}
/// <summary>
/// The path that identifies the certificate store.
/// </summary>
/// <value>
/// 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.
/// </value>
[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;
}
}
}
}
}
/// <summary>
/// The name of the certifcate store that contains the trusted certficates.
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
[Obsolete("Use StoreType/StorePath instead")]
public string StoreName
{
get { return m_storeName; }
set { m_storeName = value; }
}
/// <summary>
/// The location of the certifcate store that contains the trusted certficates.
/// </summary>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
[Obsolete("Use StoreType/StorePath instead")]
public string StoreLocation
{
get { return m_storeLocation; }
set { m_storeLocation = value; }
}
/// <summary>
/// Options that can be used to suppress certificate validation errors.
/// </summary>
[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
/// <summary>
/// The default constructor.
/// </summary>
public CertificateTrustList()
{
Initialize();
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize() => m_trustedCertificates = new CertificateIdentifierCollection();
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Persistent Properties
/// <summary>
/// The list of trusted certificates.
/// </summary>
/// <value>
/// The list of trusted certificates is set when TrustedCertificates is not a null value, otherwise new CertificateIdentifierCollection is set.
/// </value>
[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<CertificateIdentifier>
{
/// <summary>
/// Initializes an empty collection.
/// </summary>
public CertificateIdentifierCollection() { }
/// <summary>
/// Initializes the collection from another collection.
/// </summary>
/// <param name="collection">A collection of values to add to this new collection</param>
public CertificateIdentifierCollection(IEnumerable<CertificateIdentifier> collection) : base(collection) { }
/// <summary>
/// Initializes the collection with the specified capacity.
/// </summary>
public CertificateIdentifierCollection(int capacity) : base(capacity) { }
}
#endregion
#region CertificateIdentifier Class
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class CertificateIdentifier
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public CertificateIdentifier()
{
Initialize();
}
/// <summary>
/// Initializes the identifier with the raw data from a certificate.
/// </summary>
public CertificateIdentifier(X509Certificate2 certificate)
{
Initialize();
m_certificate = certificate;
}
/// <summary>
/// Initializes the identifier with the raw data from a certificate.
/// </summary>
public CertificateIdentifier(X509Certificate2 certificate, CertificateValidationOptions validationOptions)
{
Initialize();
m_certificate = certificate;
m_validationOptions = validationOptions;
}
/// <summary>
/// Initializes the identifier with the raw data from a certificate.
/// </summary>
public CertificateIdentifier(byte[] rawData)
{
Initialize();
m_certificate = CertificateFactory.Create(rawData, true);
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
}
/// <summary>
/// Initializes the object during deserialization.
/// </summary>
[OnDeserializing()]
public void Initialize(StreamingContext context) => Initialize();
#endregion
#region Public Properties
/// <summary>
/// The type of certificate store.
/// </summary>
/// <value>The type of the store - defined in the <see cref="CertificateStoreType"/>.</value>
[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;
}
}
/// <summary>
/// The path that identifies the certificate store.
/// </summary>
/// <value>The store path in the form <c>StoreName\\Store Location</c> .</value>
[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;
}
}
}
}
}
/// <summary>
/// The name of the store that contains the certificate.
/// </summary>
/// <value>The name of the store.</value>
/// <seealso cref="System.Security.Cryptography.X509Certificates.StoreName"/>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 2)]
[Obsolete("Use StoreType/StorePath instead")]
public string StoreName
{
get { return m_storeName; }
set { m_storeName = value; }
}
/// <summary>
/// The location of the store that contains the certificate.
/// </summary>
/// <value>The store location.</value>
/// <seealso cref="System.Security.Cryptography.X509Certificates.StoreLocation"/>
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 3)]
[Obsolete("Use StoreType/StorePath instead")]
public string StoreLocation
{
get { return m_storeLocation; }
set { m_storeLocation = value; }
}
/// <summary>
/// The certificate's subject name - the distinguished name of an X509 certificate.
/// </summary>
/// <value>
/// The distinguished name of an X509 certificate acording to the Abstract Syntax Notation One (ASN.1) syntax.
/// </value>
/// <remarks> 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:
/// <list type="bullet">
/// <item>CN commonName</item>
/// <item>L localityName</item>
/// <item>ST stateOrProvinceName</item>
/// <item>O organizationName</item>
/// <item>OU organizationalUnitName</item>
/// <item>C countryName</item>
/// <item>STREET streetAddress</item>
/// <item>DC domainComponent</item>
/// <item>UID userid</item>
/// </list>
/// 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):
/// <code>CN=Steve Kille,O=Isode Limited,C=GB</code>
///
/// RFC 3280 Internet X.509 Public Key Infrastructure, April 2002
/// RFC 2253 LADPv3 Distinguished Names, December 1997
/// </remarks>
/// <seealso cref="System.Security.Cryptography.X509Certificates.X500DistinguishedName"/>
/// <seealso cref="System.Security.Cryptography.AsnEncodedData"/>
[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;
}
}
/// <summary>
/// The certificate's thumbprint.
/// </summary>
/// <value>The thumbprint of a certificate..</value>
/// <seealso cref="X509Certificate2"/>
[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;
}
}
/// <summary>
/// Gets the DER encoded certificate data or create emebeded in this instance certifcate using the DER encoded certificate data.
/// </summary>
/// <value>A byte array containing the X.509 certificate data.</value>
[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;
}
}
/// <summary>
/// Gets or sets the XML encoded validation options - use to serialize the validation options.
/// </summary>
/// <value>The XML encoded validation options.</value>
[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
/// <summary>
/// Stores a list of cached enpoints.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ConfiguredEndpointCollection
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ConfiguredEndpointCollection()
{
Initialize();
}
/// <summary>
/// Called by the .NET framework during deserialization.
/// </summary>
[OnDeserializing]
public void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_knownHosts = new StringCollection();
m_discoveryUrls = new StringCollection(Utils.DiscoveryUrls);
m_endpoints = new List<ConfiguredEndpoint>();
m_defaultConfiguration = EndpointConfiguration.Create();
}
#endregion
#region Public Properties
/// <summary>
/// A list of known hosts that can be used for discovery.
/// </summary>
[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;
}
}
}
/// <summary>
/// The default configuration to use when connecting to an endpoint.
/// </summary>
[DataMember(Name = "Endpoints", IsRequired = false, Order = 2)]
public List<ConfiguredEndpoint> Endpoints
{
get
{
return m_endpoints;
}
private set
{
if (value == null)
{
m_endpoints = new List<ConfiguredEndpoint>();
}
else
{
m_endpoints = value;
}
foreach (ConfiguredEndpoint endpoint in m_endpoints)
{
endpoint.Collection = this;
}
}
}
/// <summary>
/// The URL of the UA TCP proxy server.
/// </summary>
[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<ConfiguredEndpoint> m_endpoints;
private Uri m_tcpProxyUrl;
#endregion
}
#endregion
#region ConfiguredEndpoint Class
/// <summary>
/// Stores the configuration information for an endpoint.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
[KnownType(typeof(UserNameIdentityToken))]
[KnownType(typeof(X509IdentityToken))]
[KnownType(typeof(IssuedIdentityToken))]
public partial class ConfiguredEndpoint
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ConfiguredEndpoint()
{
Initialize();
}
/// <summary>
/// Called by the .NET framework during deserialization.
/// </summary>
[OnDeserializing]
public void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
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
/// <summary>
/// The description for the endpoint.
/// </summary>
[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;
}
}
}
/// <summary>
/// The configuration to use when connecting to an endpoint.
/// </summary>
[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());
}
}
}
}
/// <summary>
/// Whether the endpoint information should be updated before connecting to the server.
/// </summary>
[DataMember(Name = "UpdateBeforeConnect", Order = 3, IsRequired = false)]
public bool UpdateBeforeConnect
{
get { return m_updateBeforeConnect; }
set { m_updateBeforeConnect = value; }
}
/// <summary>
/// The user identity to use when connecting to the endpoint.
/// </summary>
[DataMember(Name = "BinaryEncodingSupport", Order = 4, IsRequired = false)]
public BinaryEncodingSupport BinaryEncodingSupport
{
get { return m_binaryEncodingSupport; }
set { m_binaryEncodingSupport = value; }
}
/// <summary>
/// The user identity to use when connecting to the endpoint.
/// </summary>
[DataMember(Name = "SelectedUserTokenPolicy", Order = 5, IsRequired = false)]
public int SelectedUserTokenPolicyIndex
{
get { return m_selectedUserTokenPolicyIndex; }
set { m_selectedUserTokenPolicyIndex = value; }
}
/// <summary>
/// The user identity to use when connecting to the endpoint.
/// </summary>
[DataMember(Name = "UserIdentity", Order = 6, IsRequired = false)]
public UserIdentityToken UserIdentity
{
get { return m_userIdentity; }
set { m_userIdentity = value; }
}
/// <summary>
/// The reverse connect information.
/// </summary>
[DataMember(Name = "ReverseConnect", Order = 8, IsRequired = false)]
public ReverseConnectEndpoint ReverseConnect
{
get { return m_reverseConnect; }
set { m_reverseConnect = value; }
}
/// <summary>
/// A bucket to store additional application specific configuration data.
/// </summary>
[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
/// <summary>
/// The type of binary encoding support allowed by a channel.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public enum BinaryEncodingSupport
{
/// <summary>
/// The UA binary encoding may be used.
/// </summary>
[EnumMember()]
Optional,
/// <summary>
/// The UA binary encoding must be used.
/// </summary>
[EnumMember()]
Required,
/// <summary>
/// The UA binary encoding may not be used.
/// </summary>
[EnumMember()]
None
}
#endregion
#region ReverseConnectEndpoint Class
/// <summary>
/// Stores the reverse connect information for an endpoint.
/// </summary>
[DataContract(Namespace = Namespaces.OpcUaConfig)]
public partial class ReverseConnectEndpoint
{
#region Constructors
/// <summary>
/// The default constructor.
/// </summary>
public ReverseConnectEndpoint()
{
Initialize();
}
/// <summary>
/// Called by the .NET framework during deserialization.
/// </summary>
[OnDeserializing]
public void Initialize(StreamingContext context) => Initialize();
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_enabled = false;
m_serverUri = null;
m_thumbprint = null;
}
#endregion
#region Public Properties
/// <summary>
/// Whether reverse connect is enabled for the endpoint.
/// </summary>
[DataMember(Name = "Enabled", Order = 1, IsRequired = false)]
public bool Enabled
{
get { return m_enabled; }
set { m_enabled = value; }
}
/// <summary>
/// The server Uri of the endpoint.
/// </summary>
[DataMember(Name = "ServerUri", Order = 2, IsRequired = false)]
public string ServerUri
{
get { return m_serverUri; }
set { m_serverUri = value; }
}
/// <summary>
/// The thumbprint of the certificate which contains
/// the server Uri.
/// </summary>
[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
}