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); }
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})"); } }
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); }