ssurl: add support for SIP008 links (ssconf links with ss contents) (#1287)

Co-authored-by: k0tran <>
This commit is contained in:
Sorochan Ilya
2023-09-07 08:25:48 +03:00
committed by GitHub
parent 2bb675ac7a
commit a47fc19e08
3 changed files with 113 additions and 4 deletions

78
Cargo.lock generated
View File

@@ -674,6 +674,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "encoding_rs"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
dependencies = [
"cfg-if",
]
[[package]]
name = "enum-as-inner"
version = "0.6.0"
@@ -1064,6 +1073,19 @@ dependencies = [
"want",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "iana-time-zone"
version = "0.1.57"
@@ -1399,6 +1421,12 @@ dependencies = [
"libmimalloc-sys",
]
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "miniz_oxide"
version = "0.7.1"
@@ -1883,6 +1911,43 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "reqwest"
version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "resolv-conf"
version = "0.7.0"
@@ -2317,6 +2382,7 @@ dependencies = [
"num_cpus",
"qrcode",
"rand",
"reqwest",
"rpassword",
"rpmalloc",
"serde",
@@ -3025,6 +3091,18 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"

View File

@@ -164,6 +164,7 @@ tokio = { version = "1", features = ["rt", "signal"] }
num_cpus = "1.15"
ipnet = { version = "2.7", optional = true }
reqwest = { version = "0.11", features = ["blocking"] }
mimalloc = { version = "0.1", default-features = false, optional = true }
tcmalloc = { version = "0.3", optional = true }

View File

@@ -1,4 +1,4 @@
//! SIP002 URL Scheme
//! SIP002 and SIP008 URL Schemes
//!
//! SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
//! userinfo = websafe-base64-encode-utf8(method ":" password)
@@ -72,6 +72,26 @@ fn decode(encoded: &str, need_qrcode: bool) {
}
}
fn decode_outline(remote: &str, need_qrcode: bool) {
// Protect from using http and other non-ssconf links in reqwest call
if !remote.starts_with("ssconf") {
println!("Incorrect link format");
return;
}
let url = remote.replace("ssconf", "https");
let svrconfig = ServerConfig::from_url(reqwest::blocking::get(url).unwrap().text().unwrap().as_str()).unwrap();
let mut config = Config::new(ConfigType::Server);
config.server.push(ServerInstanceConfig::with_server_config(svrconfig));
println!("{config}");
if need_qrcode {
print_qrcode(remote);
}
}
fn main() {
let app = Command::new("ssurl")
.version(VERSION)
@@ -83,7 +103,7 @@ fn main() {
.action(ArgAction::Set)
.value_hint(ValueHint::FilePath)
.conflicts_with("DECODE_CONFIG_PATH")
.required_unless_present("DECODE_CONFIG_PATH")
.required_unless_present_any(["DECODE_CONFIG_PATH", "OUTLINE_CONFIG_URL"])
.help("Encode the server configuration in the provided JSON file"),
)
.arg(
@@ -92,8 +112,16 @@ fn main() {
.long("decode")
.action(ArgAction::Set)
.value_hint(ValueHint::FilePath)
.required_unless_present("ENCODE_CONFIG_PATH")
.help("Decode the server configuration from the provide ShadowSocks URL"),
.required_unless_present_any(["ENCODE_CONFIG_PATH", "OUTLINE_CONFIG_URL"])
.help("Decode the server configuration from the provided ShadowSocks URL"),
)
.arg(
Arg::new("OUTLINE_CONFIG_URL")
.short('o')
.long("outline")
.value_hint(ValueHint::Url)
.required_unless_present_any(["ENCODE_CONFIG_PATH", "DECODE_CONFIG_PATH"])
.help("Fetch and decode config from ssconf URL used by Outline"),
)
.arg(
Arg::new("QRCODE")
@@ -110,6 +138,8 @@ fn main() {
encode(file, need_qrcode);
} else if let Some(encoded) = matches.get_one::<String>("DECODE_CONFIG_PATH") {
decode(encoded, need_qrcode);
} else if let Some(remote) = matches.get_one::<String>("OUTLINE_CONFIG_URL") {
decode_outline(remote, need_qrcode);
} else {
println!("Use -h for more detail");
}