Files
2022-03-30 11:30:34 +02:00

913 lines
38 KiB
C#

/* ========================================================================
* Copyright (c) 2005-2021 The OPC Foundation, Inc. All rights reserved.
*
* OPC Foundation MIT License 1.00
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* The complete license agreement can be found here:
* http://opcfoundation.org/License/MIT/1.00/
* ======================================================================*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Xml;
namespace Opc.Ua.Configuration
{
/// <summary>
/// A class that builds a configuration for a UA application.
/// </summary>
public class ApplicationConfigurationBuilder :
IApplicationConfigurationBuilder
{
#region ctor
/// <summary>
/// Create the application instance builder.
/// </summary>
public ApplicationConfigurationBuilder(ApplicationInstance applicationInstance)
{
ApplicationInstance = applicationInstance;
}
#endregion
#region Public Properties
/// <summary>
/// The application instance used to build the configuration.
/// </summary>
public ApplicationInstance ApplicationInstance { get; private set; }
/// <summary>
/// The application configuration.
/// </summary>
public ApplicationConfiguration ApplicationConfiguration => ApplicationInstance.ApplicationConfiguration;
#endregion
#region Public Methods
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientSelected AsClient()
{
switch (ApplicationInstance.ApplicationType)
{
case ApplicationType.Client:
case ApplicationType.ClientAndServer:
break;
case ApplicationType.Server:
ApplicationInstance.ApplicationType =
m_typeSelected ? ApplicationType.ClientAndServer : ApplicationType.Client;
break;
default:
throw new ArgumentException("Invalid application type for client.");
}
m_typeSelected = true;
ApplicationConfiguration.ClientConfiguration = new ClientConfiguration();
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions AddSecurityConfiguration(
string subjectName,
string pkiRoot = null,
string appRoot = null,
string rejectedRoot = null
)
{
pkiRoot = DefaultPKIRoot(pkiRoot);
appRoot = appRoot == null ? pkiRoot : DefaultPKIRoot(appRoot);
rejectedRoot = rejectedRoot == null ? pkiRoot : DefaultPKIRoot(rejectedRoot);
var appStoreType = CertificateStoreIdentifier.DetermineStoreType(appRoot);
var pkiRootType = CertificateStoreIdentifier.DetermineStoreType(pkiRoot);
var rejectedRootType = CertificateStoreIdentifier.DetermineStoreType(rejectedRoot);
ApplicationConfiguration.SecurityConfiguration = new SecurityConfiguration {
// app cert store
ApplicationCertificate = new CertificateIdentifier() {
StoreType = appStoreType,
StorePath = DefaultCertificateStorePath(TrustlistType.Application, appRoot),
SubjectName = Utils.ReplaceDCLocalhost(subjectName)
},
// App trusted & issuer
TrustedPeerCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.Trusted, pkiRoot)
},
TrustedIssuerCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.Issuer, pkiRoot)
},
// Https trusted & issuer
TrustedHttpsCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.TrustedHttps, pkiRoot)
},
HttpsIssuerCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.IssuerHttps, pkiRoot)
},
// User trusted & issuer
TrustedUserCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.TrustedUser, pkiRoot)
},
UserIssuerCertificates = new CertificateTrustList() {
StoreType = pkiRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.IssuerUser, pkiRoot)
},
// rejected store
RejectedCertificateStore = new CertificateTrustList() {
StoreType = rejectedRootType,
StorePath = DefaultCertificateStorePath(TrustlistType.Rejected, rejectedRoot)
},
// ensure secure default settings
AutoAcceptUntrustedCertificates = false,
AddAppCertToTrustedStore = false,
RejectSHA1SignedCertificates = true,
RejectUnknownRevocationStatus = true,
SuppressNonceValidationErrors = false,
SendCertificateChain = false,
MinimumCertificateKeySize = CertificateFactory.DefaultKeySize
};
return this;
}
/// <inheritdoc/>
public async Task<ApplicationConfiguration> Create()
{
// sanity checks
if (ApplicationInstance.ApplicationType == ApplicationType.Server ||
ApplicationInstance.ApplicationType == ApplicationType.ClientAndServer)
{
if (ApplicationConfiguration.ServerConfiguration == null) throw new ArgumentException("ApplicationType Server is not configured.");
}
if (ApplicationInstance.ApplicationType == ApplicationType.Client ||
ApplicationInstance.ApplicationType == ApplicationType.ClientAndServer)
{
if (ApplicationConfiguration.ClientConfiguration == null) throw new ArgumentException("ApplicationType Client is not configured.");
}
// ensure for a user token policy
if (ApplicationConfiguration.ServerConfiguration?.UserTokenPolicies.Count == 0)
{
ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
}
// ensure for secure transport profiles
if (ApplicationConfiguration.ServerConfiguration?.SecurityPolicies.Count == 0)
{
AddSecurityPolicies();
}
ApplicationConfiguration.TraceConfiguration?.ApplySettings();
await ApplicationConfiguration.Validate(ApplicationInstance.ApplicationType).ConfigureAwait(false);
await ApplicationConfiguration.CertificateValidator.
Update(ApplicationConfiguration.SecurityConfiguration).ConfigureAwait(false);
return ApplicationConfiguration;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AsServer(
string[] baseAddresses,
string[] alternateBaseAddresses = null)
{
switch (ApplicationInstance.ApplicationType)
{
case ApplicationType.Client:
ApplicationInstance.ApplicationType =
m_typeSelected ? ApplicationType.ClientAndServer : ApplicationType.Server;
break;
case ApplicationType.Server:
case ApplicationType.ClientAndServer: break;
default:
throw new ArgumentException("Invalid application type for server.");
}
m_typeSelected = true;
// configure a server
var serverConfiguration = new ServerConfiguration();
// by default disable LDS registration
serverConfiguration.MaxRegistrationInterval = 0;
// base addresses
foreach (var baseAddress in baseAddresses)
{
serverConfiguration.BaseAddresses.Add(Utils.ReplaceLocalhost(baseAddress));
}
// alternate base addresses
if (alternateBaseAddresses != null)
{
foreach (var alternateBaseAddress in alternateBaseAddresses)
{
serverConfiguration.AlternateBaseAddresses.Add(Utils.ReplaceLocalhost(alternateBaseAddress));
}
}
// add container for policies
serverConfiguration.SecurityPolicies = new ServerSecurityPolicyCollection();
// add user token policy container and Anonymous
serverConfiguration.UserTokenPolicies = new UserTokenPolicyCollection();
ApplicationConfiguration.ServerConfiguration = serverConfiguration;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddUnsecurePolicyNone(bool addPolicy = true)
{
if (addPolicy)
{
AddSecurityPolicies(false, false, true);
}
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddSignPolicies(bool addPolicies = true)
{
if (addPolicies)
{
AddSecurityPolicies(true, false, false);
}
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddSignAndEncryptPolicies(bool addPolicies = true)
{
if (addPolicies)
{
AddSecurityPolicies(false, false, false);
}
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddPolicy(MessageSecurityMode securityMode, string securityPolicy)
{
if (SecurityPolicies.GetDisplayName(securityPolicy) == null) throw new ArgumentException("Unknown security policy", nameof(securityPolicy));
if (securityMode == MessageSecurityMode.None || securityPolicy.Equals(SecurityPolicies.None)) throw new ArgumentException("Use AddUnsecurePolicyNone to add no security policy.");
InternalAddPolicy(ApplicationConfiguration.ServerConfiguration.SecurityPolicies, securityMode, securityPolicy);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenType userTokenType)
{
ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(new UserTokenPolicy(userTokenType));
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenPolicy userTokenPolicy)
{
if (userTokenPolicy == null) throw new ArgumentNullException(nameof(userTokenPolicy));
ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetAutoAcceptUntrustedCertificates(bool autoAccept)
{
ApplicationConfiguration.SecurityConfiguration.AutoAcceptUntrustedCertificates = autoAccept;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetAddAppCertToTrustedStore(bool addToTrustedStore)
{
ApplicationConfiguration.SecurityConfiguration.AddAppCertToTrustedStore = addToTrustedStore;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetRejectSHA1SignedCertificates(bool rejectSHA1Signed)
{
ApplicationConfiguration.SecurityConfiguration.RejectSHA1SignedCertificates = rejectSHA1Signed;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetRejectUnknownRevocationStatus(bool rejectUnknownRevocationStatus)
{
ApplicationConfiguration.SecurityConfiguration.RejectUnknownRevocationStatus = rejectUnknownRevocationStatus;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetSuppressNonceValidationErrors(bool suppressNonceValidationErrors)
{
ApplicationConfiguration.SecurityConfiguration.SuppressNonceValidationErrors = suppressNonceValidationErrors;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetSendCertificateChain(bool sendCertificateChain)
{
ApplicationConfiguration.SecurityConfiguration.SendCertificateChain = sendCertificateChain;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions SetMinimumCertificateKeySize(ushort keySize)
{
ApplicationConfiguration.SecurityConfiguration.MinimumCertificateKeySize = keySize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderSecurityOptions AddCertificatePasswordProvider(ICertificatePasswordProvider certificatePasswordProvider)
{
ApplicationConfiguration.SecurityConfiguration.CertificatePasswordProvider = certificatePasswordProvider;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotasSet SetTransportQuotas(TransportQuotas transportQuotas)
{
ApplicationConfiguration.TransportQuotas = transportQuotas;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetOperationTimeout(int operationTimeout)
{
ApplicationConfiguration.TransportQuotas.OperationTimeout = operationTimeout;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetMaxStringLength(int maxStringLength)
{
ApplicationConfiguration.TransportQuotas.MaxStringLength = maxStringLength;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetMaxByteStringLength(int maxByteStringLength)
{
ApplicationConfiguration.TransportQuotas.MaxByteStringLength = maxByteStringLength;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetMaxArrayLength(int maxArrayLength)
{
ApplicationConfiguration.TransportQuotas.MaxArrayLength = maxArrayLength;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetMaxMessageSize(int maxMessageSize)
{
ApplicationConfiguration.TransportQuotas.MaxMessageSize = maxMessageSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetMaxBufferSize(int maxBufferSize)
{
ApplicationConfiguration.TransportQuotas.MaxBufferSize = maxBufferSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetChannelLifetime(int channelLifetime)
{
ApplicationConfiguration.TransportQuotas.ChannelLifetime = channelLifetime;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTransportQuotas SetSecurityTokenLifetime(int securityTokenLifetime)
{
ApplicationConfiguration.TransportQuotas.SecurityTokenLifetime = securityTokenLifetime;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMinRequestThreadCount(int minRequestThreadCount)
{
ApplicationConfiguration.ServerConfiguration.MinRequestThreadCount = minRequestThreadCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxRequestThreadCount(int maxRequestThreadCount)
{
ApplicationConfiguration.ServerConfiguration.MaxRequestThreadCount = maxRequestThreadCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxQueuedRequestCount(int maxQueuedRequestCount)
{
ApplicationConfiguration.ServerConfiguration.MaxQueuedRequestCount = maxQueuedRequestCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetDiagnosticsEnabled(bool diagnosticsEnabled)
{
ApplicationConfiguration.ServerConfiguration.DiagnosticsEnabled = diagnosticsEnabled;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxSessionCount(int maxSessionCount)
{
ApplicationConfiguration.ServerConfiguration.MaxSessionCount = maxSessionCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMinSessionTimeout(int minSessionTimeout)
{
ApplicationConfiguration.ServerConfiguration.MinSessionTimeout = minSessionTimeout;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxSessionTimeout(int maxSessionTimeout)
{
ApplicationConfiguration.ServerConfiguration.MaxSessionTimeout = maxSessionTimeout;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxBrowseContinuationPoints(int maxBrowseContinuationPoints)
{
ApplicationConfiguration.ServerConfiguration.MaxBrowseContinuationPoints = maxBrowseContinuationPoints;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxQueryContinuationPoints(int maxQueryContinuationPoints)
{
ApplicationConfiguration.ServerConfiguration.MaxQueryContinuationPoints = maxQueryContinuationPoints;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxHistoryContinuationPoints(int maxHistoryContinuationPoints)
{
ApplicationConfiguration.ServerConfiguration.MaxHistoryContinuationPoints = maxHistoryContinuationPoints;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxRequestAge(int maxRequestAge)
{
ApplicationConfiguration.ServerConfiguration.MaxRequestAge = maxRequestAge;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMinPublishingInterval(int minPublishingInterval)
{
ApplicationConfiguration.ServerConfiguration.MinPublishingInterval = minPublishingInterval;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxPublishingInterval(int maxPublishingInterval)
{
ApplicationConfiguration.ServerConfiguration.MaxPublishingInterval = maxPublishingInterval;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetPublishingResolution(int publishingResolution)
{
ApplicationConfiguration.ServerConfiguration.PublishingResolution = publishingResolution;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxSubscriptionLifetime(int maxSubscriptionLifetime)
{
ApplicationConfiguration.ServerConfiguration.MaxSubscriptionLifetime = maxSubscriptionLifetime;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxMessageQueueSize(int maxMessageQueueSize)
{
ApplicationConfiguration.ServerConfiguration.MaxMessageQueueSize = maxMessageQueueSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxNotificationQueueSize(int maxNotificationQueueSize)
{
ApplicationConfiguration.ServerConfiguration.MaxNotificationQueueSize = maxNotificationQueueSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxNotificationsPerPublish(int maxNotificationsPerPublish)
{
ApplicationConfiguration.ServerConfiguration.MaxNotificationsPerPublish = maxNotificationsPerPublish;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMinMetadataSamplingInterval(int minMetadataSamplingInterval)
{
ApplicationConfiguration.ServerConfiguration.MinMetadataSamplingInterval = minMetadataSamplingInterval;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetAvailableSamplingRates(SamplingRateGroupCollection availableSampleRates)
{
ApplicationConfiguration.ServerConfiguration.AvailableSamplingRates = availableSampleRates;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetRegistrationEndpoint(EndpointDescription registrationEndpoint)
{
ApplicationConfiguration.ServerConfiguration.RegistrationEndpoint = registrationEndpoint;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxRegistrationInterval(int maxRegistrationInterval)
{
ApplicationConfiguration.ServerConfiguration.MaxRegistrationInterval = maxRegistrationInterval;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetNodeManagerSaveFile(string nodeManagerSaveFile)
{
ApplicationConfiguration.ServerConfiguration.NodeManagerSaveFile = nodeManagerSaveFile;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMinSubscriptionLifetime(int minSubscriptionLifetime)
{
ApplicationConfiguration.ServerConfiguration.MinSubscriptionLifetime = minSubscriptionLifetime;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxPublishRequestCount(int maxPublishRequestCount)
{
ApplicationConfiguration.ServerConfiguration.MaxPublishRequestCount = maxPublishRequestCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxSubscriptionCount(int maxSubscriptionCount)
{
ApplicationConfiguration.ServerConfiguration.MaxSubscriptionCount = maxSubscriptionCount;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxEventQueueSize(int maxEventQueueSize)
{
ApplicationConfiguration.ServerConfiguration.MaxEventQueueSize = maxEventQueueSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions AddServerProfile(string serverProfile)
{
ApplicationConfiguration.ServerConfiguration.ServerProfileArray.Add(serverProfile);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetShutdownDelay(int shutdownDelay)
{
ApplicationConfiguration.ServerConfiguration.ShutdownDelay = shutdownDelay;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions AddServerCapabilities(string serverCapability)
{
ApplicationConfiguration.ServerConfiguration.ServerCapabilities.Add(serverCapability);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetSupportedPrivateKeyFormats(StringCollection supportedPrivateKeyFormats)
{
ApplicationConfiguration.ServerConfiguration.SupportedPrivateKeyFormats = supportedPrivateKeyFormats;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMaxTrustListSize(int maxTrustListSize)
{
ApplicationConfiguration.ServerConfiguration.MaxTrustListSize = maxTrustListSize;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetMultiCastDnsEnabled(bool multiCastDnsEnabled)
{
ApplicationConfiguration.ServerConfiguration.MultiCastDnsEnabled = multiCastDnsEnabled;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetReverseConnect(ReverseConnectServerConfiguration reverseConnectConfiguration)
{
ApplicationConfiguration.ServerConfiguration.ReverseConnect = reverseConnectConfiguration;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderServerOptions SetOperationLimits(OperationLimits operationLimits)
{
ApplicationConfiguration.ServerConfiguration.OperationLimits = operationLimits;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientOptions SetDefaultSessionTimeout(int defaultSessionTimeout)
{
ApplicationConfiguration.ClientConfiguration.DefaultSessionTimeout = defaultSessionTimeout;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientOptions AddWellKnownDiscoveryUrls(string wellKnownDiscoveryUrl)
{
ApplicationConfiguration.ClientConfiguration.WellKnownDiscoveryUrls.Add(wellKnownDiscoveryUrl);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientOptions AddDiscoveryServer(EndpointDescription discoveryServer)
{
ApplicationConfiguration.ClientConfiguration.DiscoveryServers.Add(discoveryServer);
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientOptions SetEndpointCacheFilePath(string endpointCacheFilePath)
{
ApplicationConfiguration.ClientConfiguration.EndpointCacheFilePath = endpointCacheFilePath;
return this;
}
/// <inheritdoc/>
IApplicationConfigurationBuilderClientOptions IApplicationConfigurationBuilderClientOptions.SetMinSubscriptionLifetime(int minSubscriptionLifetime)
{
ApplicationConfiguration.ClientConfiguration.MinSubscriptionLifetime = minSubscriptionLifetime;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderClientOptions SetReverseConnect(ReverseConnectClientConfiguration reverseConnect)
{
ApplicationConfiguration.ClientConfiguration.ReverseConnect = reverseConnect;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTraceConfiguration SetOutputFilePath(string outputFilePath)
{
ApplicationConfiguration.TraceConfiguration.OutputFilePath = outputFilePath;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTraceConfiguration SetDeleteOnLoad(bool deleteOnLoad)
{
ApplicationConfiguration.TraceConfiguration.DeleteOnLoad = deleteOnLoad;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderTraceConfiguration SetTraceMasks(int traceMasks)
{
ApplicationConfiguration.TraceConfiguration.TraceMasks = traceMasks;
return this;
}
/// <inheritdoc/>
public IApplicationConfigurationBuilderExtension AddExtension<T>(XmlQualifiedName elementName, object value)
{
ApplicationConfiguration.UpdateExtension<T>(elementName, value);
return this;
}
#endregion
#region Private Methods
/// <summary>
/// Internal enumeration of supported trust lists.
/// </summary>
private enum TrustlistType
{
Application,
Trusted,
Issuer,
TrustedHttps,
IssuerHttps,
TrustedUser,
IssuerUser,
Rejected
};
/// <summary>
/// Return the default PKI root path if root is unspecified, directory or X509Store.
/// </summary>
/// <param name="root">A real root path or the store type.</param>
private string DefaultPKIRoot(string root)
{
if (root == null ||
root.Equals(CertificateStoreType.Directory, StringComparison.OrdinalIgnoreCase))
{
return CertificateStoreIdentifier.DefaultPKIRoot;
}
else if (root.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase))
{
return CertificateStoreIdentifier.CurrentUser;
}
return root;
}
/// <summary>
/// Determine the default store path for a given trust list type.
/// </summary>
/// <param name="trustListType">The trust list type.</param>
/// <param name="pkiRoot">A PKI root for which the store path is needed.</param>
private string DefaultCertificateStorePath(TrustlistType trustListType, string pkiRoot)
{
var pkiRootType = CertificateStoreIdentifier.DetermineStoreType(pkiRoot);
if (pkiRootType.Equals(CertificateStoreType.Directory, StringComparison.OrdinalIgnoreCase))
{
string leafPath = "";
// see https://reference.opcfoundation.org/v104/GDS/docs/F.1/
switch (trustListType)
{
case TrustlistType.Application: leafPath = "own"; break;
case TrustlistType.Trusted: leafPath = "trusted"; break;
case TrustlistType.Issuer: leafPath = "issuer"; break;
case TrustlistType.TrustedHttps: leafPath = "trustedHttps"; break;
case TrustlistType.IssuerHttps: leafPath = "issuerHttps"; break;
case TrustlistType.TrustedUser: leafPath = "trustedUser"; break;
case TrustlistType.IssuerUser: leafPath = "issuerUser"; break;
case TrustlistType.Rejected: leafPath = "rejected"; break;
}
// Caller may have already provided the leaf path, then no need to add.
int startIndex = pkiRoot.Length - leafPath.Length;
char lastChar = pkiRoot.Last();
if (lastChar == Path.DirectorySeparatorChar ||
lastChar == Path.AltDirectorySeparatorChar)
{
startIndex--;
}
if (startIndex > 0)
{
if (pkiRoot.Substring(startIndex, leafPath.Length).Equals(leafPath, StringComparison.OrdinalIgnoreCase))
{
return pkiRoot;
}
}
return Path.Combine(pkiRoot, leafPath);
}
else if (pkiRootType.Equals(CertificateStoreType.X509Store, StringComparison.OrdinalIgnoreCase))
{
switch (trustListType)
{
case TrustlistType.Application:
#if !NETFRAMEWORK
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
pkiRoot.StartsWith(CertificateStoreIdentifier.CurrentUser, StringComparison.OrdinalIgnoreCase))
{
return pkiRoot + "My";
}
#endif
return pkiRoot + "UA_MachineDefault";
case TrustlistType.Trusted:
return pkiRoot + "UA_Trusted";
case TrustlistType.Issuer:
return pkiRoot + "UA_Issuer";
case TrustlistType.TrustedHttps:
return pkiRoot + "UA_Trusted_Https";
case TrustlistType.IssuerHttps:
return pkiRoot + "UA_Issuer_Https";
case TrustlistType.TrustedUser:
return pkiRoot + "UA_Trusted_User";
case TrustlistType.IssuerUser:
return pkiRoot + "UA_Issuer_User";
case TrustlistType.Rejected:
return pkiRoot + "UA_Rejected";
}
}
throw new NotSupportedException("Unsupported store type.");
}
/// <summary>
/// Add specified groups of security policies and security modes.
/// </summary>
/// <param name="includeSign">Include the Sign only policies.</param>
/// <param name="deprecated">Include the deprecated policies.</param>
/// <param name="policyNone">Include policy 'None'. (no security!)</param>
private void AddSecurityPolicies(bool includeSign = false, bool deprecated = false, bool policyNone = false)
{
// create list of supported policies
string[] defaultPolicyUris = SecurityPolicies.GetDefaultUris();
if (deprecated)
{
var names = SecurityPolicies.GetDisplayNames();
var deprecatedPolicyList = new List<string>();
foreach (var name in names)
{
var uri = SecurityPolicies.GetUri(name);
if (uri != null)
{
deprecatedPolicyList.Add(uri);
}
}
defaultPolicyUris = deprecatedPolicyList.ToArray();
}
foreach (MessageSecurityMode securityMode in typeof(MessageSecurityMode).GetEnumValues())
{
var policies = ApplicationConfiguration.ServerConfiguration.SecurityPolicies;
if (policyNone && securityMode == MessageSecurityMode.None)
{
InternalAddPolicy(policies, MessageSecurityMode.None, SecurityPolicies.None);
}
else if (securityMode >= MessageSecurityMode.SignAndEncrypt ||
(includeSign && securityMode == MessageSecurityMode.Sign))
{
foreach (var policyUri in defaultPolicyUris)
{
InternalAddPolicy(policies, securityMode, policyUri);
}
}
}
}
/// <summary>
/// Add security policy if it doesn't exist yet.
/// </summary>
/// <param name="policies">The collection to which the policies are added.</param>
/// <param name="securityMode">The message security mode.</param>
/// <param name="policyUri">The security policy Uri.</param>
private bool InternalAddPolicy(ServerSecurityPolicyCollection policies, MessageSecurityMode securityMode, string policyUri)
{
if (securityMode == MessageSecurityMode.Invalid) throw new ArgumentException("Invalid security mode selected", nameof(securityMode));
var newPolicy = new ServerSecurityPolicy() {
SecurityMode = securityMode,
SecurityPolicyUri = policyUri
};
if (policies.Find(s =>
s.SecurityMode == newPolicy.SecurityMode &&
string.Equals(s.SecurityPolicyUri, newPolicy.SecurityPolicyUri, StringComparison.Ordinal)
) == null)
{
policies.Add(newPolicy);
return true;
}
return false;
}
#endregion
#region Private Fields
private bool m_typeSelected;
#endregion
}
}