示例#1
0
        private void DeleteTokenPolicy(int number)
        {
            UserTokenPolicy userTokenPolicy = new UserTokenPolicy();

            switch (number)
            {
            case 0:
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                break;

            case 1:
                userTokenPolicy.TokenType = UserTokenType.UserName;
                break;

            case 2:
                userTokenPolicy.TokenType = UserTokenType.Certificate;
                break;

            default:
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                break;
            }
            foreach (UserTokenPolicy userToken in m_configuration.ServerConfiguration.UserTokenPolicies)
            {
                if (userTokenPolicy.TokenType == userToken.TokenType)
                {
                    m_configuration.ServerConfiguration.UserTokenPolicies.Remove(userToken);
                }
                break;
            }
        }
示例#2
0
        /// <summary>
        /// Creates the objects used to validate the user identity tokens supported by the server.
        /// </summary>
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                // create a validator for a certificate token policy.
                if (policy.TokenType == UserTokenType.Certificate)
                {
                    // check if user certificate trust lists are specified in configuration.
                    if (configuration.SecurityConfiguration.TrustedUserCertificates != null &&
                        configuration.SecurityConfiguration.UserIssuerCertificates != null)
                    {
                        CertificateValidator certificateValidator = new CertificateValidator();
                        certificateValidator.Update(configuration.SecurityConfiguration).Wait();
                        certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates,
                                                    configuration.SecurityConfiguration.TrustedUserCertificates,
                                                    configuration.SecurityConfiguration.RejectedCertificateStore);

                        // set custom validator for user certificates.
                        m_certificateValidator = certificateValidator.GetChannelValidator();
                    }
                }
            }
        }
示例#3
0
        /// <summary>
        /// Creates the endpoints and creates the hosts.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="bindingFactory">The binding factory.</param>
        /// <param name="serverDescription">The server description.</param>
        /// <param name="endpoints">The endpoints.</param>
        /// <returns>
        /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>.
        /// </returns>
        protected override IList <Task> InitializeServiceHosts(
            ApplicationConfiguration configuration,
            out ApplicationDescription serverDescription,
            out EndpointDescriptionCollection endpoints)
        {
            serverDescription = null;
            endpoints         = null;

            Dictionary <string, Task> hosts = new Dictionary <string, Task>();

            // ensure at least one security policy exists.
            if (configuration.ServerConfiguration.SecurityPolicies.Count == 0)
            {
                configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy());
            }

            // ensure at least one user token policy exists.
            if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0)
            {
                UserTokenPolicy userTokenPolicy = new UserTokenPolicy();

                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                userTokenPolicy.PolicyId  = userTokenPolicy.TokenType.ToString();

                configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
            }

            // set server description.
            serverDescription = new ApplicationDescription();

            serverDescription.ApplicationUri  = configuration.ApplicationUri;
            serverDescription.ApplicationName = new LocalizedText("en-US", configuration.ApplicationName);
            serverDescription.ApplicationType = configuration.ApplicationType;
            serverDescription.ProductUri      = configuration.ProductUri;
            serverDescription.DiscoveryUrls   = GetDiscoveryUrls();

            endpoints = new EndpointDescriptionCollection();
            IList <EndpointDescription> endpointsForHost = null;

            // create UA TCP host.
            endpointsForHost = CreateUaTcpServiceHost(
                hosts,
                configuration,
                configuration.ServerConfiguration.BaseAddresses,
                serverDescription,
                configuration.ServerConfiguration.SecurityPolicies);

            endpoints.InsertRange(0, endpointsForHost);

            // create HTTPS host.
            endpointsForHost = CreateHttpsServiceHost(
                hosts,
                configuration,
                configuration.ServerConfiguration.BaseAddresses,
                serverDescription,
                configuration.ServerConfiguration.SecurityPolicies);

            endpoints.AddRange(endpointsForHost);
            return(new List <Task>(hosts.Values));
        }
示例#4
0
        /// <summary>
        /// Creates the objects used to validate the user identity tokens supported by the server.
        /// </summary>
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                // create a validator for a certificate token policy.
                if (policy.TokenType == UserTokenType.Certificate)
                {
                    // the name of the element in the configuration file.
                    XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Opc.Ua.Namespaces.OpcUa);

                    // find the location of the trusted issuers.
                    CertificateTrustList trustedIssuers = configuration.ParseExtension <CertificateTrustList>(qname);

                    if (trustedIssuers == null)
                    {
                        Utils.Trace(
                            (int)Utils.TraceMasks.Error,
                            "Could not load CertificateTrustList for UserTokenPolicy {0}",
                            policy.PolicyId);

                        continue;
                    }

                    // trusts any certificate in the trusted people store.
                    m_certificateValidator = X509CertificateValidator.PeerTrust;
                }
            }
        }
        /// <summary>
        /// Creates the objects used to validate the user identity tokens supported by the server.
        /// </summary>
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                // ignore policies without an explicit id.
                if (String.IsNullOrEmpty(policy.PolicyId))
                {
                    continue;
                }

                // create a validator for an issued token policy.
                if (policy.TokenType == UserTokenType.IssuedToken)
                {
                    // the name of the element in the configuration file.
                    XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Namespaces.OpcUa);

                    // find the id for the issuer certificate.
                    CertificateIdentifier id = configuration.ParseExtension <CertificateIdentifier>(qname);

                    if (id == null)
                    {
                        Utils.Trace(
                            (int)Utils.TraceMasks.Error,
                            "Could not load CertificateIdentifier for UserTokenPolicy {0}",
                            policy.PolicyId);

                        continue;
                    }

                    m_tokenResolver   = CreateSecurityTokenResolver(id);
                    m_tokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
                }

                // create a validator for a certificate token policy.
                if (policy.TokenType == UserTokenType.Certificate)
                {
                    // the name of the element in the configuration file.
                    XmlQualifiedName qname = new XmlQualifiedName(policy.PolicyId, Namespaces.OpcUa);

                    // find the location of the trusted issuers.
                    CertificateTrustList trustedIssuers = configuration.ParseExtension <CertificateTrustList>(qname);

                    if (trustedIssuers == null)
                    {
                        Utils.Trace(
                            (int)Utils.TraceMasks.Error,
                            "Could not load CertificateTrustList for UserTokenPolicy {0}",
                            policy.PolicyId);

                        continue;
                    }

                    // trusts any certificate in the trusted people store.
                    m_certificateValidator = X509CertificateValidator.PeerTrust;
                }
            }
        }
 /// <inheritdoc/>
 public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenPolicy userTokenPolicy)
 {
     if (userTokenPolicy == null)
     {
         throw new ArgumentNullException(nameof(userTokenPolicy));
     }
     ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
     return(this);
 }
        /// <summary>
        /// Convert user token policy to service model
        /// </summary>
        /// <param name="policy"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public static AuthenticationMethodModel ToServiceModel(this UserTokenPolicy policy,
                                                               IJsonSerializer serializer)
        {
            if (policy == null)
            {
                return(null);
            }
            var result = new AuthenticationMethodModel {
                Id             = policy.PolicyId,
                SecurityPolicy = policy.SecurityPolicyUri
            };

            switch (policy.TokenType)
            {
            case UserTokenType.Anonymous:
                result.CredentialType = CredentialType.None;
                break;

            case UserTokenType.UserName:
                result.CredentialType = CredentialType.UserName;
                break;

            case UserTokenType.Certificate:
                result.CredentialType = CredentialType.X509Certificate;
                result.Configuration  = policy.IssuerEndpointUrl;
                break;

            case UserTokenType.IssuedToken:
                switch (policy.IssuedTokenType)
                {
                case "http://opcfoundation.org/UA/UserToken#JWT":
                    result.CredentialType = CredentialType.JwtToken;
                    try {
                        // See part 6
                        result.Configuration = serializer.Parse(
                            policy.IssuerEndpointUrl);
                    }
                    catch {
                        // Store as string
                        result.Configuration = policy.IssuerEndpointUrl;
                    }
                    break;

                default:
                    // TODO
                    return(null);
                }
                break;

            default:
                return(null);
            }
            return(result);
        }
