From 05464107a83a9e4c6e888b37f4af01b2fcace271 Mon Sep 17 00:00:00 2001 From: Danny Wensley Date: Wed, 20 Jan 2021 19:55:15 +0000 Subject: [PATCH] Update ComputerCraft.httpRules on config sync. Also removes a bit of http config related legacy code. --- .../dan200/computercraft/ComputerCraft.java | 23 +-- .../core/apis/AddressPredicate.java | 167 ------------------ .../computercraft/shared/util/Config.java | 4 +- 3 files changed, 13 insertions(+), 181 deletions(-) delete mode 100644 src/main/java/dan200/computercraft/core/apis/AddressPredicate.java diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index e2a966858..7160aef49 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -10,7 +10,6 @@ import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks; import static dan200.computercraft.shared.ComputerCraftRegistry.init; import java.nio.file.Paths; -import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -19,7 +18,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import dan200.computercraft.api.turtle.event.TurtleAction; -import dan200.computercraft.core.apis.AddressPredicate; import dan200.computercraft.core.apis.http.options.Action; import dan200.computercraft.core.apis.http.options.AddressRule; import dan200.computercraft.core.apis.http.websocket.Websocket; @@ -86,13 +84,6 @@ public final class ComputerCraft implements ModInitializer { // Logging public static final Logger log = LogManager.getLogger(MOD_ID); public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL)); - public static List httpRules = Collections.unmodifiableList(Stream.concat(Stream.of(DEFAULT_HTTP_BLACKLIST) - .map(x -> AddressRule.parse(x, Action.DENY.toPartial())) - .filter(Objects::nonNull), - Stream.of(DEFAULT_HTTP_WHITELIST) - .map(x -> AddressRule.parse(x, Action.ALLOW.toPartial())) - .filter(Objects::nonNull)) - .collect(Collectors.toList())); public static boolean commandRequireCreative = false; public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST; public static int computerSpaceLimit = 1000 * 1000; @@ -107,8 +98,6 @@ public final class ComputerCraft implements ModInitializer { public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); public static boolean http_enable = true; public static boolean http_websocket_enable = true; - public static AddressPredicate http_whitelist = new AddressPredicate(DEFAULT_HTTP_WHITELIST); - public static AddressPredicate http_blacklist = new AddressPredicate(DEFAULT_HTTP_BLACKLIST); public static int httpTimeout = 30000; public static int httpMaxRequests = 16; public static long httpMaxDownload = 16 * 1024 * 1024; @@ -131,6 +120,18 @@ public final class ComputerCraft implements ModInitializer { public static int monitorHeight = 6; public static double monitorDistanceSq = 4096; + public static List httpRules = buildHttpRulesFromConfig(DEFAULT_HTTP_BLACKLIST, DEFAULT_HTTP_WHITELIST); + + public static List buildHttpRulesFromConfig(String[] blacklist, String[] whitelist) { + return Stream.concat(Stream.of(blacklist) + .map(x -> AddressRule.parse(x, Action.DENY.toPartial())) + .filter(Objects::nonNull), + Stream.of(whitelist) + .map(x -> AddressRule.parse(x, Action.ALLOW.toPartial())) + .filter(Objects::nonNull)) + .collect(Collectors.toList()); + } + @Override public void onInitialize() { Config.load(Paths.get(FabricLoader.getInstance() diff --git a/src/main/java/dan200/computercraft/core/apis/AddressPredicate.java b/src/main/java/dan200/computercraft/core/apis/AddressPredicate.java deleted file mode 100644 index 22b7036db..000000000 --- a/src/main/java/dan200/computercraft/core/apis/AddressPredicate.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * This file is part of ComputerCraft - http://www.computercraft.info - * Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission. - * Send enquiries to dratcliffe@gmail.com - */ - -package dan200.computercraft.core.apis; - -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -import com.google.common.net.InetAddresses; -import dan200.computercraft.ComputerCraft; - -/** - * Used to determine whether a domain or IP address matches a series of patterns. - */ -public class AddressPredicate { - private final List wildcards; - private final List ranges; - - public AddressPredicate(String... filters) { - this(Arrays.asList(filters)); - } - - public AddressPredicate(Iterable filters) { - List wildcards = this.wildcards = new ArrayList<>(); - List ranges = this.ranges = new ArrayList<>(); - - for (String filter : filters) { - int cidr = filter.indexOf('/'); - if (cidr >= 0) { - String addressStr = filter.substring(0, cidr); - String prefixSizeStr = filter.substring(cidr + 1); - - int prefixSize; - try { - prefixSize = Integer.parseInt(prefixSizeStr); - } catch (NumberFormatException e) { - ComputerCraft.log.error("Malformed http whitelist/blacklist entry '{}': Cannot extract size of CIDR mask from '{}'.", - filter, - prefixSizeStr); - continue; - } - - InetAddress address; - try { - address = InetAddresses.forString(addressStr); - } catch (IllegalArgumentException e) { - ComputerCraft.log.error("Malformed http whitelist/blacklist entry '{}': Cannot extract IP address from '{}'.", filter, prefixSizeStr); - continue; - } - - // Mask the bytes of the IP address. - byte[] minBytes = address.getAddress(), maxBytes = address.getAddress(); - int size = prefixSize; - for (int i = 0; i < minBytes.length; i++) { - if (size <= 0) { - minBytes[i] &= 0; - maxBytes[i] |= 0xFF; - } else if (size < 8) { - minBytes[i] &= 0xFF << (8 - size); - maxBytes[i] |= ~(0xFF << (8 - size)); - } - - size -= 8; - } - - ranges.add(new HostRange(minBytes, maxBytes)); - } else { - wildcards.add(Pattern.compile("^\\Q" + filter.replaceAll("\\*", "\\\\E.*\\\\Q") + "\\E$")); - } - } - } - - /** - * Determine whether the given address matches a series of patterns - * - * @param address The address to check. - * @return Whether it matches any of these patterns. - */ - public boolean matches(InetAddress address) { - // Match the host name - String host = address.getHostName(); - if (host != null && this.matches(host)) { - return true; - } - - // Match the normal address - if (this.matchesAddress(address)) { - return true; - } - - // If we're an IPv4 address in disguise then let's check that. - return address instanceof Inet6Address && InetAddresses.is6to4Address((Inet6Address) address) && this.matchesAddress(InetAddresses.get6to4IPv4Address( - (Inet6Address) address)); - - } - - /** - * Determine whether a host name matches a series of patterns. - * - * This is intended to allow early exiting, before one has to look up the IP address. You should use {@link #matches(InetAddress)} instead of/in - * addition to this one. - * - * @param domain The domain to match. - * @return Whether the patterns were matched. - */ - public boolean matches(String domain) { - for (Pattern domainPattern : this.wildcards) { - if (domainPattern.matcher(domain) - .matches()) { - return true; - } - } - - return false; - } - - private boolean matchesAddress(InetAddress address) { - String addressString = address.getHostAddress(); - for (Pattern domainPattern : this.wildcards) { - if (domainPattern.matcher(addressString) - .matches()) { - return true; - } - } - - for (HostRange range : this.ranges) { - if (range.contains(address)) { - return true; - } - } - - return false; - } - - private static final class HostRange { - private final byte[] min; - private final byte[] max; - - private HostRange(byte[] min, byte[] max) { - this.min = min; - this.max = max; - } - - public boolean contains(InetAddress address) { - byte[] entry = address.getAddress(); - if (entry.length != this.min.length) { - return false; - } - - for (int i = 0; i < entry.length; i++) { - int value = 0xFF & entry[i]; - if (value < (0xFF & this.min[i]) || value > (0xFF & this.max[i])) { - return false; - } - } - - return true; - } - } -} diff --git a/src/main/java/dan200/computercraft/shared/util/Config.java b/src/main/java/dan200/computercraft/shared/util/Config.java index e2365a8d3..41c30f418 100644 --- a/src/main/java/dan200/computercraft/shared/util/Config.java +++ b/src/main/java/dan200/computercraft/shared/util/Config.java @@ -13,7 +13,6 @@ import com.google.common.base.CaseFormat; import com.google.common.base.Converter; import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.turtle.event.TurtleAction; -import dan200.computercraft.core.apis.AddressPredicate; import dan200.computercraft.core.apis.http.websocket.Websocket; public class Config { @@ -84,8 +83,7 @@ public class Config { // HTTP ComputerCraft.http_enable = config.http.enabled; ComputerCraft.http_websocket_enable = config.http.websocket_enabled; - ComputerCraft.http_whitelist = new AddressPredicate(config.http.whitelist); - ComputerCraft.http_blacklist = new AddressPredicate(config.http.blacklist); + ComputerCraft.httpRules = ComputerCraft.buildHttpRulesFromConfig(config.http.blacklist, config.http.whitelist); ComputerCraft.httpTimeout = Math.max(0, config.http.timeout); ComputerCraft.httpMaxRequests = Math.max(1, config.http.max_requests);