add support for reading a registration token from a file
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
ee1580e480
commit
7a59add8f1
|
@ -195,11 +195,14 @@ allow_guests_auto_join_rooms = false
|
||||||
|
|
||||||
# Enables registration. If set to false, no users can register on this
|
# Enables registration. If set to false, no users can register on this
|
||||||
# server.
|
# server.
|
||||||
|
#
|
||||||
# If set to true without a token configured, users can register with no form of 2nd-
|
# If set to true without a token configured, users can register with no form of 2nd-
|
||||||
# step only if you set
|
# step only if you set
|
||||||
# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` to
|
# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` to
|
||||||
# true in your config. If you would like
|
# true in your config.
|
||||||
# registration only via token reg, please configure the `registration_token` key.
|
#
|
||||||
|
# If you would like registration only via token reg, please configure
|
||||||
|
# `registration_token` or `registration_token_file`.
|
||||||
allow_registration = false
|
allow_registration = false
|
||||||
# Please note that an open registration homeserver with no second-step verification
|
# Please note that an open registration homeserver with no second-step verification
|
||||||
# is highly prone to abuse and potential defederation by homeservers, including
|
# is highly prone to abuse and potential defederation by homeservers, including
|
||||||
|
@ -208,7 +211,14 @@ allow_registration = false
|
||||||
# A static registration token that new users will have to provide when creating
|
# A static registration token that new users will have to provide when creating
|
||||||
# an account. If unset and `allow_registration` is true, registration is open
|
# an account. If unset and `allow_registration` is true, registration is open
|
||||||
# without any condition. YOU NEED TO EDIT THIS.
|
# without any condition. YOU NEED TO EDIT THIS.
|
||||||
registration_token = "change this token for something specific to your server"
|
registration_token = "change this token/string here or set registration_token_file"
|
||||||
|
|
||||||
|
# Path to a file on the system that gets read for the registration token
|
||||||
|
#
|
||||||
|
# conduwuit must be able to access the file, and it must not be empty
|
||||||
|
#
|
||||||
|
# no default
|
||||||
|
#registration_token_file = "/etc/conduwuit/.reg_token"
|
||||||
|
|
||||||
# controls whether federation is allowed or not
|
# controls whether federation is allowed or not
|
||||||
# defaults to true
|
# defaults to true
|
||||||
|
@ -344,7 +354,7 @@ allow_profile_lookup_federation_requests = true
|
||||||
# Controls the max log level for admin command log captures (logs generated from running admin commands)
|
# Controls the max log level for admin command log captures (logs generated from running admin commands)
|
||||||
#
|
#
|
||||||
# Defaults to "info" on release builds, else "debug" on debug builds
|
# Defaults to "info" on release builds, else "debug" on debug builds
|
||||||
#admin_log_capture = info
|
#admin_log_capture = "info"
|
||||||
|
|
||||||
# Allows admins to enter commands in rooms other than #admins by prefixing with \!admin. The reply
|
# Allows admins to enter commands in rooms other than #admins by prefixing with \!admin. The reply
|
||||||
# will be publicly visible to the room, originating from the sender.
|
# will be publicly visible to the room, originating from the sender.
|
||||||
|
|
|
@ -16,7 +16,7 @@ services:
|
||||||
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
||||||
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
||||||
CONDUWUIT_PORT: 6167 # should match the loadbalancer traefik label
|
CONDUWUIT_PORT: 6167 # should match the loadbalancer traefik label
|
||||||
CONDUWUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
|
CONDUWUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
|
||||||
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
||||||
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
||||||
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
||||||
|
|
|
@ -32,7 +32,7 @@ services:
|
||||||
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
||||||
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
||||||
CONDUWUIT_PORT: 6167
|
CONDUWUIT_PORT: 6167
|
||||||
CONDUWUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
|
CONDUWUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
|
||||||
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
||||||
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
||||||
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
||||||
|
|
|
@ -15,7 +15,8 @@ services:
|
||||||
CONDUWUIT_SERVER_NAME: your.server.name.example # EDIT THIS
|
CONDUWUIT_SERVER_NAME: your.server.name.example # EDIT THIS
|
||||||
CONDUWUIT_TRUSTED_SERVERS: '["matrix.org"]'
|
CONDUWUIT_TRUSTED_SERVERS: '["matrix.org"]'
|
||||||
CONDUWUIT_ALLOW_REGISTRATION: 'false' # After setting a secure registration token, you can enable this
|
CONDUWUIT_ALLOW_REGISTRATION: 'false' # After setting a secure registration token, you can enable this
|
||||||
CONDUWUIT_REGISTRATION_TOKEN: # This is a token you can use to register on the server
|
CONDUWUIT_REGISTRATION_TOKEN: "" # This is a token you can use to register on the server
|
||||||
|
#CONDUWUIT_REGISTRATION_TOKEN_FILE: "" # Alternatively you can configure a path to a token file to read
|
||||||
CONDUWUIT_ADDRESS: 0.0.0.0
|
CONDUWUIT_ADDRESS: 0.0.0.0
|
||||||
CONDUWUIT_PORT: 6167 # you need to match this with the traefik load balancer label if you're want to change it
|
CONDUWUIT_PORT: 6167 # you need to match this with the traefik load balancer label if you're want to change it
|
||||||
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
||||||
|
@ -23,7 +24,6 @@ services:
|
||||||
### Uncomment and change values as desired, note that conduwuit has plenty of config options, so you should check out the example example config too
|
### Uncomment and change values as desired, note that conduwuit has plenty of config options, so you should check out the example example config too
|
||||||
# Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging
|
# Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging
|
||||||
# CONDUWUIT_LOG: info # default is: "warn,state_res=warn"
|
# CONDUWUIT_LOG: info # default is: "warn,state_res=warn"
|
||||||
# CONDUWUIT_ALLOW_JAEGER: 'false'
|
|
||||||
# CONDUWUIT_ALLOW_ENCRYPTION: 'true'
|
# CONDUWUIT_ALLOW_ENCRYPTION: 'true'
|
||||||
# CONDUWUIT_ALLOW_FEDERATION: 'true'
|
# CONDUWUIT_ALLOW_FEDERATION: 'true'
|
||||||
# CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
# CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
||||||
|
@ -31,7 +31,7 @@ services:
|
||||||
# CONDUWUIT_ALLOW_OUTGOING_PRESENCE: true
|
# CONDUWUIT_ALLOW_OUTGOING_PRESENCE: true
|
||||||
# CONDUWUIT_ALLOW_LOCAL_PRESENCE: true
|
# CONDUWUIT_ALLOW_LOCAL_PRESENCE: true
|
||||||
# CONDUWUIT_WORKERS: 10
|
# CONDUWUIT_WORKERS: 10
|
||||||
# CONDUWUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
|
# CONDUWUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
|
||||||
# CONDUWUIT_NEW_USER_DISPLAYNAME_SUFFIX = "🏳<200d>⚧"
|
# CONDUWUIT_NEW_USER_DISPLAYNAME_SUFFIX = "🏳<200d>⚧"
|
||||||
|
|
||||||
# We need some way to serve the client and server .well-known json. The simplest way is via the CONDUWUIT_WELL_KNOWN
|
# We need some way to serve the client and server .well-known json. The simplest way is via the CONDUWUIT_WELL_KNOWN
|
||||||
|
|
|
@ -16,7 +16,7 @@ services:
|
||||||
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
CONDUWUIT_DATABASE_PATH: /var/lib/conduwuit
|
||||||
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
CONDUWUIT_DATABASE_BACKEND: rocksdb
|
||||||
CONDUWUIT_PORT: 6167
|
CONDUWUIT_PORT: 6167
|
||||||
CONDUWUIT_MAX_REQUEST_SIZE: 20_000_000 # in bytes, ~20 MB
|
CONDUWUIT_MAX_REQUEST_SIZE: 20000000 # in bytes, ~20 MB
|
||||||
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
CONDUWUIT_ALLOW_REGISTRATION: 'true'
|
||||||
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
CONDUWUIT_ALLOW_FEDERATION: 'true'
|
||||||
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
CONDUWUIT_ALLOW_CHECK_FOR_UPDATES: 'true'
|
||||||
|
|
|
@ -111,7 +111,7 @@ pub(crate) async fn register_route(
|
||||||
|
|
||||||
if is_guest
|
if is_guest
|
||||||
&& (!services.globals.allow_guest_registration()
|
&& (!services.globals.allow_guest_registration()
|
||||||
|| (services.globals.allow_registration() && services.globals.config.registration_token.is_some()))
|
|| (services.globals.allow_registration() && services.globals.registration_token.is_some()))
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
"Guest registration disabled / registration enabled with token configured, rejecting guest registration \
|
"Guest registration disabled / registration enabled with token configured, rejecting guest registration \
|
||||||
|
@ -183,7 +183,7 @@ pub(crate) async fn register_route(
|
||||||
|
|
||||||
// UIAA
|
// UIAA
|
||||||
let mut uiaainfo;
|
let mut uiaainfo;
|
||||||
let skip_auth = if services.globals.config.registration_token.is_some() {
|
let skip_auth = if services.globals.registration_token.is_some() {
|
||||||
// Registration token required
|
// Registration token required
|
||||||
uiaainfo = UiaaInfo {
|
uiaainfo = UiaaInfo {
|
||||||
flows: vec![AuthFlow {
|
flows: vec![AuthFlow {
|
||||||
|
@ -685,7 +685,7 @@ pub(crate) async fn request_3pid_management_token_via_msisdn_route(
|
||||||
pub(crate) async fn check_registration_token_validity(
|
pub(crate) async fn check_registration_token_validity(
|
||||||
State(services): State<crate::State>, body: Ruma<check_registration_token_validity::v1::Request>,
|
State(services): State<crate::State>, body: Ruma<check_registration_token_validity::v1::Request>,
|
||||||
) -> Result<check_registration_token_validity::v1::Response> {
|
) -> Result<check_registration_token_validity::v1::Response> {
|
||||||
let Some(reg_token) = services.globals.config.registration_token.clone() else {
|
let Some(reg_token) = services.globals.registration_token.clone() else {
|
||||||
return Err(Error::BadRequest(
|
return Err(Error::BadRequest(
|
||||||
ErrorKind::forbidden(),
|
ErrorKind::forbidden(),
|
||||||
"Server does not allow token registration.",
|
"Server does not allow token registration.",
|
||||||
|
|
|
@ -94,6 +94,22 @@ pub fn check(config: &Config) -> Result<()> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if we can read the token file path, and check if the file is empty
|
||||||
|
if config.registration_token_file.as_ref().is_some_and(|path| {
|
||||||
|
let Ok(token) = std::fs::read_to_string(path).inspect_err(|e| {
|
||||||
|
error!("Failed to read the registration token file: {e}");
|
||||||
|
}) else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
token == String::new()
|
||||||
|
}) {
|
||||||
|
return Err!(Config(
|
||||||
|
"registration_token_file",
|
||||||
|
"Registration token file was specified but is empty or failed to be read"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if config.max_request_size < 5_120_000 {
|
if config.max_request_size < 5_120_000 {
|
||||||
return Err!(Config(
|
return Err!(Config(
|
||||||
"max_request_size",
|
"max_request_size",
|
||||||
|
@ -111,12 +127,13 @@ pub fn check(config: &Config) -> Result<()> {
|
||||||
if config.allow_registration
|
if config.allow_registration
|
||||||
&& !config.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
&& !config.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
||||||
&& config.registration_token.is_none()
|
&& config.registration_token.is_none()
|
||||||
|
&& config.registration_token_file.is_none()
|
||||||
{
|
{
|
||||||
return Err!(Config(
|
return Err!(Config(
|
||||||
"registration_token",
|
"registration_token",
|
||||||
"!! You have `allow_registration` enabled without a token configured in your config which means you are \
|
"!! You have `allow_registration` enabled without a token configured in your config which means you are \
|
||||||
allowing ANYONE to register on your conduwuit instance without any 2nd-step (e.g. registration token).\n
|
allowing ANYONE to register on your conduwuit instance without any 2nd-step (e.g. registration token).\n
|
||||||
If this is not the intended behaviour, please set a registration token with the `registration_token` config option.\n
|
If this is not the intended behaviour, please set a registration token.\n
|
||||||
For security and safety reasons, conduwuit will shut down. If you are extra sure this is the desired behaviour you \
|
For security and safety reasons, conduwuit will shut down. If you are extra sure this is the desired behaviour you \
|
||||||
want, please set the following config option to true:
|
want, please set the following config option to true:
|
||||||
`yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`"
|
`yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`"
|
||||||
|
@ -126,6 +143,7 @@ For security and safety reasons, conduwuit will shut down. If you are extra sure
|
||||||
if config.allow_registration
|
if config.allow_registration
|
||||||
&& config.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
&& config.yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse
|
||||||
&& config.registration_token.is_none()
|
&& config.registration_token.is_none()
|
||||||
|
&& config.registration_token_file.is_none()
|
||||||
{
|
{
|
||||||
warn!(
|
warn!(
|
||||||
"Open registration is enabled via setting \
|
"Open registration is enabled via setting \
|
||||||
|
|
|
@ -139,6 +139,7 @@ pub struct Config {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse: bool,
|
pub yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse: bool,
|
||||||
pub registration_token: Option<String>,
|
pub registration_token: Option<String>,
|
||||||
|
pub registration_token_file: Option<PathBuf>,
|
||||||
#[serde(default = "true_fn")]
|
#[serde(default = "true_fn")]
|
||||||
pub allow_encryption: bool,
|
pub allow_encryption: bool,
|
||||||
#[serde(default = "true_fn")]
|
#[serde(default = "true_fn")]
|
||||||
|
@ -572,12 +573,20 @@ impl fmt::Display for Config {
|
||||||
line("Allow registration", &self.allow_registration.to_string());
|
line("Allow registration", &self.allow_registration.to_string());
|
||||||
line(
|
line(
|
||||||
"Registration token",
|
"Registration token",
|
||||||
if self.registration_token.is_some() {
|
if self.registration_token.is_none() && self.registration_token_file.is_none() && self.allow_registration {
|
||||||
"set"
|
"not set (⚠️ open registration!)"
|
||||||
|
} else if self.registration_token.is_none() && self.registration_token_file.is_none() {
|
||||||
|
"not set"
|
||||||
} else {
|
} else {
|
||||||
"not set (open registration!)"
|
"set"
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
line(
|
||||||
|
"Registration token file path",
|
||||||
|
self.registration_token_file
|
||||||
|
.as_ref()
|
||||||
|
.map_or("", |path| path.to_str().unwrap_or_default()),
|
||||||
|
);
|
||||||
line(
|
line(
|
||||||
"Allow guest registration (inherently false if allow registration is false)",
|
"Allow guest registration (inherently false if allow registration is false)",
|
||||||
&self.allow_guest_registration.to_string(),
|
&self.allow_guest_registration.to_string(),
|
||||||
|
|
|
@ -41,6 +41,7 @@ pub struct Service {
|
||||||
pub server_user: OwnedUserId,
|
pub server_user: OwnedUserId,
|
||||||
pub admin_alias: OwnedRoomAliasId,
|
pub admin_alias: OwnedRoomAliasId,
|
||||||
pub turn_secret: String,
|
pub turn_secret: String,
|
||||||
|
pub registration_token: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type RateLimitState = (Instant, u32); // Time if last failed try, number of failed tries
|
type RateLimitState = (Instant, u32); // Time if last failed try, number of failed tries
|
||||||
|
@ -96,6 +97,20 @@ impl crate::Service for Service {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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)
|
||||||
|
});
|
||||||
|
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
db,
|
db,
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
|
@ -112,6 +127,7 @@ impl crate::Service for Service {
|
||||||
server_user: UserId::parse_with_server_name(String::from("conduit"), &config.server_name)
|
server_user: UserId::parse_with_server_name(String::from("conduit"), &config.server_name)
|
||||||
.expect("@conduit:server_name is valid"),
|
.expect("@conduit:server_name is valid"),
|
||||||
turn_secret,
|
turn_secret,
|
||||||
|
registration_token,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !s
|
if !s
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
use conduit::{
|
use conduit::{
|
||||||
err, error, implement, utils,
|
err, error, implement, utils,
|
||||||
utils::{hash, string::EMPTY},
|
utils::{hash, string::EMPTY},
|
||||||
Error, Result, Server,
|
Error, Result,
|
||||||
};
|
};
|
||||||
use database::{Deserialized, Map};
|
use database::{Deserialized, Map};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
|
@ -26,7 +26,6 @@ pub struct Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Services {
|
struct Services {
|
||||||
server: Arc<Server>,
|
|
||||||
globals: Dep<globals::Service>,
|
globals: Dep<globals::Service>,
|
||||||
users: Dep<users::Service>,
|
users: Dep<users::Service>,
|
||||||
}
|
}
|
||||||
|
@ -48,7 +47,6 @@ impl crate::Service for Service {
|
||||||
userdevicesessionid_uiaainfo: args.db["userdevicesessionid_uiaainfo"].clone(),
|
userdevicesessionid_uiaainfo: args.db["userdevicesessionid_uiaainfo"].clone(),
|
||||||
},
|
},
|
||||||
services: Services {
|
services: Services {
|
||||||
server: args.server.clone(),
|
|
||||||
globals: args.depend::<globals::Service>("globals"),
|
globals: args.depend::<globals::Service>("globals"),
|
||||||
users: args.depend::<users::Service>("users"),
|
users: args.depend::<users::Service>("users"),
|
||||||
},
|
},
|
||||||
|
@ -135,7 +133,13 @@ pub async fn try_auth(
|
||||||
uiaainfo.completed.push(AuthType::Password);
|
uiaainfo.completed.push(AuthType::Password);
|
||||||
},
|
},
|
||||||
AuthData::RegistrationToken(t) => {
|
AuthData::RegistrationToken(t) => {
|
||||||
if Some(t.token.trim()) == self.services.server.config.registration_token.as_deref() {
|
if self
|
||||||
|
.services
|
||||||
|
.globals
|
||||||
|
.registration_token
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|reg_token| t.token.trim() == reg_token)
|
||||||
|
{
|
||||||
uiaainfo.completed.push(AuthType::RegistrationToken);
|
uiaainfo.completed.push(AuthType::RegistrationToken);
|
||||||
} else {
|
} else {
|
||||||
uiaainfo.auth_error = Some(ruma::api::client::error::StandardErrorBody {
|
uiaainfo.auth_error = Some(ruma::api::client::error::StandardErrorBody {
|
||||||
|
|
Loading…
Reference in New Issue