示例#8
0
        /// <summary>
        /// Creates a user identity for the policy.
        /// </summary>
        private IUserIdentity CreateUserIdentity(UserTokenPolicy policy)
        {
            if (policy == null || policy.TokenType == UserTokenType.Anonymous)
            {
                return(null);
            }

            if (policy.TokenType == UserTokenType.UserName)
            {
                return(new UserIdentity("SomeUser", "password"));
            }

            if (policy.TokenType == UserTokenType.Certificate)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                try
                {
                    foreach (X509Certificate2 certificate in store.Certificates)
                    {
                        if (certificate.HasPrivateKey)
                        {
                            return(new UserIdentity(certificate));
                        }
                    }

                    return(null);
                }
                finally
                {
                    store.Close();
                }
            }

            if (policy.TokenType == UserTokenType.IssuedToken)
            {
                CertificateIdentifier userid = new CertificateIdentifier();

                userid.StoreType   = CertificateStoreType.Windows;
                userid.StorePath   = "LocalMachine\\Root";
                userid.SubjectName = "UASampleRoot";

                X509Certificate2  certificate  = userid.Find();
                X509SecurityToken signingToken = new X509SecurityToken(certificate);

                SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken);

                return(new UserIdentity(token));
            }

            throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported.");
        }
示例#9
0
        /// <summary>
        /// Caches application description and list of available endpoints.
        /// </summary>
        private void InitializeApplicationDescription()
        {
            // this method is caches the information the first time a client connects.
            if (m_application == null)
            {
                // the serviceCertificate element in the app.config file controls what certificate is loaded.
                m_serverCertificate = OperationContext.Current.Host.Credentials.ServiceCertificate.Certificate;

                // the URL may be the discovery or the session endpoint. need to store the session endpoint.
                string endpointUrl = OperationContext.Current.Channel.LocalAddress.ToString();

                if (endpointUrl.EndsWith("/discovery", StringComparison.InvariantCulture))
                {
                    endpointUrl = endpointUrl.Substring(0, endpointUrl.Length - "/discovery".Length);
                }

                // The EndpointDescription stores the information specified in the ISessionEndpoint binding.
                // This structure is used in the UA discovery services and allows client applications to
                // discover what security settings are used by the server.

                EndpointDescription endpoint = new EndpointDescription();

                endpoint.EndpointUrl         = endpointUrl;
                endpoint.SecurityMode        = MessageSecurityMode.SignAndEncrypt_3;
                endpoint.SecurityPolicyUri   = SecurityPolicies.Basic128Rsa15;
                endpoint.ServerCertificate   = m_serverCertificate.GetRawCertData();
                endpoint.TransportProfileUri = Profiles.WsHttpXmlTransport;

                endpoint.Server = new ApplicationDescription();
                endpoint.Server.ApplicationUri  = ApplicationUri;
                endpoint.Server.ApplicationType = ApplicationType.Server_0;
                endpoint.Server.DiscoveryUrls   = new ListOfString();
                endpoint.Server.DiscoveryUrls.Add(endpointUrl + "/discovery");

                // no authorization supported at this time.
                UserTokenPolicy userTokenPolicy = new UserTokenPolicy();
                userTokenPolicy.TokenType   = UserTokenType.Anonymous_0;
                endpoint.UserIdentityTokens = new ListOfUserTokenPolicy();
                endpoint.UserIdentityTokens.Add(userTokenPolicy);

                m_application = endpoint.Server;

                // If the server supports multiple bindings it will need multiple EndpointDescriptions. These
                // structures can be constructed automatically from the bindings in the OperationContext object
                // This example simply hard codes the settings so a mismatch between the app.config could cause
                // problems.

                m_endpoints = new ListOfEndpointDescription();
                m_endpoints.Add(endpoint);
            }
        }
        /// <summary>
        /// Updates an item in the control.
        /// </summary>
        protected override void UpdateItem(ListViewItem listItem, object item)
        {
            ConfiguredEndpoint endpoint = listItem.Tag as ConfiguredEndpoint;

            if (endpoint == null)
            {
                base.UpdateItem(listItem, endpoint);
                return;
            }

            string hostname = "<Unknown>";
            string protocol = "<Unknown>";

            Uri uri = endpoint.EndpointUrl;

            if (uri != null)
            {
                hostname = uri.DnsSafeHost;
                protocol = uri.Scheme;
            }

            listItem.SubItems[0].Text = String.Format("{0}", endpoint.Description.Server.ApplicationName);
            listItem.SubItems[1].Text = String.Format("{0}", hostname);
            listItem.SubItems[2].Text = String.Format("{0}", protocol);

            listItem.SubItems[3].Text = String.Format(
                "{0}/{1}",
                SecurityPolicies.GetDisplayName(endpoint.Description.SecurityPolicyUri),
                endpoint.Description.SecurityMode);

            listItem.SubItems[4].Text = "<Unknown>";

            UserTokenPolicy policy = endpoint.SelectedUserTokenPolicy;

            if (policy != null)
            {
                StringBuilder buffer = new StringBuilder();

                buffer.Append(policy.TokenType);

                if (endpoint.UserIdentity != null)
                {
                    buffer.Append("/");
                    buffer.Append(endpoint.UserIdentity);
                }

                listItem.SubItems[4].Text = buffer.ToString();
            }

            listItem.ImageKey = GuiUtils.Icons.Process;
        }
            /// <summary>
            /// Decode user identity token from binary extension object.
            /// </summary>
            /// <param name="identityToken"></param>
            /// <param name="policy"></param>
            /// <returns></returns>
            private UserIdentityToken DecodeUserIdentityToken(ExtensionObject identityToken,
                                                              out UserTokenPolicy policy)
            {
                if (identityToken.Encoding != ExtensionObjectEncoding.Binary ||
                    !typeof(byte[]).IsInstanceOfType(identityToken.Body))
                {
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                        "Invalid user identity token provided.");
                }
                if (!(BaseVariableState.DecodeExtensionObject(null, typeof(UserIdentityToken),
                                                              identityToken, false) is UserIdentityToken token))
                {
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                        "Invalid user identity token provided.");
                }
                policy = Endpoint.FindUserTokenPolicy(token.PolicyId);
                if (policy == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                        "User token policy not supported.", "ValidateUserIdentityToken");
                }
                switch (policy.TokenType)
                {
                case UserTokenType.Anonymous:
                    return(BaseVariableState.DecodeExtensionObject(null,
                                                                   typeof(AnonymousIdentityToken), identityToken, true)
                           as AnonymousIdentityToken);

                case UserTokenType.UserName:
                    return(BaseVariableState.DecodeExtensionObject(null,
                                                                   typeof(UserNameIdentityToken), identityToken, true)
                           as UserNameIdentityToken);

                case UserTokenType.Certificate:
                    return(BaseVariableState.DecodeExtensionObject(null,
                                                                   typeof(X509IdentityToken), identityToken, true)
                           as X509IdentityToken);

                case UserTokenType.IssuedToken:
                    return(BaseVariableState.DecodeExtensionObject(null,
                                                                   typeof(IssuedIdentityToken), identityToken, true)
                           as IssuedIdentityToken);

                default:
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                        "Invalid user identity token provided.");
                }
            }
        /// <summary>
        /// Validate user identity
        /// </summary>
        /// <param name="newIdentity"></param>
        /// <param name="userTokenPolicy"></param>
        /// <returns></returns>
        private static IUserIdentity ValidateUserIdentity(UserIdentityToken newIdentity,
                                                          UserTokenPolicy userTokenPolicy)
        {
            System.Diagnostics.Contracts.Contract.Ensures(userTokenPolicy != null);
            try {
                IUserIdentity identity          = null;
                IUserIdentity effectiveIdentity = null;

                // Validate the identity token and impersonate user.

                // TODO

                // lock (_eventLock) {
                // if (_impersonateUser != null) {
                //
                //     var args = new ImpersonateEventArgs(newIdentity, userTokenPolicy);
                //     _impersonateUser(session, args);
                //
                //     if (ServiceResult.IsBad(args.IdentityValidationError)) {
                //         error = args.IdentityValidationError;
                // if (ServiceResult.IsBad(error)) {
                //     throw new ServiceResultException(error);
                // }
                //     }
                //     else {
                //         identity = args.Identity;
                //         return args.EffectiveIdentity;
                //     }
                // }
                // }

                // check for validation error.
                if (identity == null)
                {
                    identity = new UserIdentity(newIdentity);
                }
                // use the identity as the effectiveIdentity if not provided.
                return(effectiveIdentity ?? identity);
            }
            catch (ServiceResultException) {
                throw;
            }
            catch (Exception e) {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                    e, "Could not validate user identity token: {0}", newIdentity);
            }
        }
