Skip to content

Instantly share code, notes, and snippets.

@erickt
Last active July 30, 2018 17:04
Show Gist options
  • Save erickt/2b65ed09f6d9d7c42f172751d3f39e44 to your computer and use it in GitHub Desktop.
Save erickt/2b65ed09f6d9d7c42f172751d3f39e44 to your computer and use it in GitHub Desktop.
/// Returns `true` if an update occurred and `false` otherwise.
fn update_root<V, U>(&self, repo: Arc<V>, config: &Config<U>) -> TufFuture<bool>
where
V: Repository<D> + 'static,
U: PathTranslator,
{
let err_msg = "TUF claimed no update occurred when one should have. \
This is a programming error. Please report this as a bug.";
let tuf = self.tuf.clone();
let max_root_size = config.max_root_size;
let min_bytes_per_second = config.min_bytes_per_second;
let updated =
repo.fetch_metadata(
&MetadataPath::from_role(&Role::Root),
&MetadataVersion::None,
max_root_size,
min_bytes_per_second,
None,
)
.and_then(move |latest_root| {
let latest_version =
D::deserialize::<RootMetadata>(latest_root.signed())?.version();
let root_version = {
let tuf = tuf.lock().expect("poisoned lock");
tuf.root().version()
};
if latest_version < root_version {
return Err(Error::VerificationFailure(format!(
"Latest root version is lower than current root version: {} < {}",
latest_version, root_version,
)));
} else if latest_version == root_version {
return Ok(Either::A(future::ok(false)));
}
let mut updated_roots = Vec::new();
for i in (root_version + 1)..latest_version {
let tuf = tuf.clone();
updated_roots.push(
repo
.fetch_metadata(
&MetadataPath::from_role(&Role::Root),
&MetadataVersion::Number(i),
max_root_size,
min_bytes_per_second,
None,
)
.map(move |signed| {
let mut tuf = tuf.lock().expect("poisoned lock");
if !tuf.update_root(&signed)? {
error!("{}", err_msg);
return Err(Error::Programming(err_msg.into()));
}
Ok(())
}),
);
}
Ok(Either::B(future::join_all(updated_roots).and_then(
move |_| {
let mut tuf = tuf.lock().expect("poisoned lock");
if !tuf.update_root(&latest_root)? {
error!("{}", err_msg);
return Err(Error::Programming(err_msg.into()));
}
Ok(true)
}
)))
})
.flatten();
Box::new(updated)
}
/// Returns `true` if an update occurred and `false` otherwise.
fn update_timestamp<V, U>(&self, repo: &mut V, config: &Config<U>) -> Result<TufFuture<bool>>
where
V: Repository<D>,
U: PathTranslator,
{
let tuf = self.tuf.clone();
let ts = repo
.fetch_metadata(
&MetadataPath::from_role(&Role::Timestamp),
&MetadataVersion::None,
config.max_timestamp_size,
config.min_bytes_per_second,
None,
)
.and_then(move |ts| {
let mut tuf = tuf.lock().expect("poisoned lock");
tuf.update_timestamp(&ts)
});
Ok(Box::new(ts))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment