From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dietmar@proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (2048 bits))
 (No client certificate requested)
 by lists.proxmox.com (Postfix) with ESMTPS id 9DB5F61E6F
 for <pbs-devel@lists.proxmox.com>; Mon, 28 Sep 2020 18:27:47 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 932CA83AA
 for <pbs-devel@lists.proxmox.com>; Mon, 28 Sep 2020 18:27:17 +0200 (CEST)
Received: from elsa.proxmox.com (212-186-127-178.static.upcbusiness.at
 [212.186.127.178])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 3F637839E
 for <pbs-devel@lists.proxmox.com>; Mon, 28 Sep 2020 18:27:16 +0200 (CEST)
Received: by elsa.proxmox.com (Postfix, from userid 0)
 id 0EA4AAE4710; Mon, 28 Sep 2020 18:27:16 +0200 (CEST)
From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Date: Mon, 28 Sep 2020 18:27:12 +0200
Message-Id: <20200928162712.13867-1-dietmar@proxmox.com>
X-Mailer: git-send-email 2.20.1
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 AWL -1.077 Adjusted score from AWL reputation of From: address
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pbs-devel] [PATCH proxmox-backup] proxmox_backup_client key: add
 new paper-key command
X-BeenThere: pbs-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox Backup Server development discussion
 <pbs-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/>
List-Post: <mailto:pbs-devel@lists.proxmox.com>
List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, 
 <mailto:pbs-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Mon, 28 Sep 2020 16:27:47 -0000

---
 debian/control.in                    |  2 +-
 src/bin/proxmox_backup_client/key.rs | 67 ++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/debian/control.in b/debian/control.in
index 8e2312d..2e6d82f 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -19,7 +19,7 @@ Description: Proxmox Backup Server daemon with tools and GUI
 
 Package: proxmox-backup-client
 Architecture: any
-Depends: ${misc:Depends}, ${shlibs:Depends}
+Depends: qrencode ${misc:Depends}, ${shlibs:Depends}
 Description: Proxmox Backup Client tools
  This package contains the Proxmox Backup client, which provides a
  simple command line tool to create and restore backups.
diff --git a/src/bin/proxmox_backup_client/key.rs b/src/bin/proxmox_backup_client/key.rs
index f60687e..e87f048 100644
--- a/src/bin/proxmox_backup_client/key.rs
+++ b/src/bin/proxmox_backup_client/key.rs
@@ -1,4 +1,6 @@
 use std::path::PathBuf;
+use std::io::Write;
+use std::process::{Stdio, Command};
 
 use anyhow::{bail, format_err, Error};
 use serde::{Deserialize, Serialize};
@@ -261,6 +263,66 @@ fn create_master_key() -> Result<(), Error> {
     Ok(())
 }
 
+#[api(
+    input: {
+        properties: {
+            path: {
+                description: "Key file. Without this the default key's will be used.",
+                optional: true,
+            },
+            subject: {
+                description: "Include the specified subject as titel text.",
+                optional: true,
+            },
+        },
+    },
+)]
+/// Generate a printable, human readable text file containing the encryption key.
+///
+/// This also includes a scanable QR code for fast key restore.
+fn paper_key(path: Option<String>, subject: Option<String>) -> Result<(), Error> {
+    let path = match path {
+        Some(path) => PathBuf::from(path),
+        None => {
+            let path = find_default_encryption_key()?
+                .ok_or_else(|| {
+                    format_err!("no encryption file provided and no default file found")
+                })?;
+            path
+        }
+    };
+
+    let data = file_get_contents(&path)?;
+    let key_config: KeyConfig = serde_json::from_slice(&data)?;
+    let key_text = serde_json::to_string_pretty(&key_config)?;
+
+    if let Some(subject) = subject {
+        println!("Subject: {}\n", subject);
+    }
+
+    println!("-----BEGIN PROXMOX BACKUP KEY-----");
+    println!("{}", key_text);
+    println!("-----END PROXMOX BACKUP KEY-----");
+
+    let mut child = Command::new("qrencode")
+        .args(&["-t", "utf8i", "-lm"])
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()?;
+
+    {
+        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(())
+}
+
+
 pub fn cli() -> CliCommandMap {
     let key_create_cmd_def = CliCommand::new(&API_METHOD_CREATE)
         .arg_param(&["path"])
@@ -275,9 +337,14 @@ pub fn cli() -> CliCommandMap {
         .arg_param(&["path"])
         .completion_cb("path", tools::complete_file_name);
 
+    let paper_key_cmd_def = CliCommand::new(&API_METHOD_PAPER_KEY)
+        .arg_param(&["path"])
+        .completion_cb("path", tools::complete_file_name);
+
     CliCommandMap::new()
         .insert("create", key_create_cmd_def)
         .insert("create-master-key", key_create_master_key_cmd_def)
         .insert("import-master-pubkey", key_import_master_pubkey_cmd_def)
         .insert("change-passphrase", key_change_passphrase_cmd_def)
+        .insert("paper-key", paper_key_cmd_def)
 }
-- 
2.20.1