set file permissions on tempfile persist rather than creation

This commit is contained in:
Vincent Breitmoser 2019-05-05 17:01:12 +02:00
parent 8e2ccea22e
commit d005c7e283
2 changed files with 13 additions and 19 deletions

View File

@ -1,8 +1,9 @@
use std::collections::HashMap;
use std::convert::TryFrom;
use std::fs::{create_dir_all, read_link, remove_file, rename};
use std::fs::{create_dir_all, read_link, remove_file, rename, set_permissions, Permissions};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::os::unix::fs::PermissionsExt;
use tempfile;
use url;
@ -361,31 +362,24 @@ impl Database for Filesystem {
FlockMutexGuard::lock(&self.keys_internal_dir)
}
fn write_to_temp(&self, content: &[u8], public: bool) -> Result<NamedTempFile> {
fn write_to_temp(&self, content: &[u8]) -> Result<NamedTempFile> {
let mut tempfile = tempfile::Builder::new()
.prefix("key")
.rand_bytes(16)
.tempfile_in(&self.tmp_dir)?;
tempfile.write_all(content).unwrap();
// fix permissions to 644 or 640, depending on "public" value
if cfg!(unix) {
use std::fs::{set_permissions, Permissions};
use std::os::unix::fs::PermissionsExt;
let perm = Permissions::from_mode(if public { 0o644 } else { 0o640 });
set_permissions(tempfile.path(), perm)?;
}
Ok(tempfile)
}
fn move_tmp_to_full(&self, file: NamedTempFile, fpr: &Fingerprint) -> Result<()> {
set_permissions(file.path(), Permissions::from_mode(0o640))?;
let target = self.fingerprint_to_path_full(fpr);
file.persist(ensure_parent(&target)?)?;
Ok(())
}
fn move_tmp_to_published(&self, file: NamedTempFile, fpr: &Fingerprint) -> Result<()> {
set_permissions(file.path(), Permissions::from_mode(0o644))?;
let target = self.fingerprint_to_path_published(fpr);
file.persist(ensure_parent(&target)?)?;
Ok(())

View File

@ -244,9 +244,6 @@ pub trait Database: Sync + Send {
.map(|fpr| Fingerprint::try_from(fpr))
.flatten();
let full_tpk_tmp = self.write_to_temp(&tpk_to_string(&full_tpk_new)?, false)?;
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?, true)?;
let fpr_checks = fingerprints
.map(|fpr| self.check_link_fpr(&fpr, &fpr_primary))
.collect::<Vec<_>>()
@ -254,6 +251,9 @@ pub trait Database: Sync + Send {
.collect::<Result<Vec<_>>>()?;
let fpr_not_linked = fpr_checks.into_iter().flatten();
let full_tpk_tmp = self.write_to_temp(&tpk_to_string(&full_tpk_new)?)?;
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?)?;
// these are very unlikely to fail. but if it happens,
// database consistency might be compromised!
self.move_tmp_to_full(full_tpk_tmp, &fpr_primary)?;
@ -364,7 +364,7 @@ pub trait Database: Sync + Send {
return Err(failure::err_msg("Requested UserID not found!"));
}
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?, false)?;
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?)?;
self.move_tmp_to_published(published_tpk_tmp, &fpr_primary)?;
@ -422,7 +422,7 @@ pub trait Database: Sync + Send {
.iter()
.filter(|email| !published_emails_new.contains(email));
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?, false)?;
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_new)?)?;
self.move_tmp_to_published(published_tpk_tmp, &fpr_primary)?;
@ -457,7 +457,7 @@ pub trait Database: Sync + Send {
fn by_fpr_full(&self, fpr: &Fingerprint) -> Option<String>;
fn write_to_temp(&self, content: &[u8], public: bool) -> Result<NamedTempFile>;
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<()>;
}