use clap::{Parser, Subcommand};
use keyquorum::{client, daemon};
use std::path::PathBuf;
#[derive(Parser)]
#[command(
name = "keyquorum",
about = "Shamir secret sharing daemon for distributed key quorum",
version
)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Daemon {
#[arg(short, long, default_value = "/etc/keyquorum/config.toml")]
config: PathBuf,
#[arg(long)]
lockdown: bool,
#[arg(long)]
no_strict_hardening: bool,
},
Submit {
#[arg(short = 'u', long)]
user: Option<String>,
#[arg(long)]
socket: Option<String>,
#[arg(short, long)]
config: Option<PathBuf>,
},
Status {
#[arg(long)]
socket: Option<String>,
#[arg(short, long)]
config: Option<PathBuf>,
},
}
fn resolve_socket(socket: Option<String>, config: Option<PathBuf>) -> anyhow::Result<String> {
if let Some(s) = socket {
return Ok(s);
}
if let Some(path) = config {
let cfg = keyquorum_core::config::Config::from_file(&path)
.map_err(|e| anyhow::anyhow!("failed to load config from {}: {}", path.display(), e))?;
return Ok(cfg.daemon.socket_path.to_string_lossy().into_owned());
}
Ok("/run/keyquorum/keyquorum.sock".to_string())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
keyquorum_core::memory::warn_if_not_linux();
let cli = Cli::parse();
match cli.command {
Commands::Daemon {
config,
lockdown,
no_strict_hardening,
} => daemon::run(config, lockdown, no_strict_hardening).await,
Commands::Submit {
user,
socket,
config,
} => {
let socket = resolve_socket(socket, config)?;
client::submit::run(user, socket).await
}
Commands::Status { socket, config } => {
let socket = resolve_socket(socket, config)?;
client::status::run(socket).await
}
}
}