Search in sources :

Example 1 with SaslMechanism

use of com.couchbase.client.core.env.SaslMechanism in project couchbase-jvm-clients by couchbase.

the class SaslListMechanismsHandlerTest method decodesSuccessfulSaslMechsList.

@Test
void decodesSuccessfulSaslMechsList() {
    SaslListMechanismsHandler handler = new SaslListMechanismsHandler(endpointContext);
    channel.pipeline().addLast(handler);
    assertEquals(handler, channel.pipeline().get(SaslListMechanismsHandler.class));
    ChannelFuture connectFuture = channel.connect(new InetSocketAddress("1.2.3.4", 1234));
    assertFalse(connectFuture.isDone());
    channel.pipeline().fireChannelActive();
    channel.runPendingTasks();
    ByteBuf writtenRequest = channel.readOutbound();
    verifyRequest(writtenRequest, MemcacheProtocol.Opcode.SASL_LIST_MECHS.opcode(), false, false, false);
    assertNotNull(channel.pipeline().get(SaslListMechanismsHandler.class));
    ReferenceCountUtil.release(writtenRequest);
    ByteBuf response = decodeHexDump(readResource("success_sasl_list_mechs_response.txt", ErrorMapLoadingHandlerTest.class));
    channel.writeInbound(response);
    channel.runPendingTasks();
    assertTrue(connectFuture.isSuccess());
    Set<SaslMechanism> saslMechanisms = channel.attr(ChannelAttributes.SASL_MECHS_KEY).get();
    assertEquals(saslMechanisms, EnumSet.of(SaslMechanism.PLAIN, SaslMechanism.SCRAM_SHA1, SaslMechanism.SCRAM_SHA256, SaslMechanism.SCRAM_SHA512));
    assertTrue(eventBus.publishedEvents().get(0) instanceof SaslMechanismsListedEvent);
}
Also used : ChannelFuture(com.couchbase.client.core.deps.io.netty.channel.ChannelFuture) SaslMechanismsListedEvent(com.couchbase.client.core.cnc.events.io.SaslMechanismsListedEvent) InetSocketAddress(java.net.InetSocketAddress) SaslMechanism(com.couchbase.client.core.env.SaslMechanism) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Example 2 with SaslMechanism

use of com.couchbase.client.core.env.SaslMechanism in project couchbase-jvm-clients by couchbase.

the class SaslAuthenticationHandler method maybeFailConnect.

/**
 * Check if we need to do an auth retry with different mechs instead of giving up immediately.
 * <p>
 * The method performs the logic roughly as follows: we know that the current authentication attempt failed, but
 * because we are pipelining the original auth request with our allowed list it could be that they do not overlap
 * (i.e. only PLAIN is allowed because the server has LDAP enabled but we do not negotiate it by default), so give
 * it another chance to run with the updated and merged mechs list. If it still fails the next time it will terminate
 * eventually.
 * <p>
 * Most of the time though it will fail immediately since the mechs are aligned and the user just entered the
 * wrong credentials.
 */
private void maybeFailConnect(final ChannelHandlerContext ctx, final String message, final ByteBuf lastPacket, final Throwable cause, final short status) {
    final SaslMechanism currentlyUsedMech = SaslMechanism.from(saslClient.getMechanismName());
    final Set<SaslMechanism> negotiatedMechs = ctx.channel().attr(ChannelAttributes.SASL_MECHS_KEY).get();
    if (negotiatedMechs.contains(currentlyUsedMech)) {
        failConnect(ctx, message, lastPacket, cause, status);
    } else {
        Set<SaslMechanism> mergedMechs = allowedMechanisms.stream().filter(negotiatedMechs::contains).collect(Collectors.toSet());
        if (mergedMechs.isEmpty()) {
            failConnect(ctx, "Could not negotiate SASL mechanism with server. If you are using LDAP you must either" + "connect via TLS (recommended), or ONLY enable PLAIN in the allowed SASL mechanisms list on the PasswordAuthenticator" + "(this is insecure and will present the user credentials in plain-text over the wire).", lastPacket, cause, status);
        } else {
            ioContext.environment().eventBus().publish(new SaslAuthenticationRestartedEvent(ioContext));
            startAuthSequence(ctx, mergedMechs);
        }
    }
}
Also used : SaslAuthenticationRestartedEvent(com.couchbase.client.core.cnc.events.io.SaslAuthenticationRestartedEvent) SaslMechanism(com.couchbase.client.core.env.SaslMechanism)

Example 3 with SaslMechanism

use of com.couchbase.client.core.env.SaslMechanism in project couchbase-jvm-clients by couchbase.

the class SaslAuthenticationHandler method startAuthSequence.

/**
 * Starts the SASL auth sequence with the set of mechanisms that are valid for this specific run.
 *
 * @param ctx the channel handler context
 * @param usedMechanisms the mechanisms that can be used during this run
 */
private void startAuthSequence(final ChannelHandlerContext ctx, final Set<SaslMechanism> usedMechanisms) {
    try {
        saslClient = createSaslClient(usedMechanisms);
        SaslMechanism selectedMechanism = SaslMechanism.from(saslClient.getMechanismName());
        roundtripsToGo = selectedMechanism.roundtrips();
        endpointContext.environment().eventBus().publish(new SaslMechanismsSelectedEvent(ioContext, usedMechanisms, selectedMechanism));
        ctx.writeAndFlush(buildAuthRequest(ctx));
        maybePropagateChannelActive(ctx);
    } catch (SaslException e) {
        failConnect(ctx, "SASL Client could not be constructed", null, e, (short) 0);
    }
}
Also used : SaslMechanism(com.couchbase.client.core.env.SaslMechanism) SaslException(javax.security.sasl.SaslException) SaslMechanismsSelectedEvent(com.couchbase.client.core.cnc.events.io.SaslMechanismsSelectedEvent)

