proxmox_backup_client key: allow to generate paperkey for master key

This commit is contained in:
Dietmar Maurer 2020-09-29 08:19:33 +02:00
parent 82a0cd2ad4
commit b02d49ab26
2 changed files with 72 additions and 16 deletions

2
debian/control vendored
View File

@ -118,7 +118,7 @@ Description: Proxmox Backup Server daemon with tools and GUI
Package: proxmox-backup-client Package: proxmox-backup-client
Architecture: any Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends} Depends: qrencode ${misc:Depends}, ${shlibs:Depends}
Description: Proxmox Backup Client tools Description: Proxmox Backup Client tools
This package contains the Proxmox Backup client, which provides a This package contains the Proxmox Backup client, which provides a
simple command line tool to create and restore backups. simple command line tool to create and restore backups.

View File

@ -293,31 +293,63 @@ fn paper_key(path: Option<String>, subject: Option<String>) -> Result<(), Error>
}; };
let data = file_get_contents(&path)?; let data = file_get_contents(&path)?;
let key_config: KeyConfig = serde_json::from_slice(&data)?; let data = std::str::from_utf8(&data)?;
let key_text = serde_json::to_string_pretty(&key_config)?;
if let Some(subject) = subject { if let Some(subject) = subject {
println!("Subject: {}\n", subject); println!("Subject: {}\n", subject);
} }
if data.starts_with("-----BEGIN ENCRYPTED PRIVATE KEY-----\n") {
//let rsa = openssl::rsa::Rsa::private_key_from_pem(data.as_bytes())?;
let lines: Vec<String> = data.lines()
.map(|s| s.trim_end())
.filter(|s| !s.is_empty())
.map(String::from)
.collect();
if !lines[lines.len()-1].starts_with("-----END ENCRYPTED PRIVATE KEY-----") {
bail!("unexpected key format");
}
if lines.len() < 20 {
bail!("unexpected key format");
}
const BLOCK_SIZE: usize = 5;
let blocks = (lines.len() + BLOCK_SIZE -1)/BLOCK_SIZE;
for i in 0..blocks {
let start = i*BLOCK_SIZE;
let mut end = start + BLOCK_SIZE;
if end > lines.len() {
end = lines.len();
}
let data = &lines[start..end];
for l in start..end {
println!("LINE {:-2}: {}", l, lines[l]);
}
let data = data.join("\n");
let qr_code = generate_qr_code("utf8i", data.as_bytes())?;
println!("{}", qr_code);
println!("{}", char::from(12u8)); // page break
}
return Ok(());
}
let key_config: KeyConfig = serde_json::from_str(&data)?;
let key_text = serde_json::to_string_pretty(&key_config)?;
println!("-----BEGIN PROXMOX BACKUP KEY-----"); println!("-----BEGIN PROXMOX BACKUP KEY-----");
println!("{}", key_text); println!("{}", key_text);
println!("-----END PROXMOX BACKUP KEY-----"); println!("-----END PROXMOX BACKUP KEY-----");
let mut child = Command::new("qrencode") let qr_code = generate_qr_code("utf8i", key_text.as_bytes())?;
.args(&["-t", "utf8i", "-lm"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
{ println!("{}", qr_code);
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
stdin.write_all(key_text.as_bytes()).expect("Failed to write to stdin");
}
let output = child.wait_with_output().expect("Failed to read stdout");
println!("{}", String::from_utf8_lossy(&output.stdout));
Ok(()) Ok(())
} }
@ -348,3 +380,27 @@ pub fn cli() -> CliCommandMap {
.insert("change-passphrase", key_change_passphrase_cmd_def) .insert("change-passphrase", key_change_passphrase_cmd_def)
.insert("paper-key", paper_key_cmd_def) .insert("paper-key", paper_key_cmd_def)
} }
fn generate_qr_code(output_type: &str, data: &[u8]) -> Result<String, Error> {
let mut child = Command::new("qrencode")
.args(&["-t", output_type, "-lm"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
{
let stdin = child.stdin.as_mut()
.ok_or_else(|| format_err!("Failed to open stdin"))?;
stdin.write_all(data)
.map_err(|_| format_err!("Failed to write to stdin"))?;
}
let output = child.wait_with_output()
.map_err(|_| format_err!("Failed to read stdout"))?;
let output = String::from_utf8(output.stdout)
.map_err(|_| format_err!("Failed to read stdout (got non-utf8 data)"))?;
Ok(output)
}