Skip to content

Commit

Permalink
ssurl: add support for SIP008 links (ssconf links with ss contents) (#…
Browse files Browse the repository at this point in the history
…1287)

Co-authored-by: k0tran <>
  • Loading branch information
k0tran authored Sep 7, 2023
1 parent 2bb675a commit a47fc19
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 4 deletions.
78 changes: 78 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
38 changes: 34 additions & 4 deletions bin/ssurl.rs
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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(
Expand All @@ -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")
Expand All @@ -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");
}
Expand Down

0 comments on commit a47fc19

Please sign in to comment.