aboutsummaryrefslogtreecommitdiff
path: root/nitrocli/src/commands.rs
Commit message (Collapse)AuthorAge
* Check slot status before accessing the PWSRobin Krahl2019-01-26
| | | | | | | | | | | | The Nitrokey devices do not check whether a PWS slot is programmed before accessing it (upstream issues [0] [1]). Until this is fixed in the firmware, we have to manually check the slot status in pws get. This could have been done in libnitrokey or the nitrokey crate, yet this would lead to unnecessary commands if we check multiple fields of a slot at the same time. [0] https://github.com/Nitrokey/nitrokey-pro-firmware/issues/56 [1] https://github.com/Nitrokey/nitrokey-storage-firmware/issues/81
* Add the reset command to perform a factory resetRobin Krahl2019-01-26
| | | | | | After performing the factory reset, we also build the AES key so that the device is fully usable. Due to timing issue, we have to add a delay between the factory reset and building the AES key.
* Add test for storage hidden subcommandDaniel Mueller2019-01-20
| | | | | | | This change adds a test for the creation, opening, and closing of a hidden subvolume. In order to support that in a non-interactive fashion, we introduce and honor the NITROCLI_PASSWORD environment variable, that prevents an interactive password query.
* Implement storage hidden subcommandDaniel Mueller2019-01-20
| | | | | | | | | With this change we implement the storage hidden subcommand. We support creation, opening, and closing of hidden volumes. Note that the opening of a hidden volume automatically closes any opened encrypted volumes and vice versa. To that end, we force file system level caches to disk even from the storage open and storage hidden open commands.
* Drop '_pin' suffix from various pinentry functionsDaniel Mueller2019-01-19
| | | | | | Various functions in the pinentry module contain an arguably redundant '_pin' suffix in their name. Examples include inquire_pin and clear_pin. This change removes this part from their names.
* Move PIN choosing functionality into pinentry moduleDaniel Mueller2019-01-19
| | | | | | | | | The functionality we have in place for choosing a PIN can arguably be moved into the pinentry module: it can be considered logic directly related to working with PINs or secrets and that has no dependencies to unrelated modules of the program. This patch moves the choose_pin and check_pin functions into the pinentry module.
* Isolate cached PINs for multiple devices from each otherDaniel Mueller2019-01-11
| | | | | | | | | | | | | | | | | | | The application supports multiple devices both plugged in at the same time as well as when used after the other. However, the GPG cache ID we use for storing and retrieving the respective PIN is effectively a constant. This constraint can cause problems when devices have different PINs, as the PIN of a previously plugged in device may be reused for an operation on a different one. To resolve this problem this change adds the respective device's model and serial number to the cache ID. As each serial number is supposed to be different, this will ensure that the correct PIN is used for each device. With this change we also show the model and serial number of the currently used device in the pinentry dialog. Note that because we do not store the serial numbers of all previously plugged in devices, the pin clear command will only clear the PIN for the currently plugged in device. If a user wants to make sure that a cached PIN is cleared, the pin clear command should be invoked before unplugging the device.
* Implement From<&str> for ErrorRobin Krahl2019-01-26
| | | | | | This patch implements From<&str> for Error so that we can use Error::from(s) as a shorthand for Error::Error(s.to_string()). It also replaces Error::Error with Error::from where possible.
* Refactor get_device to use nitrokey::connect_modelRobin Krahl2019-01-26
| | | | | | | | | nitrokey 0.3.1 introduced the connect_model function that connects to a specific model given by an enum variant and returns a DeviceWrapper. This new function allows us to remove the manual selection of a connection method from the get_device function. We only have to implement From<DeviceModel> for nitrokey::Model to be able to convert our model enum to nitrokey's model enum.
* Report command errors properlyDaniel Mueller2019-01-09
| | | | | | | | | | | | So far we have taken all nitrokey::CommandError objects and put them in formatted form into the Error::Error variant. What we really should do, though, is to preserve the original error, with the additional context provided by the caller, and report that up the stack directly. Doing so has at least the benefit that we are able to check for expected errors without hard coding the textual representation as maintained by the nitrokey create. This change refactors the code accordingly and adds two tests for such expected error codes.
* Honor context provided Admin & User PIN in pin commandsDaniel Mueller2019-01-09
| | | | | | | | | | | 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.
* Make try_with_pin_and_data logic honor execution context PINsDaniel Mueller2019-01-09
| | | | | | | | | | The try_with_pin_and_data function is used by many commands to ask the user for a PIN in an interactive manner. Because we do not want to have any interactivity in our tests, we should honor the command execution's admin & user PIN fields from this function, if set. This change adjusts the function to honor the command execution context's admin & user PIN, if set. In order to do so it also adjusts the callers to hand through the context to begin with.
* Simplify try_with_pin_and_data functionDaniel Mueller2019-01-09
| | | | | | | | | | The try_with_pin_and_data function is a fairly complex beast. Part of that complexity stems from the returned Result value, whose error part not only contains the error but also the previously passed in data. As it turns out, though, this data as returned is never actually consumed by any client. Hence, this change simplifies the logic slightly by removing all the additional complexity that this tuple return entailed.
* Make pinentry::inquire_pin return String directlyDaniel Mueller2019-01-09
| | | | | | | | | | | | | | | The inquire_pin function of the pinentry module used to return a vector of bytes, as that is what is ultimately read from the gpg-agent process. All clients of this function, however, work with a string and, hence, convert this vector into a string. As it turns out, for better or worse, the pinentry::parse_pinentry_pin function (which produces the result of inquire_pin) internally already works with a string but then converts it back. That is both not useful and a waste of resources. This change adjusts both functions of interest to simply return a String object instead, removing the need for conversions at the clients. While at it, the patch also removes the need for a bunch of unnecessary allocations caused by sub-par parameter type choice.
* Use 'pin' instead of 'passphrase'Daniel Mueller2019-01-09
| | | | | | | | | | | | In the past we have used the term 'passphrase' to refer to the data retrieved through the pinentry module and that terminology has permeated the commands module as well. However, on the Nitrokey side we talk about PINs most of the time (despite a lack of an requirement for being actual numbers). In an attempt to unify terminology a bit more, this change renames all occurrences of the term 'passphrase' with PIN. This renaming has the nice side effect of making the code more concise because the latter is much shorter than the former.
* Show fmt::Display formatted errors instead of fmt::Debug onesDaniel Mueller2019-01-08
| | | | | | | | | At some point in the past nitrokey::CommandError was lacking an implementation of the fmt::Display trait. Hence, we fell back to printing these errors in debug format. Since version 0.2.0 of the crate fmt::Display is implemented for these errors. With this change we use it to report more user-friendly error messages.
* Emit all output to custom stdio channelsDaniel Mueller2019-01-05
| | | | | | | | | | | This change continues and concludes the effort of using customizable stdio channels for output of data from the program. It does so by replacing the standard println macro with a custom one that outputs the data to the supplied context's stdout object. Because this object is injected from the main function, it will be possible for tests invoking this function to supply custom Write objects that can buffer this data and make it available for verification purposes.
* Work with mutable ExecCtx referencesDaniel Mueller2019-01-05
| | | | | | | | | | So far we have used a read-only reference to a command execution context and passed that through to all consumers. However, with upcoming changes we would will need to provide data that can be modified. This change adjusts all function signatures accordingly. Also, because the ExecCtx will contain references itself in the future, this change already introduces a lifetime for the struct, as that also requires signature adjustments.
* Add the base32 format for OTP secretsRobin Krahl2019-01-13
| | | | | | | Many applications display OTP secrets in the base32 format (according to RFC 4648). This patch adds base32 as a possible value for the --format option to the otp set subcommand.
* Refactor prepare_secret functionRobin Krahl2019-01-13
| | | | | | | This patch refactors the prepare_secret function by renaming it to prepare_ascii_secret and by moving the formatting of a bytes slice as a hex string into the format_bytes function. This prepares for adding a the base32 format in a future patch.
* Add the --format option to otp set to select the secret formatRobin Krahl2019-01-13
| | | | | | | | | | | | | | This patch introduces the -f/--format options for the otp set subcommand to specify the format of the OTP secret. Previously, the default format was hexadecimal and ASCII format could be selected using the --ascii option. The new --format option takes the argument hex or ascii, defaulting to hex, and replaces the --ascii option. This patch does not remove the --ascii option but marks it as deprecated. It may not be set together with --format, and a warning is printed if it is set. It should be deleted with the next minor release. This patch prepares the addition of a new format, base32.
* Update nitrokey crate to 0.3.0Daniel Mueller2019-01-05
| | | | | | This change updates the nitrokey crate to version 0.3.0. Import subrepo nitrokey/:nitrokey at 3593df8844b80741e2d33c8e5af80e65760dc058
* Add the --model option to restrict the device model to connect toRobin Krahl2019-01-13
| | | | | | | | | | | | This patch adds the -m/--model option that can be used to restrict the device model to connect to. Per default, nitrocli connects to any available Nitrokey device. If this new option is set, it will instead only connect to devices of the given Nitrokey model. We introduce a new struct DeviceModel instead of using nitrokey::DeviceModel to make sure that the command-line options are parsed properly. On the long term, we should add a connect_model function to the nitrokey crate to make the connection code easier.
* Introduce -v/--verbose optionDaniel Mueller2019-01-04
| | | | | | | | | | | | | | | | This change introduces a new option, -v/--verbose, that can be used to increase the log level of libnitrokey. The option can be supplied multiple times, with each occurrence increasing the verbosity of the logging. On the implementation side, the option is set as part of connecting the device (piggy-backing on the previously introduced command execution context), although it describes global state that strictly speaking could be set anywhere. It is bad enough that libnitrokey just prints log messages to stderr (and does not accept a file handle) and that it does not track the log level on a per-device basis, but we don't want setting of global state from arbitrary locations inside the program. Instead, let's do that along with what pretty much is the first call into libnitrokey anyway: the connection to the device.
* Introduce command execution context supportDaniel Mueller2019-01-04
| | | | | | | | | In the future we will need the ability to pass additional state that is deduced from arguments or elsewhere into the commands module. To enable such scenarios, this change introduces the concept of a command execution context. Such a context can store more or less arbitrary data, and the args module will take care of passing it through to the individual commands.
* Use libc provided sync functionDaniel Mueller2019-01-04
| | | | | | | | | | | | In order to flush file system level buffers to disk we use the sync function. The way we made this function known to the crate was by explicitly declaring it as extern "C" and linking against libc. However, given that we already (indirectly) depend on libc through the nitrokey crate (and that is unlikely to change) we may as well make libc a direct dependency and invoke the function through the crate. Given that the libc crate is available for a variety of platforms, it seems likely that its approach to interfacing with the system libc library is more portable than our hand rolled version.
* Adjust get_error function to accept CommandError by valueDaniel Mueller2019-01-03
| | | | | | | | With the recent update of the nitrokey create the nitrokey::CommandError enum has become trivially copyable. Hence, there is no more point in passing a reference to it to the get_error function. To that end, this change adjusts the signature to accept an owned value instead.
* Implement the lock commandRobin Krahl2019-01-07
| | | | | | This patch implements the lock command that locks the password safe and, on the Nitrokey Storage, the encrypted volume. See issue #18 for details on the locking mechanism.
* Implement the pws status subcommandRobin Krahl2019-01-07
| | | | | This patch implements the pws status command that can be used to print status information for the slots in the password safe.
* Implement the pws clear subcommandRobin Krahl2019-01-07
| | | | | This patch implements the pws clear command which allows the user to clear a slot in the password safe.
* Implement the pws set subcommandRobin Krahl2019-01-07
| | | | This patch adds the pws set subcommand that writes a PWS slot.
* Implement the pws get subcommandRobin Krahl2019-01-07
| | | | | | | | | This patch implements the pws get subcommand that provides read access to a slot of the password safe. Per default, all available information – slot name, login and password – are printed. If one or more of the options --name, --login and --password are set, only the selected fields are printed. If --quiet is set, the field description is omitted such that the output can be easily parsed by other applications.
* Implement the pin set commandRobin Krahl2019-01-01
| | | | | This change implements the pin set command which can be used to change a Nitrokey's user or admin PIN.
* Implement the pin unblock subcommandRobin Krahl2019-01-01
| | | | | | | This patch implements the pin unblock command that unblocks and resets the user PIN. The name unblock is chosen over libnitrokey's unlock to be consistent with the GnuPG terminology and to avoid confusion with the unrelated lock command.
* Implement the pin command and rename clear to pin clearRobin Krahl2019-01-01
| | | | | | | | | We have functionality for changing the Nitrokey's user & admin PINs as well as for resetting the user PIN coming up. With the prospect of this new functionality arriving, it makes sense to introduce a new top-level command for the sole purpose of PIN management. This change introduces such a command, pin, and moves the existing clear command for clearing the PIN cache into it.
* Add mode argument to pinentry::inquire_passphraseRobin Krahl2019-01-01
| | | | | | | The mode argument is used to specify the context of the pinentry dialog: querying an existing passphrase or prompting the user to choose a new PIN. It is used to choose a description and to decide whether to show a quality bar that measures the password strength.
* Set the time before generating a TOTPRobin Krahl2019-01-01
| | | | | | | | | | This patch changes the otp get command to set the Nitrokey's time before generating a one-time password using the TOTP algorithm. Per default, it sets the time to the current system time. If the --time option is set, it uses its value instead. See issue #34 [0] for a discussion of this change. [0] https://github.com/d-e-s-o/nitrocli/issues/34
* Move printing of storage related status into 'storage status' sub-commandDaniel Mueller2018-12-28
| | | | | | | | | | The 'status' command has traditionally printed information about the connected Nitrokey and that included storage specific data if the device present is a Nitrokey Storage. Given that we have a root-level 'storage' command it arguably makes sense to move the printing of the storage related status information into a 'status' sub-command of the said command, which makes the output more predictable.
* Make 'open' and 'close' subcommands of new 'storage' commandDaniel Mueller2018-12-27
| | | | | | | | | | | | | Upon their inception, the 'open' and 'close' commands were pretty much the only relevant commands the program provided and it made sense to have them reside in the root namespace. By now we support more commands and have started to structure them in a more hierarchical fashion. To go with the flow, this change introduces a new 'storage' command and makes the existing 'open' and 'close' commands subcommands of it. We chose the name 'storage' (over, say, 'volume') because we plan to move the printing of the storage related status from the 'status' root level command into a subcommand within 'storage'.
* Implement the config set subcommandRobin Krahl2018-12-27
| | | | | | | | | | | | | This change implements the config set subcommand. The subcommand changes the configuration of a Nitrokey device. Its structure is more complex as it allows partial modifications: The user does not have to change all settings, but may choose to change only some. At the same time, the binding settings can be either set to a value or disabled. Therefore, we have the --{num,caps,scrol}lock options to set a value and the --no-{num,caps,scrol}lock options to disable the value. If none of the two is set, the setting is not changed.
* Implement the config get subcommandRobin Krahl2018-12-27
| | | | | This change implements the config get subcommand. The subcommand reads the device configuration and prints it.
* Add status output for Nitrokey ProRobin Krahl2018-12-27
| | | | | | | | Currently, the status command fails for a Nitrokey Pro. This patch changes the command to also print basic status information for Pro devices. For the sake of consistency, the common status is always queried using the common `Device` functions, even if the Storage status includes the same information.
* Extract print_status from print_storage_status functionRobin Krahl2018-12-27
| | | | | | This patch extracts the print_status function that prints the status fields common to all supported Nitrokey devices from the print_storage_status function.
* Rename print_status to print_storage_statusRobin Krahl2018-12-25
| | | | | The print_status function only prints the Storage-specific status struct. Therefore it is renamed to print_storage_status.
* Implement the otp status subcommandRobin Krahl2018-12-24
| | | | | | | | This patch introduces the `otp status` subcommand that lists all OTP slots and their current status. To avoid hardcoding the number of slots per type, we iterate all slots until we get an `InvalidSlot` error (assuming that the set of valid slots is {0, ..., n} for some n). The `status` command is quite slow as we have to query each slot separately.
* Implement the otp clear subcommandRobin Krahl2018-12-24
| | | | This patch implements the `otp clear` subcommand that erases an OTP slot.
* Implement the otp set subcommandRobin Krahl2018-12-24
| | | | | | | | | | This patch implements the `otp set` subcommand that configures an OTP slot. There are two ways to specify an OTP secret: as a hexadecimal string (that means that every two characters are interpreted as a hexadecimal representation of one byte of the secret) or as an ASCII string (that means that the ASCII code of every character is interpreted as one byte of the secret). As the HOTP RFC mentions both representations, this implementation supports both.
* Implement the otp get subcommandRobin Krahl2018-12-24
| | | | | | | This patch implements the `otp get` subcommand that allows the user to generate a one-time password on the Nitrokey device. Before generating the password, the device configuration is checked so that the user only has to enter a PIN if it is required for the OTP generation.
* Implement user and admin authenticationRobin Krahl2018-12-24
| | | | | | This patch implements authentication with the user or admin PIN. This is a preparation for the `otp get` and `otp set` commands which require user and admin access to the Nitrokey.
* Clear both user and admin PINRobin Krahl2018-12-24
| | | | | | Currently, we only clear the user PIN if clear is called. This patch changes the clear command to also clear the admin PIN as we will start to use the admin PIN in upcoming patches.