@@ -26,26 +26,80 @@ private protected virtual void Initialize()
2626        { 
2727        } 
2828
29-         protected  abstract  void  GenerateSspiClientContext ( ReadOnlySpan < byte >  incomingBlob ,  IBufferWriter < byte >  outgoingBlobWriter ,  ReadOnlySpan < string >   serverSpns ) ; 
29+         protected  abstract  bool  GenerateSspiClientContext ( ReadOnlySpan < byte >  incomingBlob ,  IBufferWriter < byte >  outgoingBlobWriter ,  SqlAuthenticationParameters   authParams ) ; 
3030
3131        internal  void  SSPIData ( ReadOnlySpan < byte >  receivedBuff ,  IBufferWriter < byte >  outgoingBlobWriter ,  string  serverSpn ) 
32-             =>  SSPIData ( receivedBuff ,  outgoingBlobWriter ,  new [ ]  {  serverSpn  } ) ; 
32+         { 
33+             if  ( ! RunGenerateSspiClientContext ( receivedBuff ,  outgoingBlobWriter ,  serverSpn ) ) 
34+             { 
35+                 // If we've hit here, the SSPI context provider implementation failed to generate the SSPI context. 
36+                 SSPIError ( SQLMessage . SSPIGenerateError ( ) ,  TdsEnums . GEN_CLIENT_CONTEXT ) ; 
37+             } 
38+         } 
3339
34-         internal  void  SSPIData ( ReadOnlySpan < byte >  receivedBuff ,  IBufferWriter < byte >  outgoingBlobWriter ,  string [ ]  serverSpns ) 
40+         internal  void  SSPIData ( ReadOnlySpan < byte >  receivedBuff ,  IBufferWriter < byte >  outgoingBlobWriter ,  ReadOnlySpan < string >  serverSpns ) 
3541        { 
3642            using  ( TrySNIEventScope . Create ( nameof ( SSPIContextProvider ) ) ) 
3743            { 
38-                 try 
44+                 foreach   ( var   serverSpn   in   serverSpns ) 
3945                { 
40-                     GenerateSspiClientContext ( receivedBuff ,  outgoingBlobWriter ,  serverSpns ) ; 
41-                 } 
42-                 catch  ( Exception  e ) 
43-                 { 
44-                     SSPIError ( e . Message  +  Environment . NewLine  +  e . StackTrace ,  TdsEnums . GEN_CLIENT_CONTEXT ) ; 
46+                     if  ( RunGenerateSspiClientContext ( receivedBuff ,  outgoingBlobWriter ,  serverSpn ) ) 
47+                     { 
48+                         return ; 
49+                     } 
4550                } 
51+ 
52+                 // If we've hit here, the SSPI context provider implementation failed to generate the SSPI context. 
53+                 SSPIError ( SQLMessage . SSPIGenerateError ( ) ,  TdsEnums . GEN_CLIENT_CONTEXT ) ; 
54+             } 
55+         } 
56+ 
57+         private  bool  RunGenerateSspiClientContext ( ReadOnlySpan < byte >  incomingBlob ,  IBufferWriter < byte >  outgoingBlobWriter ,  string  serverSpn ) 
58+         { 
59+             var  authParams  =  CreateSqlAuthParams ( _parser . Connection ,  serverSpn ) ; 
60+ 
61+             try 
62+             { 
63+ #if NET8_0_OR_GREATER 
64+                 SqlClientEventSource . Log . TryTraceEvent ( "{0}.{1} | Info | Session Id {2}, SPN={3}" ,  GetType ( ) . FullName , 
65+                     nameof ( GenerateSspiClientContext ) ,  _physicalStateObj . SessionId ,  serverSpn ) ; 
66+ #else
67+                 SqlClientEventSource . Log . TryTraceEvent ( "{0}.{1} | Info | SPN={1}" ,  GetType ( ) . FullName , 
68+                     nameof ( GenerateSspiClientContext ) ,  serverSpn ) ; 
69+ #endif
70+ 
71+                 return  GenerateSspiClientContext ( incomingBlob ,  outgoingBlobWriter ,  authParams ) ; 
72+             } 
73+             catch  ( Exception  e ) 
74+             { 
75+                 //throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode); 
76+                 SSPIError ( e . Message  +  Environment . NewLine  +  e . StackTrace ,  TdsEnums . GEN_CLIENT_CONTEXT ) ; 
77+                 return  false ; 
4678            } 
4779        } 
4880
81+         private  static   SqlAuthenticationParameters  CreateSqlAuthParams ( SqlInternalConnectionTds  connection ,  string  serverSpn ) 
82+         { 
83+             var  auth  =  new  SqlAuthenticationParameters . Builder ( 
84+                 authenticationMethod :  connection . ConnectionOptions . Authentication , 
85+                 resource :  null , 
86+                 authority :  null , 
87+                 serverName :  serverSpn , 
88+                 connection . ConnectionOptions . InitialCatalog ) ; 
89+ 
90+             if  ( connection . ConnectionOptions . UserID  is  {  }  userId ) 
91+             { 
92+                 auth . WithUserId ( userId ) ; 
93+             } 
94+ 
95+             if  ( connection . ConnectionOptions . Password  is  {  }  password ) 
96+             { 
97+                 auth . WithPassword ( password ) ; 
98+             } 
99+ 
100+             return  auth ; 
101+         } 
102+ 
49103        protected  void  SSPIError ( string  error ,  string  procedure ) 
50104        { 
51105            Debug . Assert ( ! ADP . IsEmpty ( procedure ) ,  "TdsParser.SSPIError called with an empty or null procedure string" ) ; 
0 commit comments