feat: v1.10.7, add --json for piv-summary
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -487,7 +487,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "card-cli"
|
||||
version = "1.10.6"
|
||||
version = "1.10.7"
|
||||
dependencies = [
|
||||
"authenticator 0.3.1",
|
||||
"base64 0.21.7",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "card-cli"
|
||||
version = "1.10.6"
|
||||
version = "1.10.7"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::XResult;
|
||||
use rust_util::{util_msg, XResult};
|
||||
use serde::Serialize;
|
||||
use serde_json::{Map, Value};
|
||||
use spki::der::Encode;
|
||||
use tabled::{Table, Tabled};
|
||||
use tabled::settings::Style;
|
||||
use tabled::{Table, Tabled};
|
||||
use x509_parser::parse_x509_certificate;
|
||||
use yubikey::{Certificate, YubiKey};
|
||||
use yubikey::piv::{metadata, SlotId};
|
||||
use yubikey::{Certificate, YubiKey};
|
||||
|
||||
use crate::pivutil::{get_algorithm_id_by_certificate, ORDERED_SLOTS, ToStr};
|
||||
use crate::pivutil::{get_algorithm_id_by_certificate, ToStr, ORDERED_SLOTS};
|
||||
|
||||
const NA: &str = "N/A";
|
||||
|
||||
#[derive(Tabled)]
|
||||
#[derive(Tabled, Serialize)]
|
||||
struct PivSlot {
|
||||
name: String,
|
||||
id: String,
|
||||
@@ -33,6 +35,7 @@ impl Command for CommandImpl {
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("PIV subcommand")
|
||||
.arg(Arg::with_name("table").long("table").help("Show table"))
|
||||
.arg(Arg::with_name("json").long("json").help("JSON output"))
|
||||
.arg(Arg::with_name("all").long("all").help("Show all"))
|
||||
.arg(Arg::with_name("ordered").long("ordered").help("Show ordered"))
|
||||
}
|
||||
@@ -41,45 +44,69 @@ impl Command for CommandImpl {
|
||||
let show_table = sub_arg_matches.is_present("table");
|
||||
let show_all = sub_arg_matches.is_present("all");
|
||||
let show_ordered = sub_arg_matches.is_present("ordered");
|
||||
let json_output = sub_arg_matches.is_present("json");
|
||||
if json_output { util_msg::set_logger_std_out(false); }
|
||||
|
||||
let mut output = Map::new();
|
||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||
|
||||
success!("Name: {}", yk.name());
|
||||
information!("Version: {}", yk.version());
|
||||
information!("Serial: {}", yk.serial());
|
||||
output.insert("name".to_string(), Value::String(yk.name().to_string()));
|
||||
output.insert("version".to_string(), Value::String(yk.version().to_string()));
|
||||
output.insert("serial".to_string(), Value::String(yk.serial().to_string()));
|
||||
|
||||
match yk.chuid() {
|
||||
Ok(chuid) => information!("CHUID: {}",chuid.to_string()),
|
||||
Ok(chuid) => {
|
||||
information!("CHUID: {}",chuid.to_string());
|
||||
output.insert("chuid".to_string(), Value::String(chuid.to_string()));
|
||||
}
|
||||
Err(e) => warning!("CHUID: <none> {}", e),
|
||||
}
|
||||
match yk.cccid() {
|
||||
Ok(cccid) => information!("CCCID: {}",cccid.to_string()),
|
||||
Ok(cccid) => {
|
||||
information!("CCCID: {}",cccid.to_string());
|
||||
output.insert("cccid".to_string(), Value::String(cccid.to_string()));
|
||||
}
|
||||
Err(e) => warning!("CCCID: <none> {}", e),
|
||||
}
|
||||
match yk.get_pin_retries() {
|
||||
Ok(pin_retries) => information!("PIN retries: {}",pin_retries),
|
||||
Ok(pin_retries) => {
|
||||
information!("PIN retries: {}",pin_retries);
|
||||
output.insert("pin_retries".to_string(), Value::String(pin_retries.to_string()));
|
||||
}
|
||||
Err(e) => warning!("PIN retries: <none> {}", e),
|
||||
}
|
||||
|
||||
match yk.piv_keys() {
|
||||
Ok(keys) => {
|
||||
information!("Found {} PIV keys of {}", keys.len(), ORDERED_SLOTS.len());
|
||||
}
|
||||
Ok(keys) => information!("Found {} PIV keys of {}", keys.len(), ORDERED_SLOTS.len()),
|
||||
Err(e) => failure!("Get PIV keys failed: {}", e)
|
||||
}
|
||||
|
||||
let mut piv_slots = vec![];
|
||||
for slot in iff!(show_ordered, ORDERED_SLOTS, yubikey::piv::SLOTS) {
|
||||
print_summary_info(&mut yk, slot, &mut piv_slots, show_all, show_table).ok();
|
||||
print_summary_info(&mut yk, slot, &mut piv_slots, show_all, show_table, json_output).ok();
|
||||
}
|
||||
|
||||
if show_table {
|
||||
let mut table = Table::new(piv_slots);
|
||||
table.with(Style::rounded());
|
||||
println!("{}", table);
|
||||
} else if json_output {
|
||||
let piv_slots_json = serde_json::to_string(&piv_slots).unwrap();
|
||||
let piv_slots_values: Vec<Value> = serde_json::from_str(&piv_slots_json).unwrap();
|
||||
output.insert("piv_slots".to_string(), Value::Array(piv_slots_values));
|
||||
}
|
||||
if json_output {
|
||||
println!("{}", serde_json::to_string_pretty(&output).unwrap());
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId, piv_slots: &mut Vec<PivSlot>, show_all: bool, show_table: bool) -> XResult<()> {
|
||||
fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId, piv_slots: &mut Vec<PivSlot>, show_all: bool, show_table: bool, json_output: bool) -> XResult<()> {
|
||||
let slot_id: u8 = slot.into();
|
||||
let mut origin = NA.to_string();
|
||||
let mut retries = NA.to_string();
|
||||
@@ -101,7 +128,7 @@ fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId, piv_slots: &mut Vec<P
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
if show_all {
|
||||
if show_table {
|
||||
if show_table || json_output {
|
||||
piv_slots.push(PivSlot {
|
||||
name: slot.to_string(),
|
||||
id: format!("{:x}", slot_id),
|
||||
@@ -127,7 +154,7 @@ fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId, piv_slots: &mut Vec<P
|
||||
Ok((_rem, cert)) => cert.subject.to_string(),
|
||||
_ => cert.cert.tbs_certificate.subject.to_string(),
|
||||
};
|
||||
if show_table {
|
||||
if show_table || json_output {
|
||||
piv_slots.push(PivSlot {
|
||||
name: slot.to_string(),
|
||||
id: format!("{:x}", slot_id),
|
||||
|
||||
Reference in New Issue
Block a user