55
66namespace HttpSys
77{
8- public static class NetShWrapper
8+ public class NetShWrapper
99 {
10- public static void DeleteBindingIfExists ( string ipPort )
10+ public bool SupportsDisableSessionId { get ; }
11+ public bool SupportsEnableSessionTicket { get ; }
12+
13+ public NetShWrapper ( )
14+ {
15+ var sslCertCapabilitiesText = ExecuteNetShCommand ( $ "http add sslcert help") ;
16+ if ( string . IsNullOrEmpty ( sslCertCapabilitiesText ) )
17+ {
18+ throw new InvalidOperationException ( "Failed to determine http.sys capabilities" ) ;
19+ }
20+
21+ if ( sslCertCapabilitiesText . Contains ( "disablesessionid" ) )
22+ {
23+ SupportsDisableSessionId = true ;
24+ }
25+
26+ if ( sslCertCapabilitiesText . Contains ( "enablesessionticket" ) )
27+ {
28+ SupportsEnableSessionTicket = true ;
29+ }
30+
31+ Console . WriteLine ( $ """
32+ Http.SYS Capabilities:
33+ - SupportsDisableSessionId: { SupportsDisableSessionId } (if not supported, renegotiation will most likely be enabled by default)
34+ - SupportsEnableSessionTicket: { SupportsEnableSessionTicket }
35+ """ ) ;
36+ }
37+
38+ public void DeleteBindingIfExists ( string ipPort )
1139 {
1240 try
1341 {
@@ -19,7 +47,7 @@ public static void DeleteBindingIfExists(string ipPort)
1947 }
2048 }
2149
22- public static void DeleteBinding ( string ipPort )
50+ public void DeleteBinding ( string ipPort )
2351 {
2452 Console . WriteLine ( "Disabling mTLS for http.sys" ) ;
2553
@@ -29,9 +57,7 @@ public static void DeleteBinding(string ipPort)
2957 Console . WriteLine ( "Disabled http.sys settings for mTLS" ) ;
3058 }
3159
32-
33-
34- public static bool TryGetSslCertBinding ( string ipPort , out SslCertBinding result )
60+ public bool TryGetSslCertBinding ( string ipPort , out SslCertBinding result )
3561 {
3662 result = new SslCertBinding ( ) ;
3763
@@ -71,7 +97,7 @@ public static bool TryGetSslCertBinding(string ipPort, out SslCertBinding result
7197 Max Settings Per Frame : 2796202
7298 Max Settings Per Minute : 4294967295
7399 */
74- var bindings = ExecuteNetShCommand ( $ "http show sslcert ipport={ ipPort } ") ;
100+ var bindings = ExecuteNetShCommand ( $ "http show sslcert ipport={ ipPort } ", ignoreErrorExit : true ) ;
75101 if ( string . IsNullOrEmpty ( bindings ) || ! bindings . Contains ( ipPort ) )
76102 {
77103 return false ;
@@ -123,12 +149,12 @@ public static bool TryGetSslCertBinding(string ipPort, out SslCertBinding result
123149 } ;
124150 }
125151
126- public static void LogSslCertBinding ( string ipPort )
152+ public void LogSslCertBinding ( string ipPort )
127153 {
128154 ExecuteNetShCommand ( $ "http show sslcert ipport={ ipPort } ", alwaysLogOutput : true ) ;
129155 }
130156
131- public static void SetTestCertBinding ( string ipPort , bool enableClientCertNegotiation )
157+ public void SetTestCertBinding ( string ipPort , bool enableClientCertNegotiation )
132158 {
133159 Console . WriteLine ( "Setting up binding for testCert for http.sys" ) ;
134160
@@ -148,7 +174,7 @@ public static void SetTestCertBinding(string ipPort, bool enableClientCertNegoti
148174 Console . WriteLine ( "Configured binding for testCert for http.sys" ) ;
149175 }
150176
151- public static bool TrySelfSignCertificate ( string ipPort , out string certThumbprint )
177+ public bool TrySelfSignCertificate ( string ipPort , out string certThumbprint )
152178 {
153179 certThumbprint = string . Empty ;
154180 try
@@ -175,31 +201,31 @@ public static bool TrySelfSignCertificate(string ipPort, out string certThumbpri
175201 }
176202 }
177203
178- public static void AddCertBinding (
204+ public void AddCertBinding (
179205 string ipPort , string certThumbprint ,
180206 string ? appId = null ,
181207 NetShFlag clientCertNegotiation = NetShFlag . Disabled ,
182208 NetShFlag disablesessionid = NetShFlag . Enable ,
183209 NetShFlag enablesessionticket = NetShFlag . Disabled )
184210 => CertBindingCore ( "add" , ipPort , certThumbprint , appId , clientCertNegotiation , disablesessionid , enablesessionticket ) ;
185211
186- public static void UpdateCertBinding ( string ipPort , SslCertBinding binding ) => UpdateCertBinding (
212+ public void UpdateCertBinding ( string ipPort , SslCertBinding binding ) => UpdateCertBinding (
187213 ipPort ,
188214 binding . CertificateThumbprint ,
189215 binding . ApplicationId ,
190216 binding . NegotiateClientCertificate ,
191217 binding . DisableSessionIdTlsResumption ,
192218 binding . EnableSessionTicketTlsResumption ) ;
193219
194- public static void UpdateCertBinding (
220+ public void UpdateCertBinding (
195221 string ipPort , string certThumbprint ,
196222 string ? appId = null ,
197223 NetShFlag clientCertNegotiation = NetShFlag . Disabled ,
198224 NetShFlag disablesessionid = NetShFlag . Enable ,
199225 NetShFlag enablesessionticket = NetShFlag . Disabled )
200226 => CertBindingCore ( "update" , ipPort , certThumbprint , appId , clientCertNegotiation , disablesessionid , enablesessionticket ) ;
201227
202- private static void CertBindingCore (
228+ private void CertBindingCore (
203229 string httpOperation ,
204230 string ipPort , string certThumbprint ,
205231 string ? appId = null ,
@@ -224,17 +250,15 @@ private static void CertBindingCore(
224250
225251 // below options are supported only in later versions of HTTP.SYS
226252 // you can identify if it is available by running `netsh http add sslcert help`
227- // ---
228- // workaround is to control SChannel settings via registry
229-
230- //if (disablesessionidFlag != null)
231- //{
232- // command += $" disablesessionid={disablesessionidFlag}";
233- //}
234- //if (enablesessionticketFlag != null)
235- //{
236- // command += $" enablesessionticket={enablesessionticketFlag}";
237- //}
253+
254+ if ( SupportsDisableSessionId && disablesessionidFlag != null )
255+ {
256+ command += $ " disablesessionid={ disablesessionidFlag } ";
257+ }
258+ if ( SupportsEnableSessionTicket && enablesessionticketFlag != null )
259+ {
260+ command += $ " enablesessionticket={ enablesessionticketFlag } ";
261+ }
238262
239263 ExecuteNetShCommand ( command , alwaysLogOutput : true ) ;
240264 Console . WriteLine ( $ "Performed cert binding for { ipPort } ") ;
@@ -248,13 +272,13 @@ private static void CertBindingCore(
248272 } ;
249273 }
250274
251- private static string ExecutePowershellCommand ( string command , bool alwaysLogOutput = false )
252- => ExecuteCommand ( "powershell.exe" , command , alwaysLogOutput ) ;
275+ private static string ExecutePowershellCommand ( string command , bool ignoreErrorExit = false , bool alwaysLogOutput = false )
276+ => ExecuteCommand ( "powershell.exe" , command , ignoreErrorExit , alwaysLogOutput ) ;
253277
254- private static string ExecuteNetShCommand ( string command , bool alwaysLogOutput = false )
255- => ExecuteCommand ( "netsh" , command , alwaysLogOutput ) ;
278+ private static string ExecuteNetShCommand ( string command , bool ignoreErrorExit = false , bool alwaysLogOutput = false )
279+ => ExecuteCommand ( "netsh" , command , ignoreErrorExit , alwaysLogOutput ) ;
256280
257- private static string ExecuteCommand ( string fileName , string command , bool logOutput = false )
281+ private static string ExecuteCommand ( string fileName , string command , bool ignoreErrorExit = false , bool logOutput = false )
258282 {
259283 ProcessStartInfo processInfo = new ProcessStartInfo ( fileName , command )
260284 {
@@ -274,7 +298,7 @@ private static string ExecuteCommand(string fileName, string command, bool logOu
274298 Console . WriteLine ( output ) ;
275299 }
276300
277- if ( process . ExitCode != 0 )
301+ if ( ! ignoreErrorExit && process . ExitCode != 0 )
278302 {
279303 throw new InvalidOperationException ( $ "{ fileName } command execution failure: { output } ") ;
280304 }
0 commit comments