use clap::Parser;
use linux_keyutils::{Key, KeyRing, KeyRingIdentifier, KeySerialId};
use linux_keyutils::{KeyPermissionsBuilder, Permission};
use std::error::Error;
use zeroize::Zeroizing;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
#[clap(subcommand)]
subcommand: Command,
}
#[derive(clap::Subcommand, Debug, PartialEq)]
enum Command {
Create {
#[clap(short, long)]
description: String,
#[clap(short, long)]
secret: String,
},
Read {
#[clap(short, long)]
id: i32,
},
Chown {
#[clap(short, long)]
id: i32,
#[clap(short, long)]
uid: Option<u32>,
#[clap(short, long)]
gid: Option<u32>,
},
Chmod {
#[clap(short, long)]
id: i32,
},
Invalidate {
#[clap(short, long)]
id: i32,
},
}
fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
let ring = KeyRing::from_special_id(KeyRingIdentifier::User, false)?;
_ = match args.subcommand {
Command::Create {
description,
secret,
} => {
let key = ring.add_key(&description, &secret)?;
println!("Created key with ID {:?}", key.get_id());
}
Command::Read { id } => {
let key = Key::from_id(KeySerialId(id));
let mut buf = Zeroizing::new([0u8; 2048]);
let len = key.read(&mut buf)?;
println!("Secret {:?}", std::str::from_utf8(&buf[..len])?);
}
Command::Chown { id, uid, gid } => {
let key = Key::from_id(KeySerialId(id));
key.chown(uid, gid)?;
}
Command::Chmod { id } => {
let key = Key::from_id(KeySerialId(id));
let perms = KeyPermissionsBuilder::builder()
.user(Permission::ALL)
.build();
key.set_perm(perms)?;
}
Command::Invalidate { id } => {
let key = Key::from_id(KeySerialId(id));
key.invalidate()?;
}
};
Ok(())
}