示例#13
0
        /// <summary>
        /// Updates an item in the control.
        /// </summary>
        public void UpdateItem(ListViewItem listItem, object item)
        {
            ConfiguredEndpoint endpoint = listItem.Tag as ConfiguredEndpoint;

            if (endpoint == null)
            {
                listItem.Tag = endpoint;
                return;
            }

            string hostname = "<Unknown>";
            string protocol = "<Unknown>";

            Uri uri = endpoint.EndpointUrl;

            if (uri != null)
            {
                hostname = uri.DnsSafeHost;
                protocol = uri.Scheme;
            }

            String          user   = "******";
            UserTokenPolicy policy = endpoint.SelectedUserTokenPolicy;

            if (policy != null)
            {
                StringBuilder buffer = new StringBuilder();
                buffer.Append(policy.TokenType);
                if (endpoint.UserIdentity != null)
                {
                    buffer.Append("/");
                    buffer.Append(endpoint.UserIdentity);
                }
                user = buffer.ToString();
            }

            listItem.Content = String.Format("Application: {0}\r\nHost: {1}\r\nProtocol: {2}\r\nSecurity: {3}/{4}\r\nUser: {5}",
                                             endpoint.Description.Server.ApplicationName,
                                             hostname,
                                             protocol,
                                             SecurityPolicies.GetDisplayName(endpoint.Description.SecurityPolicyUri),
                                             endpoint.Description.SecurityMode,
                                             user);
        }
        /// <summary>
        /// Finds the best match for the current protocol and security selections.
        /// </summary>
        private int FindBestUserTokenPolicy(EndpointDescription endpoint)
        {
            // filter by the current token type.
            UserTokenType currentTokenType = UserTokenType.Anonymous;

            if (UserTokenTypeCB.SelectedIndex != -1)
            {
                currentTokenType = (UserTokenType)UserTokenTypeCB.SelectedItem;
            }

            // filter by issued token type.
            string currentIssuedTokenType = (string)IssuedTokenTypeCB.SelectedItem;

            // find all matching descriptions.
            UserTokenPolicyCollection matches = new UserTokenPolicyCollection();

            if (endpoint != null)
            {
                for (int ii = 0; ii < endpoint.UserIdentityTokens.Count; ii++)
                {
                    UserTokenPolicy policy = endpoint.UserIdentityTokens[ii];

                    if (currentTokenType != policy.TokenType)
                    {
                        continue;
                    }

                    if (policy.TokenType == UserTokenType.IssuedToken)
                    {
                        if (currentIssuedTokenType != policy.IssuedTokenType)
                        {
                            continue;
                        }
                    }

                    return(ii);
                }
            }

            return(-1);
        }
示例#15
0
        private void CreateUserIdentityValidators(ApplicationConfiguration configuration)
        {
            for (int ii = 0; ii < configuration.ServerConfiguration.UserTokenPolicies.Count; ii++)
            {
                UserTokenPolicy policy = configuration.ServerConfiguration.UserTokenPolicies[ii];

                if (policy.TokenType == UserTokenType.Certificate)
                {
                    if (configuration.SecurityConfiguration.TrustedUserCertificates != null &&
                        configuration.SecurityConfiguration.UserIssuerCertificates != null)
                    {
                        CertificateValidator certificateValidator = new CertificateValidator();
                        certificateValidator.Update(configuration.SecurityConfiguration).Wait();
                        certificateValidator.Update(configuration.SecurityConfiguration.UserIssuerCertificates,
                                                    configuration.SecurityConfiguration.TrustedUserCertificates,
                                                    configuration.SecurityConfiguration.RejectedCertificateStore);

                        m_userCertificateValidator = certificateValidator.GetChannelValidator();
                    }
                }
            }
        }
