diff --git a/pom.xml b/pom.xml index 90da5b689..7e2db7804 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ UTF-8 1.0.0.RELEASE 2022.0.16 - 2.1 + 3.0 5.3.32 1.19.5 1.19.0 @@ -127,7 +127,7 @@ com.ongres.scram - client + scram-client ${scram-client.version} diff --git a/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java b/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java index dcfe2ed29..c38c6baca 100644 --- a/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java +++ b/src/main/java/io/r2dbc/postgresql/authentication/SASLAuthenticationHandler.java @@ -1,10 +1,9 @@ package io.r2dbc.postgresql.authentication; import com.ongres.scram.client.ScramClient; -import com.ongres.scram.client.ScramSession; -import com.ongres.scram.common.exception.ScramInvalidServerSignatureException; -import com.ongres.scram.common.exception.ScramParseException; -import com.ongres.scram.common.exception.ScramServerErrorException; +import com.ongres.scram.common.StringPreparation; +import com.ongres.scram.common.exception.ScramException; + import io.r2dbc.postgresql.message.backend.AuthenticationMessage; import io.r2dbc.postgresql.message.backend.AuthenticationSASL; import io.r2dbc.postgresql.message.backend.AuthenticationSASLContinue; @@ -17,18 +16,13 @@ import reactor.core.Exceptions; import reactor.util.annotation.Nullable; -import static com.ongres.scram.client.ScramClient.ChannelBinding.NO; -import static com.ongres.scram.common.stringprep.StringPreparations.NO_PREPARATION; - public class SASLAuthenticationHandler implements AuthenticationHandler { private final CharSequence password; private final String username; - private ScramSession.ClientFinalProcessor clientFinalProcessor; - - private ScramSession scramSession; + private ScramClient scramClient; /** * Create a new handler. @@ -73,25 +67,22 @@ public FrontendMessage handle(AuthenticationMessage message) { } private FrontendMessage handleAuthenticationSASL(AuthenticationSASL message) { - ScramClient scramClient = ScramClient - .channelBinding(NO) - .stringPreparation(NO_PREPARATION) - .selectMechanismBasedOnServerAdvertised(message.getAuthenticationMechanisms().toArray(new String[0])) - .setup(); - - this.scramSession = scramClient.scramSession(this.username); - - return new SASLInitialResponse(ByteBufferUtils.encode(this.scramSession.clientFirstMessage()), scramClient.getScramMechanism().getName()); + this.scramClient = ScramClient.builder() + .advertisedMechanisms(message.getAuthenticationMechanisms()) + .username(username) // ignored by the server, use startup message + .password(password.toString().toCharArray()) + .stringPreparation(StringPreparation.POSTGRESQL_PREPARATION) + .build(); + + return new SASLInitialResponse(ByteBufferUtils.encode(this.scramClient.clientFirstMessage().toString()), scramClient.getScramMechanism().getName()); } private FrontendMessage handleAuthenticationSASLContinue(AuthenticationSASLContinue message) { try { - this.clientFinalProcessor = this.scramSession - .receiveServerFirstMessage(ByteBufferUtils.decode(message.getData())) - .clientFinalProcessor(this.password.toString()); + this.scramClient.serverFirstMessage(ByteBufferUtils.decode(message.getData())); - return new SASLResponse(ByteBufferUtils.encode(clientFinalProcessor.clientFinalMessage())); - } catch (ScramParseException e) { + return new SASLResponse(ByteBufferUtils.encode(this.scramClient.clientFinalMessage().toString())); + } catch (ScramException e) { throw Exceptions.propagate(e); } } @@ -99,9 +90,9 @@ private FrontendMessage handleAuthenticationSASLContinue(AuthenticationSASLConti @Nullable private FrontendMessage handleAuthenticationSASLFinal(AuthenticationSASLFinal message) { try { - this.clientFinalProcessor.receiveServerFinalMessage(ByteBufferUtils.decode(message.getAdditionalData())); + this.scramClient.serverFinalMessage(ByteBufferUtils.decode(message.getAdditionalData())); return null; - } catch (ScramParseException | ScramInvalidServerSignatureException | ScramServerErrorException e) { + } catch (ScramException e) { throw Exceptions.propagate(e); } } diff --git a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java index 7fdd5c22c..cb6db4f23 100644 --- a/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java +++ b/src/test/java/io/r2dbc/postgresql/PostgresqlConnectionFactoryUnitTests.java @@ -29,14 +29,13 @@ import io.r2dbc.postgresql.message.frontend.StartupMessage; import io.r2dbc.postgresql.util.ByteBufferUtils; import io.r2dbc.spi.R2dbcNonTransientResourceException; + import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.util.Collections; -import static com.ongres.scram.client.ScramClient.ChannelBinding.NO; -import static com.ongres.scram.common.stringprep.StringPreparations.NO_PREPARATION; import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -82,17 +81,17 @@ void createAuthenticationMD5Password() { @Test void createAuthenticationSASL() { - ScramClient scramClient = ScramClient - .channelBinding(NO) - .stringPreparation(NO_PREPARATION) - .selectMechanismBasedOnServerAdvertised("SCRAM-SHA-256") - .setup(); + ScramClient scramClient = ScramClient.builder() + .advertisedMechanisms(Collections.singletonList("SCRAM-SHA-256")) + .username("test-username") + .password("test-password".toCharArray()) + .build(); // @formatter:off Client client = TestClient.builder() .window() .expectRequest(new StartupMessage( "test-database", "test-username", new TestStartupParameterProvider())).thenRespond(new AuthenticationSASL(Collections.singletonList("SCRAM-SHA-256"))) - .expectRequest(new SASLInitialResponse(ByteBufferUtils.encode(scramClient.scramSession("test-username").clientFirstMessage()), "SCRAM-SHA-256")).thenRespond(AuthenticationOk.INSTANCE) + .expectRequest(new SASLInitialResponse(ByteBufferUtils.encode(scramClient.clientFirstMessage().toString()), "SCRAM-SHA-256")).thenRespond(AuthenticationOk.INSTANCE) .done() .build(); // @formatter:on