Skip to content

Commit

Permalink
Make otp-cache a binary target of nitrocli
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
robinkrahl authored and d-e-s-o committed Apr 25, 2021
1 parent e5876e9 commit cad981a
Show file tree
Hide file tree
Showing 7 changed files with 12 additions and 88 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Unreleased
----------
- Introduced extension support crate, `nitrocli-ext`
- Introduced `otp-cache` core extension


Expand Down
21 changes: 0 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ default-run = "nitrocli"
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
Expand Down Expand Up @@ -79,6 +83,3 @@ version = "1"

[dev-dependencies.tempfile]
version = "3.1"

[workspace]
members = ["ext/*"]
22 changes: 1 addition & 21 deletions ext/ext/src/lib.rs → ext/ext.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// lib.rs
// ext.rs

// Copyright (C) 2020-2021 The Nitrocli Developers
// SPDX-License-Identifier: GPL-3.0-or-later
Expand Down Expand Up @@ -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<String> {
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")?;
Expand Down
15 changes: 0 additions & 15 deletions ext/ext/Cargo.toml

This file was deleted.

21 changes: 0 additions & 21 deletions ext/otp-cache/Cargo.toml

This file was deleted.

13 changes: 7 additions & 6 deletions ext/otp-cache/src/main.rs → ext/otp_cache.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// main.rs
// otp_cache.rs

// Copyright (C) 2020-2021 The Nitrocli Developers
// SPDX-License-Identifier: GPL-3.0-or-later
Expand All @@ -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<Slot>,
Expand Down Expand Up @@ -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 {
Expand All @@ -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()
Expand Down Expand Up @@ -99,7 +100,7 @@ fn cmd_list(cache: &Cache) {
}
}

fn get_cache(ctx: &nitrocli_ext::Context, force_update: bool) -> anyhow::Result<Cache> {
fn get_cache(ctx: &ext::Context, force_update: bool) -> anyhow::Result<Cache> {
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)?;
Expand Down Expand Up @@ -165,7 +166,7 @@ fn get_otp_slots(device: &impl nitrokey::GenerateOtp) -> anyhow::Result<Cache> {
})
}

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"])
Expand Down

0 comments on commit cad981a

Please sign in to comment.