diff options
author | Martin Polden <mpolden@mpolden.no> | 2018-03-12 15:58:45 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2018-03-13 08:53:42 +0100 |
commit | cbc059bc552a3524d8dd415bfb7605c7b3bc31be (patch) | |
tree | 27e94284395570418ef6989346437146d22f52d2 | |
parent | b17afb040ad32887d6ec49c9b844a1610c36ed5e (diff) |
Add localhost filter
2 files changed, 82 insertions, 0 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilter.java new file mode 100644 index 00000000000..00e89582dff --- /dev/null +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilter.java @@ -0,0 +1,51 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.provision.restapi.v2.filter; + +import com.yahoo.jdisc.handler.FastContentWriter; +import com.yahoo.jdisc.handler.ResponseDispatch; +import com.yahoo.jdisc.handler.ResponseHandler; +import com.yahoo.jdisc.http.filter.DiscFilterRequest; +import com.yahoo.jdisc.http.filter.SecurityRequestFilter; +import com.yahoo.vespa.hosted.provision.restapi.v2.ErrorResponse; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; + +/** + * A security filter that rejects requests not originating from localhost. + * + * @author mpolden + */ +@SuppressWarnings("unused") // Injected +public class LocalhostFilter implements SecurityRequestFilter { + + private static final String inet4Loopback = "127.0.0.1"; + private static final String inet6Loopback = "::1"; + + @Override + public void filter(DiscFilterRequest request, ResponseHandler handler) { + switch (request.getRemoteAddr()) { + case inet4Loopback: + case inet6Loopback: + break; // Allowed + default: + write(ErrorResponse.unauthorized(String.format("%s %s denied for %s: Unauthorized host", + request.getMethod(), request.getUri().getPath(), + request.getRemoteAddr())), handler); + } + } + + private static void write(ErrorResponse response, ResponseHandler handler) { + try (FastContentWriter writer = ResponseDispatch.newInstance(response.getJdiscResponse()) + .connectFastWriter(handler)) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + response.render(out); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + writer.write(out.toByteArray()); + } + } +} diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilterTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilterTest.java new file mode 100644 index 00000000000..b65cf31aca4 --- /dev/null +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/LocalhostFilterTest.java @@ -0,0 +1,31 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.provision.restapi.v2.filter; + +import com.yahoo.application.container.handler.Request.Method; +import com.yahoo.vespa.hosted.provision.restapi.v2.filter.FilterTester.Request; +import org.junit.Before; +import org.junit.Test; + +/** + * @author mpolden + */ +public class LocalhostFilterTest { + + private FilterTester tester; + + @Before + public void before() { + tester = new FilterTester(new LocalhostFilter()); + } + + @Test + public void filter() { + tester.assertRequest(new Request(Method.GET, "/").remoteAddr("1.2.3.4"), 401, + "{\"error-code\":\"UNAUTHORIZED\",\"message\":\"GET / denied for " + + "1.2.3.4: Unauthorized host\"}"); + + tester.assertSuccess(new Request(Method.GET, "/").remoteAddr("127.0.0.1")); + tester.assertSuccess(new Request(Method.GET, "/").remoteAddr("::1")); + } + +} |