Veröffentlichte Quellen
Quellen als ZIP herunterladen
CH-J Tools
Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.
CH-J / Server Manager
872 Dateien
core-20261030T220507Z-61e4558d889f
Hinzugefügt: · Erstellt:
1
//! HTTPS transport for update and module catalogs (port of `security/testHttpsFetch.js`).2
//!3
//! * only explicitly allowed HTTPS origins, TLS 1.2–1.3, no automatic redirects;4
//! * the owner-approved certificate exception applies to exactly one legacy origin5
//! (`https://sm.ch-j.de/`), unchanged from 0.1.0. Integrity of Core updates never relies6
//! on transport: payloads are verified by SHA-512 and an OpenPGP signature.8
use crate::core::error::{CoreError, CoreResult};9
use std::collections::HashSet;10
use std::time::Duration;11
use url::Url;13
pub const INSECURE_LEGACY_ORIGINS: [&str; 1] = ["https://sm.ch-j.de/"];15
fn origin_of(value: &str) -> CoreResult<String> {16
let url = Url::parse(value).map_err(|_| CoreError::plain("Invalid HTTPS origin."))?;17
if url.scheme() != "https" {18
return Err(CoreError::plain("Test update transport accepts HTTPS origins only."));19
}20
Ok(url.origin().ascii_serialization())21
}23
pub struct HttpsClient {24
allowed: HashSet<String>,25
insecure: HashSet<String>,26
strict: reqwest::Client,27
legacy: reqwest::Client,28
}30
fn builder() -> reqwest::ClientBuilder {31
reqwest::Client::builder()32
.redirect(reqwest::redirect::Policy::none())33
.min_tls_version(reqwest::tls::Version::TLS_1_2)34
.use_rustls_tls()35
.no_proxy()36
.connect_timeout(Duration::from_secs(10))37
.user_agent(concat!("CH-J-Server-Manager/", env!("CARGO_PKG_VERSION")))38
}40
impl HttpsClient {41
pub fn new(allowed_base_urls: &[String], insecure_base_urls: &[&str]) -> CoreResult<Self> {42
let allowed = allowed_base_urls.iter().map(|u| origin_of(u)).collect::<CoreResult<HashSet<_>>>()?;43
if allowed.is_empty() {44
return Err(CoreError::plain("At least one test HTTPS origin is required."));45
}46
let insecure = insecure_base_urls.iter().map(|u| origin_of(u)).collect::<CoreResult<HashSet<_>>>()?;47
if insecure.iter().any(|o| !allowed.contains(o)) {48
return Err(CoreError::plain("An insecure test origin must also be explicitly allowed."));49
}50
let strict = builder().build().map_err(|e| CoreError::plain(e.to_string()))?;51
let legacy = builder().danger_accept_invalid_certs(true).build().map_err(|e| CoreError::plain(e.to_string()))?;52
Ok(Self { allowed, insecure, strict, legacy })53
}55
pub fn client_for(&self, url: &Url) -> CoreResult<&reqwest::Client> {56
let origin = url.origin().ascii_serialization();57
if url.scheme() != "https" || !self.allowed.contains(&origin) {58
return Err(CoreError::plain("Test HTTPS request is outside the allowed origins."));59
}60
Ok(if self.insecure.contains(&origin) { &self.legacy } else { &self.strict })61
}63
pub async fn get(&self, url: &Url, accept: &str, timeout: Duration) -> CoreResult<reqwest::Response> {64
self.client_for(url)?65
.get(url.clone())66
.header(reqwest::header::ACCEPT, accept)67
.timeout(timeout)68
.send()69
.await70
.map_err(|e| CoreError::plain(if e.is_timeout() { "Request timeout.".to_string() } else { e.to_string() }))71
}73
/// GET with a hard size limit on the decoded body.74
pub async fn get_text(&self, url: &Url, accept: &str, timeout: Duration, max_bytes: usize) -> CoreResult<(u16, String)> {75
let response = self.get(url, accept, timeout).await?;76
let status = response.status().as_u16();77
if response.content_length().map(|l| l as usize > max_bytes).unwrap_or(false) {78
return Err(CoreError::plain("Response is too large."));79
}80
let mut body = Vec::new();81
let mut response = response;82
while let Some(chunk) = response.chunk().await.map_err(|e| CoreError::plain(e.to_string()))? {83
body.extend_from_slice(&chunk);84
if body.len() > max_bytes {85
return Err(CoreError::plain("Response is too large."));86
}87
}88
Ok((status, String::from_utf8_lossy(&body).to_string()))89
}90
}SHA-256
5f235a96f0c34d18cb639ab9c0359c03cdbe4705932a4a6334e75ce77bb639e1CH-J Proprietary Software License 1.14 · Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.
SHA-256 des Archivs
77380d4805485ffa4027fbe7858b5836f197a4aa9d52358a43e2d12d018744df