From e0b2595905c293e9a4340f53940b03f00fe27612 Mon Sep 17 00:00:00 2001 From: strawberry Date: Fri, 20 Sep 2024 22:57:04 -0400 Subject: [PATCH] support reading TURN secret from a file (turn_secret_file) Signed-off-by: strawberry --- conduwuit-example.toml | 11 +++++++++++ docs/turn.md | 6 +++--- src/api/client/voip.rs | 2 +- src/core/config/mod.rs | 8 +++++++- src/service/globals/mod.rs | 15 +++++++++++++-- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/conduwuit-example.toml b/conduwuit-example.toml index 7cf9716d..2792f792 100644 --- a/conduwuit-example.toml +++ b/conduwuit-example.toml @@ -845,9 +845,20 @@ allow_profile_lookup_federation_requests = true # vector list of TURN URIs/servers to use # +# replace "example.turn.uri" with your TURN domain, such as the coturn "realm". +# if using TURN over TLS, replace "turn:" with "turns:" +# # No default #turn_uris = ["turn:example.turn.uri?transport=udp", "turn:example.turn.uri?transport=tcp"] +# TURN secret to use that's read from the file path specified +# +# this takes priority over "turn_secret" first, and falls back to "turn_secret" if invalid or +# failed to open. +# +# no default +#turn_secret_file = "/path/to/secret.txt" + # TURN secret to use for generating the HMAC-SHA1 hash apart of username and password generation # # this is more secure, but if needed you can use traditional username/password below. diff --git a/docs/turn.md b/docs/turn.md index 12e7e3ae..287f2545 100644 --- a/docs/turn.md +++ b/docs/turn.md @@ -21,9 +21,9 @@ These same values need to be set in conduwuit. See the [example config](configuration/examples.md) in the TURN section for configuring these and restart conduwuit after. -`turn_secret` must be set to your coturn `static-auth-secret`, or use -`turn_username` and `turn_password` if using legacy username:password -TURN authentication (not preferred). +`turn_secret` or a path to `turn_secret_file` must have a value of your +coturn `static-auth-secret`, or use `turn_username` and `turn_password` +if using legacy username:password TURN authentication (not preferred). `turn_uris` must be the list of TURN URIs you would like to send to the client. Typically you will just replace the example domain `example.turn.uri` with the diff --git a/src/api/client/voip.rs b/src/api/client/voip.rs index a51e2657..7ee4571f 100644 --- a/src/api/client/voip.rs +++ b/src/api/client/voip.rs @@ -24,7 +24,7 @@ pub(crate) async fn turn_server_route( return Err!(Request(NotFound("Not Found"))); } - let turn_secret = services.globals.turn_secret().clone(); + let turn_secret = services.globals.turn_secret.clone(); let (username, password) = if !turn_secret.is_empty() { let expiry = SecondsSinceUnixEpoch::from_system_time( diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 9b5405b9..f48c78c9 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -194,6 +194,7 @@ pub struct Config { pub turn_uris: Vec, #[serde(default)] pub turn_secret: String, + pub turn_secret_file: Option, #[serde(default = "default_turn_ttl")] pub turn_ttl: u64, @@ -681,12 +682,17 @@ impl fmt::Display for Config { } }); line("TURN secret", { - if self.turn_secret.is_empty() { + if self.turn_secret.is_empty() && self.turn_secret_file.is_none() { "not set" } else { "set" } }); + line("TURN secret file path", { + self.turn_secret_file + .as_ref() + .map_or("", |path| path.to_str().unwrap_or_default()) + }); line("Turn TTL", &self.turn_ttl.to_string()); line("Turn URIs", { let mut lst = vec![]; diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 25e0f402..a044d30a 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -40,6 +40,7 @@ pub struct Service { pub stateres_mutex: Arc>, pub server_user: OwnedUserId, pub admin_alias: OwnedRoomAliasId, + pub turn_secret: String, } type RateLimitState = (Instant, u32); // Time if last failed try, number of failed tries @@ -84,6 +85,17 @@ impl crate::Service for Service { .collect::>() .map_err(|e| err!(Config("ip_range_denylist", e)))?; + let turn_secret = config + .turn_secret_file + .as_ref() + .map_or(config.turn_secret.clone(), |path| { + std::fs::read_to_string(path).unwrap_or_else(|e| { + error!("Failed to read the TURN secret file: {e}"); + + config.turn_secret.clone() + }) + }); + let mut s = Self { db, config: config.clone(), @@ -99,6 +111,7 @@ impl crate::Service for Service { .expect("#admins:server_name is valid alias name"), server_user: UserId::parse_with_server_name(String::from("conduit"), &config.server_name) .expect("@conduit:server_name is valid"), + turn_secret, }; if !s @@ -207,8 +220,6 @@ impl Service { pub fn turn_username(&self) -> &String { &self.config.turn_username } - pub fn turn_secret(&self) -> &String { &self.config.turn_secret } - pub fn allow_profile_lookup_federation_requests(&self) -> bool { self.config.allow_profile_lookup_federation_requests }