aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex <alex@adnab.me>2024-02-13 10:04:49 +0000
committerAlex <alex@adnab.me>2024-02-13 10:04:49 +0000
commit823078b4cdaf93e09de0847c5eaa75beb7b26b7f (patch)
treeb7ff8f713f9cc8a897c15f4332e1ea6b71e8d889
parentea09b483fe7482f834d0ec8f8410325f6faf55a2 (diff)
parentbf283c99240787c7ffeba8ff3222283ee9fc61aa (diff)
downloadgarage-823078b4cdaf93e09de0847c5eaa75beb7b26b7f.tar.gz
garage-823078b4cdaf93e09de0847c5eaa75beb7b26b7f.zip
Merge pull request 'small fixes to config/secrets handling' (#715) from fix-secrets-695 into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/715
-rw-r--r--src/garage/main.rs23
-rw-r--r--src/garage/secrets.rs22
-rw-r--r--src/util/config.rs6
3 files changed, 30 insertions, 21 deletions
diff --git a/src/garage/main.rs b/src/garage/main.rs
index 5c92dae4..1a6a6e32 100644
--- a/src/garage/main.rs
+++ b/src/garage/main.rs
@@ -174,7 +174,9 @@ async fn main() {
}
async fn cli_command(opt: Opt) -> Result<(), Error> {
- let config = if opt.secrets.rpc_secret.is_none() || opt.rpc_host.is_none() {
+ let config = if (opt.secrets.rpc_secret.is_none() && opt.secrets.rpc_secret_file.is_none())
+ || opt.rpc_host.is_none()
+ {
Some(garage_util::config::read_config(opt.config_file.clone())
.err_context(format!("Unable to read configuration file {}. Configuration file is needed because -h or -s is not provided on the command line.", opt.config_file.to_string_lossy()))?)
} else {
@@ -182,14 +184,19 @@ async fn cli_command(opt: Opt) -> Result<(), Error> {
};
// Find and parse network RPC secret
- let net_key_hex_str = opt
- .secrets
- .rpc_secret
- .as_ref()
- .or_else(|| config.as_ref().and_then(|c| c.rpc_secret.as_ref()))
- .ok_or("No RPC secret provided")?;
+ let mut rpc_secret = config.as_ref().and_then(|c| c.rpc_secret.clone());
+ secrets::fill_secret(
+ &mut rpc_secret,
+ &config.as_ref().and_then(|c| c.rpc_secret_file.clone()),
+ &opt.secrets.rpc_secret,
+ &opt.secrets.rpc_secret_file,
+ "rpc_secret",
+ true,
+ )?;
+
+ let net_key_hex_str = rpc_secret.ok_or("No RPC secret provided")?;
let network_key = NetworkKey::from_slice(
- &hex::decode(net_key_hex_str).err_context("Invalid RPC secret key (bad hex)")?[..],
+ &hex::decode(&net_key_hex_str).err_context("Invalid RPC secret key (bad hex)")?[..],
)
.ok_or("Invalid RPC secret provided (wrong length)")?;
diff --git a/src/garage/secrets.rs b/src/garage/secrets.rs
index 8c89a262..c3d704aa 100644
--- a/src/garage/secrets.rs
+++ b/src/garage/secrets.rs
@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
use structopt::StructOpt;
use garage_util::config::Config;
@@ -23,7 +25,7 @@ pub struct Secrets {
/// RPC secret network key, used to replace rpc_secret in config.toml and rpc-secret
/// when running the daemon or doing admin operations
#[structopt(long = "rpc-secret-file", env = "GARAGE_RPC_SECRET_FILE")]
- pub rpc_secret_file: Option<String>,
+ pub rpc_secret_file: Option<PathBuf>,
/// Admin API authentication token, replaces admin.admin_token in config.toml when
/// running the Garage daemon
@@ -33,7 +35,7 @@ pub struct Secrets {
/// Admin API authentication token file path, replaces admin.admin_token in config.toml
/// and admin-token when running the Garage daemon
#[structopt(long = "admin-token-file", env = "GARAGE_ADMIN_TOKEN_FILE")]
- pub admin_token_file: Option<String>,
+ pub admin_token_file: Option<PathBuf>,
/// Metrics API authentication token, replaces admin.metrics_token in config.toml when
/// running the Garage daemon
@@ -43,7 +45,7 @@ pub struct Secrets {
/// Metrics API authentication token file path, replaces admin.metrics_token in config.toml
/// and metrics-token when running the Garage daemon
#[structopt(long = "metrics-token-file", env = "GARAGE_METRICS_TOKEN_FILE")]
- pub metrics_token_file: Option<String>,
+ pub metrics_token_file: Option<PathBuf>,
}
/// Single function to fill all secrets in the Config struct from their correct source (value
@@ -83,11 +85,11 @@ pub fn fill_secrets(mut config: Config, secrets: Secrets) -> Result<Config, Erro
Ok(config)
}
-fn fill_secret(
+pub(crate) fn fill_secret(
config_secret: &mut Option<String>,
- config_secret_file: &Option<String>,
+ config_secret_file: &Option<PathBuf>,
cli_secret: &Option<String>,
- cli_secret_file: &Option<String>,
+ cli_secret_file: &Option<PathBuf>,
name: &'static str,
allow_world_readable: bool,
) -> Result<(), Error> {
@@ -117,14 +119,14 @@ fn fill_secret(
Ok(())
}
-fn read_secret_file(file_path: &String, allow_world_readable: bool) -> Result<String, Error> {
+fn read_secret_file(file_path: &PathBuf, allow_world_readable: bool) -> Result<String, Error> {
if !allow_world_readable {
#[cfg(unix)]
{
use std::os::unix::fs::MetadataExt;
let metadata = std::fs::metadata(file_path)?;
if metadata.mode() & 0o077 != 0 {
- return Err(format!("File {} is world-readable! (mode: 0{:o}, expected 0600)\nRefusing to start until this is fixed, or environment variable GARAGE_ALLOW_WORLD_READABLE_SECRETS is set to true.", file_path, metadata.mode()).into());
+ return Err(format!("File {} is world-readable! (mode: 0{:o}, expected 0600)\nRefusing to start until this is fixed, or environment variable GARAGE_ALLOW_WORLD_READABLE_SECRETS is set to true.", file_path.display(), metadata.mode()).into());
}
}
}
@@ -260,7 +262,7 @@ mod tests {
let config = fill_secrets(
config,
Secrets {
- rpc_secret_file: Some(path_secret2.display().to_string()),
+ rpc_secret_file: Some(path_secret2.clone()),
..Default::default()
},
)?;
@@ -271,7 +273,7 @@ mod tests {
config,
Secrets {
rpc_secret: Some("baz".into()),
- rpc_secret_file: Some(path_secret2.display().to_string()),
+ rpc_secret_file: Some(path_secret2.clone()),
..Default::default()
}
)
diff --git a/src/util/config.rs b/src/util/config.rs
index 65c0b5c0..a9a72110 100644
--- a/src/util/config.rs
+++ b/src/util/config.rs
@@ -52,7 +52,7 @@ pub struct Config {
/// RPC secret key: 32 bytes hex encoded
pub rpc_secret: Option<String>,
/// Optional file where RPC secret key is read from
- pub rpc_secret_file: Option<String>,
+ pub rpc_secret_file: Option<PathBuf>,
/// Address to bind for RPC
pub rpc_bind_addr: SocketAddr,
/// Public IP address of this node
@@ -166,12 +166,12 @@ pub struct AdminConfig {
/// Bearer token to use to scrape metrics
pub metrics_token: Option<String>,
/// File to read metrics token from
- pub metrics_token_file: Option<String>,
+ pub metrics_token_file: Option<PathBuf>,
/// Bearer token to use to access Admin API endpoints
pub admin_token: Option<String>,
/// File to read admin token from
- pub admin_token_file: Option<String>,
+ pub admin_token_file: Option<PathBuf>,
/// OTLP server to where to export traces
pub trace_sink: Option<String>,