diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index 365a4483c4e..b902e0d25e5 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -144,7 +144,8 @@ impl ClientBuilder { } /// Set the server name to discover the homeserver from, assuming an HTTP - /// (not secured) scheme. + /// (not secured) scheme. This also relaxes OIDC discovery checks to allow + /// HTTP schemes. /// /// This method is mutually exclusive with /// [`homeserver_url()`][Self::homeserver_url], if you set both whatever was @@ -371,7 +372,7 @@ impl ClientBuilder { let http_client = HttpClient::new(inner_http_client.clone(), self.request_config); #[cfg(feature = "experimental-oidc")] - let mut authentication_server_info = None; + let (mut authentication_server_info, mut allow_insecure_oidc) = (None, false); #[cfg(feature = "experimental-sliding-sync")] let mut sliding_sync_proxy: Option = None; @@ -411,6 +412,7 @@ impl ClientBuilder { #[cfg(feature = "experimental-oidc")] { authentication_server_info = well_known.authentication; + allow_insecure_oidc = matches!(protocol, UrlScheme::Http); } #[cfg(feature = "experimental-sliding-sync")] @@ -437,7 +439,7 @@ impl ClientBuilder { reload_session_callback: OnceCell::default(), save_session_callback: OnceCell::default(), #[cfg(feature = "experimental-oidc")] - oidc: OidcCtx::new(authentication_server_info), + oidc: OidcCtx::new(authentication_server_info, allow_insecure_oidc), }); let inner = Arc::new(ClientInner::new( @@ -457,7 +459,7 @@ impl ClientBuilder { } } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] enum UrlScheme { Http, Https, diff --git a/crates/matrix-sdk/src/oidc/backend/mock.rs b/crates/matrix-sdk/src/oidc/backend/mock.rs index 8aef89b03e8..422087fb4b4 100644 --- a/crates/matrix-sdk/src/oidc/backend/mock.rs +++ b/crates/matrix-sdk/src/oidc/backend/mock.rs @@ -101,7 +101,11 @@ impl MockImpl { #[async_trait::async_trait] impl OidcBackend for MockImpl { - async fn discover(&self, issuer: &str) -> Result { + async fn discover( + &self, + issuer: &str, + _insecure: bool, + ) -> Result { Ok(ProviderMetadata { issuer: Some(self.issuer.clone()), authorization_endpoint: Some(Url::parse(&self.authorization_endpoint).unwrap()), diff --git a/crates/matrix-sdk/src/oidc/backend/mod.rs b/crates/matrix-sdk/src/oidc/backend/mod.rs index f76ae0e9cad..5f1883afb26 100644 --- a/crates/matrix-sdk/src/oidc/backend/mod.rs +++ b/crates/matrix-sdk/src/oidc/backend/mod.rs @@ -42,7 +42,11 @@ pub(super) struct RefreshedSessionTokens { #[async_trait::async_trait] pub(super) trait OidcBackend: std::fmt::Debug + Send + Sync { - async fn discover(&self, issuer: &str) -> Result; + async fn discover( + &self, + issuer: &str, + insecure: bool, + ) -> Result; async fn register_client( &self, diff --git a/crates/matrix-sdk/src/oidc/backend/server.rs b/crates/matrix-sdk/src/oidc/backend/server.rs index 0163e61375d..b2ea157aaa0 100644 --- a/crates/matrix-sdk/src/oidc/backend/server.rs +++ b/crates/matrix-sdk/src/oidc/backend/server.rs @@ -24,7 +24,7 @@ use mas_oidc_client::{ access_token_with_authorization_code, build_par_authorization_url, AuthorizationRequestData, AuthorizationValidationData, }, - discovery::discover, + discovery::{discover, insecure_discover}, jose::{fetch_jwks, JwtVerificationData}, refresh_token::refresh_access_token, registration::register_client, @@ -71,8 +71,16 @@ impl OidcServer { #[async_trait::async_trait] impl OidcBackend for OidcServer { - async fn discover(&self, issuer: &str) -> Result { - discover(&self.http_service(), issuer).await.map_err(Into::into) + async fn discover( + &self, + issuer: &str, + insecure: bool, + ) -> Result { + if insecure { + insecure_discover(&self.http_service(), issuer).await.map_err(Into::into) + } else { + discover(&self.http_service(), issuer).await.map_err(Into::into) + } } async fn trade_authorization_code_for_tokens( diff --git a/crates/matrix-sdk/src/oidc/mod.rs b/crates/matrix-sdk/src/oidc/mod.rs index 80c0528a38e..c7697335ca1 100644 --- a/crates/matrix-sdk/src/oidc/mod.rs +++ b/crates/matrix-sdk/src/oidc/mod.rs @@ -229,12 +229,19 @@ pub(crate) struct OidcCtx { /// Note: only required because we're using the crypto store that might not /// be present before reloading a session. deferred_cross_process_lock_init: Mutex>, + + /// Whether to allow HTTP issuer URLs. + insecure_discover: bool, } impl OidcCtx { - pub(crate) fn new(authentication_server_info: Option) -> Self { + pub(crate) fn new( + authentication_server_info: Option, + insecure_discover: bool, + ) -> Self { Self { authentication_server_info, + insecure_discover, cross_process_token_refresh_manager: Default::default(), deferred_cross_process_lock_init: Default::default(), } @@ -420,7 +427,7 @@ impl Oidc { &self, issuer: &str, ) -> Result { - self.backend.discover(issuer).await + self.backend.discover(issuer, self.ctx().insecure_discover).await } /// Fetch the OpenID Connect metadata of the issuer. @@ -639,7 +646,7 @@ impl Oidc { client_metadata: VerifiedClientMetadata, software_statement: Option, ) -> Result { - let provider_metadata = self.backend.discover(issuer).await?; + let provider_metadata = self.backend.discover(issuer, self.ctx().insecure_discover).await?; let registration_endpoint = provider_metadata .registration_endpoint