mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-28 06:23:08 -08:00
proper permission for secrets aka 0o600
When creating secret keys or use the out file feature, the material shouldn't be readble to everyone by default. Fix: #260 Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
@@ -4,7 +4,7 @@ use anyhow::Result;
|
|||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use mio::Interest;
|
use mio::Interest;
|
||||||
use mio::Token;
|
use mio::Token;
|
||||||
use rosenpass_util::file::fopen_w;
|
use rosenpass_util::file::{fopen_w, Visibility};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
@@ -609,7 +609,7 @@ impl AppServer {
|
|||||||
// data will linger in the linux page cache anyways with the current
|
// data will linger in the linux page cache anyways with the current
|
||||||
// implementation, going to great length to erase the secret here is
|
// implementation, going to great length to erase the secret here is
|
||||||
// not worth it right now.
|
// not worth it right now.
|
||||||
b64_writer(fopen_w(of)?).write_all(key.secret())?;
|
b64_writer(fopen_w(of, Visibility::Secret)?).write_all(key.secret())?;
|
||||||
let why = match why {
|
let why = match why {
|
||||||
KeyOutputReason::Exchanged => "exchanged",
|
KeyOutputReason::Exchanged => "exchanged",
|
||||||
KeyOutputReason::Stale => "stale",
|
KeyOutputReason::Stale => "stale",
|
||||||
|
|||||||
@@ -334,5 +334,5 @@ fn generate_and_save_keypair(secret_key: PathBuf, public_key: PathBuf) -> anyhow
|
|||||||
let mut spk = crate::protocol::SPk::random();
|
let mut spk = crate::protocol::SPk::random();
|
||||||
StaticKem::keygen(ssk.secret_mut(), spk.secret_mut())?;
|
StaticKem::keygen(ssk.secret_mut(), spk.secret_mut())?;
|
||||||
ssk.store_secret(secret_key)?;
|
ssk.store_secret(secret_key)?;
|
||||||
spk.store_secret(public_key)
|
spk.store(public_key)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{bail, ensure};
|
use anyhow::{bail, ensure};
|
||||||
use rosenpass_util::file::fopen_w;
|
use rosenpass_util::file::{fopen_w, Visibility};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@@ -151,7 +151,7 @@ impl Rosenpass {
|
|||||||
|
|
||||||
/// Commit the configuration to where it came from, overwriting the original file
|
/// Commit the configuration to where it came from, overwriting the original file
|
||||||
pub fn commit(&self) -> anyhow::Result<()> {
|
pub fn commit(&self) -> anyhow::Result<()> {
|
||||||
let mut f = fopen_w(&self.config_file_path)?;
|
let mut f = fopen_w(&self.config_file_path, Visibility::Public)?;
|
||||||
f.write_all(toml::to_string_pretty(&self)?.as_bytes())?;
|
f.write_all(toml::to_string_pretty(&self)?.as_bytes())?;
|
||||||
|
|
||||||
self.store(&self.config_file_path)
|
self.store(&self.config_file_path)
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ pub trait StoreSecret {
|
|||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
fn store_secret<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error>;
|
fn store_secret<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error>;
|
||||||
|
fn store<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ use rosenpass_util::functional::mutating;
|
|||||||
use crate::alloc::{secret_box, SecretBox, SecretVec};
|
use crate::alloc::{secret_box, SecretBox, SecretVec};
|
||||||
use crate::file::StoreSecret;
|
use crate::file::StoreSecret;
|
||||||
|
|
||||||
|
use rosenpass_util::file::{fopen_w, Visibility};
|
||||||
|
use std::io::Write;
|
||||||
// This might become a problem in library usage; it's effectively a memory
|
// This might become a problem in library usage; it's effectively a memory
|
||||||
// leak which probably isn't a problem right now because most memory will
|
// leak which probably isn't a problem right now because most memory will
|
||||||
// be reused…
|
// be reused…
|
||||||
@@ -272,7 +274,12 @@ impl<const N: usize> StoreSecret for Secret<N> {
|
|||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
||||||
std::fs::write(path, self.secret())?;
|
fopen_w(path, Visibility::Secret)?.write_all(self.secret())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
|
||||||
|
fopen_w(path, Visibility::Public)?.write_all(self.secret())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,24 @@
|
|||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::os::unix::fs::OpenOptionsExt;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::{fs::OpenOptions, path::Path};
|
use std::{fs::OpenOptions, path::Path};
|
||||||
|
|
||||||
|
pub enum Visibility {
|
||||||
|
Public,
|
||||||
|
Secret,
|
||||||
|
}
|
||||||
|
|
||||||
/// Open a file writable
|
/// Open a file writable
|
||||||
pub fn fopen_w<P: AsRef<Path>>(path: P) -> std::io::Result<File> {
|
pub fn fopen_w<P: AsRef<Path>>(path: P, visibility: Visibility) -> std::io::Result<File> {
|
||||||
OpenOptions::new()
|
let mut options = OpenOptions::new();
|
||||||
.read(false)
|
options.create(true).write(true).read(false).truncate(true);
|
||||||
.write(true)
|
match visibility {
|
||||||
.create(true)
|
Visibility::Public => options.mode(0o644),
|
||||||
.truncate(true)
|
Visibility::Secret => options.mode(0o600),
|
||||||
.open(path)
|
};
|
||||||
|
options.open(path)
|
||||||
}
|
}
|
||||||
/// Open a file readable
|
/// Open a file readable
|
||||||
pub fn fopen_r<P: AsRef<Path>>(path: P) -> std::io::Result<File> {
|
pub fn fopen_r<P: AsRef<Path>>(path: P) -> std::io::Result<File> {
|
||||||
|
|||||||
Reference in New Issue
Block a user