diff --git a/.gitignore b/.gitignore index 5cce3c2..9a2b7b1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ cert.pem key.pem bundle +config.toml diff --git a/Cargo.lock b/Cargo.lock index 48a65be..d5d89d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -396,6 +396,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.9" @@ -499,6 +505,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -617,6 +629,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.12.1" @@ -776,8 +798,11 @@ dependencies = [ "anyhow", "axum", "lazy_static", + "serde", + "serde_json", "tokio", "tokio-rustls", + "toml", "tower", "tower-http", "tracing", @@ -972,9 +997,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1344,18 +1369,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -1384,6 +1409,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1476,9 +1510,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.58" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -1638,6 +1672,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.5.1" @@ -1817,9 +1885,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -2064,6 +2132,15 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + [[package]] name = "wtransport" version = "0.1.13" diff --git a/Cargo.toml b/Cargo.toml index fb22e14..0e650e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,11 @@ edition = "2021" anyhow = "1.0.86" axum = "0.7.7" lazy_static = "1.4.0" +serde = { version = "1.0.214", features = ["derive"] } +serde_json = "1.0.132" tokio = { version = "1.37.0", features = ["full"] } tokio-rustls = "0.26.0" +toml = "0.8.19" tower = "0.5.1" tower-http = { version = "0.6.1", features = ["fs"] } tracing = { version = "0.1.40", features = ["async-await"] } diff --git a/config.toml.example b/config.toml.example new file mode 100644 index 0000000..e5bb959 --- /dev/null +++ b/config.toml.example @@ -0,0 +1,10 @@ +proxy_listen_address = "127.0.0.1:4433" +http_listen_address = "127.0.0.1:4434" +cert_path = "./cert.pem" +key_path = "./key.pem" +mumble_server_url = "voip.ohea.xyz:64738" +gui_path = "../mumble-web2/dist" + +[gui] +proxy_url = "https://voip2.ohea.xyz" +# cert_hash = [...] diff --git a/src/main.rs b/src/main.rs index 93d101a..365007a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,13 @@ -use anyhow::{Context, Result}; +use anyhow::{anyhow, Context, Result}; use axum::extract::State; use axum::http::{Response, StatusCode}; use axum::response::IntoResponse; -use std::env; +use serde::{Deserialize, Serialize}; use std::future::IntoFuture; use std::net::{SocketAddr, ToSocketAddrs}; use std::path::PathBuf; use std::time::Duration; +use tokio::fs::read_to_string; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::TcpStream; use tokio::pin; @@ -87,48 +88,39 @@ impl ServerCertVerifier for NoCertificateVerification { } } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] +struct GuiConfig { + proxy_url: Option, + cert_hash: Option>, +} + +#[derive(Clone, Deserialize)] struct Config { proxy_listen_address: String, http_listen_address: String, cert_path: String, key_path: String, - mumble_server_address: SocketAddr, + mumble_server_url: String, gui_path: PathBuf, -} - -impl Config { - fn get() -> Result { - Ok(Config { - proxy_listen_address: env::var("MUMBLE_WEBTRANSPORT_PROXY_LISTEN_ADDRESS") - .unwrap_or("127.0.0.1:4433".to_string()), - http_listen_address: env::var("MUMBLE_WEBTRANSPORT_HTTP_LISTEN_ADDRESS") - .unwrap_or("127.0.0.1:4434".to_string()), - cert_path: env::var("MUMBLE_WEBTRANSPORT_CERT_PATH").unwrap_or("cert.pem".to_string()), - key_path: env::var("MUMBLE_WEBTRANSPORT_KEY_PATH").unwrap_or("key.pem".to_string()), - mumble_server_address: env::var("MUMBLE_WEBTRANSPORT_MUMBLE_SERVER_ADDRESS") - .with_context(|| "Please set MUMBLE_WEBTRANSPORT_MUMBLE_SERVER_ADDRESS")? - .to_socket_addrs()? - .next() - .ok_or(anyhow::anyhow!("Invalid mumble server address"))?, - gui_path: PathBuf::from( - env::var("MUMBLE_WEBTRANSPORT_GUI_PATH").unwrap_or("gui".to_string()), - ), - }) - } + gui: GuiConfig, } //async fn serve_index_html_with_config(State(config): State) -> impl IntoResponse { async fn serve_index_html_with_config(State(config): State) -> impl IntoResponse { // Load the HTML file - let html = match tokio::fs::read_to_string(config.gui_path.join("index.html")).await { + let html = match read_to_string(config.gui_path.join("index.html")).await { Ok(content) => content, Err(_) => return (StatusCode::NOT_FOUND, "File not found").into_response(), }; // Insert the script tag with configuration - let config_script = ""; - let modified_html = html.replace("", &format!("{}\n", config_script)); + let modified_html = html.replace( + "", + &format!( + "\n", + serde_json::to_string(&config.gui).unwrap(), + ), + ); // Create a response with the modified HTML Response::builder() @@ -143,7 +135,24 @@ async fn serve_index_html_with_config(State(config): State) -> impl Into async fn main() -> Result<()> { init_logging(); - let proxy_config = Config::get()?; + let proxy_config: Config = toml::from_str( + &read_to_string("./config.toml") + .await + .context("reading config.toml (try making a copy of config.toml.example)")?, + )?; + + let mumble_server_addr = proxy_config + .mumble_server_url + .to_socket_addrs() + .context(format!( + "parsing mumble_server_url={}", + proxy_config.mumble_server_url + ))? + .next() + .ok_or(anyhow!( + "no socket addrs in mumble_server_url={}", + proxy_config.mumble_server_url + ))?; // Setup HTTP Server //let http = axum::Router::new().route("/", axum::routing::get(serve_gui)); @@ -172,7 +181,7 @@ async fn main() -> Result<()> { for id in 0.. { let incoming_session = server.accept().await; tokio::spawn( - handle_connection(incoming_session, id, proxy_config.mumble_server_address) + handle_connection(incoming_session, id, mumble_server_addr) .instrument(info_span!("Connection", id)), ); }