diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d3d9c51..9b451fe4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,8 @@
* Added fallback to binary mode on failure in zip digest computation
+* Added support for user defined host whitelist from system property
+
## 1.8.7 - May 24, 2022
* Paths in classpath are specified relative to appdir to avoid excessively long command lines.
diff --git a/core/src/main/java/io/github/bekoenig/getdown/data/Build.java.tmpl b/core/src/main/java/io/github/bekoenig/getdown/data/Build.java.tmpl
index 46996d98..6e9f57ac 100644
--- a/core/src/main/java/io/github/bekoenig/getdown/data/Build.java.tmpl
+++ b/core/src/main/java/io/github/bekoenig/getdown/data/Build.java.tmpl
@@ -5,11 +5,6 @@
package io.github.bekoenig.getdown.data;
-import java.util.Arrays;
-import java.util.List;
-
-import io.github.bekoenig.getdown.util.StringUtil;
-
/**
* Contains static data provided during the build process.
*/
@@ -26,7 +21,7 @@ public class Build {
}
/**
- *
The hosts which Getdown is allowed to communicate with. An empty list indicates that
+ *
The hosts which Getdown is allowed to communicate with. An empty string indicates that
* no whitelist is configured and there are no limitations. By default, no host whitelist
* is added to the binary, so it can be used to download and run applications from any
* server.
@@ -37,7 +32,7 @@ public class Build {
* (e.g. {@code *.mycompany.com}) and multiple values can be separated by commas
* (e.g. {@code app1.foo.com,app2.bar.com,app3.baz.com}).
*/
- public static List hostWhitelist () {
- return Arrays.asList(StringUtil.parseStringArray("@host_whitelist@"));
+ public static String hostWhitelist () {
+ return "@host_whitelist@";
}
}
diff --git a/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java b/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java
index 161a49d0..eb27390d 100644
--- a/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java
+++ b/core/src/main/java/io/github/bekoenig/getdown/data/SysProps.java
@@ -175,6 +175,13 @@ public static int threadPoolSize() {
return Integer.getInteger("thread_pool_size", defaultSize);
}
+ /**
+ * Returns the host whitelist from system property.
+ */
+ public static String hostWhitelist() {
+ return System.getProperty("getdown.host.whitelist", "");
+ }
+
/**
* Parses a Java version system property using the supplied regular expression. The numbers
* extracted from the regexp will be placed in each consecutive hundreds position in the
diff --git a/core/src/main/java/io/github/bekoenig/getdown/util/HostWhitelist.java b/core/src/main/java/io/github/bekoenig/getdown/util/HostWhitelist.java
index d37c34f2..c2e3bb24 100644
--- a/core/src/main/java/io/github/bekoenig/getdown/util/HostWhitelist.java
+++ b/core/src/main/java/io/github/bekoenig/getdown/util/HostWhitelist.java
@@ -6,24 +6,44 @@
package io.github.bekoenig.getdown.util;
import io.github.bekoenig.getdown.data.Build;
+import io.github.bekoenig.getdown.data.SysProps;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Arrays;
import java.util.List;
/**
- * Optional support for compiling a URL host whitelist into the Getdown JAR.
+ * Optional support for compiling a URL host whitelist into the Getdown JAR or defined by system
+ * property.
* Useful if you're on the paranoid end of the security spectrum.
*
* @see Build#hostWhitelist()
+ * @see SysProps#hostWhitelist()
*/
public final class HostWhitelist {
+
+ /**
+ * Returns the active host whitelist. If no host whitelist was set in the build (default
+ * behavior), the system property with the same name is used.
+ */
+ private static List activeHostWhitelist() {
+ // The compiled host whitelist has the highest priority.
+ String hostWhitelist = Build.hostWhitelist();
+ // If the compiled host whitelist is blank, the system property can be used.
+ if (StringUtil.isBlank(hostWhitelist)) {
+ hostWhitelist = SysProps.hostWhitelist();
+ }
+
+ return Arrays.asList(StringUtil.parseStringArray(hostWhitelist));
+ }
+
/**
* Verifies that the specified URL should be accessible, per the built-in host whitelist.
* See {@link Build#hostWhitelist()} and {@link #verify(List, URL)}.
*/
public static URL verify(URL url) throws MalformedURLException {
- return verify(Build.hostWhitelist(), url);
+ return verify(activeHostWhitelist(), url);
}
/**
diff --git a/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java b/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java
index 67d6287a..43bf6647 100644
--- a/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java
+++ b/core/src/test/java/io/github/bekoenig/getdown/data/SysPropsTest.java
@@ -7,7 +7,10 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.ClearSystemProperty;
+import org.junitpioneer.jupiter.SetSystemProperty;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
class SysPropsTest {
@@ -66,4 +69,29 @@ void testAppbaseOverride() {
assertEquals("https://barbaz.com/newapp", SysProps.overrideAppbase(appbase));
}
}
+
+ @Test
+ @ClearSystemProperty(key = "getdown.host.whitelist")
+ void test_hostWhitelist_undefined() {
+ // GIVEN
+
+ // WHEN
+ String hostWhitelist = SysProps.hostWhitelist();
+
+ // THEN
+ assertThat(hostWhitelist).isEqualTo("");
+ }
+
+ @Test
+ @SetSystemProperty(key = "getdown.host.whitelist", value = "app1.foo.com,app2.bar.com,app3.baz.com")
+ void test_hostWhitelist_defined() {
+ // GIVEN
+
+ // WHEN
+ String hostWhitelist = SysProps.hostWhitelist();
+
+ // THEN
+ assertThat(hostWhitelist).isEqualTo("app1.foo.com,app2.bar.com,app3.baz.com");
+ }
+
}