Fix error messages for new Internet Card filtering system.

This commit is contained in:
Adrian Siekierka 2023-06-27 15:19:45 +02:00
parent c30f083072
commit 4b1229f26e
5 changed files with 66 additions and 28 deletions

View File

@ -41,7 +41,7 @@ public final class InetAddressRange {
address = InetAddresses.forString(addressStr); address = InetAddresses.forString(addressStr);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new IllegalArgumentException(String.format("Malformed address range entry '%s': Cannot extract IP address from '%s'.", throw new IllegalArgumentException(String.format("Malformed address range entry '%s': Cannot extract IP address from '%s'.",
addressStr + '/' + prefixSizeStr, prefixSizeStr)); addressStr + '/' + prefixSizeStr, addressStr));
} }
// Mask the bytes of the IP address. // Mask the bytes of the IP address.

View File

@ -61,8 +61,18 @@ object OpenComputers {
CommandHandler.register(e) CommandHandler.register(e)
ThreadPoolFactory.safePools.foreach(_.newThreadPool()) ThreadPoolFactory.safePools.foreach(_.newThreadPool())
if (e.getServer.isDedicatedServer) { if (Settings.get.internetAccessConfigured()) {
if ((Settings.get.httpEnabled || Settings.get.tcpEnabled) && !Settings.get.internetFilteringRulesObserved) { if (Settings.get.internetFilteringRulesInvalid()) {
OpenComputers.log.warn("####################################################")
OpenComputers.log.warn("# #")
OpenComputers.log.warn("# Could not parse Internet Card filtering rules! #")
OpenComputers.log.warn("# Review the server log and adjust the filtering #")
OpenComputers.log.warn("# list to ensure it is appropriately configured. #")
OpenComputers.log.warn("# (config/OpenComputers.cfg => filteringRules) #")
OpenComputers.log.warn("# Internet access has been automatically disabled. #")
OpenComputers.log.warn("# #")
OpenComputers.log.warn("####################################################")
} else if (!Settings.get.internetFilteringRulesObserved && e.getServer.isDedicatedServer) {
OpenComputers.log.warn("####################################################") OpenComputers.log.warn("####################################################")
OpenComputers.log.warn("# #") OpenComputers.log.warn("# #")
OpenComputers.log.warn("# It appears that you're running a dedicated #") OpenComputers.log.warn("# It appears that you're running a dedicated #")
@ -72,6 +82,8 @@ object OpenComputers {
OpenComputers.log.warn("# (config/OpenComputers.cfg => filteringRules) #") OpenComputers.log.warn("# (config/OpenComputers.cfg => filteringRules) #")
OpenComputers.log.warn("# #") OpenComputers.log.warn("# #")
OpenComputers.log.warn("####################################################") OpenComputers.log.warn("####################################################")
} else {
OpenComputers.log.info(f"Successfully applied ${Settings.get.internetFilteringRules.length} Internet Card filtering rules.")
} }
} }
} }

View File

