apt: move the keyserver lookup URL to data/keyserver.yml
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
## Keyserver lookup endpoint used to fetch PPA signing keys.
|
||||||
|
## Like host_keys.yml, this file exists so that a static endpoint is data,
|
||||||
|
## updatable in one reviewable place, instead of hardcoded in the source —
|
||||||
|
## the URL was previously duplicated in the apt keyring and release
|
||||||
|
## modules. Sparse on purpose: it grows if keyserver pools or alternates
|
||||||
|
## ever need to be tried.
|
||||||
|
##
|
||||||
|
## The template carries its variable part as a {fingerprint} placeholder,
|
||||||
|
## substituted by the accessor of src/apt/keyring.rs with plain string
|
||||||
|
## replacement.
|
||||||
|
##
|
||||||
|
## Where the value comes from: keyserver.ubuntu.com, Ubuntu's OpenPKS
|
||||||
|
## (formerly SKS) keyserver; op=get with search=0x<fingerprint> is the
|
||||||
|
## documented machine interface fetching one key by fingerprint
|
||||||
|
## (https://keyserver.ubuntu.com).
|
||||||
|
|
||||||
|
lookup_template: "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{fingerprint}"
|
||||||
+32
-4
@@ -4,6 +4,7 @@
|
|||||||
//! for mmdebstrap operations and for PPA packages by downloading them.
|
//! for mmdebstrap operations and for PPA packages by downloading them.
|
||||||
|
|
||||||
use crate::context;
|
use crate::context;
|
||||||
|
use crate::data::embed_data;
|
||||||
use crate::distro_info;
|
use crate::distro_info;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@@ -11,6 +12,26 @@ use std::os::unix::fs::MetadataExt;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
/// Keyserver endpoint, loaded from the bundled `keyserver.yml` data file
|
||||||
|
/// (same pattern as `distro_info.yml`): the lookup URL is a static
|
||||||
|
/// endpoint that was previously hardcoded in two modules.
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct KeyserverData {
|
||||||
|
/// OpenPGP key lookup URL template (`{fingerprint}`)
|
||||||
|
lookup_template: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
embed_data! {
|
||||||
|
static ref KEYSERVER_DATA: KeyserverData = "../../data/keyserver.yml"
|
||||||
|
}
|
||||||
|
|
||||||
|
/// URL fetching the OpenPGP key of `fingerprint` from the keyserver
|
||||||
|
pub(crate) fn keyserver_lookup_url(fingerprint: &str) -> String {
|
||||||
|
KEYSERVER_DATA
|
||||||
|
.lookup_template
|
||||||
|
.replace("{fingerprint}", fingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
/// Launchpad API response structure for PPA information
|
/// Launchpad API response structure for PPA information
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct LaunchpadPpaResponse {
|
struct LaunchpadPpaResponse {
|
||||||
@@ -276,10 +297,7 @@ pub async fn download_trust_ppa_key(
|
|||||||
log::debug!("Found PPA signing key fingerprint: {}", fingerprint);
|
log::debug!("Found PPA signing key fingerprint: {}", fingerprint);
|
||||||
|
|
||||||
// Download the actual key from the keyserver using the fingerprint
|
// Download the actual key from the keyserver using the fingerprint
|
||||||
let keyserver_url = format!(
|
let keyserver_url = keyserver_lookup_url(&fingerprint);
|
||||||
"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{}",
|
|
||||||
fingerprint
|
|
||||||
);
|
|
||||||
log::debug!("Downloading key from keyserver: {}", keyserver_url);
|
log::debug!("Downloading key from keyserver: {}", keyserver_url);
|
||||||
|
|
||||||
let mut curl_cmd = ctx.command("curl");
|
let mut curl_cmd = ctx.command("curl");
|
||||||
@@ -314,6 +332,16 @@ pub async fn download_trust_ppa_key(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// The data-driven template renders the lookup URL the hardcoded
|
||||||
|
/// format! used to build (verified against the live keyserver)
|
||||||
|
#[test]
|
||||||
|
fn keyserver_lookup_url_substitutes_the_fingerprint() {
|
||||||
|
assert_eq!(
|
||||||
|
keyserver_lookup_url("0123456789ABCDEF"),
|
||||||
|
"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0123456789ABCDEF"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_validate_keyring_dir_accepts_private_dir_owned_by_current_user() {
|
fn test_validate_keyring_dir_accepts_private_dir_owned_by_current_user() {
|
||||||
assert!(validate_keyring_dir(1000, 0o700, 1000).is_ok());
|
assert!(validate_keyring_dir(1000, 0o700, 1000).is_ok());
|
||||||
|
|||||||
+1
-1
@@ -905,7 +905,7 @@ pub async fn ppa_keyring_bytes(
|
|||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let key_url = format!("https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{fingerprint}");
|
let key_url = crate::apt::keyring::keyserver_lookup_url(&fingerprint);
|
||||||
let armored = fetch_keyring_cached(&key_url).await?;
|
let armored = fetch_keyring_cached(&key_url).await?;
|
||||||
let keyring = dearmor(&armored)
|
let keyring = dearmor(&armored)
|
||||||
.map_err(|e| format!("invalid PGP armor in the key of PPA '{owner}/{name}': {e}"))?;
|
.map_err(|e| format!("invalid PGP armor in the key of PPA '{owner}/{name}': {e}"))?;
|
||||||
|
|||||||
+3
-2
@@ -7,8 +7,9 @@
|
|||||||
//!
|
//!
|
||||||
//! This module is deliberately not a central registry: each file is
|
//! This module is deliberately not a central registry: each file is
|
||||||
//! embedded by the module that owns it (distro_info.rs owns
|
//! embedded by the module that owns it (distro_info.rs owns
|
||||||
//! data/distro_info.yml, launchpad.rs owns data/launchpad.yml, put/ssh.rs
|
//! data/distro_info.yml, launchpad.rs owns data/launchpad.yml,
|
||||||
//! owns data/host_keys.yml, quirks.rs owns data/quirks.yml) through the
|
//! apt/keyring.rs owns data/keyserver.yml, put/ssh.rs owns
|
||||||
|
//! data/host_keys.yml, quirks.rs owns data/quirks.yml) through the
|
||||||
//! [`embed_data!`] macro below, so data
|
//! [`embed_data!`] macro below, so data
|
||||||
//! and its accessors stay together and a diff touching one domain cannot
|
//! and its accessors stay together and a diff touching one domain cannot
|
||||||
//! half-touch another. The macro embeds the file at compile time and
|
//! half-touch another. The macro embeds the file at compile time and
|
||||||
|
|||||||
Reference in New Issue
Block a user