2022-10-05 20:34:31 +02:00
|
|
|
use std::time::{Duration, SystemTime};
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-07-16 08:05:25 +00:00
|
|
|
use axum::extract::State;
|
2025-02-23 01:17:45 -05:00
|
|
|
use base64::{Engine as _, engine::general_purpose};
|
2026-05-26 13:28:23 -04:00
|
|
|
use conduwuit::{Err, Result};
|
2026-04-12 16:29:02 +01:00
|
|
|
use hmac::{Hmac, KeyInit, Mac};
|
2026-05-26 13:28:23 -04:00
|
|
|
use ruma::{SecondsSinceUnixEpoch, api::client::voip::get_turn_server_info};
|
2021-10-02 00:37:39 +02:00
|
|
|
use sha1::Sha1;
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2025-04-04 03:30:13 +00:00
|
|
|
use crate::Ruma;
|
2021-10-02 00:37:39 +02:00
|
|
|
|
|
|
|
|
type HmacSha1 = Hmac<Sha1>;
|
2020-07-30 18:14:47 +02:00
|
|
|
|
2021-08-31 19:14:37 +02:00
|
|
|
/// # `GET /_matrix/client/r0/voip/turnServer`
|
|
|
|
|
///
|
|
|
|
|
/// TODO: Returns information about the recommended turn server.
|
2024-04-22 23:48:57 -04:00
|
|
|
pub(crate) async fn turn_server_route(
|
2024-12-15 00:05:47 -05:00
|
|
|
State(services): State<crate::State>,
|
|
|
|
|
body: Ruma<get_turn_server_info::v3::Request>,
|
2022-02-18 15:33:14 +01:00
|
|
|
) -> Result<get_turn_server_info::v3::Response> {
|
2024-07-30 00:05:22 -04:00
|
|
|
// MSC4166: return M_NOT_FOUND 404 if no TURN URIs are specified in any way
|
|
|
|
|
if services.server.config.turn_uris.is_empty() {
|
|
|
|
|
return Err!(Request(NotFound("Not Found")));
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-20 22:57:04 -04:00
|
|
|
let turn_secret = services.globals.turn_secret.clone();
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2021-11-26 20:36:40 +01:00
|
|
|
let (username, password) = if !turn_secret.is_empty() {
|
2021-10-02 00:37:39 +02:00
|
|
|
let expiry = SecondsSinceUnixEpoch::from_system_time(
|
2024-05-03 21:42:47 -04:00
|
|
|
SystemTime::now()
|
2024-07-16 08:05:25 +00:00
|
|
|
.checked_add(Duration::from_secs(services.globals.turn_ttl()))
|
2024-05-03 21:42:47 -04:00
|
|
|
.expect("TURN TTL should not get this high"),
|
2021-10-02 00:37:39 +02:00
|
|
|
)
|
|
|
|
|
.expect("time is valid");
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2026-05-26 13:28:23 -04:00
|
|
|
let username: String = format!("{}:{}", expiry.get(), body.identity.sender_user());
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-12-15 00:05:47 -05:00
|
|
|
let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes())
|
|
|
|
|
.expect("HMAC can take key of any size");
|
2021-10-02 00:37:39 +02:00
|
|
|
mac.update(username.as_bytes());
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2023-08-01 14:48:50 -10:00
|
|
|
let password: String = general_purpose::STANDARD.encode(mac.finalize().into_bytes());
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2021-10-02 00:37:39 +02:00
|
|
|
(username, password)
|
|
|
|
|
} else {
|
|
|
|
|
(
|
2024-07-16 08:05:25 +00:00
|
|
|
services.globals.turn_username().clone(),
|
|
|
|
|
services.globals.turn_password().clone(),
|
2021-10-02 00:37:39 +02:00
|
|
|
)
|
|
|
|
|
};
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2026-04-12 11:16:52 -04:00
|
|
|
Ok(get_turn_server_info::v3::Response::new(
|
2021-11-26 19:28:47 +01:00
|
|
|
username,
|
|
|
|
|
password,
|
2026-04-12 11:16:52 -04:00
|
|
|
services.globals.turn_uris().to_vec(),
|
|
|
|
|
Duration::from_secs(services.globals.turn_ttl()),
|
|
|
|
|
))
|
2020-07-30 18:14:47 +02:00
|
|
|
}
|