コード例 #1
0
        public static bool AddReservedUrl(string url)
        {
            try
            {
                // add reserved URL
                using var process = new Process();
                var start = process.StartInfo;
                start.Verb            = "runas";
                start.UseShellExecute = true;
                start.FileName        = "cmd";
                start.Arguments       = $"/c \"\"{CertificateInstallerLocator.FileName}\" /u:\"{url}\"";
                start.CreateNoWindow  = true;
                start.WindowStyle     = ProcessWindowStyle.Hidden;
                process.Start();
                process.WaitForExit();
                return(process.ExitCode == 0);
            }
            catch (Win32Exception ex)
            {
                // elevation is cancelled.
                if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                {
                    RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                        { "native", ex.NativeErrorCode }
                    });
                    // throw;
                }
            }
            catch (Exception ex)
            {
                RollbarLocator.RollbarInstance.Error(ex);
            }

            return(false);
        }
コード例 #2
0
        public static string CleanUpSni(this Binding binding)
        {
#if !IIS
            if (!binding.GetIsSni())
            {
                return(string.Empty);
            }
#endif
            try
            {
                var hash = binding.CertificateHash == null ? string.Empty : Hex.ToHexString(binding.CertificateHash);
                // remove sni mapping
                using var process = new Process();
                var start = process.StartInfo;
                start.Verb            = "runas";
                start.UseShellExecute = true;
                start.FileName        = "cmd";
                start.Arguments       =
                    $"/c \"\"{CertificateInstallerLocator.FileName}\" /h:\"{hash}\" /s:{binding.CertificateStoreName}\" /i:{AppIdIisExpress} /o:{binding.EndPoint.Port} /x:{binding.Host}";
                start.CreateNoWindow = true;
                start.WindowStyle    = ProcessWindowStyle.Hidden;
                process.Start();
                process.WaitForExit();

                if (process.ExitCode != 0)
                {
                    return("Remove SNI certificate failed: access is denied");
                }

                return(string.Empty);
            }
            catch (Win32Exception ex)
            {
                // elevation is cancelled.
                if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                {
                    RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                        { "native", ex.NativeErrorCode }
                    });
                    return($"Remove SNI certificate failed: unknown (native {ex.NativeErrorCode})");
                }

                return("Remove SNI certificate failed: operation is cancelled");
            }
            catch (NullReferenceException ex)
            {
                RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                    { "binding", binding.ToString() }, { "endpointNull", binding.EndPoint == null }
                });
                return($"Remove SNI certificate failed: unknown ({ex.Message})");
            }
            catch (Exception ex)
            {
                RollbarLocator.RollbarInstance.Error(ex);
                return($"Remove SNI certificate failed: unknown ({ex.Message})");
            }
        }
