@@ -528,8 +528,11 @@ public async Task DisposeAsync(IOBehavior ioBehavior, CancellationToken cancella
528528 if ( m_supportsConnectionAttributes && cs . ConnectionAttributes is null )
529529 cs . ConnectionAttributes = CreateConnectionAttributes ( cs . ApplicationName ) ;
530530
531+ // send a caching_sha2_password response if the server advertised support in the initial handshake
532+ var useCachingSha2 = initialHandshake . AuthPluginName == "caching_sha2_password" ;
533+
531534 var password = GetPassword ( cs , connection ) ;
532- using ( var handshakeResponsePayload = HandshakeResponse41Payload . Create ( initialHandshake , cs , password , m_compressionMethod , connection . ZstandardPlugin ? . CompressionLevel , m_characterSet , m_supportsConnectionAttributes ? cs . ConnectionAttributes : null ) )
535+ using ( var handshakeResponsePayload = HandshakeResponse41Payload . Create ( initialHandshake , cs , password , useCachingSha2 , m_compressionMethod , connection . ZstandardPlugin ? . CompressionLevel , m_characterSet , m_supportsConnectionAttributes ? cs . ConnectionAttributes : null ) )
533536 await SendReplyAsync ( handshakeResponsePayload , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
534537 payload = await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
535538
@@ -539,6 +542,26 @@ public async Task DisposeAsync(IOBehavior ioBehavior, CancellationToken cancella
539542 payload = await SwitchAuthenticationAsync ( cs , password , payload , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
540543 }
541544
545+ // check if caching_sha2_password response was sent
546+ if ( useCachingSha2 && payload . HeaderByte == CachingSha2ServerResponsePayload . Signature )
547+ {
548+ // process a successful response, or fall back to sending the password if the server doesn't have it
549+ var cachingSha2ServerResponsePayload = CachingSha2ServerResponsePayload . Create ( payload . Span ) ;
550+ if ( cachingSha2ServerResponsePayload . Succeeded )
551+ {
552+ payload = await ReceiveReplyAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
553+ }
554+ else if ( ! m_isSecureConnection && password . Length != 0 )
555+ {
556+ var publicKey = await GetRsaPublicKeyAsync ( m_currentAuthenticationMethod , cs , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
557+ payload = await SendEncryptedPasswordAsync ( AuthPluginData , publicKey , password , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
558+ }
559+ else
560+ {
561+ payload = await SendClearPasswordAsync ( password , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
562+ }
563+ }
564+
542565 var ok = OkPayload . Create ( payload . Span , this ) ;
543566
544567 if ( m_sslPolicyErrors != SslPolicyErrors . None )
0 commit comments