summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
* 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-13
| | | | | | 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-13
| | | | | | | | | 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.2v0.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.
* 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.
* Add the base32 crate in version 0.4.0 as a dependencyRobin Krahl2019-01-13
| | | | | | | To parse OTP secrets in base32 representation, we need a new dependency: the base32 crate. Import subrepo base32/:base32 at a74cd9246fc0e08d6f5cfcb644bfdf76dd438613
* 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.
* Run unit tests as part of continuous integrationDaniel Mueller2019-01-05
| | | | | | | | | | For a while now the unit tests no longer require a Nitrokey device to be present in order to run. Right now that is because we lack device specific tests, but even in the future we will take measures to not fail when a device is not present (by default). Hence, there is no reason not to run the unit tests as part of the continuous integration pipeline. To that end, this change adds them to said pipeline.
* 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.
* Bump version to 0.2.1v0.2.1Daniel Mueller2019-01-07
| | | | | | | | | | | | | This change bumps the version of the crate to 0.2.1. The following notable changes have been made since 0.2.0: - Added the pws command for accessing the password safe - Added the lock command for locking the Nitrokey device - Adjust release build compile options to optimize binary for size - Bumped nitrokey dependency to 0.2.3 - Bumped rand dependency to 0.6.1 - Added rustc_version version 0.2.3, semver version 0.9.0, and semver-parser version 0.7.0 as indirect dependencies - Bumped cc dependency to 1.0.28
* Properly report io::Error objectsDaniel Mueller2019-01-06
| | | | | | | | | | We have a Result::unwrap in the error path of handling io::Error objects. I have actually seen that fail, masking the original error. We should not unwrap there and in fact we don't have to, as io::Error implements fmt::Display just fine. This may have changed in the past, as the construct we had is much more convoluted than necessary and would only have been written if a direct formatting was not possible.
* Reference official Gentoo ebuild from READMEDaniel Mueller2019-01-05
| | | | | | | | By now the nitrocli ebuild has been upstreamed for recent releases and is available in the official Gentoo Portage tree. This change updates the references to the Gentoo ebuild in the README from the custom Github mirror to the official Gentoo Portage tree to move users towards using the official ebuild.
* 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.
* Add 'nitrokey-pro' keyword to Cargo.tomlDaniel Mueller2019-01-04
| | | | | | | | For a while now the program has supported the Nitrokey Pro device in addition to the Nitrokey Storage. To reflect this change, this patch adjusts the keywords in Cargo.toml to include 'nitrokey-pro' as well. In order to not exceed the crates.io imposed limit, it removes the 'hid' keyword.
* Remove 'test' target from MakefileDaniel Mueller2019-01-04
| | | | | | | | | | A while ago we removed all device specific tests from the project as part of the move to using the nitrokey crate. While adding additional tests is a work in progress, the intention is to have them run solely by issuing 'cargo test'. In any case, this change removes the 'test' target from the Makefile as it is no longer needed, because all tests can run concurrently just fine.
* 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.
* Update nitrokey crate to 0.2.3Daniel Mueller2019-01-02
| | | | | | | | | | | | This change updates the nitrokey crate to version 0.2.3. This version bumps the rand crate used to 0.6.1, which in turn requires an additional set of dependencies. Import subrepo nitrokey/:nitrokey at b3e2adc5bb1300441ca74cc7672617c042f3ea31 Import subrepo rand/:rand at 73613ff903512e9503e41cc8ba9eae76269dc598 Import subrepo rustc_version/:rustc_version at 0294f2ba2018bf7be672abd53db351ce5055fa02 Import subrepo semver-parser/:semver-parser at 750da9b11a04125231b1fb293866ca036845acee Import subrepo semver/:semver at 5eb6db94fa03f4d5c64a625a56188f496be47598
* Adjust clippy target in Gitlab CIDaniel Mueller2019-01-01
| | | | | | | | | | | The clippy target as executed by the Gitlab CI excludes a bunch of lints when performing an initial run. That is necessary because some of the source code we rely on violates those rules and would cause the target to fail. The problem with the approach taken is that we list all the individual failing lints, which quickly becomes a maintenance burden. As it turns out clippy has the clippy::all meta-lint that subsumes all of the explicitly specified ones and so with this change we use that instead.
* Adjust README to reflect that we support Pro & Storage devicesDaniel Mueller2019-01-02
| | | | | This change adjusts the README to reflect that we support both Nitrokey Pro and Nitrokey Storage devices with the program.
* Update cc crate to 1.0.28Daniel Mueller2019-01-01
| | | | | | This change updates the cc crate to version 1.0.28. Import subrepo cc/:cc at 9490b5ecb43b8b926f96a7e484fa83e39620d8e5
* Add packaging documentationRobin Krahl2019-01-07
| | | | | | | To make life easier for possible future maintainers, this change documentes the packaging process for Arch Linux and Debian in the doc/packaging.md file. Note that nitrocli is not yet packaged for Debian, so that section is hypothetical.
* Document the lock commandRobin Krahl2019-01-07
| | | | | | This patch adds documentation and examples for the lock command to the README and to the man page. It also adds the lock command to the top-level help message.
* Document the pws commandsRobin Krahl2019-01-07
| | | | | This patch adds documentation and examples for the pws commands to the README and to the man page.
* Enable LTO and more optimizations for release buildsDaniel Mueller2018-12-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The program's binary is more than 1,5 MiB in size (after stripping debug symbols). Although in general that is not a size to worry about, keeping a small binary and memory footprint is beneficial in the majority of cases and leaves a tangentially better impression with users. To that end, this change enables the following optimizations to be performed when creating a release build: 1) We compile with optimization for code size. We have no performance sensitive code and are communicating with a slow I/O device to begin with, meaning that binary size will ultimately have the most weight when judging the program. Hence, minimizing it seems like the best trade-off. 2) We enable link-time optimization (LTO). At the expense of compilation time (which is not a concern for what may almost be considered a one-off operation), this step can reduce binary size by eliminating more unused code as well as enable performance related optimizations not possible without this setting. For similar reasons we disable incremental builds and treat the entire compilation as one unit. The end result of these optimizations is a reduction of binary size by almost a fourth (420 KiB). Those optimizations come at little to no cost (depending on one's view). There is another one that we could enable and that is to abort on panics instead of unwinding, yielding savings of 44 KiB. However, we refrained from doing so because that has a negative impact on the amount of error reporting happening in case of a panic.