feat(hololake): bind release chain to public path namespace
This commit is contained in:
parent
ba80036282
commit
9006075310
13 changed files with 223 additions and 29 deletions
|
|
@ -3,6 +3,7 @@ use tauri::{AppHandle, Runtime, Url};
|
|||
use tauri_plugin_updater::UpdaterExt;
|
||||
|
||||
const EMBEDDED_RELEASE_TRUST: &str = include_str!("../release-trust.json");
|
||||
const PUBLIC_RELEASE_ENDPOINT_PATH: &str = "/hololake/releases/latest.json";
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
|
|
@ -108,6 +109,12 @@ fn validate_release_trust(raw: &str) -> Result<ValidatedReleaseTrust, String> {
|
|||
"the updater endpoint is not owned by the configured HoloLake host".into(),
|
||||
);
|
||||
}
|
||||
if endpoint.path() != PUBLIC_RELEASE_ENDPOINT_PATH
|
||||
|| endpoint.query().is_some()
|
||||
|| endpoint.fragment().is_some()
|
||||
{
|
||||
return Err("the HoloLake release endpoint path is not registered".into());
|
||||
}
|
||||
Ok(ValidatedReleaseTrust::Enabled {
|
||||
endpoints: vec![endpoint],
|
||||
public_key: trust.public_key,
|
||||
|
|
@ -166,7 +173,7 @@ mod tests {
|
|||
fn accepts_https_shape_but_rejects_insecure_endpoints() {
|
||||
let owned_shape = document(
|
||||
"PROVISIONED",
|
||||
"\"https://releases.example.test/latest.json\"",
|
||||
"\"https://releases.example.test/hololake/releases/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
|
|
@ -176,18 +183,25 @@ mod tests {
|
|||
);
|
||||
let insecure = document(
|
||||
"PROVISIONED",
|
||||
"\"http://releases.example.test/latest.json\"",
|
||||
"\"http://releases.example.test/hololake/releases/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(validate_release_trust(&insecure).is_err());
|
||||
let mismatched_host = document(
|
||||
"PROVISIONED",
|
||||
"\"https://upstream.example.test/latest.json\"",
|
||||
"\"https://upstream.example.test/hololake/releases/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(validate_release_trust(&mismatched_host).is_err());
|
||||
let mismatched_path = document(
|
||||
"PROVISIONED",
|
||||
"\"https://releases.example.test/latest.json\"",
|
||||
"public",
|
||||
"\"releases.example.test\"",
|
||||
);
|
||||
assert!(validate_release_trust(&mismatched_path).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const RECEIPT_SCHEMA: &str = "hololake.release-install-receipt/v1";
|
|||
const RECOVERY_SCHEMA: &str = "hololake.release-recovery/v1";
|
||||
const CANDIDATE_TTL_MS: u128 = 30 * 60 * 1000;
|
||||
const EXPECTED_BUNDLE_IDENTIFIER: &str = "world.guanghu.hololake";
|
||||
const PUBLIC_RELEASE_PACKAGE_PREFIX: &str = "/hololake/releases/";
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
|
|
@ -472,7 +473,12 @@ fn validate_update(update: &Update, allowed_host: &str) -> Result<UpdateSnapshot
|
|||
return Err("HOLOLAKE_RELEASE_BROADCAST_POLICY_INVALID".into());
|
||||
}
|
||||
let url = &update.download_url;
|
||||
if url.scheme() != "https" || url.host_str() != Some(allowed_host) {
|
||||
if url.scheme() != "https"
|
||||
|| url.host_str() != Some(allowed_host)
|
||||
|| !url.path().starts_with(PUBLIC_RELEASE_PACKAGE_PREFIX)
|
||||
|| url.query().is_some()
|
||||
|| url.fragment().is_some()
|
||||
{
|
||||
return Err("HOLOLAKE_RELEASE_PACKAGE_HOST_NOT_TRUSTED".into());
|
||||
}
|
||||
let platform = envelope
|
||||
|
|
|
|||
Loading…
Reference in a new issue