Update crates (#4074)

* Remove another header for websocket connections

* Fix small bake issue

* Update crates

Updated crates and adjusted code where needed.
One major update is Rocket rc4, no need anymore (again) for crates.io patching.

The only item still pending is openssl/openssl-sys for which we need to
wait if https://github.com/sfackler/rust-openssl/pull/2094 will be
merged. If, then we can remove the pinned versions for the openssl crate.
This commit is contained in:
Mathijs van Veluw 2023-11-15 10:41:14 +01:00 committed by GitHub
parent f863ffb89a
commit 48836501bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 393 additions and 361 deletions

673
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -55,32 +55,31 @@ num-traits = "0.2.17"
num-derive = "0.4.1" num-derive = "0.4.1"
# Web framework # Web framework
rocket = { version = "0.5.0-rc.3", features = ["tls", "json"], default-features = false } rocket = { version = "0.5.0-rc.4", features = ["tls", "json"], default-features = false }
# rocket_ws = { version ="0.1.0-rc.3" } rocket_ws = { version ="0.1.0-rc.4" }
rocket_ws = { git = 'https://github.com/SergioBenitez/Rocket', rev = "ce441b5f46fdf5cd99cb32b8b8638835e4c2a5fa" } # v0.5 branch
# WebSockets libraries # WebSockets libraries
tokio-tungstenite = "0.19.0" tokio-tungstenite = "0.20.1"
rmpv = "1.0.1" # MessagePack library rmpv = "1.0.1" # MessagePack library
# Concurrent HashMap used for WebSocket messaging and favicons # Concurrent HashMap used for WebSocket messaging and favicons
dashmap = "5.5.3" dashmap = "5.5.3"
# Async futures # Async futures
futures = "0.3.28" futures = "0.3.29"
tokio = { version = "1.33.0", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal"] } tokio = { version = "1.34.0", features = ["rt-multi-thread", "fs", "io-util", "parking_lot", "time", "signal"] }
# A generic serialization/deserialization framework # A generic serialization/deserialization framework
serde = { version = "1.0.189", features = ["derive"] } serde = { version = "1.0.192", features = ["derive"] }
serde_json = "1.0.107" serde_json = "1.0.108"
# A safe, extensible ORM and Query builder # A safe, extensible ORM and Query builder
diesel = { version = "2.1.3", features = ["chrono", "r2d2"] } diesel = { version = "2.1.4", features = ["chrono", "r2d2"] }
diesel_migrations = "2.1.0" diesel_migrations = "2.1.0"
diesel_logger = { version = "0.3.0", optional = true } diesel_logger = { version = "0.3.0", optional = true }
# Bundled/Static SQLite # Bundled/Static SQLite
libsqlite3-sys = { version = "0.26.0", features = ["bundled"], optional = true } libsqlite3-sys = { version = "0.27.0", features = ["bundled"], optional = true }
# Crypto-related libraries # Crypto-related libraries
rand = { version = "0.8.5", features = ["small_rng"] } rand = { version = "0.8.5", features = ["small_rng"] }
@ -91,7 +90,7 @@ uuid = { version = "1.5.0", features = ["v4"] }
# Date and time libraries # Date and time libraries
chrono = { version = "0.4.31", features = ["clock", "serde"], default-features = false } chrono = { version = "0.4.31", features = ["clock", "serde"], default-features = false }
chrono-tz = "0.8.3" chrono-tz = "0.8.4"
time = "0.3.30" time = "0.3.30"
# Job scheduler # Job scheduler
@ -101,10 +100,10 @@ job_scheduler_ng = "2.0.4"
data-encoding = "2.4.0" data-encoding = "2.4.0"
# JWT library # JWT library
jsonwebtoken = "9.0.0" jsonwebtoken = "9.1.0"
# TOTP library # TOTP library
totp-lite = "2.0.0" totp-lite = "2.0.1"
# Yubico Library # Yubico Library
yubico = { version = "0.11.0", features = ["online-tokio"], default-features = false } yubico = { version = "0.11.0", features = ["online-tokio"], default-features = false }
@ -116,12 +115,12 @@ webauthn-rs = "0.3.2"
url = "2.4.1" url = "2.4.1"
# Email libraries # Email libraries
lettre = { version = "0.11.0", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false } lettre = { version = "0.11.1", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false }
percent-encoding = "2.3.0" # URL encoding library used for URL's in the emails percent-encoding = "2.3.0" # URL encoding library used for URL's in the emails
email_address = "0.2.4" email_address = "0.2.4"
# HTML Template library # HTML Template library
handlebars = { version = "4.4.0", features = ["dir_source"] } handlebars = { version = "4.5.0", features = ["dir_source"] }
# HTTP client (Used for favicons, version check, DUO and HIBP API) # HTTP client (Used for favicons, version check, DUO and HIBP API)
reqwest = { version = "0.11.22", features = ["stream", "json", "deflate", "gzip", "brotli", "socks", "cookies", "trust-dns", "native-tls-alpn"] } reqwest = { version = "0.11.22", features = ["stream", "json", "deflate", "gzip", "brotli", "socks", "cookies", "trust-dns", "native-tls-alpn"] }
@ -133,14 +132,14 @@ data-url = "0.3.0"
bytes = "1.5.0" bytes = "1.5.0"
# Cache function results (Used for version check and favicon fetching) # Cache function results (Used for version check and favicon fetching)
cached = { version = "0.46.0", features = ["async"] } cached = { version = "0.46.1", features = ["async"] }
# Used for custom short lived cookie jar during favicon extraction # Used for custom short lived cookie jar during favicon extraction
cookie = "0.16.2" cookie = "0.16.2"
cookie_store = "0.19.1" cookie_store = "0.19.1"
# Used by U2F, JWT and PostgreSQL # Used by U2F, JWT and PostgreSQL
openssl = "0.10.57" openssl = "=0.10.57"
# Set openssl-sys fixed to v0.9.92 to prevent building issues with musl, arm and 32bit pointer width # Set openssl-sys fixed to v0.9.92 to prevent building issues with musl, arm and 32bit pointer width
# It will force add a dynamically linked library which prevents the build from being static # It will force add a dynamically linked library which prevents the build from being static
openssl-sys = "=0.9.92" openssl-sys = "=0.9.92"
@ -164,12 +163,7 @@ which = "5.0.0"
argon2 = "0.5.2" argon2 = "0.5.2"
# Reading a password from the cli for generating the Argon2id ADMIN_TOKEN # Reading a password from the cli for generating the Argon2id ADMIN_TOKEN
rpassword = "7.2.0" rpassword = "7.3.1"
[patch.crates-io]
rocket = { git = 'https://github.com/SergioBenitez/Rocket', rev = 'ce441b5f46fdf5cd99cb32b8b8638835e4c2a5fa' } # v0.5 branch
# rocket_ws = { git = 'https://github.com/SergioBenitez/Rocket', rev = 'ce441b5f46fdf5cd99cb32b8b8638835e4c2a5fa' } # v0.5 branch
# Strip debuginfo from the release builds # Strip debuginfo from the release builds

View file

@ -88,7 +88,7 @@ target "debian" {
inherits = ["_default_attributes"] inherits = ["_default_attributes"]
dockerfile = "docker/Dockerfile.debian" dockerfile = "docker/Dockerfile.debian"
tags = generate_tags("", platform_tag()) tags = generate_tags("", platform_tag())
output = [join(",", flatten([["type=docker"], image_index_annotations()]))] output = ["type=docker"]
} }
// Multi Platform target, will build one tagged manifest with all supported architectures // Multi Platform target, will build one tagged manifest with all supported architectures
@ -138,7 +138,7 @@ target "alpine" {
inherits = ["_default_attributes"] inherits = ["_default_attributes"]
dockerfile = "docker/Dockerfile.alpine" dockerfile = "docker/Dockerfile.alpine"
tags = generate_tags("-alpine", platform_tag()) tags = generate_tags("-alpine", platform_tag())
output = [join(",", flatten([["type=docker"], image_index_annotations()]))] output = ["type=docker"]
} }
// Multi Platform target, will build one tagged manifest with all supported architectures // Multi Platform target, will build one tagged manifest with all supported architectures