Example 4 with SaslMechanism

use of com.couchbase.client.core.env.SaslMechanism in project couchbase-jvm-clients by couchbase.

the class SaslListMechanismsHandler method channelRead.

/**
 * As soon as we get a response, turn it into a list of SASL mechanisms the server supports.
 * <p>
 * If the server responds with an empty list this is an issue and as a result we need to fail the connection
 * immediately.
 *
 * @param ctx the {@link ChannelHandlerContext} for which the channel read operation is made.
 * @param msg the incoming msg that needs to be parsed.
 */
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
    if (msg instanceof ByteBuf) {
        Optional<Duration> latency = ConnectTimings.stop(ctx.channel(), this.getClass(), false);
        if (successful((ByteBuf) msg)) {
            String[] rawMechansisms = body((ByteBuf) msg).orElse(Unpooled.EMPTY_BUFFER).toString(UTF_8).split(" ");
            boolean isEmpty = rawMechansisms.length == 1 && rawMechansisms[0].isEmpty();
            if (rawMechansisms.length > 0 && !isEmpty) {
                final Set<SaslMechanism> serverMechanisms = decodeMechanisms(rawMechansisms);
                ioContext.environment().eventBus().publish(new SaslMechanismsListedEvent(ioContext, serverMechanisms, latency.orElse(Duration.ZERO)));
                ctx.channel().attr(ChannelAttributes.SASL_MECHS_KEY).set(serverMechanisms);
                interceptedConnectPromise.trySuccess();
                ctx.pipeline().remove(this);
            } else {
                failConnection("Received empty mechanism list from server", status((ByteBuf) msg), latency);
            }
        } else {
            failConnection("Received non-success status from server", status((ByteBuf) msg), latency);
        }
    } else {
        interceptedConnectPromise.tryFailure(new CouchbaseException("Unexpected response " + "type on channel read, this is a bug - please report. " + msg));
    }
    ReferenceCountUtil.release(msg);
}
Also used : SaslMechanismsListedEvent(com.couchbase.client.core.cnc.events.io.SaslMechanismsListedEvent) CouchbaseException(com.couchbase.client.core.error.CouchbaseException) SaslMechanism(com.couchbase.client.core.env.SaslMechanism) Duration(java.time.Duration) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf)

Example 5 with SaslMechanism

use of com.couchbase.client.core.env.SaslMechanism in project couchbase-jvm-clients by couchbase.

the class SaslListMechanismsHandlerTest method ignoresUnknownSaslMech.

@Test
void ignoresUnknownSaslMech() {
    SaslListMechanismsHandler handler = new SaslListMechanismsHandler(endpointContext);
    channel.pipeline().addLast(handler);
    assertEquals(handler, channel.pipeline().get(SaslListMechanismsHandler.class));
    ChannelFuture connectFuture = channel.connect(new InetSocketAddress("1.2.3.4", 1234));
    assertFalse(connectFuture.isDone());
    channel.pipeline().fireChannelActive();
    channel.runPendingTasks();
    ByteBuf writtenRequest = channel.readOutbound();
    verifyRequest(writtenRequest, MemcacheProtocol.Opcode.SASL_LIST_MECHS.opcode(), false, false, false);
    assertNotNull(channel.pipeline().get(SaslListMechanismsHandler.class));
    ReferenceCountUtil.release(writtenRequest);
    ByteBuf response = decodeHexDump(readResource("success_sasl_list_mechs_unknown_mech_response.txt", ErrorMapLoadingHandlerTest.class));
    channel.writeInbound(response);
    channel.runPendingTasks();
    assertTrue(connectFuture.isSuccess());
    Set<SaslMechanism> saslMechanisms = channel.attr(ChannelAttributes.SASL_MECHS_KEY).get();
    assertEquals(saslMechanisms, EnumSet.of(SaslMechanism.SCRAM_SHA1, SaslMechanism.SCRAM_SHA256, SaslMechanism.SCRAM_SHA512));
    UnknownSaslMechanismDetectedEvent event = (UnknownSaslMechanismDetectedEvent) eventBus.publishedEvents().get(0);
    assertEquals("FLAUN", event.mechanism());
}
Also used : ChannelFuture(com.couchbase.client.core.deps.io.netty.channel.ChannelFuture) UnknownSaslMechanismDetectedEvent(com.couchbase.client.core.cnc.events.io.UnknownSaslMechanismDetectedEvent) InetSocketAddress(java.net.InetSocketAddress) SaslMechanism(com.couchbase.client.core.env.SaslMechanism) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) Test(org.junit.jupiter.api.Test)

Aggregations

SaslMechanism (com.couchbase.client.core.env.SaslMechanism)5 ByteBuf (com.couchbase.client.core.deps.io.netty.buffer.ByteBuf)3 SaslMechanismsListedEvent (com.couchbase.client.core.cnc.events.io.SaslMechanismsListedEvent)2 ChannelFuture (com.couchbase.client.core.deps.io.netty.channel.ChannelFuture)2 InetSocketAddress (java.net.InetSocketAddress)2 Test (org.junit.jupiter.api.Test)2 SaslAuthenticationRestartedEvent (com.couchbase.client.core.cnc.events.io.SaslAuthenticationRestartedEvent)1 SaslMechanismsSelectedEvent (com.couchbase.client.core.cnc.events.io.SaslMechanismsSelectedEvent)1 UnknownSaslMechanismDetectedEvent (com.couchbase.client.core.cnc.events.io.UnknownSaslMechanismDetectedEvent)1 CouchbaseException (com.couchbase.client.core.error.CouchbaseException)1 Duration (java.time.Duration)1 SaslException (javax.security.sasl.SaslException)1