@@ -12,14 +12,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys;
1212
1313internal sealed partial class UrlGroup : IDisposable
1414{
15- private static readonly int BindingInfoSize =
16- Marshal . SizeOf < HTTP_BINDING_INFO > ( ) ;
17- private static readonly int QosInfoSize =
18- Marshal . SizeOf < HTTP_QOS_SETTING_INFO > ( ) ;
19- private static readonly int RequestPropertyInfoSize =
20- Marshal . SizeOf < HTTP_BINDING_INFO > ( ) ;
21- private static readonly int ChannelBindInfoSize =
22- Marshal . SizeOf < HTTP_CHANNEL_BIND_INFO > ( ) ;
15+ // See https://learn.microsoft.com/windows/win32/api/http/ns-http-http_channel_bind_info
16+ private const uint HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN = 0x00000008 ;
17+
18+ private static readonly int BindingInfoSize = Marshal . SizeOf < HTTP_BINDING_INFO > ( ) ;
19+ private static readonly int QosInfoSize = Marshal . SizeOf < HTTP_QOS_SETTING_INFO > ( ) ;
20+ private static readonly int RequestPropertyInfoSize = Marshal . SizeOf < HTTP_BINDING_INFO > ( ) ;
21+ private static readonly int ChannelBindInfoSize = Marshal . SizeOf < HTTP_CHANNEL_BIND_INFO > ( ) ;
2322
2423 private readonly ILogger _logger ;
2524
@@ -44,17 +43,30 @@ internal unsafe UrlGroup(ServerSession serverSession, RequestQueue requestQueue,
4443
4544 Debug . Assert ( urlGroupId != 0 , "Invalid id returned by HttpCreateUrlGroup" ) ;
4645 Id = urlGroupId ;
46+ }
4747
48- if ( AppContext . TryGetSwitch ( "Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening" , out var enabled ) && enabled )
48+ // Sets HttpServerChannelBindProperty with the requested hardening level and the HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN flag
49+ // so the per-request CBT is delivered to the app.
50+ internal unsafe void SetChannelBindingProperty ( HttpAuthenticationHardeningLevel level )
51+ {
52+ var info = new HTTP_CHANNEL_BIND_INFO
4953 {
50- var channelBindingSettings = new HTTP_CHANNEL_BIND_INFO
54+ Hardening = level switch
5155 {
52- Hardening = HTTP_AUTHENTICATION_HARDENING_LEVELS . HttpAuthenticationHardeningMedium ,
53- ServiceNames = ( HTTP_SERVICE_BINDING_BASE * * ) IntPtr . Zero ,
54- NumberOfServiceNames = 0 ,
55- } ;
56- SetProperty ( HTTP_SERVER_PROPERTY . HttpServerChannelBindProperty , new ( & channelBindingSettings ) , ( uint ) ChannelBindInfoSize ) ;
57- }
56+ HttpAuthenticationHardeningLevel . Strict => HTTP_AUTHENTICATION_HARDENING_LEVELS . HttpAuthenticationHardeningStrict ,
57+ HttpAuthenticationHardeningLevel . Legacy => HTTP_AUTHENTICATION_HARDENING_LEVELS . HttpAuthenticationHardeningLegacy ,
58+ HttpAuthenticationHardeningLevel . Medium or _ => HTTP_AUTHENTICATION_HARDENING_LEVELS . HttpAuthenticationHardeningMedium ,
59+ } ,
60+ ServiceNames = ( HTTP_SERVICE_BINDING_BASE * * ) IntPtr . Zero ,
61+ NumberOfServiceNames = 0 ,
62+
63+ // optimize: Flags control if CBT is included in NativeRequest, and if legacy level is used, no point to load the CBT data.
64+ Flags = level == HttpAuthenticationHardeningLevel . Legacy
65+ ? default
66+ : HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN ,
67+ } ;
68+
69+ SetProperty ( HTTP_SERVER_PROPERTY . HttpServerChannelBindProperty , new IntPtr ( & info ) , ( uint ) ChannelBindInfoSize , throwOnError : false ) ;
5870 }
5971
6072 internal ulong Id { get ; private set ; }
0 commit comments