示例#1
0
        /// <summary>
        /// Returns the domain names which the server is configured to use.
        /// </summary>
        /// <returns>A list of domain names.</returns>
        public IList <string> GetServerDomainNames()
        {
            StringCollection baseAddresses = new StringCollection();

            if (this.ServerConfiguration != null)
            {
                if (this.ServerConfiguration.BaseAddresses != null)
                {
                    baseAddresses.AddRange(this.ServerConfiguration.BaseAddresses);
                }

                if (this.ServerConfiguration.AlternateBaseAddresses != null)
                {
                    baseAddresses.AddRange(this.ServerConfiguration.AlternateBaseAddresses);
                }
            }

            if (this.DiscoveryServerConfiguration != null)
            {
                if (this.DiscoveryServerConfiguration.BaseAddresses != null)
                {
                    baseAddresses.AddRange(this.DiscoveryServerConfiguration.BaseAddresses);
                }

                if (this.DiscoveryServerConfiguration.AlternateBaseAddresses != null)
                {
                    baseAddresses.AddRange(this.DiscoveryServerConfiguration.AlternateBaseAddresses);
                }
            }

            var domainNames = new List <string>();

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

                if (url == null)
                {
                    continue;
                }

                string domainName = url.DnsSafeHost;

                if (url.HostNameType == UriHostNameType.Dns)
                {
                    domainName = Utils.ReplaceLocalhost(domainName);
                }
                else // IPv4/IPv6 address
                {
                    domainName = Utils.NormalizedIPAddress(domainName);
                }

                if (!Utils.FindStringIgnoreCase(domainNames, domainName))
                {
                    domainNames.Add(domainName);
                }
            }

            return(domainNames);
        }
        /// <summary>
        /// Patch returned endpoints urls with url used to reached the endpoint.
        /// </summary>
        private EndpointDescriptionCollection PatchEndpointUrls(EndpointDescriptionCollection endpoints)
        {
            // if a server is behind a firewall, can only be accessed with a FQDN or IP address
            // it may return URLs that are not accessible to the client. This problem can be avoided
            // by assuming that the domain in the URL used to call GetEndpoints can be used to
            // access any of the endpoints. This code patches the returned endpoints accordingly.
            Uri endpointUrl = Utils.ParseUri(this.Endpoint.EndpointUrl);

            if (endpointUrl != null)
            {
                // patch discovery Url to endpoint Url used for service call
                foreach (EndpointDescription discoveryEndPoint in endpoints)
                {
                    Uri discoveryEndPointUri = Utils.ParseUri(discoveryEndPoint.EndpointUrl);
                    if (endpointUrl.Scheme == discoveryEndPointUri.Scheme)
                    {
                        UriBuilder builder = new UriBuilder(discoveryEndPointUri);
                        builder.Host = endpointUrl.DnsSafeHost;
                        builder.Port = endpointUrl.Port;
                        discoveryEndPoint.EndpointUrl = builder.ToString();
                    }

                    if (discoveryEndPoint.Server != null &&
                        discoveryEndPoint.Server.DiscoveryUrls != null)
                    {
                        discoveryEndPoint.Server.DiscoveryUrls.Clear();
                        discoveryEndPoint.Server.DiscoveryUrls.Add(this.Endpoint.EndpointUrl.ToString());
                    }
                }
            }
            return(endpoints);
        }
