aboutsummaryrefslogtreecommitdiff
path: root/nitrocli/src
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-06-08 11:02:12 -0700
committerDaniel Mueller <deso@posteo.net>2019-06-08 11:02:12 -0700
commita83454bcc9cb3f7d10b4ee5926490c80b222430b (patch)
tree3a48e86219c175258130c3854287d08b7b046597 /nitrocli/src
parent74be24daf592f3408524081c3760ca153294d643 (diff)
downloadnitrocli-a83454bcc9cb3f7d10b4ee5926490c80b222430b.tar.gz
nitrocli-a83454bcc9cb3f7d10b4ee5926490c80b222430b.tar.bz2
Add support for changing read-write mode of unencrypted volume
This change adds support for changing the read-write mode of the unencrypted volume. To do so, we introduce a new top-level command, unencrypted, with a new subcommand, set, that accepts the new mode of the volume.
Diffstat (limited to 'nitrocli/src')
-rw-r--r--nitrocli/src/args.rs50
-rw-r--r--nitrocli/src/commands.rs24
-rw-r--r--nitrocli/src/tests/mod.rs1
-rw-r--r--nitrocli/src/tests/unencrypted.rs41
4 files changed, 116 insertions, 0 deletions
diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs
index 16ff314..ae09c07 100644
--- a/nitrocli/src/args.rs
+++ b/nitrocli/src/args.rs
@@ -129,6 +129,7 @@ Enum! {Command, [
Pws => ("pws", pws),
Reset => ("reset", reset),
Status => ("status", status),
+ Unencrypted => ("unencrypted", unencrypted),
]}
Enum! {ConfigCommand, [
@@ -247,6 +248,55 @@ fn reset(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
commands::reset(ctx)
}
+Enum! {UnencryptedCommand, [
+ Set => ("set", unencrypted_set),
+]}
+
+Enum! {UnencryptedVolumeMode, [
+ ReadWrite => "read-write",
+ ReadOnly => "read-only",
+]}
+
+/// Execute an unencrypted subcommand.
+fn unencrypted(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
+ let mut subcommand = UnencryptedCommand::Set;
+ let help = cmd_help!(subcommand);
+ let mut subargs = vec![];
+ let mut parser = argparse::ArgumentParser::new();
+ parser.set_description("Interacts with the device's unencrypted volume");
+ let _ =
+ parser
+ .refer(&mut subcommand)
+ .required()
+ .add_argument("subcommand", argparse::Store, &help);
+ let _ = parser.refer(&mut subargs).add_argument(
+ "arguments",
+ argparse::List,
+ "The arguments for the subcommand",
+ );
+ parser.stop_on_first_argument(true);
+ parse(ctx, parser, args)?;
+
+ subargs.insert(0, format!("nitrocli {}", subcommand));
+ subcommand.execute(ctx, subargs)
+}
+
+/// Change the configuration of the unencrypted volume.
+fn unencrypted_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> {
+ let mut mode = UnencryptedVolumeMode::ReadWrite;
+ let help = format!("The mode to change to ({})", fmt_enum!(mode));
+ let mut parser = argparse::ArgumentParser::new();
+ parser
+ .set_description("Changes the configuration of the unencrypted volume on a Nitrokey Storage");
+ let _ = parser
+ .refer(&mut mode)
+ .required()
+ .add_argument("type", argparse::Store, &help);
+ parse(ctx, parser, args)?;
+
+ commands::unencrypted_set(ctx, mode)
+}
+
Enum! {EncryptedCommand, [
Close => ("close", encrypted_close),
Open => ("open", encrypted_open),
diff --git a/nitrocli/src/commands.rs b/nitrocli/src/commands.rs
index 3cad8f1..8db5cd8 100644
--- a/nitrocli/src/commands.rs
+++ b/nitrocli/src/commands.rs
@@ -361,6 +361,30 @@ pub fn reset(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
})
}
+/// Change the configuration of the unencrypted volume.
+pub fn unencrypted_set(
+ ctx: &mut args::ExecCtx<'_>,
+ mode: args::UnencryptedVolumeMode,
+) -> Result<()> {
+ let device = get_storage_device(ctx)?;
+ let pin_entry = pinentry::PinEntry::from(pinentry::PinType::Admin, &device)?;
+ let mode = match mode {
+ args::UnencryptedVolumeMode::ReadWrite => nitrokey::VolumeMode::ReadWrite,
+ args::UnencryptedVolumeMode::ReadOnly => nitrokey::VolumeMode::ReadOnly,
+ };
+
+ // The unencrypted volume may reconnect, so be sure to flush caches to
+ // disk.
+ unsafe { sync() };
+
+ try_with_pin(
+ ctx,
+ &pin_entry,
+ "Changing unencrypted volume mode failed",
+ |pin| device.set_unencrypted_volume_mode(&pin, mode),
+ )
+}
+
/// Open the encrypted volume on the Nitrokey.
pub fn encrypted_open(ctx: &mut args::ExecCtx<'_>) -> Result<()> {
let device = get_storage_device(ctx)?;
diff --git a/nitrocli/src/tests/mod.rs b/nitrocli/src/tests/mod.rs
index 70a3d20..2f2926f 100644
--- a/nitrocli/src/tests/mod.rs
+++ b/nitrocli/src/tests/mod.rs
@@ -46,6 +46,7 @@ mod pws;
mod reset;
mod run;
mod status;
+mod unencrypted;
/// A trait simplifying checking for expected errors.
pub trait UnwrapError {
diff --git a/nitrocli/src/tests/unencrypted.rs b/nitrocli/src/tests/unencrypted.rs
new file mode 100644
index 0000000..c976f50
--- /dev/null
+++ b/nitrocli/src/tests/unencrypted.rs
@@ -0,0 +1,41 @@
+// unencrypted.rs
+
+// *************************************************************************
+// * Copyright (C) 2019 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 super::*;
+
+#[test_device]
+fn unencrypted_set_read_write(device: nitrokey::Storage) -> crate::Result<()> {
+ let mut ncli = Nitrocli::with_dev(device);
+ let out = ncli.handle(&["unencrypted", "set", "read-write"])?;
+ assert!(out.is_empty());
+
+ let device = nitrokey::Storage::connect()?;
+ assert!(device.get_status()?.unencrypted_volume.active);
+ assert!(!device.get_status()?.unencrypted_volume.read_only);
+ drop(device);
+
+ let out = ncli.handle(&["unencrypted", "set", "read-only"])?;
+ assert!(out.is_empty());
+
+ let device = nitrokey::Storage::connect()?;
+ assert!(device.get_status()?.unencrypted_volume.active);
+ assert!(device.get_status()?.unencrypted_volume.read_only);
+
+ Ok(())
+}