Browse Source

feat: add option to ignore specific server signing keys

merge-requests/731/merge
Matthias Ahouansou 1 month ago
parent
commit
d058dab7aa
No known key found for this signature in database
  1. 1
      docs/configuration.md
  2. 20
      src/config/mod.rs
  3. 30
      src/service/globals/mod.rs
  4. 3
      src/service/rooms/event_handler/mod.rs

1
docs/configuration.md

@ -57,6 +57,7 @@ The `global` section contains the following fields:
| `turn_uris` | `array` | The TURN URIs | `[]` |
| `turn_secret` | `string` | The TURN secret | `""` |
| `turn_ttl` | `integer` | The TURN TTL in seconds | `86400` |
| `ignored_keys` | `[string]` | Server keys that should be ignored | `["l/O9hxMVKB6Lg+3Hqf0FQQZhVESQcMzbPN1Cz2nM3og"]` ([ESS compromised key](https://github.com/element-hq/ess-helm/security/advisories/GHSA-qwcj-h6m8-vp6q)) |
| `media` | `table` | See the [media configuration](#media) | See the [media configuration](#media) |
| `emergency_password` | `string` | Set a password to login as the `conduit` user in case of emergency | N/A |
| `well_known` | `table` | Used for [delegation](delegation.md) | See [delegation](delegation.md) |

20
src/config/mod.rs

@ -8,7 +8,7 @@ use std::{
};
use bytesize::ByteSize;
use ruma::{OwnedServerName, RoomVersionId};
use ruma::{api::federation::discovery::VerifyKey, serde::Base64, OwnedServerName, RoomVersionId};
use serde::{de::IgnoredAny, Deserialize};
use tokio::time::{interval, Interval};
use tracing::warn;
@ -89,6 +89,9 @@ pub struct IncompleteConfig {
pub turn: Option<TurnConfig>,
#[serde(default = "default_ignored_keys")]
pub ignored_keys: Vec<VerifyKey>,
#[serde(default)]
pub media: IncompleteMediaConfig,
@ -136,6 +139,8 @@ pub struct Config {
pub turn: Option<TurnConfig>,
pub ignored_keys: Vec<Base64>,
pub media: MediaConfig,
pub emergency_password: Option<String>,
@ -186,6 +191,7 @@ impl From<IncompleteConfig> for Config {
media,
emergency_password,
catchall,
ignored_keys,
} = val;
let turn = turn.or_else(|| {
@ -204,6 +210,8 @@ impl From<IncompleteConfig> for Config {
}
});
let ignored_keys = ignored_keys.into_iter().map(|key| key.key).collect();
let well_known_client = well_known
.client
.map(String::from)
@ -283,6 +291,7 @@ impl From<IncompleteConfig> for Config {
media,
emergency_password,
catchall,
ignored_keys,
}
}
}
@ -786,3 +795,12 @@ pub fn default_default_room_version() -> RoomVersionId {
fn default_s3_duration() -> u64 {
30
}
fn default_ignored_keys() -> Vec<VerifyKey> {
vec![VerifyKey::new(Base64::new(
// Compromised Element Server Suite (ESS) signing key:
//
// https://github.com/element-hq/ess-helm/security/advisories/GHSA-qwcj-h6m8-vp6q
b"l/O9hxMVKB6Lg+3Hqf0FQQZhVESQcMzbPN1Cz2nM3og".to_vec(),
))]
}

30
src/service/globals/mod.rs

@ -421,7 +421,7 @@ impl Service {
}
/// Filters the key map of multiple servers down to keys that should be accepted given the expiry time,
/// room version, and timestamp of the parameters
/// room version, and timestamp of the parameters, as well as ignoring keys that are listed in `ignored_keys`.
pub fn filter_keys_server_map(
&self,
keys: BTreeMap<String, SigningKeys>,
@ -437,7 +437,7 @@ impl Service {
}
/// Filters the keys of a single server down to keys that should be accepted given the expiry time,
/// room version, and timestamp of the parameters
/// room version, and timestamp of the parameters, as well as removing any keys in `ignored_keys`.
pub fn filter_keys_single_server(
&self,
keys: SigningKeys,
@ -449,22 +449,32 @@ impl Service {
// https://spec.matrix.org/v1.10/server-server-api/#get_matrixkeyv2server
|| !rules.enforce_key_validity
{
let filter_ignored_keys = |(_, base64): &(_, Base64)| {
!services().globals.config.ignored_keys.contains(base64)
};
// Given that either the room version allows stale keys, or the valid_until_ts is
// in the future, all verify_keys are valid
let mut map: BTreeMap<_, _> = keys
.verify_keys
.into_iter()
.map(|(id, key)| (id, key.key))
.filter(filter_ignored_keys)
.collect();
map.extend(keys.old_verify_keys.into_iter().filter_map(|(id, key)| {
// Even on old room versions, we don't allow old keys if they are expired
if key.expired_ts > timestamp {
Some((id, key.key))
} else {
None
}
}));
map.extend(
keys.old_verify_keys
.into_iter()
.filter_map(|(id, key)| {
// Even on old room versions, we don't allow old keys if they are expired
if key.expired_ts > timestamp {
Some((id, key.key))
} else {
None
}
})
.filter(filter_ignored_keys),
);
Some(map)
} else {

3
src/service/rooms/event_handler/mod.rs

@ -1421,7 +1421,8 @@ impl Service {
Ok((sorted, eventid_info))
}
/// Filters down the given signing keys, only keeping those which could be valid for this event.
/// Filters down the given signing keys, only keeping those which could be valid for this event,
/// as well as ignoring those listed in `ignored_keys`.
#[tracing::instrument(skip_all)]
pub async fn filter_required_signing_keys(
&self,

Loading…
Cancel
Save