From ea2f9d0f64c6cf42f0ea7d5f91681c5a5e1484c2 Mon Sep 17 00:00:00 2001 From: Lyssieth Date: Tue, 28 Nov 2023 04:45:27 +0200 Subject: [PATCH] feat: support `p` in authentication We just fuzz it to a token+salt implementation instead :> --- Cargo.lock | 43 ++++++++++++------------ rave/Cargo.toml | 1 + rave/src/authentication.rs | 67 +++++++++++++++++++++++++------------- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 29cbe4a..93e943f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -615,9 +615,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.8" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "46ca43acc1b21c6cc2d1d3129c19e323a613935b5bc28fb3b33b5b2e5fb00030" dependencies = [ "clap_builder", "clap_derive", @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" dependencies = [ "anstream", "anstyle", @@ -960,12 +960,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1636,9 +1636,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -2454,6 +2454,7 @@ dependencies = [ "once_cell", "poem", "quick-xml 0.31.0", + "rand", "sea-orm", "serde", "serde_json", @@ -3707,9 +3708,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3717,9 +3718,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -3732,9 +3733,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -3744,9 +3745,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3754,9 +3755,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -3767,9 +3768,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" diff --git a/rave/Cargo.toml b/rave/Cargo.toml index 812cf28..1b46ee6 100644 --- a/rave/Cargo.toml +++ b/rave/Cargo.toml @@ -44,3 +44,4 @@ tracing-appender = "0.2" blake3 = "1.5" image = "0.24" nate = "0.4" +rand = "0.8.5" diff --git a/rave/src/authentication.rs b/rave/src/authentication.rs index fcc15b6..a2d653d 100644 --- a/rave/src/authentication.rs +++ b/rave/src/authentication.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, fmt::Display, str::FromStr, string::ToString}; use color_eyre::Report; use poem::{Error, FromRequest, IntoResponse, Request, RequestBody, Result}; +use rand::Rng; use tracing::trace; use crate::subsonic::{self, SubsonicResponse, SubsonicResponseJson, SubsonicResponseXml}; @@ -72,31 +73,53 @@ impl<'a> FromRequest<'a> for Authentication { trace!("User: {user}"); let password = query.get("p").map(ToString::to_string); - if password.is_some() { - return_json_or_xml!( - json, - subsonic::Error::Generic(Some( - "password authentication is not supported".to_string(), - )) - ); - } trace!("Password: {password:?}"); - let token = query.get("t").map(ToString::to_string); - let salt = query.get("s").map(ToString::to_string); - if token.is_none() || salt.is_none() { - return_json_or_xml!( - json, - subsonic::Error::RequiredParameterMissing(Some( - "please provide both `t` and `s` parameters".to_string(), - )) - ); - } - let token = token.expect("Missing token"); - trace!("Token: {token}"); - let salt = salt.expect("Missing salt"); - trace!("Salt: {salt}"); + let (token, salt) = if let Some(password) = password { + #[allow(clippy::option_if_let_else)] + let password = if let Some(password) = password.strip_prefix("enc:") { + let mut bytes = Vec::with_capacity(password.len() / 2); + + for i in 0..password.len() / 2 { + let byte = u8::from_str_radix(&password[i * 2..i * 2 + 2], 16) + .expect("Failed to parse hex"); + + bytes.push(byte); + } + + String::from_utf8(bytes).expect("Failed to parse utf8") + } else { + password + }; + + let salt = rand::thread_rng() + .sample_iter(rand::distributions::Alphanumeric) + .take(12) + .map(char::from) + .collect::(); + + let token = md5::compute(format!("{password}{salt}")); + + (format!("{token:x}"), salt) + } else { + let token = query.get("t").map(ToString::to_string); + let salt = query.get("s").map(ToString::to_string); + if token.is_none() || salt.is_none() { + return_json_or_xml!( + json, + subsonic::Error::RequiredParameterMissing(Some( + "please provide both `t` and `s` parameters, or `p`".to_string(), + )) + ); + } + let token = token.expect("Missing token"); + trace!("Token: {token}"); + let salt = salt.expect("Missing salt"); + trace!("Salt: {salt}"); + + (token, salt) + }; let version = { let version = query.get("v").map(ToString::to_string);