@ -487,6 +487,18 @@ class Settings(val config: Config) {
val maxNetworkClientPacketDistance: Double = config.getDouble("misc.maxNetworkClientPacketDistance") max 0 val maxNetworkClientPacketDistance: Double = config.getDouble("misc.maxNetworkClientPacketDistance") max 0
val maxNetworkClientEffectPacketDistance: Double = config.getDouble("misc.maxNetworkClientEffectPacketDistance") max 0 val maxNetworkClientEffectPacketDistance: Double = config.getDouble("misc.maxNetworkClientEffectPacketDistance") max 0
val maxNetworkClientSoundPacketDistance: Double = config.getDouble("misc.maxNetworkClientSoundPacketDistance") max 0 val maxNetworkClientSoundPacketDistance: Double = config.getDouble("misc.maxNetworkClientSoundPacketDistance") max 0
def internetFilteringRulesInvalid(): Boolean = {
internetFilteringRules.exists(p => p.invalid())
}
def internetAccessConfigured(): Boolean = {
httpEnabled || tcpEnabled
}
def internetAccessAllowed(): Boolean = {
internetAccessConfigured() && !internetFilteringRulesInvalid()
}
} }
object Settings { object Settings {

View File

@ -64,6 +64,9 @@ class InternetCard extends prefab.ManagedEnvironment with DeviceInfo {
def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
checkOwner(context) checkOwner(context)
val address = args.checkString(0) val address = args.checkString(0)
if (!Settings.get.internetAccessAllowed()) {
return result(Unit, "internet access is unavailable")
}
if (!Settings.get.httpEnabled) { if (!Settings.get.httpEnabled) {
return result(Unit, "http requests are unavailable") return result(Unit, "http requests are unavailable")
} }
@ -92,6 +95,9 @@ class InternetCard extends prefab.ManagedEnvironment with DeviceInfo {
checkOwner(context) checkOwner(context)
val address = args.checkString(0) val address = args.checkString(0)
val port = args.optInteger(1, -1) val port = args.optInteger(1, -1)
if (!Settings.get.internetAccessAllowed()) {
return result(Unit, "internet access is unavailable")
}
if (!Settings.get.tcpEnabled) { if (!Settings.get.tcpEnabled) {
return result(Unit, "tcp connections are unavailable") return result(Unit, "tcp connections are unavailable")
} }
@ -361,29 +367,33 @@ object InternetCard {
} }
def isRequestAllowed(settings: Settings, inetAddress: InetAddress, host: String): Boolean = { def isRequestAllowed(settings: Settings, inetAddress: InetAddress, host: String): Boolean = {
val rules = settings.internetFilteringRules if (!settings.internetAccessAllowed()) {
inetAddress match { false
// IPv6 handling } else {
case inet6Address: Inet6Address => val rules = settings.internetFilteringRules
// If the IP address is an IPv6 address with an embedded IPv4 address, and the IPv4 address is blocked, inetAddress match {
// block this request. // IPv6 handling
if (InetAddresses.hasEmbeddedIPv4ClientAddress(inet6Address)) { case inet6Address: Inet6Address =>
val inet4in6Address = InetAddresses.getEmbeddedIPv4ClientAddress(inet6Address) // If the IP address is an IPv6 address with an embedded IPv4 address, and the IPv4 address is blocked,
if (!rules.map(r => r.apply(inet4in6Address, host)).collectFirst({ case Some(r) => r }).getOrElse(true)) { // block this request.
return false if (InetAddresses.hasEmbeddedIPv4ClientAddress(inet6Address)) {
val inet4in6Address = InetAddresses.getEmbeddedIPv4ClientAddress(inet6Address)
if (!rules.map(r => r.apply(inet4in6Address, host)).collectFirst({ case Some(r) => r }).getOrElse(true)) {
return false
}
} }
}
// Process address as an IPv6 address. // Process address as an IPv6 address.
rules.map(r => r.apply(inet6Address, host)).collectFirst({ case Some(r) => r }).getOrElse(false) rules.map(r => r.apply(inet6Address, host)).collectFirst({ case Some(r) => r }).getOrElse(false)
// IPv4 handling // IPv4 handling
case inet4Address: Inet4Address => case inet4Address: Inet4Address =>
// Process address as an IPv4 address. // Process address as an IPv4 address.
rules.map(r => r.apply(inet4Address, host)).collectFirst({ case Some(r) => r }).getOrElse(false) rules.map(r => r.apply(inet4Address, host)).collectFirst({ case Some(r) => r }).getOrElse(false)
case _ => case _ =>
// Unrecognized address type - block. // Unrecognized address type - block.
OpenComputers.log.warn("Internet Card blocked unrecognized address type: " + inetAddress.toString) OpenComputers.log.warn("Internet Card blocked unrecognized address type: " + inetAddress.toString)
false false
}
} }
} }

View File

@ -7,7 +7,8 @@ import java.net.{Inet4Address, Inet6Address, InetAddress}
import scala.collection.mutable import scala.collection.mutable
class InternetFilteringRule(val ruleString: String) { class InternetFilteringRule(val ruleString: String) {
val validator: (InetAddress, String) => Option[Boolean] = { private var _invalid: Boolean = false
private val validator: (InetAddress, String) => Option[Boolean] = {
try { try {
val ruleParts = ruleString.split(' ') val ruleParts = ruleString.split(' ')
ruleParts.head match { ruleParts.head match {
@ -52,7 +53,7 @@ class InternetFilteringRule(val ruleString: String) {
host == domain || addresses.exists(a => a.equals(inetAddress)) host == domain || addresses.exists(a => a.equals(inetAddress))
}) })
case "ip" => case "ip" =>
val ipStringParts = f.split("/", 2) val ipStringParts = filter(1).split("/", 2)
if (ipStringParts.length == 2) { if (ipStringParts.length == 2) {
val ipRange = InetAddressRange.parse(ipStringParts(0), ipStringParts(1)) val ipRange = InetAddressRange.parse(ipStringParts(0), ipStringParts(1))
predicates += ((inetAddress: InetAddress, _: String) => ipRange.matches(inetAddress)) predicates += ((inetAddress: InetAddress, _: String) => ipRange.matches(inetAddress))
@ -78,11 +79,14 @@ class InternetFilteringRule(val ruleString: String) {
} }
} catch { } catch {
case t: Throwable => case t: Throwable =>
OpenComputers.log.warn("Invalid internet filtering rule in configuration: " + ruleString, t) OpenComputers.log.error("Invalid Internet filteringRules rule in configuration: \"" + ruleString + "\".", t)
(_: InetAddress, _: String) => None _invalid = true
(_: InetAddress, _: String) => Some(false)
} }
} }
def invalid(): Boolean = _invalid
def apply(inetAddress: InetAddress, host: String) = validator(inetAddress, host) def apply(inetAddress: InetAddress, host: String) = validator(inetAddress, host)
} }