public static IEnumerable <UrlAcl> GetAllBindings() { HttpApi.ThrowWin32ExceptionIfError(HttpApi.HttpInitialize( HttpApi.HttpApiVersion, HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero)); try { var szQuery = Marshal.SizeOf(typeof(URLACL_QUERY)); var pQuery = Marshal.AllocHGlobal(szQuery); var szOutputBuffer = 4096; const int szMaxOutputBuffer = 4194304 /* 4 mb */; var pOutputBuffer = Marshal.AllocHGlobal(szOutputBuffer); try { for (int i = 0; i < int.MaxValue; i++) { // setup the query var query = new URLACL_QUERY(); query.dwToken = i; query.QueryDesc = URLACL_QUERY_TYPE.HttpServiceConfigQueryNext; Marshal.StructureToPtr(query, pQuery, false); while (true) { int szRequiredOutputBuffer; var result = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo, pQuery, szQuery, pOutputBuffer, szOutputBuffer, out szRequiredOutputBuffer, IntPtr.Zero); if (result == HttpApi.ERROR_NO_MORE_ITEMS) { yield break; } else if (result == HttpApi.ERROR_INSUFFICIENT_BUFFER) { if (szOutputBuffer >= szMaxOutputBuffer) { throw new InvalidOperationException(); } Marshal.FreeHGlobal(pOutputBuffer); Marshal.AllocHGlobal(szOutputBuffer *= 2); continue; } else if (result == HttpApi.NO_ERROR) { break; } else { throw new Win32Exception((int)result); } } var output = (URLACL_SET)Marshal.PtrToStructure(pOutputBuffer, typeof(URLACL_SET)); yield return(new UrlAcl(output.KeyDesc.pUrlPrefix, output.ParamDesc.pStringSecurityDescriptor)); } } finally { Marshal.FreeHGlobal(pQuery); Marshal.FreeHGlobal(pOutputBuffer); } } finally { HttpApi.HttpTerminate(HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero); } }
public bool Bind(CertificateBinding binding) { bool bindingUpdated = false; HttpApi.CallHttpApi( delegate { GCHandle sockAddrHandle = SockaddrInterop.CreateSockaddrStructure(binding.IpPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); var httpServiceConfigSslKey = new HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); byte[] hash = GetHash(binding.Thumbprint); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); var options = binding.Options; var configSslParam = new HttpApi.HTTP_SERVICE_CONFIG_SSL_PARAM { AppId = binding.AppId, DefaultCertCheckMode = (options.DoNotVerifyCertificateRevocation ? HttpApi.CertCheckModes.DoNotVerifyCertificateRevocation : 0) | (options.VerifyRevocationWithCachedCertificateOnly ? HttpApi.CertCheckModes.VerifyRevocationWithCachedCertificateOnly : 0) | (options.EnableRevocationFreshnessTime ? HttpApi.CertCheckModes.EnableRevocationFreshnessTime : 0) | (options.NoUsageCheck ? HttpApi.CertCheckModes.NoUsageCheck : 0), DefaultFlags = (options.NegotiateCertificate ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NEGOTIATE_CLIENT_CERT : 0) | (options.UseDsMappers ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.USE_DS_MAPPER : 0) | (options.DoNotPassRequestsToRawFilters ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NO_RAW_FILTER : 0), DefaultRevocationFreshnessTime = (int)options.RevocationFreshnessTime.TotalSeconds, DefaultRevocationUrlRetrievalTimeout = (int)options.RevocationUrlRetrievalTimeout.TotalMilliseconds, pSslCertStoreName = binding.StoreName, pSslHash = handleHash.AddrOfPinnedObject(), SslHashLength = hash.Length, pDefaultSslCtlIdentifier = options.SslCtlIdentifier, pDefaultSslCtlStoreName = options.SslCtlStoreName }; var configSslSet = new HttpApi.HTTP_SERVICE_CONFIG_SSL_SET { ParamDesc = configSslParam, KeyDesc = httpServiceConfigSslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (HttpApi.ERROR_ALREADY_EXISTS != retVal) { HttpApi.ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); bindingUpdated = true; } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) { handleHash.Free(); } if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } }); return(bindingUpdated); }
private static CertificateBinding[] QueryInternal() { var result = new List <CertificateBinding>(); HttpApi.CallHttpApi( delegate { uint token = 0; uint retVal; do { var inputConfigInfoQuery = new HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY { QueryDesc = HttpApi.HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext, dwToken = token, }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY))); Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false); IntPtr pOutputConfigInfo = IntPtr.Zero; int returnLength = 0; try { int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery); retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); if (HttpApi.ERROR_NO_MORE_ITEMS == retVal) { break; } if (HttpApi.ERROR_INSUFFICIENT_BUFFER == retVal) { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); try { retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); var outputConfigInfo = (HttpApi.HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure( pOutputConfigInfo, typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET)); var resultItem = CreateCertificateBindingInfo(outputConfigInfo); result.Add(resultItem); token++; } finally { Marshal.FreeCoTaskMem(pOutputConfigInfo); } } else { HttpApi.ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); } } while (HttpApi.NOERROR == retVal); }); return(result.ToArray()); }
private static CertificateBinding QueryExact(IPEndPoint ipPort) { CertificateBinding result = null; uint retVal; HttpApi.CallHttpApi( delegate { GCHandle sockAddrHandle = SockaddrInterop.CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); var sslKey = new HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); var inputConfigInfoQuery = new HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY { QueryDesc = HttpApi.HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact, KeyDesc = sslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY))); Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false); IntPtr pOutputConfigInfo = IntPtr.Zero; int returnLength = 0; try { int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery); retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); if (retVal == HttpApi.ERROR_FILE_NOT_FOUND) { return; } if (HttpApi.ERROR_INSUFFICIENT_BUFFER == retVal) { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); try { retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); var outputConfigInfo = (HttpApi.HTTP_SERVICE_CONFIG_SSL_SET) Marshal.PtrToStructure(pOutputConfigInfo, typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET)); result = CreateCertificateBindingInfo(outputConfigInfo); } finally { Marshal.FreeCoTaskMem(pOutputConfigInfo); } } else { HttpApi.ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } }); return(result); }