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