| Commit message (Collapse) | Author | Age |
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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>.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
This change updates the nitrokey crate to version 0.3.1.
Import subrepo nitrokey/:nitrokey at bad12ad3c57c67d42243338af7d65c3591fed327
|
|
|
|
|
| |
The help text for the otp set -a/--algorithm option is lacking the
closing parenthesis in the help text. This change adds it.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
To parse OTP secrets in base32 representation, we need a new dependency:
the base32 crate.
Import subrepo base32/:base32 at a74cd9246fc0e08d6f5cfcb644bfdf76dd438613
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
This change updates the nitrokey crate to version 0.3.0.
Import subrepo nitrokey/:nitrokey at 3593df8844b80741e2d33c8e5af80e65760dc058
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
This change adjusts the README to reflect that we support both Nitrokey
Pro and Nitrokey Storage devices with the program.
|
|
|
|
|
|
| |
This change updates the cc crate to version 1.0.28.
Import subrepo cc/:cc at 9490b5ecb43b8b926f96a7e484fa83e39620d8e5
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
This patch adds documentation and examples for the pws commands to the
README and to the man page.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
This patch implements the pws status command that can be used to print
status information for the slots in the password safe.
|
|
|
|
|
| |
This patch implements the pws clear command which allows the user to
clear a slot in the password safe.
|
|
|
|
| |
This patch adds the pws set subcommand that writes a PWS slot.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
This patch adds the basic structure for the pws command that can be used
to access the password safe on the Nitrokey Pro and Nitrokey Storage.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change bumps the version of the crate to 0.2.0. The following
notable changes have been made since 0.1.3:
- Use the nitrokey crate for the 'open', 'close', and 'status'
commands instead of directly communicating with the Nitrokey device
- Added nitrokey version 0.2.1 as a direct dependency and
nitrokey-sys version 3.4.1 as well as rand version 0.4.3 as
indirect dependencies
- Removed the hid, hidapi-sys and pkg-config dependencies
- Added the 'otp' command for working with one-time passwords
- Added the 'config' command for reading and writing the device configuration
- Added the 'pin' command for managing PINs
- Renamed the 'clear' command to 'pin clear'
- Moved 'open' and 'close' commands as subcommands into newly introduced
'storage' command
- Moved printing of storage related information from 'status' command
into new 'storage status' subcommand
- Made 'status' command work with Nitrokey Pro devices
- Enabled CI pipeline comprising code style conformance checks, linting,
and building of the project
- Added badges indicating pipeline status, current crates.io published
version of the crate, and minimum version of rustc required
- Fixed wrong messages in the pinentry dialog that were caused by unescaped
spaces in a string
- Use the argparse crate to parse the command-line arguments
- Added argparse dependency in version 0.2.2
|
|
|
|
|
|
| |
This change adds a new file, CONTRIBUTING.md, that details some
generally applicable rules for the contribution to this project. It also
links this file from the README.
|