aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
...
* Return Cow object from SecretEntry methodsDaniel Mueller2019-01-20
| | | | | | | | | We do not know what kind of data future implementers of the SecretEntry trait may want to return. For all we know these could just be static strings, in which case the forced conversion into a String by virtue of the return type is wasteful. To be more flexible in the future while gaining some consistency, this change makes all those trait's methods return a Cow object instead.
* Introduce SecretEntry traitDaniel Mueller2019-01-19
| | | | | | | | | | | | Now that we have introduced the notion of a secret abstracting over whether something is a PIN or a password in terms of terminology, we need to define what makes a secret in code. From the pinentry module's perspective, the commonality between the two is that they both can be entered through a dialog containing a prompt and a description, and they can be cached. This change introduces a trait, SecretEntry, that defines methods representing those properties. Right now only the existing PinEntry struct implements this trait.
* Generalize terminology from "PIN" to "secret"Daniel Mueller2019-01-19
| | | | | | | | | | | | In the past we have worked solely with PINs. PINs in our (or rather, the Nitrokey's) sense are not necessarily numbers but they can be reasonably short in length, because they can only be retried a limited number of times. In the future, however, we will introduce the notion of a password, which does not carry such a restriction. The commonality between the two is that they are secrets and so with this change we refer to secrets -- rather than PINs -- in places where both passwords and PINs can conceptually be used.
* 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.
* Add tests for the storage commandDaniel Mueller2019-01-19
| | | | | | | | This change adds two tests for the storage command. The first one verifies that a proper error message is emitted if a storage command is attempted on a Pro device. The second one checks the output of the status subcommand and expected changes to it when opening or closing the encrypted volume.
* Add tests for pws commandDaniel Mueller2019-01-19
| | | | | This change adds a set of tests for the pws command. Covered are all subcommands with the most commonly used parameter combinations.
* Auto-generate help text for Option-based argumentsDaniel Mueller2019-01-15
| | | | | | | | | The previous change to properly format the help text for optional arguments left one thing out: parameters that are based on an Option as opposed to an enum. The problem with those is that we cannot simply ask the value (i.e., the Option) for all the variants of the inner type. Instead, we have to reference the actual type of the inner enum in order to retrieve all its possible variants.
* Auto-generate help text for enum-backed optional argumentsDaniel Mueller2019-01-15
| | | | | | | This change continues the effort of auto-generating more of the help text content by extending the logic to optional arguments. We make use of the fmt_enum macro to format the description of the argument with the available variants (as well as the default, if any) interpolated.
* Auto-populate help text contentDaniel Mueller2019-01-14
| | | | | | | | | With the ability to fully generate the command enums we use for working with the argparse crate, we can now take things one step further and populate the contents of the help string we print for the user that lists the available commands. Doing so we also fix a bug where we forgot to mention the "storage status" command in the help text.
* Auto-generate execute methods for generated command enumsDaniel Mueller2019-01-14
| | | | | | | | | | | | | | | Not too long ago we added a macro to auto generate the command enums and the required trait implementations from a concise declarative representation. This change extends this mechanism to the execute method implementation that some of those enums provide. When a tuple is specified as the "destination", e.g., here: > Enum! {ConfigCommand, [ > Get => ("get", config_get), > Set => ("set", config_set) > ]} the second component of this tuple will be interpreted as the function to invoke when this variant used in the newly generated execute method.
* Add a script to determine the nitrocli binary size at a git revisionDaniel Mueller2019-01-16
| | | | | | | | | | | We have been loosely tracking the resulting size of the stripped release binary as that is arguably the most relevant metric to optimize for. To have a better idea of the influence of various changes and their effect on the binary size, this change adds a script that automates the process of gathering this metric. E.g., $ var/binary-size.py HEAD~3 HEAD --unit kib > 994 > 970
* Remove no longer required dependenciesDaniel Mueller2019-01-16
| | | | | | | | | | With the update to rand 0.6.4 we no longer require the dependencies to rustc_version, semver, and semver-parser. Hence, this change removes them. Delete subrepo rustc_version/:rustc_version Delete subrepo semver/:semver Delete subrepo semver-parser/:semver-parser
* Update nitrokey crate to 0.3.3Daniel Mueller2019-01-16
| | | | | | | | | | | This change updates the nitrokey crate to version 0.3.3. Along with that change we update rand to 0.6.4 because rand 0.6.1 does not yet contain a publicly accessible rand_os. Note that we no longer require all crates in rand's workspace, but only rand_os and rand_core, which is a significant reduction in the number of lines of code compiled. Import subrepo nitrokey/:nitrokey at 7cf747d56ddc0b7eeedc3caf36dcc909907a171c Import subrepo rand/:rand at 4336232dda03323634b10ec72ddf27914aebc3a2
* Add tests for config commandDaniel Mueller2019-01-14
| | | | | | This change adds a set of tests for the config get and set commands. We cover chosen valid parameter combinations and verify that they work as expected as well as an invalid one.
* Add tests for otp commandDaniel Mueller2019-01-14
| | | | | | | This change adds a set of tests for the otp command. We cover some variants of the status, set, get, and clear. Testing all the possible combinations is out of scope and so only a more or less arbitrary subset of arguments was chosen.
* Update libc crate to 0.2.46Daniel Mueller2019-01-14
| | | | | | This change updates the libc crate to version 0.2.46. Import subrepo libc/:libc at a9e3cc6c1b529eaffef5b82934d0c47203edebe5
* Replace license identifier GPL-3.0+ with GPL-3.0-or-laterRobin Krahl2019-01-26
| | | | | | | | | Cargo uses SPDX 2.1 license identifiers. The identifier GPL-3.0+ is deprecated as of version 2.0rc2 [0]. The current license identifier for GNU General Public License v3.0 or later is GPL-3.0-or-later [1]. [0] https://spdx.org/licenses/GPL-3.0+.html [1] https://spdx.org/licenses/GPL-3.0-or-later.html
* Document known problems on macOSRobin Krahl2019-01-26
| | | | | This change adds a new section briefly elaborating on the problem of using the program on macOS and details a possible solution.
* Update nitrokey crate to 0.3.2Daniel Mueller2019-01-12
| | | | | | This change updates the nitrokey crate to version 0.3.2. Import subrepo nitrokey/:nitrokey at 6ea73f29daa5db0215663a0a38334b764863671d
* Update nitrokey-sys crate to 3.4.3Daniel Mueller2019-01-12
| | | | | | This change updates the nitrokey-sys crate to version 3.4.3. Import subrepo nitrokey-sys/:nitrokey-sys at fe86df47853718983e1f45d6a4289a1d93ace45c
* Use [patch] section to control local crate replacementsDaniel Mueller2019-01-06
| | | | | | | | | | | The nitrokey-sys crate poses a challenge in that upgrading it causes build errors caused by linking against the system's nitrokey library from multiple crates, which is not allowed. The exact cause of the problem is unclear but the suspicion is that a bug in Cargo's replacing logic is the cause of the issue. To work around this problem, this change switches to using the [patch] section for replacing crates with local copies instead of the [replace] one.
* Do not intermix path and replace attributes in Cargo.tomlDaniel Mueller2019-01-06
| | | | | | | | | | With the first usage of the nitrokey crate we have used the dependency's path attribute to perform the replacement with a local version of the source code, while most other dependencies are replaced using the [replace] section. Because the [replace] section is more flexible (it allows for replacement of transitive dependencies), this change unifies all dependencies to use it.
* Properly flush stdout before process exitDaniel Mueller2019-01-12
| | | | | | | | | | | We exit the program using the process::exit function. This function just exits the program directly, without any cleanup. That can be a problem because IO buffers may not be flushed either. For a (typically) line buffered entity like stdout that may result in data not terminated by a newline symbol being not displayed properly. This change explicitly flushes stdout before exiting the process to alleviate this problem. Note that stderr output is unaffected, because stderr is not buffered by design.
* 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.
* Remove unused fmt::Display implementation for PinTypeDaniel Mueller2019-01-11
| | | | | The implementation of the fmt::Display trait for the PinType is seemingly unused. Remove it.
* 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.
* Switch to using the system allocatorDaniel Mueller2019-01-07
| | | | | | | | | | | | | | | | | | In the past we have already taken a couple of steps to reduce the size of the final binary, arguing that binary size is the metric of most relevance for the program at hand: - the memory footprint is close to irrelevant because the program does not stay resident in memory for long - execution speed is likely dominated by communication with the Nitrokey itself, which is a slow I/O device With that in mind, this change decreases the binary size further by swapping the default allocator we use (typically jemalloc) with the system allocator (which is malloc based on Unix systems). Given that we are by no means allocation sensitive, there is no point in wasting binary size on something that adds no value. This change decreases the binary size by another 324 KiB (for an already stripped release mode binary).
* Bump version to 0.2.2Daniel Mueller2019-01-13
| | | | | | | | | | | | | | | | This change bumps the version of the crate to 0.2.2. The following notable changes have been made since 0.2.1: - Added the -v/--verbose option to control libnitrokey log level - Added the -m/--model option to restrict connections to a device model - 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
* Remove inconsistent spacing for PIN documentationDaniel Mueller2019-01-10
| | | | | | | | | The command detailed in the PIN section in the man page exhibit a larger line spacing than all the other commands documented. The reason is that we have an addition newline between each of the individual subcommands in this section. This patch removes this additional newline to achieve a more consistent appearance.
* 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.
* Add tests for pin set and pin unblock commandsDaniel Mueller2019-01-10
| | | | | | | Now that we have the infrastructure for non-interactive PIN supply in place, we can add tests for commands that require the entry of a PIN. To that end, this change adds tests for the pin set as well as pin unblock commands.
* 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.
* Introduce Admin and User PIN fields to execution contextDaniel Mueller2019-01-09
| | | | | | | | | | | | | | 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.
* Refactor integration test code internals for program invocationDaniel Mueller2019-01-10
| | | | | | | | | | | | | In the future we will need to perform a sequence of invocations of the program for testing purposes, with each having a slightly different execution context. Such a scheme does not map very well to the existing design where we essentially just have a function invocation to run the program. We would either have functions that produce a different execution context or pass in the data to modify. Neither of these approaches is appealing and so this change reworks the code slightly. With it, we now can create a Nitrocli object, which contains the data that diverges from the default execution context. This data will eventually be modifiable by callers.
* 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.
* Introduce UnwrapError trait to simplify error testingDaniel Mueller2019-01-08
| | | | | | | | For testing purposes it is beneficial to be able to check for expected errors with the least amount of boiler plate code possible. This change attempts to be a first step into this direction. It introduces a test-only trait that can be used to directly unwrap a specific error from a Result<T, crate::error::Error>.
* 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.
* Update nitrokey crate to 0.3.1Daniel Mueller2019-01-09
| | | | | | This change updates the nitrokey crate to version 0.3.1. Import subrepo nitrokey/:nitrokey at bad12ad3c57c67d42243338af7d65c3591fed327
* Add missing closing parenthesis for otp set -a/--algorithm helpDaniel Mueller2019-01-08
| | | | | The help text for the otp set -a/--algorithm option is lacking the closing parenthesis in the help text. This change adds it.
* Auto generate argument enumsDaniel Mueller2019-01-06
| | | | | | | | | | | | The argparse module we use for parsing events expects an enum in order to convey what subcommand has been supplied as an argument. Such an enum also needs to implement str::FromStr and, preferably, fmt::Display. Manually writing down those definitions is error-prone, tedious, and adds no value -- only lines of code. As it turns out the proper definitions can be generated with relative easy with a declarative macro, making the code much more concise. Hence, with this change we use a newly introduced macro for generating those enums.
* Add recipe for signing Github release source codeDaniel Mueller2018-12-24
| | | | | | | | | Upon creation of a release on Github, the platform publishes the source code. It is good practice to sign this source code, but it obviously should be verified first. The procedure is not quite as trivial as it should be and tedious to do manually. To aid the process, this change adds a Makefile recipe that contains the core logic and guides the user through the steps that are necessary.
* Add first set of integration testsDaniel Mueller2019-01-05
| | | | | | | | | This change introduces the first set of integration-style test for the application. Those tests may or may not connect to an actual Nitrokey device (depending on what they test). We use the nitrokey-test crate's test attribute macro to automatically dispatch tests to connected devices or skip them if a required device is not present. It also provides the means for automatically serializing tests.
* 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.
* Supply customizable stdio channels to argparseDaniel Mueller2019-01-05
| | | | | | | | | | | | | | | | | | | | | | | | | In order to properly test the program we need to have a way to intercept data printed to the stdio channels. There are different ways to accomplish that task. While it is reasonably easy to just start the program as a dedicated process doing so properly may be problematic from inside a test because either the path to the binary has to be retrieved or cargo -- the entity which knows the path -- be invoked. None of these approaches is very appealing from a testing and code complexity point of view: an additional fork means additional sources of errors and flakiness, executing cargo has the potential to even cause rebuilds of parts of the program, and while we are already testing against a slow I/O device this additional code running is unlikely to go unnoticed in the long-term. Lastly, doing so also means that we leave Rust's type safety behind when dealing with errors that could be nicely match'ed on when the test invocation is just a function call. To avoid all this complexity we instead strive for basically just running the main function. This patch marks a first step towards achieving this goal. It introduces the infrastructure to supply custom Write objects to the argument parsing functionality. Once more we piggy-back on the command execution context and add objects representing stdout and stderr to it. We further ensure that this context is passed to the argument parser invocations.
* 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.