1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-27 20:07:39 +00:00

HTTP rules now allow filtering by port

This commit is contained in:
Merith-TK
2021-02-22 02:56:04 -08:00
parent 2e527eb11e
commit 71d764f122
10 changed files with 106 additions and 20 deletions

View File

@@ -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());
}

View File

@@ -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);

View File

@@ -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");
}

View File

@@ -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()) {

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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;