feat(appservice): ensure users/aliases outside of namespaces are not accessed

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
Matthias Ahouansou 2024-04-16 22:39:49 -04:00 committed by June
parent b303a774d8
commit 19e4befcb8
7 changed files with 154 additions and 61 deletions

View file

@ -83,7 +83,7 @@ pub async fn get_register_available_route(
/// access_token
#[allow(clippy::doc_markdown)]
pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<register::v3::Response> {
if !services().globals.allow_registration() && !body.from_appservice {
if !services().globals.allow_registration() && body.appservice_info.is_none() {
info!(
"Registration disabled and request not from known appservice, rejecting registration attempt for username \
{:?}",
@ -92,10 +92,6 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
return Err(Error::BadRequest(ErrorKind::forbidden(), "Registration has been disabled."));
}
if body.body.login_type == Some(LoginType::ApplicationService) && !body.from_appservice {
return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing Appservice token."));
}
let is_guest = body.kind == RegistrationKind::Guest;
if is_guest
@ -160,6 +156,18 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
},
};
if body.body.login_type == Some(LoginType::ApplicationService) {
if let Some(ref info) = body.appservice_info {
if !info.is_user_match(&user_id) {
return Err(Error::BadRequest(ErrorKind::Exclusive, "User is not in namespace."));
}
} else {
return Err(Error::BadRequest(ErrorKind::MissingToken, "Missing appservice token."));
}
} else if services().appservice.is_exclusive_user_id(&user_id).await {
return Err(Error::BadRequest(ErrorKind::Exclusive, "User ID reserved by appservice."));
}
// UIAA
let mut uiaainfo;
let skip_auth;
@ -174,7 +182,7 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
session: None,
auth_error: None,
};
skip_auth = body.from_appservice;
skip_auth = body.appservice_info.is_some();
} else {
// No registration token necessary, but clients must still go through the flow
uiaainfo = UiaaInfo {
@ -186,7 +194,7 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
session: None,
auth_error: None,
};
skip_auth = body.from_appservice || is_guest;
skip_auth = body.appservice_info.is_some() || is_guest;
}
if !skip_auth {
@ -281,7 +289,7 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
info!("New user \"{}\" registered on this server.", user_id);
// log in conduit admin channel if a non-guest user registered
if !body.from_appservice && !is_guest {
if body.appservice_info.is_none() && !is_guest {
services()
.admin
.send_message(RoomMessageEventContent::notice_plain(format!(
@ -290,7 +298,7 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
}
// log in conduit admin channel if a guest registered
if !body.from_appservice && is_guest && services().globals.log_guest_registrations() {
if body.appservice_info.is_none() && is_guest && services().globals.log_guest_registrations() {
if let Some(device_display_name) = &body.initial_device_display_name {
if body
.initial_device_display_name
@ -339,7 +347,7 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
}
}
if !body.from_appservice
if body.appservice_info.is_none()
&& !services().globals.config.auto_join_rooms.is_empty()
&& (services().globals.allow_guests_auto_join_rooms() || !is_guest)
{
@ -468,7 +476,7 @@ pub async fn whoami_route(body: Ruma<whoami::v3::Request>) -> Result<whoami::v3:
Ok(whoami::v3::Response {
user_id: sender_user.clone(),
device_id,
is_guest: services().users.is_deactivated(sender_user)? && !body.from_appservice,
is_guest: services().users.is_deactivated(sender_user)? && body.appservice_info.is_none(),
})
}