From 51f9d66963f5ff0968b955a81bd00660bbc67f74 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 25 Apr 2021 10:23:05 +0200 Subject: [PATCH] Make otp-cache a binary target of nitrocli Upon its inception, the common nitrocli extension glue code was put into a crate, nitrocli-ext. Doing so comes with a slew of challenges in terms of distribution, versioning, and compatibility with the main program. Because a different crate is used, that property transfers to extensions, meaning that they also have to be separate crates, for example. Packaging of Rust programs on some Linux distributions is based on content downloaded from crates.io, effectively forcing us to publish the extension crates, which in turn forces us to publish nitrocli-ext and to commit to a stable API. Then we get into questions of how to version separately published creates and how to ensure or enforce compatibility. In short, nitrocli-ext being a crate has trickle down effects that introduce additional complications that we did not anticipate initially. To that end, with this change we make nitrocli-ext a mere module of the crate and the otp-cache core extension a binary target. This implies that both are versioned as the main program is and are also available when pulling the published archive from crates.io, circumventing most if not all of the aforementioned problems. --- CHANGELOG.md | 1 - Cargo.lock | 21 -------------------- Cargo.toml | 7 ++++--- ext/{ext/src/lib.rs => ext.rs} | 22 +-------------------- ext/ext/Cargo.toml | 15 -------------- ext/otp-cache/Cargo.toml | 21 -------------------- ext/{otp-cache/src/main.rs => otp_cache.rs} | 13 ++++++------ 7 files changed, 12 insertions(+), 88 deletions(-) rename ext/{ext/src/lib.rs => ext.rs} (84%) delete mode 100644 ext/ext/Cargo.toml delete mode 100644 ext/otp-cache/Cargo.toml rename ext/{otp-cache/src/main.rs => otp_cache.rs} (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bc3351b..839afdee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ Unreleased ---------- -- Introduced extension support crate, `nitrocli-ext` - Introduced `otp-cache` core extension - Enabled usage of empty PWS slot fields - Changed error reporting format to make up only a single line diff --git a/Cargo.lock b/Cargo.lock index bf9cef1f..a644916e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,27 +233,6 @@ dependencies = [ "toml", ] -[[package]] -name = "nitrocli-ext" -version = "0.1.0" -dependencies = [ - "anyhow", - "directories", - "nitrokey", -] - -[[package]] -name = "nitrocli-otp-cache" -version = "0.1.0" -dependencies = [ - "anyhow", - "nitrocli-ext", - "nitrokey", - "serde", - "structopt", - "toml", -] - [[package]] name = "nitrokey" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index a4c3624d..4baefe10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,10 @@ gitlab = { repository = "d-e-s-o/nitrocli", branch = "master" } name = "shell-complete" path = "var/shell-complete.rs" +[[bin]] +name = "nitrocli-otp-cache" +path = "ext/otp_cache.rs" + [profile.release] opt-level = "z" lto = true @@ -82,6 +86,3 @@ version = "1" [dev-dependencies.tempfile] version = "3.1" - -[workspace] -members = ["ext/*"] diff --git a/ext/ext/src/lib.rs b/ext/ext.rs similarity index 84% rename from ext/ext/src/lib.rs rename to ext/ext.rs index 12339628..ad89b1c4 100644 --- a/ext/ext/src/lib.rs +++ b/ext/ext.rs @@ -1,4 +1,4 @@ -// lib.rs +// ext.rs // Copyright (C) 2020-2021 The Nitrocli Developers // SPDX-License-Identifier: GPL-3.0-or-later @@ -148,26 +148,6 @@ impl Nitrocli { self } - /// Invoke `nitrocli` and retrieve its output as a string. - /// - /// Note that any error messages emitted by `nitrocli` will not be - /// intercepted/captured but will directly be passed through. It is - /// recommended that extensions terminate on failure. - pub fn text(&mut self) -> anyhow::Result { - let output = self.cmd.output().context("Failed to invoke nitrocli")?; - // We want additional nitrocli emitted output to be visible to the - // user (typically controlled through -v/--verbose below). Note that - // this means that we will not be able to access this output for - // error reporting purposes. - self.cmd.stderr(process::Stdio::inherit()); - - if output.status.success() { - String::from_utf8(output.stdout).map_err(From::from) - } else { - Err(anyhow::anyhow!("nitrocli call failed")) - } - } - /// Invoke `nitrocli`. pub fn spawn(&mut self) -> anyhow::Result<()> { let mut child = self.cmd.spawn().context("Failed to invoke nitrocli")?; diff --git a/ext/ext/Cargo.toml b/ext/ext/Cargo.toml deleted file mode 100644 index e2ddcfb6..00000000 --- a/ext/ext/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -# Cargo.toml - -# Copyright (C) 2021 The Nitrocli Developers -# SPDX-License-Identifier: GPL-3.0-or-later - -[package] -name = "nitrocli-ext" -version = "0.1.0" -authors = ["Robin Krahl "] -edition = "2018" - -[dependencies] -anyhow = "1" -directories = "3" -nitrokey = "0.9" diff --git a/ext/otp-cache/Cargo.toml b/ext/otp-cache/Cargo.toml deleted file mode 100644 index 66fa77b7..00000000 --- a/ext/otp-cache/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -# Cargo.toml - -# Copyright (C) 2020-2021 The Nitrocli Developers -# SPDX-License-Identifier: GPL-3.0-or-later - -[package] -name = "nitrocli-otp-cache" -version = "0.1.0" -authors = ["Robin Krahl "] -edition = "2018" - -[dependencies] -anyhow = "1" -nitrokey = "0.9" -serde = { version = "1", features = ["derive"] } -structopt = { version = "0.3.21", default-features = false } -toml = "0.5" - -[dependencies.nitrocli-ext] -version = "0.1" -path = "../ext" diff --git a/ext/otp-cache/src/main.rs b/ext/otp_cache.rs similarity index 93% rename from ext/otp-cache/src/main.rs rename to ext/otp_cache.rs index 46355de0..6d3952d5 100644 --- a/ext/otp-cache/src/main.rs +++ b/ext/otp_cache.rs @@ -1,4 +1,4 @@ -// main.rs +// otp_cache.rs // Copyright (C) 2020-2021 The Nitrocli Developers // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,9 +8,10 @@ use std::io::Write as _; use std::path; use anyhow::Context as _; - use structopt::StructOpt as _; +mod ext; + #[derive(Debug, serde::Deserialize, serde::Serialize)] struct Cache { hotp: Vec, @@ -55,7 +56,7 @@ enum Command { fn main() -> anyhow::Result<()> { let args = Args::from_args(); - let ctx = nitrocli_ext::Context::from_env()?; + let ctx = ext::Context::from_env()?; let cache = get_cache(&ctx, args.force_update)?; match &args.cmd { @@ -65,7 +66,7 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn cmd_get(ctx: &nitrocli_ext::Context, cache: &Cache, slot_name: &str) -> anyhow::Result<()> { +fn cmd_get(ctx: &ext::Context, cache: &Cache, slot_name: &str) -> anyhow::Result<()> { let totp_slots = cache .totp .iter() @@ -99,7 +100,7 @@ fn cmd_list(cache: &Cache) { } } -fn get_cache(ctx: &nitrocli_ext::Context, force_update: bool) -> anyhow::Result { +fn get_cache(ctx: &ext::Context, force_update: bool) -> anyhow::Result { let mut mgr = nitrokey::take().context("Failed to obtain Nitrokey manager instance")?; let device = ctx.connect(&mut mgr)?; let serial_number = get_serial_number(&device)?; @@ -165,7 +166,7 @@ fn get_otp_slots(device: &impl nitrokey::GenerateOtp) -> anyhow::Result { }) } -fn generate_otp(ctx: &nitrocli_ext::Context, algorithm: &str, slot: u8) -> anyhow::Result<()> { +fn generate_otp(ctx: &ext::Context, algorithm: &str, slot: u8) -> anyhow::Result<()> { ctx .nitrocli() .args(&["otp", "get"])