2024-06-02 00:18:57 +00:00
mod data ;
pub ( super ) mod migrations ;
2024-03-05 19:19:06 -05:00
use std ::{
collections ::{ BTreeMap , HashMap } ,
2024-07-04 03:26:19 +00:00
fmt ::Write ,
sync ::{ Arc , RwLock } ,
2024-05-09 15:59:08 -07:00
time ::Instant ,
2022-10-09 17:25:06 +02:00
} ;
2022-08-07 19:42:22 +02:00
2024-09-01 11:09:36 +00:00
use conduit ::{ err , error , trace , Config , Result } ;
2024-05-26 21:29:19 +00:00
use data ::Data ;
2024-04-21 22:32:45 -07:00
use ipaddress ::IPAddress ;
2024-03-05 19:19:06 -05:00
use regex ::RegexSet ;
2021-01-14 21:32:22 -05:00
use ruma ::{
2024-06-17 07:49:52 +00:00
api ::{
client ::discovery ::discover_support ::ContactRole ,
federation ::discovery ::{ ServerSigningKeys , VerifyKey } ,
} ,
2024-03-05 19:19:06 -05:00
serde ::Base64 ,
2024-07-09 21:10:14 +00:00
DeviceId , OwnedEventId , OwnedRoomAliasId , OwnedServerName , OwnedServerSigningKeyId , OwnedUserId , RoomAliasId ,
RoomVersionId , ServerName , UserId ,
2021-06-06 16:58:32 +04:30
} ;
2024-07-13 08:07:49 +00:00
use tokio ::sync ::Mutex ;
2024-04-11 20:17:30 -04:00
use url ::Url ;
2020-07-23 23:03:24 -04:00
2024-07-22 07:43:51 +00:00
use crate ::service ;
2023-08-01 14:48:50 -10:00
2024-05-09 15:59:08 -07:00
pub struct Service {
2024-05-27 03:17:20 +00:00
pub db : Data ,
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub config : Config ,
pub cidr_range_denylist : Vec < IPAddress > ,
2020-09-15 16:13:54 +02:00
keypair : Arc < ruma ::signatures ::Ed25519KeyPair > ,
2022-10-09 15:34:36 +02:00
jwt_decoding_key : Option < jsonwebtoken ::DecodingKey > ,
2024-05-09 15:59:08 -07:00
pub stable_room_versions : Vec < RoomVersionId > ,
pub unstable_room_versions : Vec < RoomVersionId > ,
pub bad_event_ratelimiter : Arc < RwLock < HashMap < OwnedEventId , RateLimitState > > > ,
pub bad_query_ratelimiter : Arc < RwLock < HashMap < OwnedServerName , RateLimitState > > > ,
pub stateres_mutex : Arc < Mutex < ( ) > > ,
2024-06-12 02:10:59 -04:00
pub server_user : OwnedUserId ,
pub admin_alias : OwnedRoomAliasId ,
2024-09-20 22:57:04 -04:00
pub turn_secret : String ,
2024-09-29 01:54:07 -04:00
pub registration_token : Option < String > ,
2021-07-14 12:31:38 +02:00
}
2024-07-09 20:04:43 +00:00
type RateLimitState = ( Instant , u32 ) ; // Time if last failed try, number of failed tries
2024-07-04 03:26:19 +00:00
impl crate ::Service for Service {
fn build ( args : crate ::Args < '_ > ) -> Result < Arc < Self > > {
2024-07-18 06:37:47 +00:00
let db = Data ::new ( & args ) ;
2024-07-04 03:26:19 +00:00
let config = & args . server . config ;
2022-09-07 13:25:51 +02:00
let keypair = db . load_keypair ( ) ;
2024-03-05 19:48:54 -05:00
2020-09-15 21:46:10 +02:00
let keypair = match keypair {
Ok ( k ) = > k ,
Err ( e ) = > {
error! ( " Keypair invalid. Deleting... " ) ;
2022-10-08 13:02:52 +02:00
db . remove_keypair ( ) ? ;
2020-09-15 21:46:10 +02:00
return Err ( e ) ;
} ,
} ;
2024-03-05 19:48:54 -05:00
2024-03-25 17:05:11 -04:00
let jwt_decoding_key = config
. jwt_secret
. as_ref ( )
. map ( | secret | jsonwebtoken ::DecodingKey ::from_secret ( secret . as_bytes ( ) ) ) ;
2024-03-05 19:48:54 -05:00
2021-11-01 01:58:26 +00:00
// Supported and stable room versions
2022-02-18 13:41:37 +01:00
let stable_room_versions = vec! [
RoomVersionId ::V6 ,
RoomVersionId ::V7 ,
RoomVersionId ::V8 ,
RoomVersionId ::V9 ,
2022-10-10 15:00:44 +02:00
RoomVersionId ::V10 ,
2023-09-02 12:18:46 -04:00
RoomVersionId ::V11 ,
] ;
2024-04-11 17:44:00 -04:00
// Experimental, partially supported room versions
let unstable_room_versions = vec! [ RoomVersionId ::V2 , RoomVersionId ::V3 , RoomVersionId ::V4 , RoomVersionId ::V5 ] ;
2024-09-01 00:59:43 -04:00
let cidr_range_denylist : Vec < _ > = config
. ip_range_denylist
. iter ( )
2024-09-01 11:09:36 +00:00
. map ( IPAddress ::parse )
. inspect ( | cidr | trace! ( " Denied CIDR range: {cidr:?} " ) )
. collect ::< Result < _ , String > > ( )
. map_err ( | e | err! ( Config ( " ip_range_denylist " , e ) ) ) ? ;
2024-04-21 22:32:45 -07:00
2024-09-20 22:57:04 -04:00
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 ( )
} )
} ) ;
2024-09-29 01:54:07 -04:00
let registration_token =
config
. registration_token_file
. as_ref ( )
. map_or ( config . registration_token . clone ( ) , | path | {
let Ok ( token ) = std ::fs ::read_to_string ( path ) . inspect_err ( | e | {
error! ( " Failed to read the registration token file: {e} " ) ;
} ) else {
return config . registration_token . clone ( ) ;
} ;
Some ( token )
} ) ;
2021-11-05 20:47:11 +00:00
let mut s = Self {
2022-09-07 13:25:51 +02:00
db ,
2024-03-16 15:54:58 -07:00
config : config . clone ( ) ,
2024-04-21 22:32:45 -07:00
cidr_range_denylist ,
2020-09-15 21:46:10 +02:00
keypair : Arc ::new ( keypair ) ,
2022-02-07 12:55:21 +01:00
jwt_decoding_key ,
stable_room_versions ,
2021-01-29 11:20:33 -05:00
unstable_room_versions ,
bad_event_ratelimiter : Arc ::new ( RwLock ::new ( HashMap ::new ( ) ) ) ,
2021-04-15 22:07:27 -03:00
bad_query_ratelimiter : Arc ::new ( RwLock ::new ( HashMap ::new ( ) ) ) ,
2021-07-18 20:43:39 +02:00
stateres_mutex : Arc ::new ( Mutex ::new ( ( ) ) ) ,
2024-06-12 02:10:59 -04:00
admin_alias : RoomAliasId ::parse ( format! ( " #admins: {} " , & config . server_name ) )
. 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 " ) ,
2024-09-20 22:57:04 -04:00
turn_secret ,
2024-09-29 01:54:07 -04:00
registration_token ,
2024-03-05 19:48:54 -05:00
} ;
2024-03-25 17:05:11 -04:00
if ! s
. supported_room_versions ( )
. contains ( & s . config . default_room_version )
{
2024-07-18 06:37:47 +00:00
error! ( config = ? s . config . default_room_version , fallback = ? conduit ::config ::default_default_room_version ( ) , " Room version in config isn't supported, falling back to default version " ) ;
s . config . default_room_version = conduit ::config ::default_default_room_version ( ) ;
2024-03-05 19:48:54 -05:00
} ;
2024-07-04 03:26:19 +00:00
Ok ( Arc ::new ( s ) )
}
fn memory_usage ( & self , out : & mut dyn Write ) -> Result < ( ) > {
let bad_event_ratelimiter = self
. bad_event_ratelimiter
. read ( )
. expect ( " locked for reading " )
. len ( ) ;
writeln! ( out , " bad_event_ratelimiter: {bad_event_ratelimiter} " ) ? ;
let bad_query_ratelimiter = self
. bad_query_ratelimiter
. read ( )
. expect ( " locked for reading " )
. len ( ) ;
writeln! ( out , " bad_query_ratelimiter: {bad_query_ratelimiter} " ) ? ;
Ok ( ( ) )
}
fn clear_cache ( & self ) {
self . bad_event_ratelimiter
. write ( )
. expect ( " locked for writing " )
. clear ( ) ;
self . bad_query_ratelimiter
. write ( )
. expect ( " locked for writing " )
. clear ( ) ;
2024-03-05 19:48:54 -05:00
}
2024-07-16 22:00:54 +00:00
fn name ( & self ) -> & str { service ::make_name ( std ::module_path! ( ) ) }
2024-07-04 03:26:19 +00:00
}
impl Service {
2021-07-18 20:43:39 +02:00
/// Returns this server's keypair.
2024-05-09 15:59:08 -07:00
pub fn keypair ( & self ) -> & ruma ::signatures ::Ed25519KeyPair { & self . keypair }
2024-03-05 19:48:54 -05:00
2024-07-02 07:56:45 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn next_count ( & self ) -> Result < u64 > { self . db . next_count ( ) }
2024-03-05 19:48:54 -05:00
2024-07-02 07:56:45 +00:00
#[ inline ]
pub fn current_count ( & self ) -> Result < u64 > { Ok ( self . db . current_count ( ) ) }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub async fn watch ( & self , user_id : & UserId , device_id : & DeviceId ) -> Result < ( ) > {
2022-01-28 12:42:47 -06:00
self . db . watch ( user_id , device_id ) . await
2024-03-05 19:48:54 -05:00
}
2024-07-16 08:05:25 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn server_name ( & self ) -> & ServerName { self . config . server_name . as_ref ( ) }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn max_fetch_prev_events ( & self ) -> u16 { self . config . max_fetch_prev_events }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_registration ( & self ) -> bool { self . config . allow_registration }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_guest_registration ( & self ) -> bool { self . config . allow_guest_registration }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_guests_auto_join_rooms ( & self ) -> bool { self . config . allow_guests_auto_join_rooms }
2024-04-13 20:33:24 -04:00
2024-05-09 15:59:08 -07:00
pub fn log_guest_registrations ( & self ) -> bool { self . config . log_guest_registrations }
2024-04-13 20:19:10 -04:00
2024-05-09 15:59:08 -07:00
pub fn allow_encryption ( & self ) -> bool { self . config . allow_encryption }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_federation ( & self ) -> bool { self . config . allow_federation }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_public_room_directory_over_federation ( & self ) -> bool {
2022-01-28 12:42:47 -06:00
self . config . allow_public_room_directory_over_federation
2020-05-03 17:25:31 +02:00
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_device_name_federation ( & self ) -> bool { self . config . allow_device_name_federation }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_room_creation ( & self ) -> bool { self . config . allow_room_creation }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_unstable_room_versions ( & self ) -> bool { self . config . allow_unstable_room_versions }
2024-03-05 19:48:54 -05:00
2024-07-03 20:06:43 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn default_room_version ( & self ) -> RoomVersionId { self . config . default_room_version . clone ( ) }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn new_user_displayname_suffix ( & self ) -> & String { & self . config . new_user_displayname_suffix }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_check_for_updates ( & self ) -> bool { self . config . allow_check_for_updates }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn trusted_servers ( & self ) -> & [ OwnedServerName ] { & self . config . trusted_servers }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn query_trusted_key_servers_first ( & self ) -> bool { self . config . query_trusted_key_servers_first }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn jwt_decoding_key ( & self ) -> Option < & jsonwebtoken ::DecodingKey > { self . jwt_decoding_key . as_ref ( ) }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_password ( & self ) -> & String { & self . config . turn_password }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_ttl ( & self ) -> u64 { self . config . turn_ttl }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_uris ( & self ) -> & [ String ] { & self . config . turn_uris }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_username ( & self ) -> & String { & self . config . turn_username }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_profile_lookup_federation_requests ( & self ) -> bool {
2024-04-07 22:38:33 -04:00
self . config . allow_profile_lookup_federation_requests
}
2024-05-09 15:59:08 -07:00
pub fn notification_push_path ( & self ) -> & String { & self . config . notification_push_path }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn emergency_password ( & self ) -> & Option < String > { & self . config . emergency_password }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_contains_allowlist ( & self ) -> & Vec < String > {
2021-01-01 13:47:53 +01:00
& self . config . url_preview_domain_contains_allowlist
2020-06-06 19:02:31 +02:00
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_explicit_allowlist ( & self ) -> & Vec < String > {
2023-12-21 20:44:58 -05:00
& self . config . url_preview_domain_explicit_allowlist
2024-03-05 19:48:54 -05:00
}
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_explicit_denylist ( & self ) -> & Vec < String > {
2024-04-14 21:12:48 -04:00
& self . config . url_preview_domain_explicit_denylist
}
2024-05-09 15:59:08 -07:00
pub fn url_preview_url_contains_allowlist ( & self ) -> & Vec < String > { & self . config . url_preview_url_contains_allowlist }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_max_spider_size ( & self ) -> usize { self . config . url_preview_max_spider_size }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_check_root_domain ( & self ) -> bool { self . config . url_preview_check_root_domain }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn forbidden_alias_names ( & self ) -> & RegexSet { & self . config . forbidden_alias_names }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn forbidden_usernames ( & self ) -> & RegexSet { & self . config . forbidden_usernames }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_local_presence ( & self ) -> bool { self . config . allow_local_presence }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_incoming_presence ( & self ) -> bool { self . config . allow_incoming_presence }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_outgoing_presence ( & self ) -> bool { self . config . allow_outgoing_presence }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_incoming_read_receipts ( & self ) -> bool { self . config . allow_incoming_read_receipts }
2024-03-17 12:16:04 -04:00
2024-05-09 15:59:08 -07:00
pub fn allow_outgoing_read_receipts ( & self ) -> bool { self . config . allow_outgoing_read_receipts }
2024-04-10 15:22:50 -07:00
2024-05-09 15:59:08 -07:00
pub fn forbidden_remote_room_directory_server_names ( & self ) -> & [ OwnedServerName ] {
2024-04-15 22:02:08 -04:00
& self . config . forbidden_remote_room_directory_server_names
}
2024-05-09 15:59:08 -07:00
pub fn well_known_support_page ( & self ) -> & Option < Url > { & self . config . well_known . support_page }
2024-04-06 18:42:00 -04:00
2024-05-09 15:59:08 -07:00
pub fn well_known_support_role ( & self ) -> & Option < ContactRole > { & self . config . well_known . support_role }
2024-04-06 18:42:00 -04:00
2024-05-09 15:59:08 -07:00
pub fn well_known_support_email ( & self ) -> & Option < String > { & self . config . well_known . support_email }
2024-04-06 18:42:00 -04:00
2024-05-09 15:59:08 -07:00
pub fn well_known_support_mxid ( & self ) -> & Option < OwnedUserId > { & self . config . well_known . support_mxid }
2024-04-06 18:42:00 -04:00
2024-05-09 15:59:08 -07:00
pub fn block_non_admin_invites ( & self ) -> bool { self . config . block_non_admin_invites }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn supported_room_versions ( & self ) -> Vec < RoomVersionId > {
2024-09-20 23:34:49 -04:00
if self . config . allow_unstable_room_versions {
self . stable_room_versions
. clone ( )
. into_iter ( )
. chain ( self . unstable_room_versions . clone ( ) )
. collect ( )
} else {
self . stable_room_versions . clone ( )
}
2021-11-01 01:58:26 +00:00
}
2024-03-05 19:48:54 -05:00
2023-07-29 20:01:38 +02:00
/// This returns an empty `Ok(BTreeMap<..>)` when there are no keys found
2022-10-09 17:25:06 +02:00
/// for the server.
2024-08-08 17:18:30 +00:00
pub async fn verify_keys_for ( & self , origin : & ServerName ) -> Result < BTreeMap < OwnedServerSigningKeyId , VerifyKey > > {
let mut keys = self . db . verify_keys_for ( origin ) . await ? ;
2020-12-06 11:05:51 +01:00
if origin = = self . server_name ( ) {
keys . insert (
2024-06-07 03:44:59 -04:00
format! ( " ed25519: {} " , self . keypair ( ) . version ( ) )
2020-12-06 11:05:51 +01:00
. try_into ( )
. expect ( " found invalid server signing keys in DB " ) ,
VerifyKey {
key : Base64 ::new ( self . keypair . public_key ( ) . to_vec ( ) ) ,
2024-03-05 19:48:54 -05:00
} ,
) ;
2020-12-06 11:05:51 +01:00
}
2021-01-14 21:32:22 -05:00
2022-10-09 15:34:36 +02:00
Ok ( keys )
2021-02-07 17:38:45 +01:00
}
2021-01-14 21:32:22 -05:00
2024-08-08 17:18:30 +00:00
pub async fn signing_keys_for ( & self , origin : & ServerName ) -> Result < ServerSigningKeys > {
self . db . signing_keys_for ( origin ) . await
2024-06-17 07:49:52 +00:00
}
2024-05-09 15:59:08 -07:00
pub fn well_known_client ( & self ) -> & Option < Url > { & self . config . well_known . client }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn well_known_server ( & self ) -> & Option < OwnedServerName > { & self . config . well_known . server }
2024-03-05 19:48:54 -05:00
2024-07-03 20:06:43 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn valid_cidr_range ( & self , ip : & IPAddress ) -> bool {
2024-04-21 22:32:45 -07:00
for cidr in & self . cidr_range_denylist {
if cidr . includes ( ip ) {
return false ;
}
}
true
}
2024-07-22 07:43:51 +00:00
/// checks if `user_id` is local to us via server_name comparison
#[ inline ]
pub fn user_is_local ( & self , user_id : & UserId ) -> bool { self . server_is_ours ( user_id . server_name ( ) ) }
2024-03-05 19:48:54 -05:00
2024-07-22 07:43:51 +00:00
#[ inline ]
pub fn server_is_ours ( & self , server_name : & ServerName ) -> bool { server_name = = self . config . server_name }
2024-10-01 04:20:31 +00:00
#[ inline ]
pub fn is_read_only ( & self ) -> bool { self . db . db . is_read_only ( ) }
2024-07-22 07:43:51 +00:00
}