Add OnlineSource and MapfileSource
OnlineSource: the remote key-service client (moved out of autorip), posting the disc's Unit_Key_RO.inf + MKB + Volume ID + encrypted content samples to the service and returning the resolved unit key as a terminal Key::Unit candidate. Kept out of libfreemkv so the library stays network-free. Source-internal failures (unreachable / status / parse) are logged and surface as "no candidate" so the next source is tried. MapfileSource: reads a rip mapfile's persisted unit keys (the resume / deferred- mux fast path) and offers them as a Key::Unit candidate. Keyed by mapfile path. DiscInputs gained an app-populated `samples` field for sources that validate against ciphertext server-side (OnlineSource); local sources ignore it.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
//! Mapfile cache source (source #3).
|
||||
//!
|
||||
//! A rip's ddrescue-style mapfile persists the resolved unit keys in its
|
||||
//! `# freemkv-uk:` header (written at sweep time when the disc was keyed). On
|
||||
//! resume / deferred mux, that mapfile is the fastest source — the keys are
|
||||
//! already resolved, no keydb parse and no network round-trip. This source
|
||||
//! reads them back as a terminal [`Key::Unit`] candidate.
|
||||
//!
|
||||
//! It is keyed by the mapfile path (the disc identity is implicit in which
|
||||
//! mapfile belongs to which rip), so it ignores [`DiscInputs`].
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use libfreemkv::disc::mapfile::Mapfile;
|
||||
use libfreemkv::{DiscInputs, Key, KeySource, Result};
|
||||
|
||||
/// A [`KeySource`] backed by a rip mapfile's persisted unit keys.
|
||||
pub struct MapfileSource {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl MapfileSource {
|
||||
/// A mapfile source reading the given `*.mapfile` path.
|
||||
pub fn new(path: impl Into<PathBuf>) -> Self {
|
||||
Self { path: path.into() }
|
||||
}
|
||||
}
|
||||
|
||||
impl KeySource for MapfileSource {
|
||||
fn resolve(&self, _inputs: &DiscInputs) -> Result<Vec<Key>> {
|
||||
// A missing/unreadable/keyless mapfile simply offers nothing.
|
||||
let Ok(map) = Mapfile::load(&self.path) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let uks = map.unit_keys();
|
||||
if uks.is_empty() {
|
||||
Ok(Vec::new())
|
||||
} else {
|
||||
Ok(vec![Key::Unit(uks.to_vec())])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user