add config option to allow guests to access TURN server

`turn_allow_guests`

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-06-05 18:42:56 -04:00
parent 40e4019f7f
commit 1cc7cf54a7
3 changed files with 30 additions and 6 deletions

View file

@ -1,12 +1,15 @@
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
use conduit::utils;
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
use ruma::{api::client::voip::get_turn_server_info, SecondsSinceUnixEpoch}; use ruma::{api::client::voip::get_turn_server_info, SecondsSinceUnixEpoch, UserId};
use sha1::Sha1; use sha1::Sha1;
use crate::{services, Result, Ruma}; use crate::{services, Result, Ruma};
const RANDOM_USER_ID_LENGTH: usize = 10;
type HmacSha1 = Hmac<Sha1>; type HmacSha1 = Hmac<Sha1>;
/// # `GET /_matrix/client/r0/voip/turnServer` /// # `GET /_matrix/client/r0/voip/turnServer`
@ -15,8 +18,6 @@ type HmacSha1 = Hmac<Sha1>;
pub(crate) async fn turn_server_route( pub(crate) async fn turn_server_route(
body: Ruma<get_turn_server_info::v3::Request>, body: Ruma<get_turn_server_info::v3::Request>,
) -> Result<get_turn_server_info::v3::Response> { ) -> Result<get_turn_server_info::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
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 (username, password) = if !turn_secret.is_empty() {
@ -27,7 +28,15 @@ pub(crate) async fn turn_server_route(
) )
.expect("time is valid"); .expect("time is valid");
let username: String = format!("{}:{}", expiry.get(), sender_user); let user = body.sender_user.unwrap_or_else(|| {
UserId::parse_with_server_name(
utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(),
&services().globals.config.server_name,
)
.unwrap()
});
let username: String = format!("{}:{}", expiry.get(), user);
let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes()).expect("HMAC can take key of any size"); let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes()).expect("HMAC can take key of any size");
mac.update(username.as_bytes()); mac.update(username.as_bytes());

View file

@ -91,8 +91,21 @@ pub(super) async fn auth(
appservice_info: Some(*info), appservice_info: Some(*info),
}) })
}, },
(AuthScheme::AccessToken, Token::None) => { (AuthScheme::AccessToken, Token::None) => match request.parts.uri.path() {
// TODO: can we check this better?
"/_matrix/client/v3/voip/turnServer" | "/_matrix/client/r0/voip/turnServer" => {
if services().globals.config.turn_allow_guests {
Ok(Auth {
origin: None,
sender_user: None,
sender_device: None,
appservice_info: None,
})
} else {
Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token.")) Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token."))
}
},
_ => Err(Error::BadRequest(ErrorKind::MissingToken, "Missing access token.")),
}, },
( (
AuthScheme::AccessToken | AuthScheme::AccessTokenOptional | AuthScheme::None, AuthScheme::AccessToken | AuthScheme::AccessTokenOptional | AuthScheme::None,

View file

@ -165,6 +165,8 @@ pub struct Config {
#[serde(default)] #[serde(default)]
pub allow_public_room_directory_without_auth: bool, pub allow_public_room_directory_without_auth: bool,
#[serde(default)] #[serde(default)]
pub turn_allow_guests: bool,
#[serde(default)]
pub lockdown_public_room_directory: bool, pub lockdown_public_room_directory: bool,
#[serde(default)] #[serde(default)]
pub allow_device_name_federation: bool, pub allow_device_name_federation: bool,