cli: add status command

Provides equivalent functionality to `yubico-piv-tool`
This commit is contained in:
Tony Arcieri
2019-12-09 17:51:05 -08:00
parent 283e6fe363
commit 78d5f33695
12 changed files with 189 additions and 34 deletions
+50 -21
View File
@@ -1,9 +1,10 @@
//! Commands of the CLI application
pub mod readers;
pub mod status;
use self::readers::ReadersCmd;
use crate::status::{self, STDOUT};
use self::{readers::ReadersCmd, status::StatusCmd};
use crate::terminal::{self, STDOUT};
use gumdrop::Options;
use std::{
env,
@@ -11,36 +12,29 @@ use std::{
process::exit,
};
use termcolor::{ColorChoice, ColorSpec, WriteColor};
use yubikey_piv::{Serial, YubiKey};
/// The `yubikey` CLI utility
#[derive(Debug, Options)]
pub struct YubikeyCli {
pub struct YubiKeyCli {
/// Obtain help about the current command
#[options(short = "h", help = "print help message")]
pub help: bool,
/// Specify the serial number of the YubiKey to connect to
#[options(
short = "s",
long = "serial",
help = "serial number of the YubiKey to connect to"
)]
pub serial: Option<Serial>,
/// Subcommand to execute.
#[options(command)]
pub command: Option<Commands>,
}
impl YubikeyCli {
/// Run the underlying command type or print usage info and exit
pub fn run(&self) {
// TODO(tarcieri): make this more configurable
status::set_color_choice(ColorChoice::Auto);
// Only show logs if `RUST_LOG` is set
if env::var("RUST_LOG").is_ok() {
env_logger::builder().format_timestamp(None).init();
}
match &self.command {
Some(cmd) => cmd.run(),
None => Self::print_usage().unwrap(),
}
}
impl YubiKeyCli {
/// Print usage information
pub fn print_usage() -> Result<(), io::Error> {
let mut stdout = STDOUT.lock();
@@ -65,6 +59,36 @@ impl YubikeyCli {
Ok(())
}
/// Run the underlying command type or print usage info and exit
pub fn run(&self) {
// TODO(tarcieri): make this more configurable
terminal::set_color_choice(ColorChoice::Auto);
// Only show logs if `RUST_LOG` is set
if env::var("RUST_LOG").is_ok() {
env_logger::builder().format_timestamp(None).init();
}
match &self.command {
Some(cmd) => cmd.run(self.yubikey_init()),
None => Self::print_usage().unwrap(),
}
}
/// Initialize the YubiKey client driver
fn yubikey_init(&self) -> YubiKey {
match self.serial {
Some(serial) => YubiKey::open_by_serial(serial).unwrap_or_else(|e| {
status_err!("couldn't open YubiKey (serial #{}): {}", serial, e);
exit(1);
}),
None => YubiKey::open().unwrap_or_else(|e| {
status_err!("couldn't open default YubiKey: {}", e);
exit(1);
}),
}
}
}
/// Subcommands of this application
@@ -81,15 +105,20 @@ pub enum Commands {
/// `readers` subcommand
#[options(help = "list detected readers")]
Readers(ReadersCmd),
/// `status` subcommand
#[options(help = "show yubikey status")]
Status(StatusCmd),
}
impl Commands {
/// Run the given command
pub fn run(&self) {
pub fn run(&self, yubikey: YubiKey) {
match self {
Commands::Help(help) => help.run(),
Commands::Version(version) => version.run(),
Commands::Readers(list) => list.run(),
Commands::Status(status) => status.run(yubikey),
}
}
}