Skip to content

Commit

Permalink
Mlar/repair: add a "allow-unauthenticated-data" flag
Browse files Browse the repository at this point in the history
  • Loading branch information
commial committed Sep 3, 2024
1 parent 8167553 commit 97039b1
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 1 deletion.
15 changes: 14 additions & 1 deletion mlar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,19 @@ fn open_mla_file<'a>(matches: &ArgMatches) -> Result<ArchiveReader<'a, File>, Ml
fn open_failsafe_mla_file<'a>(
matches: &ArgMatches,
) -> Result<ArchiveFailSafeReader<'a, File>, MlarError> {
let config = readerconfig_from_matches(matches);
let mut config = readerconfig_from_matches(matches);

// Safe to use unwrap() because the option is required()
let mla_file = matches.get_one::<PathBuf>("input").unwrap();
let path = Path::new(&mla_file);
let file = File::open(path)?;

// Handle authenticated/unauthenticated data
if matches.get_flag("allow_unauthenticated_data") {
eprintln!("[WARNING] Some of the data might be unauthenticated, use it at your own risk");
config.failsafe_return_data_even_unauthenticated();
}

// Instantiate reader
Ok(ArchiveFailSafeReader::from_config(file, config)?)
}
Expand Down Expand Up @@ -1161,6 +1167,13 @@ fn app() -> clap::Command {
.subcommand(
Command::new("repair")
.about("Try to repair a MLA Archive into a fresh MLA Archive")
.arg(
Arg::new("allow_unauthenticated_data")
.long("allow-unauthenticated-data")
.help("Allow extraction of unauthenticated data from the archive. USE THIS OPTION ONLY IF NECESSARY")
.action(ArgAction::SetTrue)
.required(false),
)
.args(&input_args)
.args(&output_args),
)
Expand Down
123 changes: 123 additions & 0 deletions mlar/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,129 @@ fn test_truncated_repair_list_tar() {
assert_eq!(fname2content.len(), 0);
}

#[test]
fn test_repair_auth_unauth() {
let mlar_file = NamedTempFile::new("output.mla").unwrap();
let mlar_repaired_file = NamedTempFile::new("repaired.mla").unwrap();
let ecc_public = Path::new("../samples/test_x25519_pub.pem");
let ecc_private = Path::new("../samples/test_x25519.pem");

// Create files
let testfs = setup();

// `mlar create -o output.mla -l encrypt -p samples/test_x25519_pub.pem file1.bin`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("create")
.arg("-o")
.arg(mlar_file.path())
.arg("-l")
.arg("encrypt")
.arg("-p")
.arg(ecc_public)
.arg(testfs.files[0].path());

let file_list = format!("{}\n", testfs.files[0].path().to_string_lossy());

println!("{cmd:?}");
let assert = cmd.assert();
assert.success().stderr(String::from(&file_list));

// `mlar list -i output.mla -k samples/test_x25519.pem`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("list")
.arg("-i")
.arg(mlar_file.path())
.arg("-k")
.arg(ecc_private);

println!("{cmd:?}");
let assert = cmd.assert();
assert.success().stdout(file_list.clone());

// Truncate output.mla
let mut data = Vec::new();
File::open(mlar_file.path())
.unwrap()
.read_to_end(&mut data)
.unwrap();
File::create(mlar_file.path())
.unwrap()
.write_all(&data[..data.len() * 6 / 7])
.unwrap();

// `mlar repair -i output.mla -k samples/test_x25519.pem -p samples/test_x25519_pub.pem -o repaired.mla -l encrypt`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("repair")
.arg("-i")
.arg(mlar_file.path())
.arg("-k")
.arg(ecc_private)
.arg("-p")
.arg(ecc_public)
.arg("-o")
.arg(mlar_repaired_file.path())
.arg("-l")
.arg("encrypt");

println!("{cmd:?}");
let assert = cmd.assert();
assert.success();

// `mlar cat -i repaired.mla -k samples/test_x25519.pem file1.bin`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("cat")
.arg("-i")
.arg(mlar_repaired_file.path())
.arg("-k")
.arg(ecc_private)
.arg(testfs.files[0].path());

println!("{cmd:?}");
let assert = cmd.assert();
let output_auth = assert.get_output();

// `mlar repair --allow-unauthenticated-data -i output.mla -k samples/test_x25519.pem -p samples/test_x25519_pub.pem -o repaired.mla -l encrypt`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("repair")
.arg("--allow-unauthenticated-data")
.arg("-i")
.arg(mlar_file.path())
.arg("-k")
.arg(ecc_private)
.arg("-p")
.arg(ecc_public)
.arg("-o")
.arg(mlar_repaired_file.path())
.arg("-l")
.arg("encrypt");

println!("{cmd:?}");
let assert = cmd.assert();
assert.success();

// `mlar cat -i repaired.mla -k samples/test_x25519.pem file1.bin`
let mut cmd = Command::cargo_bin(UTIL).unwrap();
cmd.arg("cat")
.arg("-i")
.arg(mlar_repaired_file.path())
.arg("-k")
.arg(ecc_private)
.arg(testfs.files[0].path());

println!("{cmd:?}");
let assert = cmd.assert();
let output_unauth = assert.get_output();

// Output unauthenticated must be longer than the authenticated one
assert!(output_unauth.stdout.len() > output_auth.stdout.len());

// Data must be the same
assert_eq!(
output_auth.stdout,
output_unauth.stdout[..output_auth.stdout.len()]
);
}

#[test]
fn test_multiple_keys() {
// Key parsing is common for each subcommands, so test only one: `list`
Expand Down

0 comments on commit 97039b1

Please sign in to comment.