private void startNegotiation(boolean fakeLoopback) { Negotiator negotiator = new Negotiator("127.0.0.1", secContext, false); negotiator.overrideLoopbackForTests = fakeLoopback; embedder = new DecoderEmbedder<Object>(negotiator); negotiator.sendHello(embedder.getPipeline().getChannel()); }
@Test public void testTlsNegotiationAuthOnly() throws Exception { startNegotiation(true); // Expect client->server: NEGOTIATE, TLS and TLS_AUTHENTICATION_ONLY included. RpcOutboundMessage msg = (RpcOutboundMessage) embedder.poll(); NegotiatePB body = (NegotiatePB) msg.getBody(); assertEquals(NegotiateStep.NEGOTIATE, body.getStep()); assertTrue(body.getSupportedFeaturesList().contains(RpcFeatureFlag.TLS)); assertTrue(body.getSupportedFeaturesList().contains( RpcFeatureFlag.TLS_AUTHENTICATION_ONLY)); // Fake a server response with TLS and TLS_AUTHENTICATION_ONLY enabled. embedder.offer(fakeResponse( ResponseHeader.newBuilder().setCallId(Negotiator.SASL_CALL_ID).build(), NegotiatePB.newBuilder() .addSaslMechanisms(NegotiatePB.SaslMechanism.newBuilder().setMechanism("PLAIN")) .addSupportedFeatures(RpcFeatureFlag.TLS) .addSupportedFeatures(RpcFeatureFlag.TLS_AUTHENTICATION_ONLY) .setStep(NegotiateStep.NEGOTIATE) .build())); // Expect client->server: TLS_HANDSHAKE. runTlsHandshake(); // The pipeline should *not* have an SSL handler as the first handler, // since we used TLS for authentication only. assertFalse(embedder.getPipeline().getFirst() instanceof SslHandler); // The Negotiator should have sent the SASL_INITIATE at this point. msg = (RpcOutboundMessage) embedder.poll(); body = (NegotiatePB) msg.getBody(); assertEquals(NegotiateStep.SASL_INITIATE, body.getStep()); }
@Test public void testTlsNegotiation() throws Exception { startNegotiation(false); // Expect client->server: NEGOTIATE, TLS included. RpcOutboundMessage msg = (RpcOutboundMessage) embedder.poll(); NegotiatePB body = (NegotiatePB) msg.getBody(); assertEquals(NegotiateStep.NEGOTIATE, body.getStep()); assertTrue(body.getSupportedFeaturesList().contains(RpcFeatureFlag.TLS)); // Fake a server response with TLS enabled. embedder.offer(fakeResponse( ResponseHeader.newBuilder().setCallId(Negotiator.SASL_CALL_ID).build(), NegotiatePB.newBuilder() .addSaslMechanisms(NegotiatePB.SaslMechanism.newBuilder().setMechanism("PLAIN")) .addSupportedFeatures(RpcFeatureFlag.TLS) .setStep(NegotiateStep.NEGOTIATE) .build())); // Expect client->server: TLS_HANDSHAKE. runTlsHandshake(); // The pipeline should now have an SSL handler as the first handler. assertTrue(embedder.getPipeline().getFirst() instanceof SslHandler); // The Negotiator should have sent the SASL_INITIATE at this point. // NOTE: in a non-mock environment, this message would now be encrypted // by the newly-added TLS handler. But, with the DecoderEmbedder that we're // using, we don't actually end up processing outbound events. Upgrading // to Netty 4 and using EmbeddedChannel instead would make this more realistic. msg = (RpcOutboundMessage) embedder.poll(); body = (NegotiatePB) msg.getBody(); assertEquals(NegotiateStep.SASL_INITIATE, body.getStep()); }