@@ -45,6 +45,30 @@ class AuthenticationStateMachineTests: XCTestCase {
4545 XCTAssertEqual ( state. authenticationMessageReceived ( . ok) , . wait)
4646 }
4747
48+ func testAuthenticateSCRAMSHA256WithAtypicalEncoding( ) {
49+ let authContext = AuthContext ( username: " test " , password: " abc123 " , database: " test " )
50+ var state = ConnectionStateMachine ( requireBackendKeyData: true )
51+ XCTAssertEqual ( state. connected ( tls: . disable) , . provideAuthenticationContext)
52+ XCTAssertEqual ( state. provideAuthenticationContext ( authContext) , . sendStartupMessage( authContext) )
53+
54+ let saslResponse = state. authenticationMessageReceived ( . sasl( names: [ " SCRAM-SHA-256 " ] ) )
55+ guard case . sendSaslInitialResponse( name: let name, initialResponse: let responseData) = saslResponse else {
56+ return XCTFail ( " \( saslResponse) is not .sendSaslInitialResponse " )
57+ }
58+ let responseString = String ( decoding: responseData, as: UTF8 . self)
59+ XCTAssertEqual ( name, " SCRAM-SHA-256 " )
60+ XCTAssert ( responseString. starts ( with: " n,,n=test,r= " ) )
61+
62+ let saslContinueResponse = state. authenticationMessageReceived ( . saslContinue( data: . init( bytes:
63+ " r= \( responseString. dropFirst ( 12 ) ) RUJSZHhkeUVFNzRLNERKMkxmU05ITU1NZWcxaQ==,s=ijgUVaWgCDLRJyF963BKNA==,i=4096 " . utf8
64+ ) ) )
65+ guard case . sendSaslResponse( let responseData2) = saslContinueResponse else {
66+ return XCTFail ( " \( saslContinueResponse) is not .sendSaslResponse " )
67+ }
68+ let response2String = String ( decoding: responseData2, as: UTF8 . self)
69+ XCTAssertEqual ( response2String. prefix ( 76 ) , " c=biws,r= \( responseString. dropFirst ( 12 ) ) RUJSZHhkeUVFNzRLNERKMkxmU05ITU1NZWcxaQ==,p= " )
70+ }
71+
4872 func testAuthenticationFailure( ) {
4973 let authContext = AuthContext ( username: " test " , password: " abc123 " , database: " test " )
5074 var state = ConnectionStateMachine ( requireBackendKeyData: true )
0 commit comments