コード例 #3
0
        internal static string FixCertificateMapping(this Binding binding, X509Certificate2 certificate2)
        {
            if (binding.Protocol == "http")
            {
                return(string.Empty);
            }

            if (binding.Parent.Parent.Server.SupportsSni)
            {
                if (binding.GetIsSni())
                {
                    if (!certificate2.MatchHostName(binding.Host))
                    {
                        return("SNI mode requires host name matches common name of the certificate");
                    }

                    // handle SNI
                    var sni = NativeMethods.QuerySslSniInfo(new Tuple <string, int>(binding.Host,
                                                                                    binding.EndPoint.Port));
                    if (sni == null)
                    {
                        try
                        {
                            // register mapping
                            using var process = new Process();
                            var start = process.StartInfo;
                            start.Verb            = "runas";
                            start.UseShellExecute = true;
                            start.FileName        = "cmd";
                            start.Arguments       =
                                $"/c \"\"{CertificateInstallerLocator.FileName}\" /h:\"{Hex.ToHexString(binding.CertificateHash)}\" /s:{binding.CertificateStoreName}\" /i:{AppIdIisExpress} /a:{binding.EndPoint.Address} /o:{binding.EndPoint.Port} /x:{binding.Host}";
                            start.CreateNoWindow = true;
                            start.WindowStyle    = ProcessWindowStyle.Hidden;
                            process.Start();
                            process.WaitForExit();

                            if (process.ExitCode != 0)
                            {
                                return("Register new certificate failed: access is denied");
                            }

                            return(string.Empty);
                        }
                        catch (Win32Exception ex)
                        {
                            // elevation is cancelled.
                            if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                            {
                                RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                                    { "native", ex.NativeErrorCode }
                                });
                                return($"Register new certificate failed: unknown (native {ex.NativeErrorCode})");
                            }

                            return("Register new certificate failed: operation is cancelled");
                        }
                        catch (Exception ex)
                        {
                            RollbarLocator.RollbarInstance.Error(ex);
                            return($"Register new certificate failed: unknown ({ex.Message})");
                        }
                    }

                    if (!sni.Hash.SequenceEqual(binding.CertificateHash))
                    {
                        // TODO: fix the error message.
                        var result =
                            MessageBox.Show(
                                "At least one other site is using the same HTTPS binding and the binding is configured with a different certificate. Are you sure that you want to reuse this HTTPS binding and reassign the other site or sites to use the new certificate?",
                                "TODO",
                                MessageBoxButtons.YesNo,
                                MessageBoxIcon.Question,
                                MessageBoxDefaultButton.Button1);
                        if (result != DialogResult.Yes)
                        {
                            return
                                ("Certificate hash does not match. Please use the certificate that matches HTTPS binding");
                        }

                        try
                        {
                            // register mapping
                            using var process = new Process();
                            var start = process.StartInfo;
                            start.Verb            = "runas";
                            start.UseShellExecute = true;
                            start.FileName        = "cmd";
                            start.Arguments       =
                                $"/c \"\"{CertificateInstallerLocator.FileName}\" /h:\"{Hex.ToHexString(binding.CertificateHash)}\" /s:{binding.CertificateStoreName}\" /i:{AppIdIisExpress} /a:{binding.EndPoint.Address} /o:{binding.EndPoint.Port} /x:{binding.Host}";
                            start.CreateNoWindow = true;
                            start.WindowStyle    = ProcessWindowStyle.Hidden;
                            process.Start();
                            process.WaitForExit();

                            if (process.ExitCode != 0)
                            {
                                return("Register new certificate failed: access is denied");
                            }

                            return(string.Empty);
                        }
                        catch (Win32Exception ex)
                        {
                            // elevation is cancelled.
                            if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                            {
                                RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                                    { "native", ex.NativeErrorCode }
                                });
                                return($"Register new certificate failed: unknown (native {ex.NativeErrorCode})");
                            }

                            return("Register new certificate failed: operation is cancelled");
                        }
                        catch (Exception ex)
                        {
                            RollbarLocator.RollbarInstance.Error(ex);
                            return($"Register new certificate failed: unknown ({ex.Message})");
                        }
                    }

                    if (!string.Equals(sni.StoreName, binding.CertificateStoreName, StringComparison.OrdinalIgnoreCase))
                    {
                        // TODO: can this happen?
                        return
                            ("Certificate store name does not match. Please use the certificate that matches HTTPS binding");
                    }

                    return(string.Empty);
                }
            }

            // handle IP based
            if (binding.EndPoint == null)
            {
                return("This binding does not have valid IP endpoint");
            }

            var certificate = NativeMethods.QuerySslCertificateInfo(binding.EndPoint);

            if (certificate == null)
            {
                try
                {
                    // register mapping
                    using var process = new Process();
                    var start = process.StartInfo;
                    start.Verb            = "runas";
                    start.UseShellExecute = true;
                    start.FileName        = "cmd";
                    start.Arguments       =
                        $"/c \"\"{CertificateInstallerLocator.FileName}\" /h:\"{Hex.ToHexString(binding.CertificateHash)}\" /s:{binding.CertificateStoreName}\" /i:{AppIdIisExpress} /a:{binding.EndPoint.Address} /o:{binding.EndPoint.Port}";
                    start.CreateNoWindow = true;
                    start.WindowStyle    = ProcessWindowStyle.Hidden;
                    process.Start();
                    process.WaitForExit();

                    if (process.ExitCode != 0)
                    {
                        return("Register new certificate failed: access is denied");
                    }

                    return(string.Empty);
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        return($"Register new certificate failed: unknown (native {ex.NativeErrorCode})");
                    }

                    return("Register new certificate failed: operation is cancelled");
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    return($"Register new certificate failed: unknown ({ex.Message})");
                }
            }

            if (!certificate.Hash.SequenceEqual(binding.CertificateHash))
            {
                var result =
                    MessageBox.Show(
                        "At least one other site is using the same HTTPS binding and the binding is configured with a different certificate. Are you sure that you want to reuse this HTTPS binding and reassign the other site or sites to use the new certificate?",
                        "TODO",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button1);
                if (result != DialogResult.Yes)
                {
                    return("Certificate hash does not match. Please use the certificate that matches HTTPS binding");
                }

                try
                {
                    // register mapping
                    using var process = new Process();
                    var start = process.StartInfo;
                    start.Verb            = "runas";
                    start.UseShellExecute = true;
                    start.FileName        = "cmd";
                    start.Arguments       =
                        $"/c \"\"{CertificateInstallerLocator.FileName}\" /h:\"{Hex.ToHexString(binding.CertificateHash)}\" /s:{binding.CertificateStoreName}\" /i:{AppIdIisExpress} /a:{binding.EndPoint.Address} /o:{binding.EndPoint.Port}";
                    start.CreateNoWindow = true;
                    start.WindowStyle    = ProcessWindowStyle.Hidden;
                    process.Start();
                    process.WaitForExit();

                    if (process.ExitCode != 0)
                    {
                        return("Register new certificate failed: access is denied");
                    }

                    return(string.Empty);
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (!NativeMethods.ErrorCancelled(ex.NativeErrorCode))
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        return($"Register new certificate failed: unknown (native {ex.NativeErrorCode})");
                    }

                    return("Register new certificate failed: operation is cancelled");
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    return($"Register new certificate failed: unknown ({ex.Message})");
                }
            }

            if (!string.Equals(certificate.StoreName, binding.CertificateStoreName, StringComparison.OrdinalIgnoreCase))
            {
                // TODO: can this happen?
                return
                    ("Certificate store name does not match. Please use the certificate that matches HTTPS binding");
            }

            return(string.Empty);
        }