Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/cdrw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,28 @@ impl CdReader {
eject(&self.device)
}

pub fn is_cd_present(&self) -> Result<bool> {
let mut cmd = Command::new("blockdev");
let cmd = cmd.arg("--getsize64").arg(&self.device);

debug!("execting command: {:?}", cmd);
let output = cmd
.output()
.context("faild to execute blockdev, check PATH")?;

if output.status.success() {
debug!("disk detected in drive, continuing");
Ok(true)
} else {
debug!("no disk in drive");
Ok(false)
}
}

pub fn wait_for_media(&self) -> Result<()> {
wait_for_media(&self.device)
}

pub fn read(&self, name: &str) -> Result<Vec<u8>> {
let tmpdir = tempdir()?;

Expand Down
61 changes: 40 additions & 21 deletions src/secret_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use anyhow::{anyhow, Context, Result};
use clap::{Args, ValueEnum};
use glob::Paths;
use log::debug;
use log::{debug, info};
use std::{
env,
io::{self, Read, Write},
Expand Down Expand Up @@ -111,29 +111,48 @@ impl CdrPasswordReader {

impl PasswordReader for CdrPasswordReader {
fn read(&mut self, _prompt: &str) -> Result<Zeroizing<String>> {
match self.cdr.eject() {
Ok(()) => (),
Err(e) => return Err(e),
}

print!(
"Place authentication CD in the drive, close the drive, then press \n\
the \"Enter\" key to continue: "
);
match io::stdout().flush() {
Ok(()) => (),
Err(e) => return Err(e.into()),
}
util::wait_for_line()?;
let passwd = loop {
// if no cd is in the drive
if !self.cdr.is_cd_present()? {
get_media(&self.cdr)?;
}
// try to read
match self.cdr.read("password") {
Err(_) => {
// failed to read from the password file
info!("Failed to read password from CD");
get_media(&self.cdr)?;
}
// return password wrapped in Zeroizing
Ok(p) => break Zeroizing::new(String::from_utf8(p)?),
}
};
Ok(passwd)
}
}

// Passwords are utf8 and `String::from_utf8` explicitly does *not*
// copy the Vec<u8>.
let password = self.cdr.read("password")?;
let password = Zeroizing::new(String::from_utf8(password)?);
debug!("read password: {:?}", password.deref());
fn get_media(cdr: &CdReader) -> Result<()> {
// eject the drive
match cdr.eject() {
Ok(()) => (),
Err(e) => return Err(e),
}

Ok(password)
// prompt user for the cd
print!(
"Place authentication CD in the drive, close the drive, then press \n\
the \"Enter\" key to continue: "
);
match io::stdout().flush() {
Ok(()) => (),
Err(e) => return Err(e.into()),
}

// wait for user to press enter
util::wait_for_line()?;

// wait for media to "settle"
cdr.wait_for_media()
}

#[derive(Args, Clone, Debug, Default)]
Expand Down
Loading