示例#16
0
        private IUserIdentity GetKerberosToken()
        {
            // need to get the service principal name from the user token policy.
            UserTokenPolicy policy = (UserTokenPolicy)KerberosTAB.Tag;

            if (policy == null)
            {
                return(null);
            }

            // The ServicePrincipalName (SPN) for the UA Server must be specified as the IssuerEndpointUrl

            // The ServicePrincipalName (SPN) must be registered with the Kerberos Ticket Granting Server (e.g. Windows Domain Controller).
            // The SPN identifies the host that UA server is running on and the name of the application.
            // A domain admin must grant delegate permission to the domain account that the UA server runs under.
            // That can be done with the setspn.exe utility:

            // setspn -U -S <hostname>/<exename> <domain accountname>
            // setspn -C -S <hostname>/<exename> <hostname>

            // The latter form is used if the UA server runs a Windows Service using the builtin Windows Service account.

            // NOTE: Using the KerberosSecurityTokenProvider without the NetworkCredential parameter will use the
            // the credentials of the client process,

            // create the token provider.
            KerberosSecurityTokenProvider provider = new KerberosSecurityTokenProvider(
                policy.IssuerEndpointUrl,
                System.Security.Principal.TokenImpersonationLevel.Impersonation,
                new System.Net.NetworkCredential(KerberosUserNameTB.Text, KerberosPasswordTB.Text, KerberosDomainTB.Text));

            // create the token (1 minute timeout looking for the server).
            KerberosRequestorSecurityToken token = (KerberosRequestorSecurityToken)provider.GetToken(new TimeSpan(0, 1, 0));

            // TODO
            // return new UserIdentity(token);
            throw new NotImplementedException();
        }
示例#17
0
        private void AddTokenPolicy(int number)
        {
            UserTokenPolicy userTokenPolicy = new UserTokenPolicy();

            switch (number)
            {
            case 0:
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                break;

            case 1:
                userTokenPolicy.TokenType = UserTokenType.UserName;
                break;

            case 2:
                userTokenPolicy.TokenType = UserTokenType.Certificate;
                break;

            default:
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                break;
            }
            userTokenPolicy.PolicyId = userTokenPolicy.TokenType.ToString();
            int i = 0;

            foreach (UserTokenPolicy userToken in m_configuration.ServerConfiguration.UserTokenPolicies)
            {
                if (userTokenPolicy.TokenType == userToken.TokenType)
                {
                    i++;
                }
            }
            if (i == 0)
            {
                m_configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
            }
        }
        /// <summary>
        /// Convert service model to user token policy
        /// </summary>
        /// <param name="policy"></param>
        /// <returns></returns>
        public static UserTokenPolicy ToStackModel(this AuthenticationMethodModel policy)
        {
            if (policy == null)
            {
                return(null);
            }
            var result = new UserTokenPolicy {
                SecurityPolicyUri = policy.SecurityPolicy,
                PolicyId          = policy.Id
            };

            switch (policy.CredentialType)
            {
            case CredentialType.None:
                result.TokenType = UserTokenType.Anonymous;
                break;

            case CredentialType.UserName:
                result.TokenType = UserTokenType.UserName;
                break;

            case CredentialType.X509Certificate:
                result.TokenType = UserTokenType.Certificate;
                break;

            case CredentialType.JwtToken:
                result.TokenType         = UserTokenType.IssuedToken;
                result.IssuedTokenType   = "http://opcfoundation.org/UA/UserToken#JWT";
                result.IssuerEndpointUrl = policy.Configuration?.ToString();
                break;

            default:
                return(null);
            }
            return(result);
        }
        /// <summary>
        /// Validates the identity token supplied by the client.
        /// </summary>
        private UserIdentityToken ValidateUserIdentityToken(
            ExtensionObject identityToken,
            SignatureData userTokenSignature,
            out UserTokenPolicy policy )
        {
            policy = null;

            // check for empty token.
            if (identityToken == null || identityToken.Body == null)
            {
                // not changing the token if already activated.
                if (m_activated)
                {
                    return null;
                }

                // check if an anonymous login is permitted.
                if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0)
                {
                    bool found = false;

                    for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++)
                    {
                        if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous)
                        {
                            found = true;
                            policy = m_endpoint.UserIdentityTokens[ii];
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported.");
                    }
                }

                // create an anonymous token to use for subsequent validation.
                AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken();
                anonymousToken.PolicyId = policy.PolicyId;
                return anonymousToken;
            }

            UserIdentityToken token = null;
            // check for unrecognized token.
            if (!typeof( UserIdentityToken ).IsInstanceOfType( identityToken.Body ))
            {
                //handle the use case when the UserIdentityToken is binary encoded over xml message encoding
                if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof( byte[] ).IsInstanceOfType( identityToken.Body ))
                {
                    UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject( null, typeof( UserIdentityToken ), identityToken, false ) as UserIdentityToken;
                    if (newToken == null)
                    {
                        throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                    }

                    policy = m_endpoint.FindUserTokenPolicy( newToken.PolicyId );
                    if (policy == null)
                    {
                        throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken" );
                    }
                    switch (policy.TokenType)
                    {
                        case UserTokenType.Anonymous:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( AnonymousIdentityToken ), identityToken, true ) as AnonymousIdentityToken;
                            break;
                        case UserTokenType.UserName:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( UserNameIdentityToken ), identityToken, true ) as UserNameIdentityToken;
                            break;
                        case UserTokenType.Certificate:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( X509IdentityToken ), identityToken, true ) as X509IdentityToken;
                            break;
                        case UserTokenType.IssuedToken:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( IssuedIdentityToken ), identityToken, true ) as IssuedIdentityToken;
                            break;
                        default:
                            throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                    }
                }
                else
                {
                    throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                }
            }
            else
            {
                // get the token.
                token = (UserIdentityToken) identityToken.Body;
            }

            // find the user token policy.
            policy = m_endpoint.FindUserTokenPolicy( token.PolicyId );

            if (policy == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported.");
            }

            // determine the security policy uri.
            string securityPolicyUri = policy.SecurityPolicyUri;

            if (String.IsNullOrEmpty( securityPolicyUri ))
            {
                securityPolicyUri = m_endpoint.SecurityPolicyUri;
            }

            if (ServerBase.RequireEncryption(m_endpoint))
            {
                // decrypt the token.
                if (m_serverCertificate == null)
                {
                    m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true);

                    // check for valid certificate.
                    if (m_serverCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found.");
                    }
                }

                try
                {
                    token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri);
                }
                catch (Exception e)
                {
                    if (e is ServiceResultException)
                    {
                        throw;
                    }

                    throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token.");
                }

                // verify the signature.
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                    {
                        throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid, "Invalid user signature!");
                    }
                }
            }
				
            // validate user identity token.
            return token;
        }
 /// <inheritdoc/>
 public IApplicationConfigurationBuilderServerSelected AddUserTokenPolicy(UserTokenPolicy userTokenPolicy)
 {
     ApplicationConfiguration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
     return(this);
 }
        /// <summary>
        /// Creates the endpoints and creates the hosts.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="bindingFactory">The binding factory.</param>
        /// <param name="serverDescription">The server description.</param>
        /// <param name="endpoints">The endpoints.</param>
        /// <returns>
        /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>.
        /// </returns>
        protected override IList<IBackgroundTask> InitializeServiceHosts(
            ApplicationConfiguration          configuration, 
            BindingFactory                    bindingFactory,
            out ApplicationDescription        serverDescription,
            out EndpointDescriptionCollection endpoints)
        {
            serverDescription = null;
            endpoints = null;

            Dictionary<string, IBackgroundTask> hosts = new Dictionary<string, IBackgroundTask>();

            // ensure at least one security policy exists.
            if (configuration.ServerConfiguration.SecurityPolicies.Count == 0)
            {                   
                configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy());
            }
            
            // ensure at least one user token policy exists.
            if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0)
            {                   
                UserTokenPolicy userTokenPolicy = new UserTokenPolicy();
                
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                userTokenPolicy.PolicyId  = userTokenPolicy.TokenType.ToString();

                configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
            }

            // set server description.
            serverDescription = new ApplicationDescription();

            serverDescription.ApplicationUri = configuration.ApplicationUri;
            serverDescription.ApplicationName = configuration.ApplicationName;
            serverDescription.ApplicationType = configuration.ApplicationType;
            serverDescription.ProductUri = configuration.ProductUri;
            serverDescription.DiscoveryUrls = GetDiscoveryUrls();
                          
            endpoints = new EndpointDescriptionCollection();
            IList<EndpointDescription> endpointsForHost = null;

            // create hosts for protocols that require one endpoints per security policy
            foreach (ServerSecurityPolicy securityPolicy in configuration.ServerConfiguration.SecurityPolicies)
            {
                endpointsForHost = CreateSinglePolicyServiceHost(
                    hosts,
                    configuration,
                    bindingFactory, 
                    configuration.ServerConfiguration.BaseAddresses, 
                    serverDescription,
                    securityPolicy.SecurityMode, 
                    securityPolicy.SecurityPolicyUri,
                    String.Empty);

                for (int ii = 0; ii < endpointsForHost.Count; ii++)
                {
                    endpointsForHost[ii].SecurityLevel = securityPolicy.SecurityLevel;
                }

                endpoints.AddRange(endpointsForHost);
            }

            // create UA TCP host.
            endpointsForHost = CreateUaTcpServiceHost(
                hosts,
                configuration,
                bindingFactory,
                configuration.ServerConfiguration.BaseAddresses,
                serverDescription,
                configuration.ServerConfiguration.SecurityPolicies);

            endpoints.InsertRange(0, endpointsForHost);

            // create HTTPS host.
            endpointsForHost = CreateHttpsServiceHost(
                hosts,
                configuration,
                bindingFactory, 
                configuration.ServerConfiguration.BaseAddresses, 
                serverDescription,
                configuration.ServerConfiguration.SecurityPolicies);

            endpoints.AddRange(endpointsForHost);

            return new List<IBackgroundTask>(hosts.Values);
        }