示例#3
0
        /// <summary>
        /// Adds the discovery url to the hosts.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="discoveryUrls">The discovery urls.</param>
        public virtual void InitializeDiscovery(
            ApplicationConfiguration configuration,
            StringCollection discoveryUrls)
        {
            // create the binding factory.
            BindingFactory        bindingFactory        = BindingFactory.Create(configuration, configuration.CreateMessageContext());
            EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration);

            foreach (string discoveryUrl in discoveryUrls)
            {
                // parse discovery url.
                Uri url = Utils.ParseUri(discoveryUrl);

                if (url == null)
                {
                    continue;
                }

                // create endpoint.
                if (url.PathAndQuery.EndsWith("/discovery"))
                {
                    Binding binding = bindingFactory.Create(url.Scheme, endpointConfiguration);
                    this.AddServiceEndpoint(typeof(IDiscoveryEndpoint), binding, url, url);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Creates a configured endpoint from the server description.
        /// </summary>
        public ConfiguredEndpoint(
            ApplicationDescription server,
            EndpointConfiguration configuration)
        {
            if (server == null)
            {
                throw new ArgumentNullException("server");
            }

            m_description         = new EndpointDescription();
            m_updateBeforeConnect = true;

            m_description.Server = server;

            foreach (string discoveryUrl in server.DiscoveryUrls)
            {
                string baseUrl = discoveryUrl;

                if (baseUrl != null)
                {
                    if (baseUrl.EndsWith("/discovery", StringComparison.Ordinal))
                    {
                        baseUrl = baseUrl.Substring(0, baseUrl.Length - "/discovery".Length);
                    }
                }

                Uri url = Utils.ParseUri(baseUrl);

                if (url != null)
                {
                    // MY EDITS TO TRY MAKING WORK WITH USERNAME

                    m_description.EndpointUrl       = url.ToString();
                    m_description.SecurityMode      = MessageSecurityMode.None;                        // MessageSecurityMode.SignAndEncrypt;
                    m_description.SecurityPolicyUri = SecurityPolicies.None;                           //SecurityPolicies.Basic128Rsa15;
                    m_description.UserIdentityTokens.Add(new UserTokenPolicy(UserTokenType.UserName)); // Anonymous));

                    if (url.Scheme == Utils.UriSchemeHttps)
                    {
                        m_description.TransportProfileUri = Profiles.HttpsBinaryTransport;
                    }

                    if (url.Scheme == Utils.UriSchemeOpcTcp)
                    {
                        m_description.TransportProfileUri = Profiles.UaTcpTransport;
                    }

                    break;
                }
            }

            // ensure a default configuration.
            if (configuration == null)
            {
                configuration = EndpointConfiguration.Create();
            }

            Update(configuration);
        }
示例#5
0
        /// <summary>
        /// Returns the domain names which the server is configured to use.
        /// </summary>
        /// <returns>A list of domain names.</returns>
        public IList <string> GetServerDomainNames()
        {
            List <string> domainNames = new List <string>();

            StringCollection baseAddresses = new StringCollection();

            if (this.ServerConfiguration != null)
            {
                if (this.ServerConfiguration.BaseAddresses != null)
                {
                    baseAddresses.AddRange(this.ServerConfiguration.BaseAddresses);
                }

                if (this.ServerConfiguration.AlternateBaseAddresses != null)
                {
                    baseAddresses.AddRange(this.ServerConfiguration.AlternateBaseAddresses);
                }
            }

            if (this.DiscoveryServerConfiguration != null)
            {
                if (this.DiscoveryServerConfiguration.BaseAddresses != null)
                {
                    baseAddresses.AddRange(this.DiscoveryServerConfiguration.BaseAddresses);
                }

                if (this.DiscoveryServerConfiguration.AlternateBaseAddresses != null)
                {
                    baseAddresses.AddRange(this.DiscoveryServerConfiguration.AlternateBaseAddresses);
                }
            }

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

                if (url == null)
                {
                    continue;
                }

                string domainName = url.DnsSafeHost;

                if (String.Compare(domainName, "localhost", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    domainName = Utils.GetHostName();
                }

                if (!Utils.FindStringIgnoreCase(domainNames, domainName))
                {
                    domainNames.Add(domainName);
                }
            }

            return(domainNames);
        }
示例#6
0
        /// <summary>
        /// Returns a discovery url that can be used to update the endpoint description.
        /// </summary>
        public Uri GetDiscoveryUrl(Uri endpointUrl)
        {
            // update the endpoint description.
            if (endpointUrl != null)
            {
                m_description.EndpointUrl = endpointUrl.ToString();
            }
            else
            {
                endpointUrl = Utils.ParseUri(m_description.EndpointUrl);
            }

            // get the know discovery URLs.
            StringCollection discoveryUrls = null;

            if (m_description.Server != null)
            {
                discoveryUrls = m_description.Server.DiscoveryUrls;
            }

            // attempt to construct a discovery url by appending 'discovery' to the endpoint.
            if (discoveryUrls == null || discoveryUrls.Count == 0)
            {
                if (endpointUrl.Scheme != Utils.UriSchemeOpcTcp)
                {
                    return(new Uri(String.Format(CultureInfo.InvariantCulture, "{0}/discovery", endpointUrl)));
                }
                else
                {
                    return(endpointUrl);
                }
            }

            // choose the URL that uses the same protocol if one exists.
            for (int ii = 1; ii < discoveryUrls.Count; ii++)
            {
                if (discoveryUrls[ii].StartsWith(endpointUrl.Scheme, StringComparison.Ordinal))
                {
                    return(Utils.ParseUri(discoveryUrls[ii]));
                }
            }

            // return the first in the list.
            return(Utils.ParseUri(discoveryUrls[0]));
        }
示例#7
0
        /// <summary>
        /// Sets the parameters to suitable defaults.
        /// </summary>
        private static void SetSuitableDefaults(
            ref string applicationUri,
            ref string applicationName,
            ref string subjectName,
            ref IList <String> domainNames,
            ref ushort keySize,
            ref ushort lifetimeInMonths,
            bool isCA)
        {
            // enforce recommended keysize unless lower value is enforced.
            if (keySize < 1024)
            {
                keySize = defaultKeySize;
            }

            if (keySize % 1024 != 0)
            {
                throw new ArgumentNullException("keySize", "KeySize must be a multiple of 1024.");
            }

            // enforce minimum lifetime.
            if (lifetimeInMonths < 1)
            {
                lifetimeInMonths = 1;
            }

            // parse the subject name if specified.
            List <string> subjectNameEntries = null;

            if (!String.IsNullOrEmpty(subjectName))
            {
                subjectNameEntries = Utils.ParseDistinguishedName(subjectName);
            }

            // check the application name.
            if (String.IsNullOrEmpty(applicationName))
            {
                if (subjectNameEntries == null)
                {
                    throw new ArgumentNullException("applicationName", "Must specify a applicationName or a subjectName.");
                }

                // use the common name as the application name.
                for (int ii = 0; ii < subjectNameEntries.Count; ii++)
                {
                    if (subjectNameEntries[ii].StartsWith("CN="))
                    {
                        applicationName = subjectNameEntries[ii].Substring(3).Trim();
                        break;
                    }
                }
            }

            // remove special characters from name.
            StringBuilder buffer = new StringBuilder();

            for (int ii = 0; ii < applicationName.Length; ii++)
            {
                char ch = applicationName[ii];

                if (Char.IsControl(ch) || ch == '/' || ch == ',' || ch == ';')
                {
                    ch = '+';
                }

                buffer.Append(ch);
            }

            applicationName = buffer.ToString();

            // ensure at least one host name.
            if (domainNames == null || domainNames.Count == 0)
            {
                domainNames = new List <string>();
                domainNames.Add(Utils.GetHostName());
            }

            // create the application uri.
            if (String.IsNullOrEmpty(applicationUri))
            {
                StringBuilder builder = new StringBuilder();

                builder.Append("urn:");
                builder.Append(domainNames[0]);
                builder.Append(":");
                builder.Append(applicationName);

                applicationUri = builder.ToString();
            }

            Uri uri = Utils.ParseUri(applicationUri);

            if (uri == null)
            {
                throw new ArgumentNullException("applicationUri", "Must specify a valid URL.");
            }

            // create the subject name,
            if (String.IsNullOrEmpty(subjectName))
            {
                subjectName = Utils.Format("CN={0}/DC={1}", applicationName, domainNames[0]);
            }
        }
示例#8
0
        /// <summary>
        /// Updates an endpoint with information from the server's discovery endpoint.
        /// </summary>
        public void UpdateFromServer(
            Uri endpointUrl,
            MessageSecurityMode securityMode,
            string securityPolicyUri)
        {
            // get the a discovery url.
            Uri discoveryUrl = GetDiscoveryUrl(endpointUrl);

            // create the discovery client.
            DiscoveryClient client = DiscoveryClient.Create(discoveryUrl, m_configuration);

            try
            {
                // get the endpoints.
                EndpointDescriptionCollection collection = client.GetEndpoints(null);

                if (collection == null || collection.Count == 0)
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadUnknownResponse,
                              "Server does not have any endpoints defined.");
                }

                // find list of matching endpoints.
                EndpointDescriptionCollection matches = new EndpointDescriptionCollection();

                // first pass - match on the requested security parameters.
                foreach (EndpointDescription description in collection)
                {
                    // check for match on security policy.
                    if (!String.IsNullOrEmpty(securityPolicyUri))
                    {
                        if (securityPolicyUri != description.SecurityPolicyUri)
                        {
                            continue;
                        }
                    }

                    // check for match on security mode.
                    if (securityMode != MessageSecurityMode.Invalid)
                    {
                        if (securityMode != description.SecurityMode)
                        {
                            continue;
                        }
                    }

                    // add to list of matches.
                    matches.Add(description);
                }

                // no matches (security parameters may have changed).
                if (matches.Count == 0)
                {
                    matches = collection;
                }

                // check if list has to be narrowed down further.
                if (matches.Count > 1)
                {
                    collection = matches;
                    matches    = new EndpointDescriptionCollection();

                    // second pass - match on the url scheme.
                    foreach (EndpointDescription description in collection)
                    {
                        // parse the endpoint url.
                        Uri sessionUrl = Utils.ParseUri(description.EndpointUrl);

                        if (sessionUrl == null)
                        {
                            continue;
                        }

                        // check for matching protocol.
                        if (sessionUrl.Scheme != endpointUrl.Scheme)
                        {
                            continue;
                        }

                        matches.Add(description);
                    }
                }

                // no matches (protocol may not be supported).
                if (matches.Count == 0)
                {
                    matches = collection;
                }

                // choose first in list by default.
                EndpointDescription match = matches[0];

                // check if list has to be narrowed down further.
                if (matches.Count > 1)
                {
                    // third pass - match based on security level.
                    foreach (EndpointDescription description in matches)
                    {
                        if (description.SecurityMode > match.SecurityMode)
                        {
                            match = description;
                        }
                    }
                }

                // check if the endpoint url matches the endpoint used in the request.
                Uri matchUrl = Utils.ParseUri(match.EndpointUrl);

                if (matchUrl == null || String.Compare(discoveryUrl.DnsSafeHost, matchUrl.DnsSafeHost, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    UriBuilder uri = new UriBuilder(matchUrl);
                    uri.Host          = discoveryUrl.DnsSafeHost;
                    uri.Port          = discoveryUrl.Port;
                    match.EndpointUrl = uri.ToString();

                    // need to update the discovery urls.
                    match.Server.DiscoveryUrls.Clear();
                    match.Server.DiscoveryUrls.Add(discoveryUrl.ToString());
                }

                // update the endpoint.
                Update(match);
            }
            finally
            {
                client.Close();
            }
        }
        /// <summary>
        /// Sets the parameters to suitable defaults.
        /// </summary>
        private static void SetSuitableDefaults(
            ref string applicationUri,
            ref string applicationName,
            ref string subjectName,
            ref IList <String> domainNames)
        {
            // parse the subject name if specified.
            List <string> subjectNameEntries = null;

            if (!String.IsNullOrEmpty(subjectName))
            {
                subjectNameEntries = X509Utils.ParseDistinguishedName(subjectName);
            }

            // check the application name.
            if (String.IsNullOrEmpty(applicationName))
            {
                if (subjectNameEntries == null)
                {
                    throw new ArgumentNullException(nameof(applicationName), "Must specify a applicationName or a subjectName.");
                }

                // use the common name as the application name.
                for (int ii = 0; ii < subjectNameEntries.Count; ii++)
                {
                    if (subjectNameEntries[ii].StartsWith("CN=", StringComparison.Ordinal))
                    {
                        applicationName = subjectNameEntries[ii].Substring(3).Trim();
                        break;
                    }
                }
            }

            if (String.IsNullOrEmpty(applicationName))
            {
                throw new ArgumentNullException(nameof(applicationName), "Must specify a applicationName or a subjectName.");
            }

            // remove special characters from name.
            StringBuilder buffer = new StringBuilder();

            for (int ii = 0; ii < applicationName.Length; ii++)
            {
                char ch = applicationName[ii];

                if (Char.IsControl(ch) || ch == '/' || ch == ',' || ch == ';')
                {
                    ch = '+';
                }

                buffer.Append(ch);
            }

            applicationName = buffer.ToString();

            // ensure at least one host name.
            if (domainNames == null || domainNames.Count == 0)
            {
                domainNames = new List <string>();
                domainNames.Add(Utils.GetHostName());
            }

            // create the application uri.
            if (String.IsNullOrEmpty(applicationUri))
            {
                StringBuilder builder = new StringBuilder();

                builder.Append("urn:");
                builder.Append(domainNames[0]);
                builder.Append(':');
                builder.Append(applicationName);

                applicationUri = builder.ToString();
            }

            Uri uri = Utils.ParseUri(applicationUri);

            if (uri == null)
            {
                throw new ArgumentNullException(nameof(applicationUri), "Must specify a valid URL.");
            }

            // create the subject name,
            if (String.IsNullOrEmpty(subjectName))
            {
                subjectName = Utils.Format("CN={0}", applicationName);
            }

            if (!subjectName.Contains("CN="))
            {
                subjectName = Utils.Format("CN={0}", subjectName);
            }

            if (domainNames != null && domainNames.Count > 0)
            {
                if (!subjectName.Contains("DC=") && !subjectName.Contains('='))
                {
                    subjectName += Utils.Format(", DC={0}", domainNames[0]);
                }
                else
                {
                    subjectName = Utils.ReplaceDCLocalhost(subjectName, domainNames[0]);
                }
            }
        }