diff options
author | Daniel Mueller <deso@posteo.net> | 2017-03-26 17:31:28 -0700 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2017-03-26 17:31:28 -0700 |
commit | de5ae8656387267bb4614bbab6b62784323f23c0 (patch) | |
tree | 7be8d72b26b0ae355d5e157c2f36ccb30d6fa347 | |
parent | cd6e41862cea59ec306e7c9c578270575eb2a73b (diff) | |
download | nitrocli-de5ae8656387267bb4614bbab6b62784323f23c0.tar.gz nitrocli-de5ae8656387267bb4614bbab6b62784323f23c0.tar.bz2 |
Discover and open nictrokey using libhidapi
This change uses the 'hid' crate to discover and open the Nitrokey
Storage device. 'hid' is a wrapper around libhidapi (its libusb back-end
in particular).
Being a command line application some sort of parameter handling needs
to happen. The approach we take is very simple for now to minimize the
number of dependencies: we just compare the first argument against the
expected ones and raise an error if no match was found. Because we only
have positional arguments right now this is all we need.
-rw-r--r-- | nitrocli/Cargo.lock | 65 | ||||
-rw-r--r-- | nitrocli/Cargo.toml | 22 | ||||
-rw-r--r-- | nitrocli/src/error.rs | 45 | ||||
-rw-r--r-- | nitrocli/src/main.rs | 85 | ||||
-rw-r--r-- | nitrocli/src/nitrokey.rs | 24 |
5 files changed, 240 insertions, 1 deletions
diff --git a/nitrocli/Cargo.lock b/nitrocli/Cargo.lock index 8da0130..6a6d315 100644 --- a/nitrocli/Cargo.lock +++ b/nitrocli/Cargo.lock @@ -1,4 +1,69 @@ [root] name = "nitrocli" version = "0.1.0" +dependencies = [ + "gcc 0.3.45", + "hid 0.3.0", + "hidapi-sys 0.1.2", + "libc 0.2.21", + "pkg-config 0.3.9", +] +[[package]] +name = "gcc" +version = "0.3.45" + +[[package]] +name = "gcc" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +replace = "gcc 0.3.45" + +[[package]] +name = "hid" +version = "0.3.0" +dependencies = [ + "hidapi-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hidapi-sys" +version = "0.1.2" +dependencies = [ + "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hidapi-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +replace = "hidapi-sys 0.1.2" + +[[package]] +name = "libc" +version = "0.2.21" + +[[package]] +name = "libc" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +replace = "libc 0.2.21" + +[[package]] +name = "pkg-config" +version = "0.3.9" + +[[package]] +name = "pkg-config" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +replace = "pkg-config 0.3.9" + +[metadata] +"checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae" +"checksum hidapi-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "63829a2802510a8a4e3a52e1fa2fb969b8cd0826da65e04d79bd095eae21e050" +"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" diff --git a/nitrocli/Cargo.toml b/nitrocli/Cargo.toml index ceaf276..1ee63fb 100644 --- a/nitrocli/Cargo.toml +++ b/nitrocli/Cargo.toml @@ -29,3 +29,25 @@ keywords = ["hid", "nitrokey", "nitrokey-storage", "usb", "cli"] description = """ A command line tool for interacting with the Nitrokey Storage device. """ + +[dependencies.gcc] +path = "../gcc" + +[dependencies.hid] +path = "../hid" + +[dependencies.hidapi-sys] +path = "../hidapi-sys" + +[dependencies.libc] +path = "../libc" + +[dependencies.pkg-config] +path = "../pkg-config" + +[replace] +"gcc:0.3.45" = { path = "../gcc" } +"hid:0.3.0" = { path = "../hid" } +"hidapi-sys:0.1.2" = { path = "../hidapi-sys" } +"libc:0.2.21" = { path = "../libc" } +"pkg-config:0.3.9" = { path = "../pkg-config" } diff --git a/nitrocli/src/error.rs b/nitrocli/src/error.rs new file mode 100644 index 0000000..65992f0 --- /dev/null +++ b/nitrocli/src/error.rs @@ -0,0 +1,45 @@ +// error.rs + +// ************************************************************************* +// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * * +// * This program is free software: you can redistribute it and/or modify * +// * it under the terms of the GNU General Public License as published by * +// * the Free Software Foundation, either version 3 of the License, or * +// * (at your option) any later version. * +// * * +// * This program is distributed in the hope that it will be useful, * +// * but WITHOUT ANY WARRANTY; without even the implied warranty of * +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +// * GNU General Public License for more details. * +// * * +// * You should have received a copy of the GNU General Public License * +// * along with this program. If not, see <http://www.gnu.org/licenses/>. * +// ************************************************************************* + +use libhid; +use std::fmt; + + +#[derive(Debug)] +pub enum Error { + HidError(libhid::Error), + Error(String), +} + + +impl From<libhid::Error> for Error { + fn from(e: libhid::Error) -> Error { + return Error::HidError(e); + } +} + + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *&self { + &Error::HidError(ref e) => return write!(f, "hidapi error: {}", e), + &Error::Error(ref e) => return write!(f, "{}", e), + } + } +} diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs index 57e6a7a..bdbfe37 100644 --- a/nitrocli/src/main.rs +++ b/nitrocli/src/main.rs @@ -18,7 +18,90 @@ // ************************************************************************* +#![deny(missing_docs)] + +//! Nitrocli is a program providing a command line interface to certain +//! commands of the Nitrokey Storage device. + +extern crate hid as libhid; + + +mod error; +mod nitrokey; + +use error::Error; +use std::process; +use std::result; + +type Result<T> = result::Result<T, Error>; +type NitroFunc = Fn(&mut libhid::Handle) -> Result<()>; + + +/// Find and open the nitrokey device and execute a function on it. +fn nitrokey_do(function: &NitroFunc) -> Result<()> { + let hid = libhid::init()?; + // The Manager::find method is plain stupid as it still returns an + // iterable. Using it does not help in more concise error handling. + for device in hid.devices() { + if device.vendor_id() == nitrokey::VID && device.product_id() == nitrokey::PID { + return function(&mut device.open()?); + } + } + return Err(Error::Error("Nitrokey device not found".to_string())); +} + + +/// Open the encrypted volume on the nitrokey. +fn open() -> Result<()> { + return nitrokey_do(&|handle| { + println!("Found nitrokey. Opening encrypted volume..."); + return Ok(()); + }); +} + + +/// Close the previously opened encrypted volume. +fn close() -> Result<()> { + return nitrokey_do(&|handle| { + println!("Found nitrokey. Closing encrypted volume..."); + return Ok(()); + }); +} + + +// A macro for generating a match of the different supported commands. +// Each supplied command is converted into a string and matched against. +macro_rules! commands { + ( $str:expr, [ $( $command:expr), *] ) => { + match &*$str.to_string() { + $( + stringify!($command) => { + if let Err(err) = $command() { + println!("{}", err); + return 1 + } + return 0 + }, + )* + x => { + println!("Invalid command: {}", x); + println!("Available commands: {}", stringify!( $($command)* )); + return 1 + }, + } + } +} + +fn run() -> i32 { + let argv: Vec<String> = std::env::args().collect(); + if argv.len() != 2 { + println!("Usage: {} <command>", argv[0]); + return 1; + } + + commands!(&argv[1], [open, close]); +} fn main() { - println!("Hello, world!"); + process::exit(run()); } diff --git a/nitrocli/src/nitrokey.rs b/nitrocli/src/nitrokey.rs new file mode 100644 index 0000000..763bc4c --- /dev/null +++ b/nitrocli/src/nitrokey.rs @@ -0,0 +1,24 @@ +// nitrokey.rs + +// ************************************************************************* +// * Copyright (C) 2017 Daniel Mueller (deso@posteo.net) * +// * * +// * This program is free software: you can redistribute it and/or modify * +// * it under the terms of the GNU General Public License as published by * +// * the Free Software Foundation, either version 3 of the License, or * +// * (at your option) any later version. * +// * * +// * This program is distributed in the hope that it will be useful, * +// * but WITHOUT ANY WARRANTY; without even the implied warranty of * +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +// * GNU General Public License for more details. * +// * * +// * You should have received a copy of the GNU General Public License * +// * along with this program. If not, see <http://www.gnu.org/licenses/>. * +// ************************************************************************* + + +// The Nitrokey Storage vendor ID. +pub const VID: u16 = 0x20A0; +// The Nitrokey Storage product ID. +pub const PID: u16 = 0x4109; |