示例#22
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy, EndpointDescription endpointDescription = null)
 {
     m_newIdentity         = newIdentity;
     m_userTokenPolicy     = userTokenPolicy;
     m_endpointDescription = endpointDescription;
 }
示例#23
0
        /// <summary>
        /// Validates the identity token supplied by the client.
        /// </summary>
        private UserIdentityToken ValidateUserIdentityToken(
            ExtensionObject identityToken,
            SignatureData userTokenSignature,
            out UserTokenPolicy policy)
        {
            policy = null;

            // check for empty token.
            if (identityToken == null || identityToken.Body == null)
            {
                // not changing the token if already activated.
                if (m_activated)
                {
                    return(null);
                }

                // check if an anonymous login is permitted.
                if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0)
                {
                    bool found = false;

                    for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++)
                    {
                        if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous)
                        {
                            found  = true;
                            policy = m_endpoint.UserIdentityTokens[ii];
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported.");
                    }
                }

                // create an anonymous token to use for subsequent validation.
                AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken();
                anonymousToken.PolicyId = policy.PolicyId;
                return(anonymousToken);
            }

            UserIdentityToken token = null;

            // check for unrecognized token.
            if (!typeof(UserIdentityToken).IsInstanceOfType(identityToken.Body))
            {
                //handle the use case when the UserIdentityToken is binary encoded over xml message encoding
                if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof(byte[]).IsInstanceOfType(identityToken.Body))
                {
                    UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject(null, typeof(UserIdentityToken), identityToken, false) as UserIdentityToken;
                    if (newToken == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                    }

                    policy = m_endpoint.FindUserTokenPolicy(newToken.PolicyId);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken");
                    }
                    switch (policy.TokenType)
                    {
                    case UserTokenType.Anonymous:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(AnonymousIdentityToken), identityToken, true) as AnonymousIdentityToken;
                        break;

                    case UserTokenType.UserName:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(UserNameIdentityToken), identityToken, true) as UserNameIdentityToken;
                        break;

                    case UserTokenType.Certificate:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(X509IdentityToken), identityToken, true) as X509IdentityToken;
                        break;

                    case UserTokenType.IssuedToken:
                        token = BaseVariableState.DecodeExtensionObject(null, typeof(IssuedIdentityToken), identityToken, true) as IssuedIdentityToken;
                        break;

                    default:
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                    }
                }
                else
                {
                    throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Invalid user identity token provided.");
                }
            }
            else
            {
                // get the token.
                token = (UserIdentityToken)identityToken.Body;
            }

            // find the user token policy.
            policy = m_endpoint.FindUserTokenPolicy(token.PolicyId);

            if (policy == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported.");
            }

            // determine the security policy uri.
            string securityPolicyUri = policy.SecurityPolicyUri;

            if (String.IsNullOrEmpty(securityPolicyUri))
            {
                securityPolicyUri = m_endpoint.SecurityPolicyUri;
            }

            if (ServerBase.RequireEncryption(m_endpoint))
            {
                // decrypt the token.
                if (m_serverCertificate == null)
                {
                    m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true);

                    // check for valid certificate.
                    if (m_serverCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found.");
                    }
                }

                try
                {
                    token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri);
                }
                catch (Exception e)
                {
                    if (e is ServiceResultException)
                    {
                        throw;
                    }

                    throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token.");
                }

                // verify the signature.
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                    {
                        throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid, "Invalid user signature!");
                    }
                }
            }

            // validate user identity token.
            return(token);
        }
示例#24
0
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext context,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            byte[]                    serverNonce,
            out UserIdentityToken identityToken,
            out UserTokenPolicy userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);
                    //byte[] dataToSign = Utils.Append(m_serverCertificateChain, m_serverNonce);

                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }
                }

                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
示例#25
0
 public UserTokenItem(UserTokenType tokenType)
 {
     Policy = new UserTokenPolicy(tokenType);
 }
示例#26
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy)
 {
     m_newIdentity     = newIdentity;
     m_userTokenPolicy = userTokenPolicy;
 }
