mirror of
https://github.com/google/nomulus.git
synced 2025-04-30 03:57:51 +02:00
Remove the logic to add full certificate in the headers (#1143)
<!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/google/nomulus/1143) <!-- Reviewable:end -->
This commit is contained in:
parent
1a664fe95b
commit
f3a5a5aebd
4 changed files with 23 additions and 191 deletions
|
@ -35,9 +35,7 @@ import io.netty.handler.codec.http.HttpResponse;
|
||||||
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import java.security.cert.CertificateEncodingException;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/** Handler that processes EPP protocol logic. */
|
/** Handler that processes EPP protocol logic. */
|
||||||
|
@ -57,9 +55,7 @@ public class EppServiceHandler extends HttpsRelayServiceHandler {
|
||||||
private final byte[] helloBytes;
|
private final byte[] helloBytes;
|
||||||
|
|
||||||
private String sslClientCertificateHash;
|
private String sslClientCertificateHash;
|
||||||
private X509Certificate sslClientCertificate;
|
|
||||||
private String clientAddress;
|
private String clientAddress;
|
||||||
private boolean isLoggedIn = false;
|
|
||||||
|
|
||||||
public EppServiceHandler(
|
public EppServiceHandler(
|
||||||
String relayHost,
|
String relayHost,
|
||||||
|
@ -99,8 +95,7 @@ public class EppServiceHandler extends HttpsRelayServiceHandler {
|
||||||
.addListener(
|
.addListener(
|
||||||
(Promise<X509Certificate> promise) -> {
|
(Promise<X509Certificate> promise) -> {
|
||||||
if (promise.isSuccess()) {
|
if (promise.isSuccess()) {
|
||||||
sslClientCertificate = promise.get();
|
sslClientCertificateHash = getCertificateHash(promise.get());
|
||||||
sslClientCertificateHash = getCertificateHash(sslClientCertificate);
|
|
||||||
// Set the client cert hash key attribute for both this channel,
|
// Set the client cert hash key attribute for both this channel,
|
||||||
// used for collecting metrics on specific clients.
|
// used for collecting metrics on specific clients.
|
||||||
ctx.channel().attr(CLIENT_CERTIFICATE_HASH_KEY).set(sslClientCertificateHash);
|
ctx.channel().attr(CLIENT_CERTIFICATE_HASH_KEY).set(sslClientCertificateHash);
|
||||||
|
@ -129,17 +124,6 @@ public class EppServiceHandler extends HttpsRelayServiceHandler {
|
||||||
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
|
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
|
||||||
.set(HttpHeaderNames.CONTENT_TYPE, EPP_CONTENT_TYPE)
|
.set(HttpHeaderNames.CONTENT_TYPE, EPP_CONTENT_TYPE)
|
||||||
.set(HttpHeaderNames.ACCEPT, EPP_CONTENT_TYPE);
|
.set(HttpHeaderNames.ACCEPT, EPP_CONTENT_TYPE);
|
||||||
if (!isLoggedIn) {
|
|
||||||
try {
|
|
||||||
request
|
|
||||||
.headers()
|
|
||||||
.set(
|
|
||||||
ProxyHttpHeaders.FULL_CERTIFICATE,
|
|
||||||
Base64.getEncoder().encodeToString(sslClientCertificate.getEncoded()));
|
|
||||||
} catch (CertificateEncodingException e) {
|
|
||||||
throw new RuntimeException("Cannot encode client certificate", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,13 +133,9 @@ public class EppServiceHandler extends HttpsRelayServiceHandler {
|
||||||
checkArgument(msg instanceof HttpResponse);
|
checkArgument(msg instanceof HttpResponse);
|
||||||
HttpResponse response = (HttpResponse) msg;
|
HttpResponse response = (HttpResponse) msg;
|
||||||
String sessionAliveValue = response.headers().get(ProxyHttpHeaders.EPP_SESSION);
|
String sessionAliveValue = response.headers().get(ProxyHttpHeaders.EPP_SESSION);
|
||||||
String loginValue = response.headers().get(ProxyHttpHeaders.LOGGED_IN);
|
|
||||||
if (sessionAliveValue != null && sessionAliveValue.equals("close")) {
|
if (sessionAliveValue != null && sessionAliveValue.equals("close")) {
|
||||||
promise.addListener(ChannelFutureListener.CLOSE);
|
promise.addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
if (loginValue != null && loginValue.equals("true")) {
|
|
||||||
isLoggedIn = true;
|
|
||||||
}
|
|
||||||
super.write(ctx, msg, promise);
|
super.write(ctx, msg, promise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ package google.registry.proxy;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
||||||
import static google.registry.proxy.TestUtils.SAMPLE_CERT;
|
|
||||||
import static google.registry.proxy.handler.ProxyProtocolHandler.REMOTE_ADDRESS_KEY;
|
import static google.registry.proxy.handler.ProxyProtocolHandler.REMOTE_ADDRESS_KEY;
|
||||||
import static google.registry.util.ResourceUtils.readResourceBytes;
|
import static google.registry.util.ResourceUtils.readResourceBytes;
|
||||||
import static google.registry.util.X509Utils.getCertificateHash;
|
import static google.registry.util.X509Utils.getCertificateHash;
|
||||||
|
@ -26,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
import google.registry.proxy.handler.HttpsRelayServiceHandler.NonOkHttpResponseException;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
|
import google.registry.util.SelfSignedCaCertificate;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
@ -36,8 +36,6 @@ import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import io.netty.handler.codec.http.cookie.Cookie;
|
import io.netty.handler.codec.http.cookie.Cookie;
|
||||||
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.security.cert.CertificateFactory;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -98,8 +96,8 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FullHttpRequest makeEppHttpRequestWithCertificate(byte[] content, Cookie... cookies) {
|
private FullHttpRequest makeEppHttpRequest(byte[] content, Cookie... cookies) {
|
||||||
return TestUtils.makeEppHttpRequestWithCertificate(
|
return TestUtils.makeEppHttpRequest(
|
||||||
new String(content, UTF_8),
|
new String(content, UTF_8),
|
||||||
PROXY_CONFIG.epp.relayHost,
|
PROXY_CONFIG.epp.relayHost,
|
||||||
PROXY_CONFIG.epp.relayPath,
|
PROXY_CONFIG.epp.relayPath,
|
||||||
|
@ -122,10 +120,7 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
@Override
|
@Override
|
||||||
void beforeEach() throws Exception {
|
void beforeEach() throws Exception {
|
||||||
testComponent = makeTestComponent(new FakeClock());
|
testComponent = makeTestComponent(new FakeClock());
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
certificate = SelfSignedCaCertificate.create().cert();
|
||||||
certificate =
|
|
||||||
(X509Certificate)
|
|
||||||
cf.generateCertificate(new ByteArrayInputStream(SAMPLE_CERT.getBytes(UTF_8)));
|
|
||||||
initializeChannel(
|
initializeChannel(
|
||||||
ch -> {
|
ch -> {
|
||||||
ch.attr(REMOTE_ADDRESS_KEY).set(CLIENT_ADDRESS);
|
ch.attr(REMOTE_ADDRESS_KEY).set(CLIENT_ADDRESS);
|
||||||
|
@ -139,15 +134,13 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_singleFrameInboundMessage() throws Exception {
|
void testSuccess_singleFrameInboundMessage() throws Exception {
|
||||||
// First inbound message is hello.
|
// First inbound message is hello.
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(HELLO_BYTES));
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(HELLO_BYTES));
|
|
||||||
|
|
||||||
byte[] inputBytes = readResourceBytes(getClass(), "login.xml").read();
|
byte[] inputBytes = readResourceBytes(getClass(), "login.xml").read();
|
||||||
|
|
||||||
// Verify inbound message is as expected.
|
// Verify inbound message is as expected.
|
||||||
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes))).isTrue();
|
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes))).isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(inputBytes));
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes));
|
|
||||||
|
|
||||||
// Nothing more to read.
|
// Nothing more to read.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
|
@ -168,10 +161,8 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
Unpooled.wrappedBuffer(
|
Unpooled.wrappedBuffer(
|
||||||
getByteBufFromContent(inputBytes1), getByteBufFromContent(inputBytes2))))
|
getByteBufFromContent(inputBytes1), getByteBufFromContent(inputBytes2))))
|
||||||
.isTrue();
|
.isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(inputBytes1));
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes1));
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(inputBytes2));
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes2));
|
|
||||||
|
|
||||||
// Nothing more to read.
|
// Nothing more to read.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
|
@ -195,13 +186,11 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
|
|
||||||
// The second frame contains the first message, and part of the second message.
|
// The second frame contains the first message, and part of the second message.
|
||||||
assertThat(channel.writeInbound(inputBuffer.readBytes(inputBytes2.length))).isTrue();
|
assertThat(channel.writeInbound(inputBuffer.readBytes(inputBytes2.length))).isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(inputBytes1));
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes1));
|
|
||||||
|
|
||||||
// The third frame contains the rest of the second message.
|
// The third frame contains the rest of the second message.
|
||||||
assertThat(channel.writeInbound(inputBuffer)).isTrue();
|
assertThat(channel.writeInbound(inputBuffer)).isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound()).isEqualTo(makeEppHttpRequest(inputBytes2));
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes2));
|
|
||||||
|
|
||||||
// Nothing more to read.
|
// Nothing more to read.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
|
@ -263,7 +252,7 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
byte[] inputBytes1 = readResourceBytes(getClass(), "logout.xml").read();
|
byte[] inputBytes1 = readResourceBytes(getClass(), "logout.xml").read();
|
||||||
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes1))).isTrue();
|
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes1))).isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound())
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes1, cookie1, cookie2));
|
.isEqualTo(makeEppHttpRequest(inputBytes1, cookie1, cookie2));
|
||||||
|
|
||||||
// Second outbound message change cookies.
|
// Second outbound message change cookies.
|
||||||
byte[] outputBytes2 = readResourceBytes(getClass(), "logout_response.xml").read();
|
byte[] outputBytes2 = readResourceBytes(getClass(), "logout_response.xml").read();
|
||||||
|
@ -278,7 +267,7 @@ class EppProtocolModuleTest extends ProtocolModuleTest {
|
||||||
byte[] inputBytes2 = readResourceBytes(getClass(), "login.xml").read();
|
byte[] inputBytes2 = readResourceBytes(getClass(), "login.xml").read();
|
||||||
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes2))).isTrue();
|
assertThat(channel.writeInbound(getByteBufFromContent(inputBytes2))).isTrue();
|
||||||
assertThat((FullHttpRequest) channel.readInbound())
|
assertThat((FullHttpRequest) channel.readInbound())
|
||||||
.isEqualTo(makeEppHttpRequestWithCertificate(inputBytes2, cookie1, cookie2, cookie3));
|
.isEqualTo(makeEppHttpRequest(inputBytes2, cookie1, cookie2, cookie3));
|
||||||
|
|
||||||
// Nothing more to write or read.
|
// Nothing more to write or read.
|
||||||
assertThat((Object) channel.readOutbound()).isNull();
|
assertThat((Object) channel.readOutbound()).isNull();
|
||||||
|
|
|
@ -38,54 +38,6 @@ import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
|
||||||
/** Utility class for various helper methods used in testing. */
|
/** Utility class for various helper methods used in testing. */
|
||||||
public class TestUtils {
|
public class TestUtils {
|
||||||
|
|
||||||
public static final String SAMPLE_CERT =
|
|
||||||
"-----BEGIN CERTIFICATE-----\n"
|
|
||||||
+ "MIIDvTCCAqWgAwIBAgIJAK/PgPT0jTwRMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV\n"
|
|
||||||
+ "BAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxDzAN\n"
|
|
||||||
+ "BgNVBAoMBkdvb2dsZTEdMBsGA1UECwwUZG9tYWluLXJlZ2lzdHJ5LXRlc3QxEDAO\n"
|
|
||||||
+ "BgNVBAMMB2NsaWVudDEwHhcNMTUwODI2MTkxODA4WhcNNDMwMTExMTkxODA4WjB1\n"
|
|
||||||
+ "MQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZ\n"
|
|
||||||
+ "b3JrMQ8wDQYDVQQKDAZHb29nbGUxHTAbBgNVBAsMFGRvbWFpbi1yZWdpc3RyeS10\n"
|
|
||||||
+ "ZXN0MRAwDgYDVQQDDAdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n"
|
|
||||||
+ "CgKCAQEAvoE/IoFJyzb0dU4NFhL8FYgy+B/GnUd5aA66CMx5xKRMbEAtIgxU8TTO\n"
|
|
||||||
+ "W+9jdTsE00Grk3Ct4KdY73CYW+6IFXL4O0K/m5S+uajh+I2UMVZJV38RAIqNxue0\n"
|
|
||||||
+ "Egv9M4haSsCVIPcX9b+6McywfYSF1bzPb2Gb2FAQO7Jb0BjlPhPMIROCrbG40qPg\n"
|
|
||||||
+ "LWrl33dz+O52kO+DyZEzHqI55xH6au77sMITsJe+X23lzQcMFUUm8moiOw0EKrj/\n"
|
|
||||||
+ "GaMTZLHP46BCRoJDAPTNx55seIwgAHbKA2VVtqrvmA2XYJQA6ipdhfKRoJFy8Z8H\n"
|
|
||||||
+ "DYsorGtazQL2HhF/5uJD25z1m5eQHQIDAQABo1AwTjAdBgNVHQ4EFgQUParEmiSR\n"
|
|
||||||
+ "U/Oqy8hr7k+MBKhZwVkwHwYDVR0jBBgwFoAUParEmiSRU/Oqy8hr7k+MBKhZwVkw\n"
|
|
||||||
+ "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAojsUhF6PtZrStnHBFWNR\n"
|
|
||||||
+ "ryzvANB8krZlYeX9Hkqn8zIVfAkpbVmL8aZQ7yj17jSpw47PQh3x5gwA9yc/SS0G\n"
|
|
||||||
+ "E1rGuxYH02UGbua8G0+vviSQfLtskPQzK7EIR63WNhHEo/Q9umLJkZ0LguWEBf3L\n"
|
|
||||||
+ "q8CoXv2i/RNvqVPcTNp/zCKXJZAa8wAjNRJs834AZj4k5xwyYZ3F8D5PGz+YMOmV\n"
|
|
||||||
+ "M9Qd+NdXSC/Qn7HQzFhE8p5elBV35P8oX5dXEfn0S7zOXDenp5JvvLoggOWOcKsq\n"
|
|
||||||
+ "KiWDQrsT+TMKmHL94/h4t7FghtQLMzY5SGYJsYTv/LG8tewrz6KRb/Wj3JNojyEw\n"
|
|
||||||
+ "Ug==\n"
|
|
||||||
+ "-----END CERTIFICATE-----\n";
|
|
||||||
|
|
||||||
public static final String SAMPLE_CERT_ENCODED =
|
|
||||||
"MIIDvTCCAqWgAwIBAgIJAK/PgPT0jTwRMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV"
|
|
||||||
+ "BAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxDzAN"
|
|
||||||
+ "BgNVBAoMBkdvb2dsZTEdMBsGA1UECwwUZG9tYWluLXJlZ2lzdHJ5LXRlc3QxEDAO"
|
|
||||||
+ "BgNVBAMMB2NsaWVudDEwHhcNMTUwODI2MTkxODA4WhcNNDMwMTExMTkxODA4WjB1"
|
|
||||||
+ "MQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZ"
|
|
||||||
+ "b3JrMQ8wDQYDVQQKDAZHb29nbGUxHTAbBgNVBAsMFGRvbWFpbi1yZWdpc3RyeS10"
|
|
||||||
+ "ZXN0MRAwDgYDVQQDDAdjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB"
|
|
||||||
+ "CgKCAQEAvoE/IoFJyzb0dU4NFhL8FYgy+B/GnUd5aA66CMx5xKRMbEAtIgxU8TTO"
|
|
||||||
+ "W+9jdTsE00Grk3Ct4KdY73CYW+6IFXL4O0K/m5S+uajh+I2UMVZJV38RAIqNxue0"
|
|
||||||
+ "Egv9M4haSsCVIPcX9b+6McywfYSF1bzPb2Gb2FAQO7Jb0BjlPhPMIROCrbG40qPg"
|
|
||||||
+ "LWrl33dz+O52kO+DyZEzHqI55xH6au77sMITsJe+X23lzQcMFUUm8moiOw0EKrj/"
|
|
||||||
+ "GaMTZLHP46BCRoJDAPTNx55seIwgAHbKA2VVtqrvmA2XYJQA6ipdhfKRoJFy8Z8H"
|
|
||||||
+ "DYsorGtazQL2HhF/5uJD25z1m5eQHQIDAQABo1AwTjAdBgNVHQ4EFgQUParEmiSR"
|
|
||||||
+ "U/Oqy8hr7k+MBKhZwVkwHwYDVR0jBBgwFoAUParEmiSRU/Oqy8hr7k+MBKhZwVkw"
|
|
||||||
+ "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAojsUhF6PtZrStnHBFWNR"
|
|
||||||
+ "ryzvANB8krZlYeX9Hkqn8zIVfAkpbVmL8aZQ7yj17jSpw47PQh3x5gwA9yc/SS0G"
|
|
||||||
+ "E1rGuxYH02UGbua8G0+vviSQfLtskPQzK7EIR63WNhHEo/Q9umLJkZ0LguWEBf3L"
|
|
||||||
+ "q8CoXv2i/RNvqVPcTNp/zCKXJZAa8wAjNRJs834AZj4k5xwyYZ3F8D5PGz+YMOmV"
|
|
||||||
+ "M9Qd+NdXSC/Qn7HQzFhE8p5elBV35P8oX5dXEfn0S7zOXDenp5JvvLoggOWOcKsq"
|
|
||||||
+ "KiWDQrsT+TMKmHL94/h4t7FghtQLMzY5SGYJsYTv/LG8tewrz6KRb/Wj3JNojyEw"
|
|
||||||
+ "Ug==";
|
|
||||||
|
|
||||||
public static FullHttpRequest makeHttpPostRequest(String content, String host, String path) {
|
public static FullHttpRequest makeHttpPostRequest(String content, String host, String path) {
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(content.getBytes(US_ASCII));
|
ByteBuf buf = Unpooled.wrappedBuffer(content.getBytes(US_ASCII));
|
||||||
FullHttpRequest request =
|
FullHttpRequest request =
|
||||||
|
@ -151,21 +103,6 @@ public class TestUtils {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FullHttpRequest makeEppHttpRequestWithCertificate(
|
|
||||||
String content,
|
|
||||||
String host,
|
|
||||||
String path,
|
|
||||||
String accessToken,
|
|
||||||
String sslClientCertificateHash,
|
|
||||||
String clientAddress,
|
|
||||||
Cookie... cookies) {
|
|
||||||
FullHttpRequest request =
|
|
||||||
makeEppHttpRequest(
|
|
||||||
content, host, path, accessToken, sslClientCertificateHash, clientAddress, cookies);
|
|
||||||
request.headers().set("X-SSL-Full-Certificate", SAMPLE_CERT_ENCODED);
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FullHttpResponse makeWhoisHttpResponse(String content, HttpResponseStatus status) {
|
public static FullHttpResponse makeWhoisHttpResponse(String content, HttpResponseStatus status) {
|
||||||
FullHttpResponse response = makeHttpResponse(content, status);
|
FullHttpResponse response = makeHttpResponse(content, status);
|
||||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
|
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
|
||||||
|
|
|
@ -16,12 +16,10 @@ package google.registry.proxy.handler;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
import static google.registry.networking.handler.SslServerInitializer.CLIENT_CERTIFICATE_PROMISE_KEY;
|
||||||
import static google.registry.proxy.TestUtils.SAMPLE_CERT;
|
|
||||||
import static google.registry.proxy.TestUtils.assertHttpRequestEquivalent;
|
import static google.registry.proxy.TestUtils.assertHttpRequestEquivalent;
|
||||||
import static google.registry.proxy.TestUtils.makeEppHttpResponse;
|
import static google.registry.proxy.TestUtils.makeEppHttpResponse;
|
||||||
import static google.registry.proxy.handler.ProxyProtocolHandler.REMOTE_ADDRESS_KEY;
|
import static google.registry.proxy.handler.ProxyProtocolHandler.REMOTE_ADDRESS_KEY;
|
||||||
import static google.registry.util.X509Utils.getCertificateHash;
|
import static google.registry.util.X509Utils.getCertificateHash;
|
||||||
import static google.registry.util.X509Utils.loadCertificate;
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -46,10 +44,7 @@ import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import io.netty.handler.codec.http.cookie.Cookie;
|
import io.netty.handler.codec.http.cookie.Cookie;
|
||||||
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.security.cert.CertificateFactory;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Base64;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -74,11 +69,7 @@ class EppServiceHandlerTest {
|
||||||
|
|
||||||
private final EppServiceHandler eppServiceHandler =
|
private final EppServiceHandler eppServiceHandler =
|
||||||
new EppServiceHandler(
|
new EppServiceHandler(
|
||||||
RELAY_HOST,
|
RELAY_HOST, RELAY_PATH, () -> ACCESS_TOKEN, HELLO.getBytes(UTF_8), metrics);
|
||||||
RELAY_PATH,
|
|
||||||
() -> ACCESS_TOKEN,
|
|
||||||
HELLO.getBytes(UTF_8),
|
|
||||||
metrics);
|
|
||||||
|
|
||||||
private EmbeddedChannel channel;
|
private EmbeddedChannel channel;
|
||||||
|
|
||||||
|
@ -115,23 +106,9 @@ class EppServiceHandlerTest {
|
||||||
cookies);
|
cookies);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FullHttpRequest makeEppHttpRequestWithCertificate(String content, Cookie... cookies) {
|
|
||||||
return TestUtils.makeEppHttpRequestWithCertificate(
|
|
||||||
content,
|
|
||||||
RELAY_HOST,
|
|
||||||
RELAY_PATH,
|
|
||||||
ACCESS_TOKEN,
|
|
||||||
getCertificateHash(clientCertificate),
|
|
||||||
CLIENT_ADDRESS,
|
|
||||||
cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void beforeEach() throws Exception {
|
void beforeEach() throws Exception {
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
clientCertificate = SelfSignedCaCertificate.create().cert();
|
||||||
clientCertificate =
|
|
||||||
(X509Certificate)
|
|
||||||
cf.generateCertificate(new ByteArrayInputStream(SAMPLE_CERT.getBytes(UTF_8)));
|
|
||||||
channel = setUpNewChannel(eppServiceHandler);
|
channel = setUpNewChannel(eppServiceHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,11 +143,7 @@ class EppServiceHandlerTest {
|
||||||
// Setup the second channel.
|
// Setup the second channel.
|
||||||
EppServiceHandler eppServiceHandler2 =
|
EppServiceHandler eppServiceHandler2 =
|
||||||
new EppServiceHandler(
|
new EppServiceHandler(
|
||||||
RELAY_HOST,
|
RELAY_HOST, RELAY_PATH, () -> ACCESS_TOKEN, HELLO.getBytes(UTF_8), metrics);
|
||||||
RELAY_PATH,
|
|
||||||
() -> ACCESS_TOKEN,
|
|
||||||
HELLO.getBytes(UTF_8),
|
|
||||||
metrics);
|
|
||||||
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
|
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
|
||||||
setHandshakeSuccess(channel2, clientCertificate);
|
setHandshakeSuccess(channel2, clientCertificate);
|
||||||
|
|
||||||
|
@ -190,11 +163,7 @@ class EppServiceHandlerTest {
|
||||||
// Setup the second channel.
|
// Setup the second channel.
|
||||||
EppServiceHandler eppServiceHandler2 =
|
EppServiceHandler eppServiceHandler2 =
|
||||||
new EppServiceHandler(
|
new EppServiceHandler(
|
||||||
RELAY_HOST,
|
RELAY_HOST, RELAY_PATH, () -> ACCESS_TOKEN, HELLO.getBytes(UTF_8), metrics);
|
||||||
RELAY_PATH,
|
|
||||||
() -> ACCESS_TOKEN,
|
|
||||||
HELLO.getBytes(UTF_8),
|
|
||||||
metrics);
|
|
||||||
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
|
EmbeddedChannel channel2 = setUpNewChannel(eppServiceHandler2);
|
||||||
X509Certificate clientCertificate2 = SelfSignedCaCertificate.create().cert();
|
X509Certificate clientCertificate2 = SelfSignedCaCertificate.create().cert();
|
||||||
setHandshakeSuccess(channel2, clientCertificate2);
|
setHandshakeSuccess(channel2, clientCertificate2);
|
||||||
|
@ -214,7 +183,7 @@ class EppServiceHandlerTest {
|
||||||
setHandshakeSuccess();
|
setHandshakeSuccess();
|
||||||
// hello bytes should be passed to the next handler.
|
// hello bytes should be passed to the next handler.
|
||||||
FullHttpRequest helloRequest = channel.readInbound();
|
FullHttpRequest helloRequest = channel.readInbound();
|
||||||
assertThat(helloRequest).isEqualTo(makeEppHttpRequestWithCertificate(HELLO));
|
assertThat(helloRequest).isEqualTo(makeEppHttpRequest(HELLO));
|
||||||
// Nothing further to pass to the next handler.
|
// Nothing further to pass to the next handler.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
assertThat(channel.isActive()).isTrue();
|
assertThat(channel.isActive()).isTrue();
|
||||||
|
@ -236,47 +205,8 @@ class EppServiceHandlerTest {
|
||||||
String content = "<epp>stuff</epp>";
|
String content = "<epp>stuff</epp>";
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
|
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
|
||||||
FullHttpRequest request = channel.readInbound();
|
FullHttpRequest request = channel.readInbound();
|
||||||
assertThat(request).isEqualTo(makeEppHttpRequestWithCertificate(content));
|
|
||||||
// Nothing further to pass to the next handler.
|
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
|
||||||
assertThat(channel.isActive()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_requestContainsEncodedCertificate() throws Exception {
|
|
||||||
setHandshakeSuccess();
|
|
||||||
// First inbound message is hello.
|
|
||||||
channel.readInbound();
|
|
||||||
String content = "<epp>stuff</epp>";
|
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
|
|
||||||
FullHttpRequest request = channel.readInbound();
|
|
||||||
assertThat(request).isEqualTo(makeEppHttpRequestWithCertificate(content));
|
|
||||||
String encodedCert = request.headers().get(ProxyHttpHeaders.FULL_CERTIFICATE);
|
|
||||||
assertThat(encodedCert).isNotEqualTo(SAMPLE_CERT);
|
|
||||||
X509Certificate decodedCert =
|
|
||||||
loadCertificate(new ByteArrayInputStream(Base64.getDecoder().decode(encodedCert)));
|
|
||||||
X509Certificate pemCert = loadCertificate(SAMPLE_CERT);
|
|
||||||
assertThat(decodedCert).isEqualTo(pemCert);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_sendCertificateOnlyBeforeLogin() throws Exception {
|
|
||||||
setHandshakeSuccess();
|
|
||||||
// First inbound message is hello.
|
|
||||||
channel.readInbound();
|
|
||||||
String content = "<epp>stuff</epp>";
|
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
|
|
||||||
FullHttpRequest request = channel.readInbound();
|
|
||||||
assertThat(request).isEqualTo(makeEppHttpRequestWithCertificate(content));
|
|
||||||
// Receive response indicating session is logged in
|
|
||||||
HttpResponse response = makeEppHttpResponse(content, HttpResponseStatus.OK);
|
|
||||||
response.headers().set(ProxyHttpHeaders.LOGGED_IN, "true");
|
|
||||||
// Send another inbound message after login
|
|
||||||
channel.writeOutbound(response);
|
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(content.getBytes(UTF_8)));
|
|
||||||
request = channel.readInbound();
|
|
||||||
// Second request should not have full certificate
|
|
||||||
assertThat(request).isEqualTo(makeEppHttpRequest(content));
|
assertThat(request).isEqualTo(makeEppHttpRequest(content));
|
||||||
|
// Nothing further to pass to the next handler.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
assertThat(channel.isActive()).isTrue();
|
assertThat(channel.isActive()).isTrue();
|
||||||
}
|
}
|
||||||
|
@ -353,8 +283,7 @@ class EppServiceHandlerTest {
|
||||||
String requestContent = "<epp>request</epp>";
|
String requestContent = "<epp>request</epp>";
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(requestContent.getBytes(UTF_8)));
|
channel.writeInbound(Unpooled.wrappedBuffer(requestContent.getBytes(UTF_8)));
|
||||||
FullHttpRequest request = channel.readInbound();
|
FullHttpRequest request = channel.readInbound();
|
||||||
assertHttpRequestEquivalent(
|
assertHttpRequestEquivalent(request, makeEppHttpRequest(requestContent, cookie1, cookie2));
|
||||||
request, makeEppHttpRequestWithCertificate(requestContent, cookie1, cookie2));
|
|
||||||
// Nothing further to pass to the next handler.
|
// Nothing further to pass to the next handler.
|
||||||
assertThat((Object) channel.readInbound()).isNull();
|
assertThat((Object) channel.readInbound()).isNull();
|
||||||
assertThat((Object) channel.readOutbound()).isNull();
|
assertThat((Object) channel.readOutbound()).isNull();
|
||||||
|
@ -377,16 +306,13 @@ class EppServiceHandlerTest {
|
||||||
// First request written.
|
// First request written.
|
||||||
channel.writeInbound(Unpooled.wrappedBuffer(requestContent1.getBytes(UTF_8)));
|
channel.writeInbound(Unpooled.wrappedBuffer(requestContent1.getBytes(UTF_8)));
|
||||||
FullHttpRequest request1 = channel.readInbound();
|
FullHttpRequest request1 = channel.readInbound();
|
||||||
assertHttpRequestEquivalent(
|
assertHttpRequestEquivalent(request1, makeEppHttpRequest(requestContent1, cookie1, cookie2));
|
||||||
request1, makeEppHttpRequestWithCertificate(requestContent1, cookie1, cookie2));
|
|
||||||
String responseContent2 = "<epp>response2</epp>";
|
String responseContent2 = "<epp>response2</epp>";
|
||||||
Cookie cookie3 = new DefaultCookie("name3", "value3");
|
Cookie cookie3 = new DefaultCookie("name3", "value3");
|
||||||
Cookie newCookie2 = new DefaultCookie("name2", "newValue");
|
Cookie newCookie2 = new DefaultCookie("name2", "newValue");
|
||||||
// Second response written.
|
// Second response written.
|
||||||
HttpResponse response =
|
channel.writeOutbound(
|
||||||
makeEppHttpResponse(responseContent2, HttpResponseStatus.OK, cookie3, newCookie2);
|
makeEppHttpResponse(responseContent2, HttpResponseStatus.OK, cookie3, newCookie2));
|
||||||
response.headers().set(ProxyHttpHeaders.LOGGED_IN, "true");
|
|
||||||
channel.writeOutbound(response);
|
|
||||||
channel.readOutbound();
|
channel.readOutbound();
|
||||||
String requestContent2 = "<epp>request2</epp>";
|
String requestContent2 = "<epp>request2</epp>";
|
||||||
// Second request written.
|
// Second request written.
|
||||||
|
|
Loading…
Add table
Reference in a new issue