diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-09 13:41:53 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-09 13:41:53 -0800 |
commit | 4842ac86c0a805c5c4a679644594252ca5ea388b (patch) | |
tree | d49fcace411df5361f7c9fd6880629e7bec0a1d3 | |
parent | 749a5c78c2075c5d37b01ec4fd23704aa5cfdf09 (diff) | |
download | nitrocli-4842ac86c0a805c5c4a679644594252ca5ea388b.tar.gz nitrocli-4842ac86c0a805c5c4a679644594252ca5ea388b.tar.bz2 |
Introduce Admin and User PIN fields to execution context
In order to run tests fully non-interactively we need to avoid the need
for using the GPG agent's PIN entry and caching mechanism. To accomplish
that, we first need an alternate way to supply the PINs to use to the
program.
This change offers such a way by extending the execution context with
two fields representing the PINs that are populated by corresponding
environment variables, NITROCLI_ADMIN_PIN & NITROCLI_USER_PIN, if set.
While only two PINs are required right now, because the program allows
for the changing of each of the PINs, we also add two fields
representing new PINs. These latter two fields are populated by the
NITROCLI_NEW_ADMIN_PIN and NITROCLI_NEW_USER_PIN environment variables.
-rw-r--r-- | nitrocli/src/args.rs | 9 | ||||
-rw-r--r-- | nitrocli/src/main.rs | 22 | ||||
-rw-r--r-- | nitrocli/src/tests/mod.rs | 26 |
3 files changed, 56 insertions, 1 deletions
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index 6e55cb1..6f02832 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -17,6 +17,7 @@ // * along with this program. If not, see <http://www.gnu.org/licenses/>. * // ************************************************************************* +use std::ffi; use std::io; use std::result; use std::str; @@ -44,6 +45,10 @@ pub struct ExecCtx<'io> { pub model: Option<DeviceModel>, pub stdout: &'io mut dyn io::Write, pub stderr: &'io mut dyn io::Write, + pub admin_pin: Option<ffi::OsString>, + pub user_pin: Option<ffi::OsString>, + pub new_admin_pin: Option<ffi::OsString>, + pub new_user_pin: Option<ffi::OsString>, pub verbosity: u64, } @@ -817,6 +822,10 @@ fn parse_arguments<'io, 'ctx: 'io>( model, stdout: ctx.stdout, stderr: ctx.stderr, + admin_pin: ctx.admin_pin.take(), + user_pin: ctx.user_pin.take(), + new_admin_pin: ctx.new_admin_pin.take(), + new_user_pin: ctx.new_user_pin.take(), verbosity, }; Ok((command, ctx, subargs)) diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 9f56f75..9a4216a 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -81,6 +81,7 @@ mod pinentry; mod tests; use std::env; +use std::ffi; use std::io; use std::process; use std::result; @@ -89,12 +90,29 @@ use crate::error::Error; type Result<T> = result::Result<T, Error>; +const NITROCLI_ADMIN_PIN: &str = "NITROCLI_ADMIN_PIN"; +const NITROCLI_USER_PIN: &str = "NITROCLI_USER_PIN"; +const NITROCLI_NEW_ADMIN_PIN: &str = "NITROCLI_NEW_ADMIN_PIN"; +const NITROCLI_NEW_USER_PIN: &str = "NITROCLI_NEW_USER_PIN"; + /// The context used when running the program. pub(crate) struct RunCtx<'io> { /// The `Write` object used as standard output throughout the program. pub stdout: &'io mut dyn io::Write, /// The `Write` object used as standard error throughout the program. pub stderr: &'io mut dyn io::Write, + /// The admin PIN, if provided through an environment variable. + pub admin_pin: Option<ffi::OsString>, + /// The user PIN, if provided through an environment variable. + pub user_pin: Option<ffi::OsString>, + /// The new admin PIN to set, if provided through an environment variable. + /// + /// This variable is only used by commands that change the admin PIN. + pub new_admin_pin: Option<ffi::OsString>, + /// The new user PIN, if provided through an environment variable. + /// + /// This variable is only used by commands that change the user PIN. + pub new_user_pin: Option<ffi::OsString>, } fn run<'ctx, 'io: 'ctx>(ctx: &'ctx mut RunCtx<'io>, args: Vec<String>) -> i32 { @@ -120,6 +138,10 @@ fn main() { let ctx = &mut RunCtx { stdout: &mut io::stdout(), stderr: &mut io::stderr(), + admin_pin: env::var_os(NITROCLI_ADMIN_PIN), + user_pin: env::var_os(NITROCLI_USER_PIN), + new_admin_pin: env::var_os(NITROCLI_NEW_ADMIN_PIN), + new_user_pin: env::var_os(NITROCLI_NEW_USER_PIN), }; process::exit(run(ctx, args)); diff --git a/nitrocli/src/tests/mod.rs b/nitrocli/src/tests/mod.rs index c7ff222..4e25091 100644 --- a/nitrocli/src/tests/mod.rs +++ b/nitrocli/src/tests/mod.rs @@ -17,10 +17,16 @@ // * along with this program. If not, see <http://www.gnu.org/licenses/>. * // ************************************************************************* +use std::ffi; use std::fmt; use nitrokey_test::test as test_device; +// TODO: Those defines should potentially be taken from the `nitrokey` +// crate, once exported. +const NITROKEY_DEFAULT_ADMIN_PIN: &str = "12345678"; +const NITROKEY_DEFAULT_USER_PIN: &str = "123456"; + // TODO: This is a hack to make the nitrokey-test crate work across // module boundaries. Upon first use of the nitrokey_test::test // macro a new function, __nitrokey_mutex, will be emitted, but it @@ -53,11 +59,21 @@ where struct Nitrocli { model: Option<nitrokey::Model>, + admin_pin: Option<ffi::OsString>, + user_pin: Option<ffi::OsString>, + new_admin_pin: Option<ffi::OsString>, + new_user_pin: Option<ffi::OsString>, } impl Nitrocli { pub fn new() -> Self { - Self { model: None } + Self { + model: None, + admin_pin: Some(NITROKEY_DEFAULT_ADMIN_PIN.into()), + user_pin: Some(NITROKEY_DEFAULT_USER_PIN.into()), + new_admin_pin: None, + new_user_pin: None, + } } pub fn with_dev<D>(device: D) -> Self @@ -66,6 +82,10 @@ impl Nitrocli { { let result = Self { model: Some(device.get_model()), + admin_pin: Some(NITROKEY_DEFAULT_ADMIN_PIN.into()), + user_pin: Some(NITROKEY_DEFAULT_USER_PIN.into()), + new_admin_pin: None, + new_user_pin: None, }; drop(device); @@ -97,6 +117,10 @@ impl Nitrocli { let ctx = &mut crate::RunCtx { stdout: &mut stdout, stderr: &mut stderr, + admin_pin: self.admin_pin.clone(), + user_pin: self.user_pin.clone(), + new_admin_pin: self.new_admin_pin.clone(), + new_user_pin: self.new_user_pin.clone(), }; (f(ctx, args), stdout, stderr) |