diff --git a/Cargo.lock b/Cargo.lock index 9eb270683..09485efa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,6 +633,19 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "cidr-utils" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355d5b5df67e58b523953d0c1a8d3d2c05f5af51f1332b0199b9c92263614ed0" +dependencies = [ + "debug-helper", + "num-bigint", + "num-traits 0.2.15", + "once_cell", + "regex", +] + [[package]] name = "clang-sys" version = "1.3.3" @@ -1244,6 +1257,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b" +[[package]] +name = "debug-helper" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" + [[package]] name = "default-net" version = "0.11.0" @@ -3291,6 +3310,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg 1.1.0", + "num-integer", + "num-traits 0.2.15", +] + [[package]] name = "num-complex" version = "0.4.2" @@ -4375,6 +4405,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "chrono", + "cidr-utils", "clap 3.2.17", "clipboard", "cocoa", diff --git a/Cargo.toml b/Cargo.toml index c7b0c51b8..fd84b73aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ url = { version = "2.1", features = ["serde"] } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false } chrono = "0.4.23" +cidr-utils = "0.5.9" [target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies] cpal = "0.13.5" diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 35a303c0b..a6de0384f 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -133,9 +133,12 @@ void changeWhiteList({Function()? callback}) async { final ips = newWhiteListField.trim().split(RegExp(r"[\s,;\n]+")); // test ip - final ipMatch = RegExp(r"^\d+\.\d+\.\d+\.\d+$"); + final ipMatch = RegExp( + r"^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)(\/([1-9]|[1-2][0-9]|3[0-2])){0,1}$"); + final ipv6Match = RegExp( + r"^(((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7})(\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}$"); for (final ip in ips) { - if (!ipMatch.hasMatch(ip)) { + if (!ipMatch.hasMatch(ip) && !ipv6Match.hasMatch(ip)) { msg = "${translate("Invalid IP")} $ip"; setState(() { isInProgress = false; diff --git a/src/server/connection.rs b/src/server/connection.rs index 11960be8a..a337d6022 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -7,6 +7,7 @@ use crate::video_service; #[cfg(any(target_os = "android", target_os = "ios"))] use crate::{common::DEVICE_NAME, flutter::connection_manager::start_channel}; use crate::{ipc, VERSION}; +use cidr_utils::cidr::IpCidr; use hbb_common::{ config::Config, fs, @@ -631,7 +632,7 @@ impl Connection { .is_none() && whitelist .iter() - .filter(|x| x.parse() == Ok(addr.ip())) + .filter(|x| IpCidr::from_str(x).map_or(false, |y| y.contains(addr.ip()))) .next() .is_none() { diff --git a/src/ui/index.tis b/src/ui/index.tis index 8e2238b2d..9dcd4f4c4 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -395,7 +395,8 @@ class MyIdMenu: Reactor.Component { if (value) { var values = value.split(/[\s,;\n]+/g); for (var ip in values) { - if (!ip.match(/^\d+\.\d+\.\d+\.\d+$/)) { + if (!ip.match(/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)(\/([1-9]|[1-2][0-9]|3[0-2])){0,1}$/) + && !ip.match(/^(((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))*((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7})(\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}$/)) { return translate("Invalid IP") + ": " + ip; } }