refactor server configuration init

This commit is contained in:
Martin Regen
2017-11-08 17:22:48 +01:00
parent 915ad5b87c
commit f7f0ff0fa5
6 changed files with 391 additions and 221 deletions
@@ -0,0 +1,372 @@
/* ========================================================================
* Copyright (c) 2005-2016 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.Linq;
using System.Security.Cryptography.X509Certificates;
namespace Opc.Ua.Server
{
/// <summary>
/// The Server Configuration Node Manager.
/// </summary>
public class ConfigurationNodeManager : DiagnosticsNodeManager
{
#region Constructors
/// <summary>
/// Initializes the configuration and diagnostics manager.
/// </summary>
public ConfigurationNodeManager(
IServerInternal server,
ApplicationConfiguration configuration
)
:
base(server, configuration)
{
m_rejectedStorePath = configuration.SecurityConfiguration.RejectedCertificateStore.StorePath;
m_certificateGroups = new List<ServerCertificateGroup>();
// TODO: configure cert groups in configuration
ServerCertificateGroup defaultApplicationGroup = new ServerCertificateGroup
{
BrowseName = Opc.Ua.BrowseNames.DefaultApplicationGroup,
CertificateTypes = new NodeId[] { ObjectTypeIds.ApplicationCertificateType },
ApplicationStorePath = configuration.SecurityConfiguration.ApplicationCertificate.StorePath,
IssuerStorePath = configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath,
TrustedStorePath = configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath
};
m_certificateGroups.Add(defaultApplicationGroup);
}
#endregion
#region INodeManager Members
/// <summary>
/// Replaces the generic node with a node specific to the model.
/// </summary>
protected override NodeState AddBehaviourToPredefinedNode(ISystemContext context, NodeState predefinedNode)
{
BaseObjectState passiveNode = predefinedNode as BaseObjectState;
if (passiveNode != null)
{
NodeId typeId = passiveNode.TypeDefinitionId;
if (IsNodeIdInNamespace(typeId) && typeId.IdType == IdType.Numeric)
{
switch ((uint)typeId.Identifier)
{
case ObjectTypes.ServerConfigurationType:
{
ServerConfigurationState activeNode = new ServerConfigurationState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
m_serverConfigurationNode = activeNode;
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
case ObjectTypes.CertificateGroupFolderType:
{
CertificateGroupFolderState activeNode = new CertificateGroupFolderState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
// delete unsupported groups
if (m_certificateGroups.FirstOrDefault(group => group.BrowseName == activeNode.DefaultHttpsGroup?.BrowseName) == null)
{
activeNode.DefaultHttpsGroup = null;
}
if (m_certificateGroups.FirstOrDefault(group => group.BrowseName == activeNode.DefaultUserTokenGroup?.BrowseName) == null)
{
activeNode.DefaultUserTokenGroup = null;
}
if (m_certificateGroups.FirstOrDefault(group => group.BrowseName == activeNode.DefaultApplicationGroup?.BrowseName) == null)
{
activeNode.DefaultApplicationGroup = null;
}
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
case ObjectTypes.CertificateGroupType:
{
var result = m_certificateGroups.FirstOrDefault(group => group.BrowseName == passiveNode.BrowseName);
if (result != null)
{
CertificateGroupState activeNode = new CertificateGroupState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
result.NodeId = activeNode.NodeId;
result.Node = activeNode;
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
}
break;
}
}
}
return base.AddBehaviourToPredefinedNode(context, predefinedNode);
}
#endregion
#region Public methods
/// <summary>
/// Creates the configuration node for the server.
/// </summary>
public void CreateServerConfiguration(
ServerSystemContext systemContext,
ApplicationConfiguration configuration
)
{
// setup server configuration node
m_serverConfigurationNode.ServerCapabilities.Value = configuration.ServerConfiguration.ServerCapabilities.ToArray();
m_serverConfigurationNode.ServerCapabilities.ValueRank = ValueRanks.OneDimension;
m_serverConfigurationNode.ServerCapabilities.ArrayDimensions = new ReadOnlyList<uint>(new List<uint> { 0 });
m_serverConfigurationNode.SupportedPrivateKeyFormats.Value = configuration.ServerConfiguration.SupportedPrivateKeyFormats.ToArray();
m_serverConfigurationNode.SupportedPrivateKeyFormats.ValueRank = ValueRanks.OneDimension;
m_serverConfigurationNode.SupportedPrivateKeyFormats.ArrayDimensions = new ReadOnlyList<uint>(new List<uint> { 0 });
m_serverConfigurationNode.MaxTrustListSize.Value = (uint)configuration.ServerConfiguration.MaxTrustListSize;
m_serverConfigurationNode.MulticastDnsEnabled.Value = configuration.ServerConfiguration.MultiCastDnsEnabled;
m_serverConfigurationNode.UpdateCertificate.OnCall = new UpdateCertificateMethodStateMethodCallHandler(UpdateCertificate);
m_serverConfigurationNode.CreateSigningRequest.OnCall = new CreateSigningRequestMethodStateMethodCallHandler(CreateSigningRequest);
m_serverConfigurationNode.ApplyChanges.OnCallMethod = new GenericMethodCalledEventHandler(ApplyChanges);
m_serverConfigurationNode.GetRejectedList.OnCall = new GetRejectedListMethodStateMethodCallHandler(GetRejectedList);
m_serverConfigurationNode.ClearChangeMasks(systemContext, true);
// setup certificate group trust list handlers
foreach (var certGroup in m_certificateGroups)
{
certGroup.Node.CertificateTypes.Value =
certGroup.CertificateTypes;
certGroup.Node.TrustList.Handle = new TrustList(
certGroup.Node.TrustList,
certGroup.TrustedStorePath,
certGroup.IssuerStorePath
);
certGroup.Node.ClearChangeMasks(systemContext, true);
}
}
#endregion
#region Private Methods
private ServiceResult UpdateCertificate(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId certificateGroupId,
NodeId certificateTypeId,
byte[] certificate,
byte[][] issuerCertificates,
string privateKeyFormat,
byte[] privateKey,
ref bool applyChangesRequired)
{
HasApplicationSecureAdminAccess(context);
if (certificate == null)
{
throw new ArgumentNullException(nameof(certificate));
}
ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);
// Yet no support to replace private key
if (!String.IsNullOrEmpty(privateKeyFormat))
{
throw new ArgumentException(nameof(privateKeyFormat));
}
if (privateKey != null)
{
throw new ArgumentException(nameof(privateKey));
}
// build issuer chain
X509CertificateCollection newIssuerCollection = new X509CertificateCollection();
foreach (byte[] issuerRawCert in issuerCertificates)
{
var newIssuerCert = new X509Certificate2(issuerRawCert);
newIssuerCollection.Add(newIssuerCert);
}
// TODO: Verify the public key of the new certificate against the own private key
// TODO: Verify the new cert chain
// TODO: Add new cert to application store
// TODO: Remove old cert from application store
// TODO: Add issuer certs to issuer store
return ServiceResult.Good;
}
private ServiceResult CreateSigningRequest(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId certificateGroupId,
NodeId certificateTypeId,
string subjectName,
bool regeneratePrivateKey,
byte[] nonce,
ref byte[] certificateRequest)
{
HasApplicationSecureAdminAccess(context);
ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);
// TODO: use new subject
if (!String.IsNullOrEmpty(subjectName))
{
throw new ArgumentException(nameof(subjectName));
}
// TODO: implement regeneratePrivateKey
// TODO: use nonce for generating the private key
var csrCertificate = CertificateFactory.CreateCertificateFromPKCS12(null, null);
certificateRequest = CertificateFactory.CreateSigningRequest(csrCertificate);
return ServiceResult.Good;
}
private ServiceResult ApplyChanges(
ISystemContext context,
MethodState method,
IList<object> inputArguments,
IList<object> outputArguments)
{
HasApplicationSecureAdminAccess(context);
// TODO: close all sessions, load new certificate
return StatusCodes.Good;
}
private ServiceResult GetRejectedList(
ISystemContext context,
MethodState method,
NodeId objectId,
ref byte[][] certificates)
{
HasApplicationSecureAdminAccess(context);
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_rejectedStorePath))
{
X509Certificate2Collection collection = store.Enumerate().Result;
List<byte[]> rawList = new List<byte[]>();
foreach (var cert in collection)
{
rawList.Add(cert.RawData);
}
certificates = rawList.ToArray();
}
return StatusCodes.Good;
}
private void HasApplicationSecureAdminAccess(ISystemContext context)
{
OperationContext operationContext = (context as SystemContext)?.OperationContext as OperationContext;
if (operationContext != null)
{
if (operationContext.ChannelContext?.EndpointDescription?.SecurityMode != MessageSecurityMode.SignAndEncrypt)
{
throw new ServiceResultException(StatusCodes.BadUserAccessDenied, "Secure Application Administrator access required.");
}
// TODO: role based access
UserIdentity user = context.UserIdentity as UserIdentity;
if (user.TokenType == UserTokenType.Anonymous)
{
throw new ServiceResultException(StatusCodes.BadUserAccessDenied, "Secure Application Administrator access required.");
}
}
}
private ServerCertificateGroup VerifyGroupAndTypeId(
NodeId certificateGroupId,
NodeId certificateTypeId
)
{
// verify requested certificate group
if (NodeId.IsNull(certificateGroupId))
{
certificateGroupId = ObjectIds.ServerConfigurationType_CertificateGroups_DefaultApplicationGroup;
}
ServerCertificateGroup certificateGroup = m_certificateGroups.FirstOrDefault(group => Utils.IsEqual(group.NodeId, certificateGroupId));
if (certificateGroup == null)
{
throw new ServiceResultException(StatusCodes.BadInvalidArgument, "Certificate Group not found.");
}
// verify certificate type
if (!NodeId.IsNull(certificateTypeId))
{
bool foundCertType = certificateGroup.CertificateTypes.Any(t => Utils.IsEqual(t, certificateTypeId));
if (!foundCertType)
{
throw new ServiceResultException(StatusCodes.BadInvalidArgument, "Certificate Type not supported.");
}
}
return certificateGroup;
}
#endregion
private class ServerCertificateGroup
{
public string BrowseName;
public NodeId NodeId;
public CertificateGroupState Node;
public NodeId[] CertificateTypes;
public string ApplicationStorePath;
public string IssuerStorePath;
public string TrustedStorePath;
};
#region Private Fields
private ServerConfigurationState m_serverConfigurationNode;
private IList<ServerCertificateGroup> m_certificateGroups;
public readonly string m_rejectedStorePath;
#endregion
}
}
@@ -1,133 +0,0 @@
/* ========================================================================
* Copyright (c) 2005-2016 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.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
namespace Opc.Ua.Server
{
/// <summary>
/// A Certificate Group Manager
/// </summary>
public class ServerConfigurationManager
{
#region Constructors
/// <summary>
/// Initializes the group manager.
/// </summary>
public ServerConfigurationManager(
ServerConfigurationState node,
ApplicationConfiguration configuration
)
{
node.ServerCapabilities.Value = configuration.ServerConfiguration.ServerCapabilities.ToArray();
node.ServerCapabilities.ValueRank = ValueRanks.OneDimension;
node.ServerCapabilities.ArrayDimensions = new ReadOnlyList<uint>(new List<uint> { 0 });
node.SupportedPrivateKeyFormats.Value = configuration.ServerConfiguration.SupportedPrivateKeyFormats.ToArray();
node.SupportedPrivateKeyFormats.ValueRank = ValueRanks.OneDimension;
node.SupportedPrivateKeyFormats.ArrayDimensions = new ReadOnlyList<uint>(new List<uint> { 0 });
node.MaxTrustListSize.Value = (uint)configuration.ServerConfiguration.MaxTrustListSize;
node.MulticastDnsEnabled.Value = configuration.ServerConfiguration.MultiCastDnsEnabled;
node.UpdateCertificate.OnCall += UpdateCertificate;
node.CreateSigningRequest.OnCall += CreateSigningRequest;
node.ApplyChanges.OnCallMethod += ApplyChanges;
node.GetRejectedList.OnCall += GetRejectedList;
m_node = node;
m_rejectedListPath = configuration.SecurityConfiguration.RejectedCertificateStore.StorePath;
}
#endregion
#region Private Methods
private ServiceResult UpdateCertificate(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId certificateGroupId,
NodeId certificateTypeId,
byte[] certificate,
byte[][] issuerCertificates,
string privateKeyFormat,
byte[] privateKey,
ref bool applyChangesRequired)
{
return StatusCodes.BadUserAccessDenied;
}
private ServiceResult CreateSigningRequest(
ISystemContext context,
MethodState method,
NodeId objectId,
NodeId certificateGroupId,
NodeId certificateTypeId,
string subjectName,
bool regeneratePrivateKey,
byte[] nonce,
ref byte[] certificateRequest)
{
return StatusCodes.BadUserAccessDenied;
}
private ServiceResult ApplyChanges(
ISystemContext context,
MethodState method,
IList<object> inputArguments,
IList<object> outputArguments)
{
return StatusCodes.BadUserAccessDenied;
}
private ServiceResult GetRejectedList(
ISystemContext context,
MethodState method,
NodeId objectId,
ref byte[][] certificates)
{
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_rejectedListPath))
{
X509Certificate2Collection collection = store.Enumerate().Result;
List<byte[]> rawList = new List<byte[]>();
foreach (var cert in collection)
{
rawList.Add(cert.RawData);
}
certificates = rawList.ToArray();
}
return StatusCodes.Good;
}
#endregion
#region Private Fields
private readonly string m_rejectedListPath;
private ServerConfigurationState m_node;
#endregion
}
}
@@ -39,8 +39,8 @@ namespace Opc.Ua.Server
public TrustList(Opc.Ua.TrustListState node, string trustedListPath, string issuerListPath)
{
m_node = node;
m_trustedListPath = trustedListPath;
m_issuerListPath = issuerListPath;
m_trustedStorePath = trustedListPath;
m_issuerStorePath = issuerListPath;
node.Open.OnCall = new OpenMethodStateMethodCallHandler(Open);
node.OpenWithMasks.OnCall = new OpenWithMasksMethodStateMethodCallHandler(OpenWithMasks);
@@ -104,7 +104,7 @@ namespace Opc.Ua.Server
{
SpecifiedLists = masks
};
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustedListPath))
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustedStorePath))
{
if ((masks & (uint)TrustListMasks.TrustedCertificates) != 0)
{
@@ -124,7 +124,7 @@ namespace Opc.Ua.Server
}
}
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_issuerListPath))
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_issuerStorePath))
{
if ((masks & (uint)TrustListMasks.IssuerCertificates) != 0)
{
@@ -262,7 +262,7 @@ namespace Opc.Ua.Server
byte[] certificate,
bool isTrustedCertificate)
{
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedListPath : m_issuerListPath))
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath))
{
store.Add(new X509Certificate2(certificate));
}
@@ -276,7 +276,7 @@ namespace Opc.Ua.Server
string certificate,
bool isTrustedCertificate)
{
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedListPath : m_issuerListPath))
using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath))
{
store.Delete(new X509Certificate2(certificate).Thumbprint);
}
@@ -288,8 +288,8 @@ namespace Opc.Ua.Server
private object m_lock = new object();
private NodeId m_sessionId;
private uint m_fileHandle;
private readonly string m_trustedListPath;
private readonly string m_issuerListPath;
private readonly string m_trustedStorePath;
private readonly string m_issuerStorePath;
private TrustListState m_node;
private Stream m_strm;
#endregion
@@ -347,53 +347,6 @@ namespace Opc.Ua.Server
return activeNode;
}
case ObjectTypes.ServerConfigurationType:
{
ServerConfigurationState activeNode = new ServerConfigurationState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
m_serverConfiguration = activeNode;
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
case ObjectTypes.CertificateGroupFolderType:
{
CertificateGroupFolderState activeNode = new CertificateGroupFolderState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
// delete unsupported groups
activeNode.DefaultHttpsGroup = null;
activeNode.DefaultUserTokenGroup = null;
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
case ObjectTypes.CertificateGroupType:
{
if (passiveNode.BrowseName == Opc.Ua.BrowseNames.DefaultApplicationGroup)
{
CertificateGroupState activeNode = new CertificateGroupState(passiveNode.Parent);
activeNode.Create(context, passiveNode);
m_defaultApplicationGroup = activeNode;
// replace the node in the parent.
if (passiveNode.Parent != null)
{
passiveNode.Parent.ReplaceChild(context, activeNode);
}
return activeNode;
}
}
}
return predefinedNode;
@@ -601,29 +554,6 @@ namespace Opc.Ua.Server
}
}
/// <summary>
/// Creates the configuration node for the server.
/// </summary>
public void CreateServerConfiguration(
ServerSystemContext systemContext,
ApplicationConfiguration configuration
)
{
m_serverConfigurationManager = new ServerConfigurationManager(
m_serverConfiguration,
configuration
);
m_defaultApplicationGroup.CertificateTypes.Value = new NodeId[] { ObjectTypeIds.ApplicationCertificateType };
m_defaultApplicationGroup.TrustList.Handle = new TrustList(
m_defaultApplicationGroup.TrustList,
configuration.SecurityConfiguration.TrustedPeerCertificates.StorePath,
configuration.SecurityConfiguration.TrustedIssuerCertificates.StorePath
);
m_defaultApplicationGroup.ClearChangeMasks(systemContext, true);
}
/// <summary>
/// Creates the diagnostics node for the server.
/// </summary>
@@ -1845,9 +1775,6 @@ namespace Opc.Ua.Server
private List<MonitoredItem> m_sampledItems;
private double m_minimumSamplingInterval;
private HistoryServerCapabilitiesState m_historyCapabilities;
private CertificateGroupState m_defaultApplicationGroup;
private ServerConfigurationState m_serverConfiguration;
private ServerConfigurationManager m_serverConfigurationManager;
#endregion
}
}
@@ -77,9 +77,9 @@ namespace Opc.Ua.Server
namespaceManagers[0] = registeredManagers = new List<INodeManager>();
namespaceManagers[1] = registeredManagers = new List<INodeManager>();
// always add the diagnostics node manager to the start of the list.
DiagnosticsNodeManager diagnosticsManager = new DiagnosticsNodeManager(server, configuration);
RegisterNodeManager(diagnosticsManager, registeredManagers, namespaceManagers);
// always add the diagnostics and configuration node manager to the start of the list.
ConfigurationNodeManager configurationAndDiagnosticsManager = new ConfigurationNodeManager(server, configuration);
RegisterNodeManager(configurationAndDiagnosticsManager, registeredManagers, namespaceManagers);
// add the core node manager second because the diagnostics node manager takes priority.
// always add the core node manager to the second of the list.
@@ -593,7 +593,7 @@ namespace Opc.Ua.Server
serverObject.ServerDiagnostics.EnabledFlag.OnSimpleReadValue = OnReadDiagnosticsEnabledFlag;
serverObject.ServerDiagnostics.EnabledFlag.OnSimpleWriteValue = OnWriteDiagnosticsEnabledFlag;
serverObject.ServerDiagnostics.EnabledFlag.MinimumSamplingInterval = 1000;
// initialize status.
ServerStatusDataType serverStatus = new ServerStatusDataType();
@@ -644,6 +644,10 @@ namespace Opc.Ua.Server
m_defaultSystemContext,
m_configuration.ServerConfiguration.DiagnosticsEnabled);
ConfigurationNodeManager configurationNodeManager = m_diagnosticsNodeManager as ConfigurationNodeManager;
configurationNodeManager?.CreateServerConfiguration(
m_defaultSystemContext,
m_configuration);
}
}
@@ -730,9 +734,9 @@ namespace Opc.Ua.Server
return ServiceResult.Good;
}
#endregion
#endregion
#region Private Fields
#region Private Fields
private ServerProperties m_serverDescription;
private ApplicationConfiguration m_configuration;
private List<Uri> m_endpointAddresses;
@@ -761,6 +765,6 @@ namespace Opc.Ua.Server
private ServerObjectState m_serverObject;
private ServerStatusValue m_serverStatus;
private ServerDiagnosticsSummaryDataType m_serverDiagnostics;
#endregion
#endregion
}
}