private void ReadEndpoints()
        {
            _endpoints = new List <EndpointConfig>();

            var endpointsConfig = _configuration.GetSection(EndpointsKey).GetChildren();

            foreach (var endpointConfig in endpointsConfig)
            {
                // "EndpointName": {
                //    "Url": "https://*:5463",
                //    "Protocols": "Http1AndHttp2",
                //    "Certificate": {
                //        "Path": "testCert.pfx",
                //        "Password": "******"
                //    }
                // }

                var url = endpointConfig[UrlKey];
                if (string.IsNullOrEmpty(url))
                {
                    throw new InvalidOperationException(ReplicaCoreStrings.FormatEndpointMissingUrl(endpointConfig.Key));
                }

                var endpoint = new EndpointConfig
                {
                    Name          = endpointConfig.Key,
                    Url           = url,
                    Protocols     = ParseProtocols(endpointConfig[ProtocolsKey]),
                    ConfigSection = endpointConfig,
                    Certificate   = new CertificateConfig(endpointConfig.GetSection(CertificateKey)),
                };
                _endpoints.Add(endpoint);
            }
        }
예제 #2
0
        public static X509Certificate2 LoadFromStoreCert(string subject, string storeName, StoreLocation storeLocation, bool allowInvalid)
        {
            using (var store = new X509Store(storeName, storeLocation))
            {
                X509Certificate2Collection storeCertificates = null;
                X509Certificate2           foundCertificate  = null;

                try
                {
                    store.Open(OpenFlags.ReadOnly);
                    storeCertificates = store.Certificates;
                    var foundCertificates = storeCertificates.Find(X509FindType.FindBySubjectName, subject, !allowInvalid);
                    foundCertificate = foundCertificates
                                       .OfType <X509Certificate2>()
                                       .Where(IsCertificateAllowedForServerAuth)
                                       .OrderByDescending(certificate => certificate.NotAfter)
                                       .FirstOrDefault();

                    if (foundCertificate == null)
                    {
                        throw new InvalidOperationException(ReplicaCoreStrings.FormatCertNotFoundInStore(subject, storeLocation, storeName, allowInvalid));
                    }

                    return(foundCertificate);
                }
                finally
                {
                    DisposeCertificates(storeCertificates, except: foundCertificate);
                }
            }
        }
        internal override async Task BindAsync(ReplicaAddressBindContext context)
        {
            var exceptions = new List <Exception>();

            try
            {
                var v4Options = Clone(IPAddress.Loopback);
                await ReplicaAddressBinder.BindEndpointAsync(v4Options, context).ConfigureAwait(false);
            }
            catch (Exception ex) when(!(ex is IOException))
            {
                context.Logger.LogWarning(0, ReplicaCoreStrings.NetworkInterfaceBindingFailed, GetDisplayName(), "IPv4 loopback", ex.Message);
                exceptions.Add(ex);
            }

            try
            {
                var v6Options = Clone(IPAddress.IPv6Loopback);
                await ReplicaAddressBinder.BindEndpointAsync(v6Options, context).ConfigureAwait(false);
            }
            catch (Exception ex) when(!(ex is IOException))
            {
                context.Logger.LogWarning(0, ReplicaCoreStrings.NetworkInterfaceBindingFailed, GetDisplayName(), "IPv6 loopback", ex.Message);
                exceptions.Add(ex);
            }

            if (exceptions.Count == 2)
            {
                throw new IOException(ReplicaCoreStrings.FormatAddressBindingFailed(GetDisplayName()), new AggregateException(exceptions));
            }

            // If StartLocalhost doesn't throw, there is at least one listener.
            // The port cannot change for "localhost".
            context.Addresses.Add(GetDisplayName());
        }
예제 #4
0
        internal static async Task BindEndpointAsync(ReplicaListenOptions endpoint, ReplicaAddressBindContext context)
        {
            try
            {
                await context.CreateBinding(endpoint).ConfigureAwait(false);
            }
            catch (AddressInUseException ex)
            {
                throw new IOException(ReplicaCoreStrings.FormatEndpointAlreadyInUse(endpoint), ex);
            }

            context.ListenOptions.Add(endpoint);
        }
예제 #5
0
        internal override async Task BindAsync(ReplicaAddressBindContext context)
        {
            // when address is 'http://hostname:port', 'http://*:port', or 'http://+:port'
            try
            {
                await base.BindAsync(context).ConfigureAwait(false);
            }
            catch (Exception ex) when(!(ex is IOException))
            {
                context.Logger.LogDebug(ReplicaCoreStrings.FormatFallbackToIPv4Any(IPEndPoint.Port));

                // for machines that do not support IPv6
                IPEndPoint = new IPEndPoint(IPAddress.Any, IPEndPoint.Port);
                await base.BindAsync(context).ConfigureAwait(false);
            }
        }
 private X509Certificate2 LoadCertificate(CertificateConfig certInfo, string endpointName)
 {
     if (certInfo.IsFileCert && certInfo.IsStoreCert)
     {
         throw new InvalidOperationException(ReplicaCoreStrings.FormatMultipleCertificateSources(endpointName));
     }
     else if (certInfo.IsFileCert)
     {
         var env = Options.ApplicationServices.GetRequiredService <IHostingEnvironment>();
         return(new X509Certificate2(Path.Combine(env.ContentRootPath, certInfo.Path), certInfo.Password));
     }
     else if (certInfo.IsStoreCert)
     {
         return(LoadFromStoreCert(certInfo));
     }
     return(null);
 }
예제 #7
0
        internal static ReplicaListenOptions ParseAddress(string address, out bool https)
        {
            var parsedAddress = BindingAddress.Parse(address);

            https = false;

            if (parsedAddress.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
            {
                https = true;
            }
            else if (!parsedAddress.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException(ReplicaCoreStrings.FormatUnsupportedAddressScheme(address));
            }

            if (!string.IsNullOrEmpty(parsedAddress.PathBase))
            {
                throw new InvalidOperationException(ReplicaCoreStrings.FormatConfigurePathBaseFromMethodCall($"{nameof(IApplicationBuilder)}.UsePathBase()"));
            }

            ReplicaListenOptions options = null;

            if (parsedAddress.IsUnixPipe)
            {
                options = new ReplicaListenOptions(parsedAddress.UnixPipePath);
            }
            else if (string.Equals(parsedAddress.Host, "localhost", StringComparison.OrdinalIgnoreCase))
            {
                // "localhost" for both IPv4 and IPv6 can't be represented as an IPEndPoint.
                options = new ReplicaLocalhostListenOptions(parsedAddress.Port);
            }
            else if (TryCreateIPEndPoint(parsedAddress, out var endpoint))
            {
                options = new ReplicaListenOptions(endpoint);
            }
            else
            {
                // when address is 'http://hostname:port', 'http://*:port', or 'http://+:port'
                options = new ReplicaAnyIPListenOptions(parsedAddress.Port);
            }

            return(options);
        }