示例#27
0
        public async Task <Session> CreateSession(OPCUAServer server, string sessionName)
        {
            try
            {
                lock (dicOfSession)
                {
                    if (dicOfSession.ContainsKey(sessionName))
                    {
                        return(dicOfSession[sessionName]);
                    }
                }


                #region OPCUAServer
                UAServer objUAServer = new UAServer();
                objUAServer.Protocol           = server.protocol;
                objUAServer.SecurityMode       = server.securityMode;
                objUAServer.SecurityPolicy     = server.securityMode;
                objUAServer.SecurityPolicy     = server.securityPolicy;
                objUAServer.UserIdentityString = server.UserIdentityString;
                objUAServer.ServerName         = server.serverName;
                try
                {
                    objUAServer.UserIdentity = (UserIdentityType)Enum.Parse(typeof(UserIdentityType), objUAServer.UserIdentityString);
                }
                catch
                {
                    if (objUAServer.UserIdentityString.Equals("Anonymous"))
                    {
                        objUAServer.UserIdentity = UserIdentityType.Anonymous;
                    }
                    else if (objUAServer.UserIdentityString.Equals("UserName"))
                    {
                        objUAServer.UserIdentity = UserIdentityType.UserName;
                    }
                    else
                    {
                        objUAServer.UserIdentity = UserIdentityType.Certificate;
                    }
                }

                if (objUAServer.UserIdentity.Equals(UserIdentityType.Certificate))
                {
                    objUAServer.IsSecurityStoreEnabled = false;
                    objUAServer.CertificationPath      = server.certificationPath;
                    objUAServer.CertificationPassword  = server.certificationPassword;
                }
                else if (objUAServer.UserIdentity.Equals(UserIdentityType.UserName))
                {
                    objUAServer.UserName     = server.userName;
                    objUAServer.UserPassword = server.userPassword;
                }
                #endregion

                await CheckAndLoadConfiguration();

                // Create the configuration.
                ApplicationConfiguration configuration = _appConfiguration; // Helpers.CreateClientConfiguration(myServer);

                // Create the endpoint description.
                EndpointDescription endpointDescription = Helpers.CreateEndpointDescription(objUAServer);

                // Create the endpoint configuration (use the application configuration to provide default values).
                EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

                // The default timeout for a requests sent using the channel.
                endpointConfiguration.OperationTimeout = 300000;

                // Use the pure binary encoding on the wire.
                //OA-2018-04-11
                // endpointConfiguration.UseBinaryEncoding = true;
                if (objUAServer.MessageEncoding.ToLower().Equals("binary"))
                {
                    endpointConfiguration.UseBinaryEncoding = true;
                }
                else
                {
                    endpointConfiguration.UseBinaryEncoding = false;
                }

                IUserIdentity identity;


                var t = _appConfiguration.SecurityConfiguration.ApplicationCertificate.Find(true);
                X509Certificate2 clientCertificate = t.Result;

                UserTokenPolicy poly;


                if (objUAServer.UserIdentity.Equals(UserIdentityType.UserName))
                {
                    identity = new UserIdentity(objUAServer.UserName, objUAServer.UserPassword);
                    poly     = new UserTokenPolicy(UserTokenType.UserName);
                    //added by kais wali
                    bool exist = false;
                    foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens)
                    {
                        if (poltemp.TokenType.ToString() == poly.TokenType.ToString())
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist)
                    {
                        endpointDescription.UserIdentityTokens.Add(poly);
                    }
                }
                else if (objUAServer.UserIdentity.Equals(UserIdentityType.Certificate))
                {
                    CertificateIdentifier certificateIdentifier = new CertificateIdentifier();
                    X509Certificate2      currentCertificate;
                    certificateIdentifier.StoreType = CertificateStoreType.Directory;
                    currentCertificate = new X509Certificate2(objUAServer.CertificationPath, objUAServer.CertificationPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
                    if (currentCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Could not find certificate: {0}", certificateIdentifier.SubjectName);
                    }
                    identity = new UserIdentity(currentCertificate);
                    //

                    poly = new UserTokenPolicy(UserTokenType.Certificate);
                    //added by kais wali
                    bool exist = false;
                    foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens)
                    {
                        if (poltemp.TokenType.ToString() == poly.TokenType.ToString())
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist)
                    {
                        endpointDescription.UserIdentityTokens.Add(poly);
                    }
                }
                else
                {
                    identity = new UserIdentity();
                    poly     = new UserTokenPolicy(UserTokenType.Anonymous);
                    //added by kais wali
                    bool exist = false;
                    foreach (UserTokenPolicy poltemp in endpointDescription.UserIdentityTokens)
                    {
                        if (poltemp.TokenType.ToString() == poly.TokenType.ToString())
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (!exist)
                    {
                        endpointDescription.UserIdentityTokens.Add(poly);
                    }
                }

                // Create the endpoint.
                ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);

                // Update endpoint description using the discovery endpoint.
                // create message context.
                ServiceMessageContext messageContext = configuration.CreateMessageContext();

                //Set to true in default configuration (If the user have not configured an OPC UA Server in the ONBS)
                endpoint.UpdateBeforeConnect = false;
                // update endpoint description using the discovery endpoint.

                //OA-2018-06-19 Commented

                /*if (endpoint.UpdateBeforeConnect)
                 * {
                 *  BindingFactory bindingFactory = BindingFactory.Create(configuration, messageContext);
                 *  endpoint.UpdateFromServer(bindingFactory);
                 *
                 *  endpointDescription = endpoint.Description;
                 *  endpointConfiguration = endpoint.Configuration;
                 * }*/

                // Set up a callback to handle certificate validation errors.
                //  configuration.CertificateValidator.CertificateValidation += new CertificateValidationEventHandler(CertificateValidator_CertificateValidation);


                // initialize the channel which will be created with the server.
                ITransportChannel channel = SessionChannel.Create(
                    configuration,
                    endpointDescription,
                    endpointConfiguration,
                    //clientCertificateChain,
                    clientCertificate,
                    messageContext);

                // create the session object.
                //OA-2017-08-15
                Session m_session = new Session(channel, configuration, endpoint, clientCertificate);
                //m_session = new Session(channel, configuration, endpoint, null);

                //OA-2017-09-20
                byte[] certificateData = endpoint.Description.ServerCertificate;
                //islem Commented serverCertificate
                if (certificateData != null) //OA-2018-04-27
                                             //serverCertificate = Utils.ParseCertificateBlob(certificateData);
                                             //

                {
                    m_session.ReturnDiagnostics = DiagnosticsMasks.All;
                }

                // Register keep alive callback.
                //islem Commented KeepAlive
                // m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);

                // create the session.
                try
                {
                    m_session.Open(sessionName, 60000, identity, null);
                    dicOfSession.Add(sessionName, m_session);//OA-2017-09-20
                }
                catch (Exception e)
                {
                }

                return(m_session);
            }
            catch (Exception e)
            {
                return(null);
            }
        }
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext          context,
            SignatureData             clientSignature,
            List<SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject           userIdentityToken,
            SignatureData             userTokenSignature,
            StringCollection          localeIds,
            byte[]                    serverNonce,
            out UserIdentityToken     identityToken,
            out UserTokenPolicy       userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);
                    
                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }
                }
                   
                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }    
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
        /// <summary>
        /// Creates the endpoint description from current selections.
        /// </summary>
        private EndpointDescription CreateDescriptionFromSelections()
        {
            string currentProtocol = (string)ProtocolCB.SelectedItem;

            EndpointDescription endpoint = null;

            for (int ii = 0; ii < m_availableEndpoints.Count; ii++)
            {
                Uri url = Utils.ParseUri(m_availableEndpoints[ii].EndpointUrl);

                if (url == null)
                {
                    continue;
                }

                if (endpoint == null)
                {
                    endpoint = m_availableEndpoints[ii];
                }

                if (url.Scheme == currentProtocol)
                {
                    endpoint = m_availableEndpoints[ii];
                    break;
                }
            }

            UriBuilder builder = null;

            if (endpoint == null)
            {
                builder      = new UriBuilder();
                builder.Host = "localhost";

                if (currentProtocol == Utils.UriSchemeOpcTcp)
                {
                    builder.Port = Utils.UaTcpDefaultPort;
                }
            }
            else
            {
                builder = new UriBuilder(endpoint.EndpointUrl);
            }

            builder.Scheme = currentProtocol;

            endpoint                        = new EndpointDescription();
            endpoint.EndpointUrl            = builder.ToString();
            endpoint.SecurityMode           = (MessageSecurityMode)SecurityModeCB.SelectedItem;
            endpoint.SecurityPolicyUri      = SecurityPolicies.GetUri((string)SecurityPolicyCB.SelectedItem);
            endpoint.Server.ApplicationName = endpoint.EndpointUrl;
            endpoint.Server.ApplicationType = ApplicationType.Server;
            endpoint.Server.ApplicationUri  = endpoint.EndpointUrl;

            UserTokenType   userTokenType   = (UserTokenType)UserTokenTypeCB.SelectedItem;
            UserTokenPolicy userTokenPolicy = new UserTokenPolicy(userTokenType);

            if (userTokenType == UserTokenType.IssuedToken)
            {
                userTokenPolicy.IssuedTokenType = (string)IssuedTokenTypeCB.SelectedItem;
            }

            endpoint.UserIdentityTokens.Add(userTokenPolicy);

            return(endpoint);
        }
        public async Task <ConnectionStatus> OpcClient(string endpointURL)
        {
            try
            {
                Uri endpointURI      = new Uri(endpointURL);
                var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, false, 15000);

                info.LabelText = "Selected endpoint uses: " + selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1);

                var endpointConfiguration = EndpointConfiguration.Create(config);
                var endpoint = new ConfiguredEndpoint(selectedEndpoint.Server, endpointConfiguration);
                endpoint.Update(selectedEndpoint);

                var platform    = Device.RuntimePlatform;
                var sessionName = "";

                switch (Device.RuntimePlatform)
                {
                case "Android":
                    sessionName = "AIS Demonstrator Android Applikation";
                    break;

                // other cases are irrelevant for the Industrie 4.0 Demonstrator as of now
                case "UWP":
                    sessionName = "OPC UA Xamarin Client UWP";
                    break;

                case "iOS":
                    sessionName = "OPC UA Xamarin Client IOS";
                    break;
                }
                #region OPC UA User Authentication handling

                /*
                 * Partially copied from https://github.com/OPCFoundation/UA-.NETStandard/issues/446
                 */
                UserTokenPolicy utp = new UserTokenPolicy();
                utp.TokenType = UserTokenType.UserName;

                UserTokenPolicyCollection utpCollection = new UserTokenPolicyCollection();
                utpCollection.Add(utp);
                selectedEndpoint.UserIdentityTokens = utpCollection;
                selectedEndpoint.SecurityMode       = MessageSecurityMode.SignAndEncrypt;
                UserIdentity SessionUserIdentity = new UserIdentity(MainActivity.UserName, MainActivity.UserPassword);

                #endregion
                session = await Session.Create(config, endpoint, false, sessionName, 30000, SessionUserIdentity, null);


                if (session != null)
                {
                    connectionStatus = ConnectionStatus.Connected;

                    #region Subscription + monitoredItems
                    // Code for Monitored Items based on http://opcfoundation.github.io/UA-.NETStandard/help/index.htm#client_development.htm

                    // Create Subscription
                    Subscription subscription = new Subscription() // new Subscription(OpcClient.session.DefaultSubscription)
                    {
                        PublishingInterval = 1000,
                        PublishingEnabled  = true
                    };
                    // CoffeeLevel
                    MonitoredItem CoffeeLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=CoffeeLevel",
                        DisplayName      = "MonitoredCoffeeLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    CoffeeLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCoffeeLevel);

                    // WaterLevel
                    MonitoredItem WaterLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=WaterLevel",
                        DisplayName      = "MonitoredWaterLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    WaterLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueWaterLevel);

                    // CleanlinessLevel
                    MonitoredItem CleanlinessLevel = new MonitoredItem(subscription.DefaultItem)
                    {
                        StartNodeId      = "ns=1;s=Cleanliness",
                        DisplayName      = "MonitoredCleanlinessLevel",
                        AttributeId      = Attributes.Value,
                        MonitoringMode   = MonitoringMode.Reporting,
                        SamplingInterval = 1000, // check the CoffeeLevel every second
                        QueueSize        = 1,    // only the most recent value for the CoffeeLevel is needed, thus we only need a queuesize of one
                        DiscardOldest    = true  // we only need the most recent value for CoffeeLevel
                    };
                    CleanlinessLevel.Notification += (sender, e) => OnNotification(sender, e, ref valueCleanlinessLevel);

                    // add MonitoredItems to Subscription
                    subscription.AddItem(CoffeeLevel);
                    subscription.AddItem(WaterLevel);
                    subscription.AddItem(CleanlinessLevel);

                    // add Subscription to Session
                    session.AddSubscription(subscription);
                    subscription.Create();

                    #endregion
                }
                else
                {
                    connectionStatus = ConnectionStatus.NotConnected;
                }
                // register keep alive handler
                session.KeepAlive += Client_KeepAlive;
            }
            catch
            {
                connectionStatus = ConnectionStatus.Error;
            }
            return(connectionStatus);
        }
        /// <summary>
        /// Creates the endpoints and creates the hosts.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="bindingFactory">The binding factory.</param>
        /// <param name="serverDescription">The server description.</param>
        /// <param name="endpoints">The endpoints.</param>
        /// <returns>
        /// Returns IList of a host for a UA service which type is <seealso cref="ServiceHost"/>.
        /// </returns>
        protected override IList<Task> InitializeServiceHosts(
            ApplicationConfiguration          configuration, 
            out ApplicationDescription        serverDescription,
            out EndpointDescriptionCollection endpoints)
        {
            serverDescription = null;
            endpoints = null;

            Dictionary<string, Task> hosts = new Dictionary<string, Task>();

            // ensure at least one security policy exists.
            if (configuration.ServerConfiguration.SecurityPolicies.Count == 0)
            {                   
                configuration.ServerConfiguration.SecurityPolicies.Add(new ServerSecurityPolicy());
            }
            
            // ensure at least one user token policy exists.
            if (configuration.ServerConfiguration.UserTokenPolicies.Count == 0)
            {                   
                UserTokenPolicy userTokenPolicy = new UserTokenPolicy();
                
                userTokenPolicy.TokenType = UserTokenType.Anonymous;
                userTokenPolicy.PolicyId  = userTokenPolicy.TokenType.ToString();

                configuration.ServerConfiguration.UserTokenPolicies.Add(userTokenPolicy);
            }

            // set server description.
            serverDescription = new ApplicationDescription();

            serverDescription.ApplicationUri = configuration.ApplicationUri;
            serverDescription.ApplicationName = configuration.ApplicationName;
            serverDescription.ApplicationType = configuration.ApplicationType;
            serverDescription.ProductUri = configuration.ProductUri;
            serverDescription.DiscoveryUrls = GetDiscoveryUrls();
                          
            endpoints = new EndpointDescriptionCollection();
            IList<EndpointDescription> endpointsForHost = null;

            // create UA TCP host.
            endpointsForHost = CreateUaTcpServiceHost(
                hosts,
                configuration,
                configuration.ServerConfiguration.BaseAddresses,
                serverDescription,
                configuration.ServerConfiguration.SecurityPolicies);

            endpoints.InsertRange(0, endpointsForHost);

            // create HTTPS host.
#if !NO_HTTPS
            endpointsForHost = CreateHttpsServiceHost(
            hosts,
            configuration,
            configuration.ServerConfiguration.BaseAddresses,
            serverDescription,
            configuration.ServerConfiguration.SecurityPolicies);

            endpoints.AddRange(endpointsForHost);
#endif
            return new List<Task>(hosts.Values);
        }
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy)
 {
     m_newIdentity = newIdentity;
     m_userTokenPolicy = userTokenPolicy;
 }
