mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-09-02 02:27:56 +00:00
HTTP rules now allow filtering by port
This commit is contained in:
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||
mod_version=1.92.0
|
||||
|
||||
# Minecraft properties
|
||||
mc_version=1.16.3
|
||||
mc_version=1.16.2
|
||||
mappings_version=31
|
||||
|
||||
# Dependencies
|
||||
|
20
patchwork.md
20
patchwork.md
@@ -52,4 +52,24 @@ were due to unrelated Forge changes.
|
||||
Fix additional `-` in docs
|
||||
|
||||
Why isn't this automatically stripped! Bad squid.
|
||||
```
|
||||
|
||||
```
|
||||
275ca58a82c627128a145a8754cbe32568536bd9
|
||||
HTTP rules now allow filtering by port
|
||||
|
||||
The HTTP filtering system becomes even more complex! Though in this
|
||||
case, it's pretty minimal, and definitely worth doing.
|
||||
|
||||
For instance, the following rule will allow connecting to localhost on
|
||||
port :8080.
|
||||
|
||||
[[http.rules]]
|
||||
host = "127.0.0.1"
|
||||
port = 8080
|
||||
action = "allow"
|
||||
|
||||
# Other rules as before.
|
||||
|
||||
Closes #540
|
||||
```
|
@@ -126,10 +126,10 @@ public final class ComputerCraft implements ModInitializer {
|
||||
|
||||
public static List<AddressRule> buildHttpRulesFromConfig(String[] blacklist, String[] whitelist) {
|
||||
return Stream.concat(Stream.of(blacklist)
|
||||
.map(x -> AddressRule.parse(x, Action.DENY.toPartial()))
|
||||
.map( x -> AddressRule.parse( x, null, Action.DENY.toPartial()))
|
||||
.filter(Objects::nonNull),
|
||||
Stream.of(whitelist)
|
||||
.map(x -> AddressRule.parse(x, Action.ALLOW.toPartial()))
|
||||
.map( x -> AddressRule.parse( x, null, Action.ALLOW.toPartial()))
|
||||
.filter(Objects::nonNull))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
@@ -21,14 +21,14 @@ public class CheckUrl extends Resource<CheckUrl> {
|
||||
private static final String EVENT = "http_check";
|
||||
private final IAPIEnvironment environment;
|
||||
private final String address;
|
||||
private final String host;
|
||||
private final URI uri;
|
||||
private Future<?> future;
|
||||
|
||||
public CheckUrl(ResourceGroup<CheckUrl> limiter, IAPIEnvironment environment, String address, URI uri) {
|
||||
super(limiter);
|
||||
this.environment = environment;
|
||||
this.address = address;
|
||||
this.host = uri.getHost();
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@@ -45,8 +45,9 @@ public class CheckUrl extends Resource<CheckUrl> {
|
||||
}
|
||||
|
||||
try {
|
||||
InetSocketAddress netAddress = NetworkUtils.getAddress(this.host, 80, false);
|
||||
NetworkUtils.getOptions(this.host, netAddress);
|
||||
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
|
||||
InetSocketAddress netAddress = NetworkUtils.getAddress( uri, ssl );
|
||||
NetworkUtils.getOptions( uri.getHost(), netAddress );
|
||||
|
||||
if (this.tryClose()) {
|
||||
this.environment.queueEvent(EVENT, this.address, true);
|
||||
|
@@ -7,6 +7,7 @@
|
||||
package dan200.computercraft.core.apis.http;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.security.KeyStore;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
@@ -94,6 +95,21 @@ public final class NetworkUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link InetSocketAddress} from a {@link java.net.URI}.
|
||||
*
|
||||
* Note, this may require a DNS lookup, and so should not be executed on the main CC thread.
|
||||
*
|
||||
* @param uri The URI to fetch.
|
||||
* @param ssl Whether to connect with SSL. This is used to find the default port if not otherwise specified.
|
||||
* @return The resolved address.
|
||||
* @throws HTTPRequestException If the host is not malformed.
|
||||
*/
|
||||
public static InetSocketAddress getAddress( URI uri, boolean ssl ) throws HTTPRequestException
|
||||
{
|
||||
return getAddress( uri.getHost(), uri.getPort(), ssl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link InetSocketAddress} from the resolved {@code host} and port.
|
||||
*
|
||||
@@ -125,7 +141,7 @@ public final class NetworkUtils {
|
||||
* @throws HTTPRequestException If the host is not permitted
|
||||
*/
|
||||
public static Options getOptions(String host, InetSocketAddress address) throws HTTPRequestException {
|
||||
Options options = AddressRule.apply(ComputerCraft.httpRules, host, address.getAddress());
|
||||
Options options = AddressRule.apply( ComputerCraft.httpRules, host, address );
|
||||
if (options.action == Action.DENY) {
|
||||
throw new HTTPRequestException("Domain not permitted");
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ package dan200.computercraft.core.apis.http.options;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -26,15 +27,22 @@ public final class AddressRule {
|
||||
public static final int WEBSOCKET_MESSAGE = 128 * 1024;
|
||||
private final HostRange ip;
|
||||
private final Pattern domainPattern;
|
||||
private final Integer port;
|
||||
private final PartialOptions partial;
|
||||
private AddressRule(@Nullable HostRange ip, @Nullable Pattern domainPattern, @Nonnull PartialOptions partial) {
|
||||
private AddressRule(
|
||||
@Nullable HostRange ip,
|
||||
@Nullable Pattern domainPattern,
|
||||
@Nullable Integer port,
|
||||
@Nonnull PartialOptions partial )
|
||||
{
|
||||
this.ip = ip;
|
||||
this.domainPattern = domainPattern;
|
||||
this.partial = partial;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AddressRule parse(String filter, @Nonnull PartialOptions partial) {
|
||||
public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial ) {
|
||||
int cidr = filter.indexOf('/');
|
||||
if (cidr >= 0) {
|
||||
String addressStr = filter.substring(0, cidr);
|
||||
@@ -73,14 +81,14 @@ public final class AddressRule {
|
||||
size -= 8;
|
||||
}
|
||||
|
||||
return new AddressRule(new HostRange(minBytes, maxBytes), null, partial);
|
||||
return new AddressRule(new HostRange(minBytes, maxBytes), null, port, partial);
|
||||
} else {
|
||||
Pattern pattern = Pattern.compile("^\\Q" + filter.replaceAll("\\*", "\\\\E.*\\\\Q") + "\\E$");
|
||||
return new AddressRule(null, pattern, partial);
|
||||
return new AddressRule(null, pattern, port, partial);
|
||||
}
|
||||
}
|
||||
|
||||
public static Options apply(Iterable<? extends AddressRule> rules, String domain, InetAddress address) {
|
||||
public static Options apply(Iterable<? extends AddressRule> rules, String domain, InetSocketAddress address) {
|
||||
PartialOptions options = null;
|
||||
boolean hasMany = false;
|
||||
|
||||
@@ -108,11 +116,14 @@ public final class AddressRule {
|
||||
/**
|
||||
* Determine whether the given address matches a series of patterns.
|
||||
*
|
||||
* @param domain The domain to match
|
||||
* @param address The address to check.
|
||||
* @param domain The domain to match
|
||||
* @param socketAddress The address to check.
|
||||
* @return Whether it matches any of these patterns.
|
||||
*/
|
||||
private boolean matches(String domain, InetAddress address) {
|
||||
private boolean matches(String domain, InetSocketAddress socketAddress) {
|
||||
InetAddress address = socketAddress.getAddress();
|
||||
if( port != null && port != socketAddress.getPort() ) return false;
|
||||
|
||||
if (this.domainPattern != null) {
|
||||
if (this.domainPattern.matcher(domain)
|
||||
.matches()) {
|
||||
|
@@ -9,6 +9,8 @@ package dan200.computercraft.core.apis.http.options;
|
||||
public class AddressRuleConfig {
|
||||
// TODO haha config is gone, do fix
|
||||
|
||||
// TODO FIGURE OUT WHY THE HELL THE PREVIOUS GUY HAD TO COMMENT THIS OUT
|
||||
|
||||
// public static UnmodifiableConfig makeRule( String host, Action action )
|
||||
// {
|
||||
// CommentedConfig config = InMemoryCommentedFormat.defaultInstance().createConfig( ConcurrentHashMap::new );
|
||||
@@ -39,17 +41,19 @@ public class AddressRuleConfig {
|
||||
// {
|
||||
// String hostObj = get( builder, "host", String.class ).orElse( null );
|
||||
// return hostObj != null && checkEnum( builder, "action", Action.class )
|
||||
// && check( builder, "port", Number.class )
|
||||
// && check( builder, "timeout", Number.class )
|
||||
// && check( builder, "max_upload", Number.class )
|
||||
// && check( builder, "max_download", Number.class )
|
||||
// && check( builder, "websocket_message", Number.class )
|
||||
// && AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
|
||||
// && AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
|
||||
// }
|
||||
//
|
||||
// @Nullable
|
||||
// public static AddressRule parseRule( UnmodifiableConfig builder )
|
||||
// {
|
||||
// String hostObj = get( builder, "host", String.class ).orElse( null );
|
||||
// Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
|
||||
// if( hostObj == null ) return null;
|
||||
//
|
||||
// Action action = getEnum( builder, "action", Action.class ).orElse( null );
|
||||
@@ -66,7 +70,7 @@ public class AddressRuleConfig {
|
||||
// websocketMessage
|
||||
// );
|
||||
//
|
||||
// return AddressRule.parse( hostObj, options );
|
||||
// return AddressRule.parse( hostObj, port, options );
|
||||
// }
|
||||
//
|
||||
// private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
|
||||
|
@@ -131,7 +131,7 @@ public class HttpRequest extends Resource<HttpRequest> {
|
||||
try {
|
||||
boolean ssl = uri.getScheme()
|
||||
.equalsIgnoreCase("https");
|
||||
InetSocketAddress socketAddress = NetworkUtils.getAddress(uri.getHost(), uri.getPort(), ssl);
|
||||
InetSocketAddress socketAddress = NetworkUtils.getAddress(uri, ssl);
|
||||
Options options = NetworkUtils.getOptions(uri.getHost(), socketAddress);
|
||||
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
||||
|
||||
|
@@ -117,7 +117,7 @@ public class Websocket extends Resource<Websocket> {
|
||||
boolean ssl = this.uri.getScheme()
|
||||
.equalsIgnoreCase("wss");
|
||||
|
||||
InetSocketAddress socketAddress = NetworkUtils.getAddress(this.uri.getHost(), this.uri.getPort(), ssl);
|
||||
InetSocketAddress socketAddress = NetworkUtils.getAddress(uri, ssl);
|
||||
Options options = NetworkUtils.getOptions(this.uri.getHost(), socketAddress);
|
||||
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
||||
|
||||
|
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core.apis.http.options;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class AddressRuleTest
|
||||
{
|
||||
@Test
|
||||
public void matchesPort()
|
||||
{
|
||||
Iterable<AddressRule> rules = Collections.singletonList( AddressRule.parse(
|
||||
"127.0.0.1", 8080,
|
||||
new PartialOptions( Action.ALLOW, null, null, null, null )
|
||||
) );
|
||||
|
||||
assertEquals( apply( rules, "localhost", 8080 ).action, Action.ALLOW );
|
||||
assertEquals( apply( rules, "localhost", 8081 ).action, Action.DENY );
|
||||
}
|
||||
|
||||
private Options apply( Iterable<AddressRule> rules, String host, int port )
|
||||
{
|
||||
return AddressRule.apply( rules, host, new InetSocketAddress( host, port ) );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user