diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-09 16:31:31 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-09 16:31:31 -0800 |
commit | eea4f7357d7a3e3b365d887671ba78fd386a6d2d (patch) | |
tree | d1d230385c6985f4b112d4028ef9203a934c83ba | |
parent | ae939694c598ae23690f6a56f977c66ae7c0f020 (diff) | |
download | nitrocli-eea4f7357d7a3e3b365d887671ba78fd386a6d2d.tar.gz nitrocli-eea4f7357d7a3e3b365d887671ba78fd386a6d2d.tar.bz2 |
Honor context provided Admin & User PIN in pin commands
The second source of interactivity comes from the pin set and pin
unblock commands, which also inquire with the pinentry module to ask the
user for a PIN.
This change adjusts the two commands to honor the PINs as available in
the command execution context. It also updates the documentation
to reflect the availability of the newly introduced and honored
environment variables NITROCLI_ADMIN_PIN & NITROCLI_USER_PIN as well as
NITROCLI_NEW_ADMIN_PIN & NITROCLI_NEW_USER_PIN.
-rw-r--r-- | nitrocli/CHANGELOG.md | 3 | ||||
-rw-r--r-- | nitrocli/doc/nitrocli.1 | 19 | ||||
-rw-r--r-- | nitrocli/doc/nitrocli.1.pdf | bin | 14513 -> 15436 bytes | |||
-rw-r--r-- | nitrocli/src/commands.rs | 42 |
4 files changed, 61 insertions, 3 deletions
diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index da44c4a..fe9b69c 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -6,6 +6,9 @@ Unreleased - Added the `-f`/`--format` option for the `otp set` subcommand to choose the secret format - Deprecated the `--ascii` option +- Honor `NITROCLI_ADMIN_PIN` and `NITROCLI_USER_PIN` as well as + `NITROCLI_NEW_ADMIN_PIN` and `NITROCLI_NEW_USER_PIN` environment + variables for non-interactive PIN supply - Format `nitrokey` reported errors in more user-friendly format - Bumped `nitrokey` dependency to `0.3.1` diff --git a/nitrocli/doc/nitrocli.1 b/nitrocli/doc/nitrocli.1 index 036c25f..234b588 100644 --- a/nitrocli/doc/nitrocli.1 +++ b/nitrocli/doc/nitrocli.1 @@ -220,6 +220,25 @@ The admin PIN cannot be unblocked. This operation is equivalent to the unblock PIN option provided by \fBgpg\fR(1) (using the \fB\-\-change\-pin\fR option). +.SH ENVIRONMENT +The program honors a set of environment variables that can be used to +suppress interactive PIN entry through \fBpinentry\fR(1). The following +variables are recognized: +.TP +.B NITROCLI_ADMIN_PIN +The admin PIN to use. +.TP +.B NITROCLI_USER_PIN +The user PIN to use. +.TP +.B NITROCLI_NEW_ADMIN_PIN +The new admin PIN to set. This variable is only used by the \fBnitrocli +pin set\fR command for the \fBadmin\fR type. +.TP +.B NITROCLI_NEW_USER_PIN +The new user PIN to set. This variable is only used by the \fBnitrocli +pin set\fR command for the \fBuser\fR type. + .SH EXAMPLES .SS One-time passwords Configure a one-time password slot with a hexadecimal secret representation: diff --git a/nitrocli/doc/nitrocli.1.pdf b/nitrocli/doc/nitrocli.1.pdf Binary files differindex 5fa9049..3d28310 100644 --- a/nitrocli/doc/nitrocli.1.pdf +++ b/nitrocli/doc/nitrocli.1.pdf diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs index 6316c92..f8765cc 100644 --- a/nitrocli/src/commands.rs +++ b/nitrocli/src/commands.rs @@ -610,7 +610,7 @@ fn check_pin(pin_type: pinentry::PinType, pin: &str) -> Result<()> { } } -fn choose_pin(pin_type: pinentry::PinType) -> Result<String> { +fn choose_pin_with_pinentry(pin_type: pinentry::PinType) -> Result<String> { pinentry::clear_pin(pin_type)?; let new_pin = pinentry::inquire_pin(pin_type, pinentry::Mode::Choose, None)?; pinentry::clear_pin(pin_type)?; @@ -626,10 +626,46 @@ fn choose_pin(pin_type: pinentry::PinType) -> Result<String> { } } +/// Choose a PIN of the given type. +/// +/// If the user has set the respective environment variable for the +/// given PIN type, it will be used. +fn choose_pin( + ctx: &mut args::ExecCtx<'_>, + pin_type: pinentry::PinType, + new: bool, +) -> Result<String> { + let new_pin = match pin_type { + pinentry::PinType::Admin => { + if new { + &ctx.new_admin_pin + } else { + &ctx.admin_pin + } + } + pinentry::PinType::User => { + if new { + &ctx.new_user_pin + } else { + &ctx.user_pin + } + } + }; + + if let Some(new_pin) = new_pin { + new_pin + .to_str() + .ok_or_else(|| Error::Error("Failed to read PIN: invalid Unicode data found".into())) + .map(ToOwned::to_owned) + } else { + choose_pin_with_pinentry(pin_type) + } +} + /// Change a PIN. pub fn pin_set(ctx: &mut args::ExecCtx<'_>, pin_type: pinentry::PinType) -> Result<()> { let device = get_device(ctx)?; - let new_pin = choose_pin(pin_type)?; + let new_pin = choose_pin(ctx, pin_type, true)?; try_with_pin( ctx, pin_type, @@ -644,7 +680,7 @@ pub fn pin_set(ctx: &mut args::ExecCtx<'_>, pin_type: pinentry::PinType) -> Resu /// Unblock and reset the user PIN. pub fn pin_unblock(ctx: &mut args::ExecCtx<'_>) -> Result<()> { let device = get_device(ctx)?; - let user_pin = choose_pin(pinentry::PinType::User)?; + let user_pin = choose_pin(ctx, pinentry::PinType::User, false)?; try_with_pin( ctx, pinentry::PinType::Admin, |