示例#33
0
        /// <summary>
        /// Activates an existing session
        /// </summary>
        public virtual bool ActivateSession(
            OperationContext context,
            NodeId authenticationToken,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            out byte[] serverNonce)
        {
            serverNonce = null;

            Session           session         = null;
            UserIdentityToken newIdentity     = null;
            UserTokenPolicy   userTokenPolicy = null;

            lock (m_lock)
            {
                // find session.
                if (!m_sessions.TryGetValue(authenticationToken, out session))
                {
                    throw new ServiceResultException(StatusCodes.BadSessionClosed);
                }

                // check if session timeout has expired.
                if (session.HasExpired)
                {
                    m_server.CloseSession(null, session.Id, false);
                    throw new ServiceResultException(StatusCodes.BadSessionClosed);
                }

                // create new server nonce.
                serverNonce = Utils.Nonce.CreateNonce((uint)m_minNonceLength);

                // validate before activation.
                session.ValidateBeforeActivate(
                    context,
                    clientSignature,
                    clientSoftwareCertificates,
                    userIdentityToken,
                    userTokenSignature,
                    localeIds,
                    serverNonce,
                    out newIdentity,
                    out userTokenPolicy);
            }

            IUserIdentity identity          = null;
            IUserIdentity effectiveIdentity = null;
            ServiceResult error             = null;

            try
            {
                // check if the application has a callback which validates the identity tokens.
                lock (m_eventLock)
                {
                    if (m_ImpersonateUser != null)
                    {
                        ImpersonateEventArgs args = new ImpersonateEventArgs(newIdentity, userTokenPolicy);
                        m_ImpersonateUser(session, args);

                        if (ServiceResult.IsBad(args.IdentityValidationError))
                        {
                            error = args.IdentityValidationError;
                        }
                        else
                        {
                            identity          = args.Identity;
                            effectiveIdentity = args.EffectiveIdentity;
                        }
                    }
                }

                // parse the token manually if the identity is not provided.
                if (identity == null)
                {
                    identity = new UserIdentity(newIdentity);
                }

                // use the identity as the effectiveIdentity if not provided.
                if (effectiveIdentity == null)
                {
                    effectiveIdentity = identity;
                }
            }
            catch (Exception e)
            {
                if (e is ServiceResultException)
                {
                    throw e;
                }

                throw ServiceResultException.Create(
                          StatusCodes.BadIdentityTokenInvalid,
                          e,
                          "Could not validate user identity token: {0}",
                          newIdentity);
            }

            // check for validation error.
            if (ServiceResult.IsBad(error))
            {
                throw new ServiceResultException(error);
            }

            // activate session.
            bool contextChanged = session.Activate(
                context,
                clientSoftwareCertificates,
                newIdentity,
                identity,
                effectiveIdentity,
                localeIds,
                serverNonce);

            // raise session related event.
            if (contextChanged)
            {
                RaiseSessionEvent(session, SessionEventReason.Activated);
            }

            // indicates that the identity context for the session has changed.
            return(contextChanged);
        }