View file

@ -184,12 +184,11 @@ fn post_admin_login(data: Form<LoginForm>, cookies: &CookieJar<'_>, ip: ClientIp
let claims = generate_admin_claims(); let claims = generate_admin_claims();
let jwt = encode_jwt(&claims); let jwt = encode_jwt(&claims);
let cookie = Cookie::build(COOKIE_NAME, jwt) let cookie = Cookie::build((COOKIE_NAME, jwt))
.path(admin_path()) .path(admin_path())
.max_age(rocket::time::Duration::minutes(CONFIG.admin_session_lifetime())) .max_age(rocket::time::Duration::minutes(CONFIG.admin_session_lifetime()))
.same_site(SameSite::Strict) .same_site(SameSite::Strict)
.http_only(true) .http_only(true);
.finish();
cookies.add(cookie); cookies.add(cookie);
if let Some(redirect) = redirect { if let Some(redirect) = redirect {
@ -313,7 +312,7 @@ async fn test_smtp(data: Json<InviteData>, _token: AdminToken) -> EmptyResult {
#[get("/logout")] #[get("/logout")]
fn logout(cookies: &CookieJar<'_>) -> Redirect { fn logout(cookies: &CookieJar<'_>) -> Redirect {
cookies.remove(Cookie::build(COOKIE_NAME, "").path(admin_path()).finish()); cookies.remove(Cookie::build(COOKIE_NAME).path(admin_path()));
Redirect::to(admin_path()) Redirect::to(admin_path())
} }
@ -786,16 +785,16 @@ impl<'r> FromRequest<'r> for AdminToken {
if requested_page.is_empty() { if requested_page.is_empty() {
return Outcome::Forward(Status::Unauthorized); return Outcome::Forward(Status::Unauthorized);
} else { } else {
return Outcome::Failure((Status::Unauthorized, "Unauthorized")); return Outcome::Error((Status::Unauthorized, "Unauthorized"));
} }
} }
}; };
if decode_admin(access_token).is_err() { if decode_admin(access_token).is_err() {
// Remove admin cookie // Remove admin cookie
cookies.remove(Cookie::build(COOKIE_NAME, "").path(admin_path()).finish()); cookies.remove(Cookie::build(COOKIE_NAME).path(admin_path()));
error!("Invalid or expired admin JWT. IP: {}.", &ip.ip); error!("Invalid or expired admin JWT. IP: {}.", &ip.ip);
return Outcome::Failure((Status::Unauthorized, "Session expired")); return Outcome::Error((Status::Unauthorized, "Session expired"));
} }
Outcome::Success(Self { Outcome::Success(Self {

View file

@ -910,26 +910,23 @@ impl<'r> FromRequest<'r> for KnownDevice {
let email_bytes = match data_encoding::BASE64URL_NOPAD.decode(email_b64.as_bytes()) { let email_bytes = match data_encoding::BASE64URL_NOPAD.decode(email_b64.as_bytes()) {
Ok(bytes) => bytes, Ok(bytes) => bytes,
Err(_) => { Err(_) => {
return Outcome::Failure(( return Outcome::Error((Status::BadRequest, "X-Request-Email value failed to decode as base64url"));
Status::BadRequest,
"X-Request-Email value failed to decode as base64url",
));
} }
}; };
match String::from_utf8(email_bytes) { match String::from_utf8(email_bytes) {
Ok(email) => email, Ok(email) => email,
Err(_) => { Err(_) => {
return Outcome::Failure((Status::BadRequest, "X-Request-Email value failed to decode as UTF-8")); return Outcome::Error((Status::BadRequest, "X-Request-Email value failed to decode as UTF-8"));
} }
} }
} else { } else {
return Outcome::Failure((Status::BadRequest, "X-Request-Email value is required")); return Outcome::Error((Status::BadRequest, "X-Request-Email value is required"));
}; };
let uuid = if let Some(uuid) = req.headers().get_one("X-Device-Identifier") { let uuid = if let Some(uuid) = req.headers().get_one("X-Device-Identifier") {
uuid.to_string() uuid.to_string()
} else { } else {
return Outcome::Failure((Status::BadRequest, "X-Device-Identifier value is required")); return Outcome::Error((Status::BadRequest, "X-Device-Identifier value is required"));
}; };
Outcome::Success(KnownDevice { Outcome::Success(KnownDevice {

View file

@ -7,7 +7,6 @@ use diesel::{
use rocket::{ use rocket::{
http::Status, http::Status,
outcome::IntoOutcome,
request::{FromRequest, Outcome}, request::{FromRequest, Outcome},
Request, Request,
}; };
@ -413,8 +412,11 @@ impl<'r> FromRequest<'r> for DbConn {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> { async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match request.rocket().state::<DbPool>() { match request.rocket().state::<DbPool>() {
Some(p) => p.get().await.map_err(|_| ()).into_outcome(Status::ServiceUnavailable), Some(p) => match p.get().await {
None => Outcome::Failure((Status::InternalServerError, ())), Ok(dbconn) => Outcome::Success(dbconn),
_ => Outcome::Error((Status::ServiceUnavailable, ())),
},
None => Outcome::Error((Status::InternalServerError, ())),
} }
} }
} }

View file

@ -291,10 +291,10 @@ macro_rules! err_json {
macro_rules! err_handler { macro_rules! err_handler {
($expr:expr) => {{ ($expr:expr) => {{
error!(target: "auth", "Unauthorized Error: {}", $expr); error!(target: "auth", "Unauthorized Error: {}", $expr);
return ::rocket::request::Outcome::Failure((rocket::http::Status::Unauthorized, $expr)); return ::rocket::request::Outcome::Error((rocket::http::Status::Unauthorized, $expr));
}}; }};
($usr_msg:expr, $log_value:expr) => {{ ($usr_msg:expr, $log_value:expr) => {{
error!(target: "auth", "Unauthorized Error: {}. {}", $usr_msg, $log_value); error!(target: "auth", "Unauthorized Error: {}. {}", $usr_msg, $log_value);
return ::rocket::request::Outcome::Failure((rocket::http::Status::Unauthorized, $usr_msg)); return ::rocket::request::Outcome::Error((rocket::http::Status::Unauthorized, $usr_msg));
}}; }};
} }

View file

@ -46,6 +46,7 @@ impl Fairing for AppHeaders {
// Remove headers which could cause websocket connection issues // Remove headers which could cause websocket connection issues
res.remove_header("X-Frame-Options"); res.remove_header("X-Frame-Options");
res.remove_header("X-Content-Type-Options"); res.remove_header("X-Content-Type-Options");
res.remove_header("Permissions-Policy");
return; return;
} }
(_, _) => (), (_, _) => (),