db: add "quarantine" capability

This commit is contained in:
Vincent Breitmoser 2019-06-04 20:02:52 +02:00
parent cae1d16b77
commit 0a56cc8824
2 changed files with 31 additions and 1 deletions

View File

@ -26,6 +26,7 @@ pub struct Filesystem {
keys_internal_dir: PathBuf,
keys_external_dir: PathBuf,
keys_dir_full: PathBuf,
keys_dir_quarantined: PathBuf,
keys_dir_published: PathBuf,
links_dir_by_fingerprint: PathBuf,
@ -94,8 +95,10 @@ impl Filesystem {
let keys_internal_dir: PathBuf = keys_internal_dir.into();
let keys_external_dir: PathBuf = keys_external_dir.into();
let keys_dir_full = keys_internal_dir.join("full");
let keys_dir_quarantined = keys_internal_dir.join("quarantined");
let keys_dir_published = keys_external_dir.join("published");
create_dir_all(&keys_dir_full)?;
create_dir_all(&keys_dir_quarantined)?;
create_dir_all(&keys_dir_published)?;
let links_dir_by_keyid = keys_external_dir.join("by-keyid");
@ -116,6 +119,7 @@ impl Filesystem {
keys_dir_full,
keys_dir_published,
keys_dir_quarantined,
links_dir_by_keyid,
links_dir_by_fingerprint,
@ -129,6 +133,12 @@ impl Filesystem {
self.keys_dir_full.join(path_split(&hex))
}
/// Returns the path to the given Fingerprint.
fn fingerprint_to_path_quarantined(&self, fingerprint: &Fingerprint) -> PathBuf {
let hex = fingerprint.to_string();
self.keys_dir_quarantined.join(&hex)
}
/// Returns the path to the given Fingerprint.
fn fingerprint_to_path_published(&self, fingerprint: &Fingerprint) -> PathBuf {
let hex = fingerprint.to_string();
@ -385,6 +395,19 @@ impl Database for Filesystem {
Ok(())
}
fn write_to_quarantine(&self, fpr: &Fingerprint, content: &[u8]) -> Result<()> {
let mut tempfile = tempfile::Builder::new()
.prefix("key")
.rand_bytes(16)
.tempfile_in(&self.tmp_dir)?;
tempfile.write_all(content).unwrap();
let target = self.fingerprint_to_path_quarantined(fpr);
tempfile.persist(ensure_parent(&target)?)?;
Ok(())
}
fn check_link_fpr(&self, fpr: &Fingerprint, fpr_target: &Fingerprint) -> Result<Option<Fingerprint>> {
let link_keyid = self.link_by_keyid(&fpr.into());
let link_fpr = self.link_by_fingerprint(&fpr);

View File

@ -258,7 +258,13 @@ pub trait Database: Sync + Send {
.map(|fpr| self.check_link_fpr(&fpr, &fpr_primary))
.collect::<Vec<_>>()
.into_iter()
.collect::<Result<Vec<_>>>()?;
.collect::<Result<Vec<_>>>();
if fpr_checks.is_err() {
self.write_to_quarantine(&fpr_primary, &tpk_to_string(&full_tpk_new)?)?;
}
let fpr_checks = fpr_checks?;
let fpr_not_linked = fpr_checks.into_iter().flatten();
let full_tpk_tmp = self.write_to_temp(&tpk_to_string(&full_tpk_new)?)?;
@ -479,4 +485,5 @@ pub trait Database: Sync + Send {
fn write_to_temp(&self, content: &[u8]) -> Result<NamedTempFile>;
fn move_tmp_to_full(&self, content: NamedTempFile, fpr: &Fingerprint) -> Result<()>;
fn move_tmp_to_published(&self, content: NamedTempFile, fpr: &Fingerprint) -> Result<()>;
fn write_to_quarantine(&self, fpr: &Fingerprint, content: &[u8]) -> Result<()>;
}