示例#34
0
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext context,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            byte[] serverNonce,
            out UserIdentityToken identityToken,
            out UserTokenPolicy userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    if (m_endpoint.SecurityPolicyUri != SecurityPolicies.None && clientSignature != null && clientSignature.Signature == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }

                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        // verify for certificate chain in endpoint.
                        // validate the signature with complete chain if the check with leaf certificate failed.
                        X509Certificate2Collection serverCertificateChain = Utils.ParseCertificateChainBlob(m_endpoint.ServerCertificate);

                        if (serverCertificateChain.Count > 1)
                        {
                            List <byte> serverCertificateChainList = new List <byte>();

                            for (int i = 0; i < serverCertificateChain.Count; i++)
                            {
                                serverCertificateChainList.AddRange(serverCertificateChain[i].RawData);
                            }

                            byte[] serverCertificateChainData = serverCertificateChainList.ToArray();
                            dataToSign = Utils.Append(serverCertificateChainData, m_serverNonce);

                            if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                            {
                                throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                            }
                        }
                        else
                        {
                            throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                        }
                    }
                }

                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
示例#35
0
        /// <summary>
        /// Creates a user identity for the policy.
        /// </summary>
        private IUserIdentity CreateUserIdentity(UserTokenPolicy policy)
        {
            if (policy == null || policy.TokenType == UserTokenType.Anonymous)
            {
                return null;
            }

            if (policy.TokenType == UserTokenType.UserName)
            {
                return new UserIdentity("SomeUser", "password");
            }

            if (policy.TokenType == UserTokenType.Certificate)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);

                try
                {
                    foreach (X509Certificate2 certificate in store.Certificates)
                    {
                        if (certificate.HasPrivateKey)
                        {
                            return new UserIdentity(certificate);
                        }
                    }
                    
                    return null;
                }
                finally
                {
                    store.Close();
                }
            }

            if (policy.TokenType == UserTokenType.IssuedToken)
            {
                CertificateIdentifier userid = new CertificateIdentifier();

                userid.StoreType   = CertificateStoreType.Windows;
                userid.StorePath   = "LocalMachine\\Root";
                userid.SubjectName = "UASampleRoot";

                X509Certificate2 certificate = userid.Find();
                X509SecurityToken signingToken = new X509SecurityToken(certificate);

                SamlSecurityToken token = CreateSAMLToken("*****@*****.**", signingToken);
                          
                return new UserIdentity(token);            
            }

            throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "User token policy is not supported.");
        }
示例#36
0
 public UserTokenItem(UserTokenPolicy policy)
 {
     Policy = policy;
 }