summaryrefslogtreecommitdiffstats
path: root/fish/inspect.c
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2010-11-05 11:39:24 +0000
committerRichard W.M. Jones <rjones@redhat.com>2010-11-05 11:39:24 +0000
commita232e62dcf508517a32b9a8d7e4529e827be721b (patch)
tree8fccb1e49fd75aacbc7190eb55685525b6df0f88 /fish/inspect.c
parent446db62e113594fef84d2f533ef3a1330153f0bb (diff)
downloadlibguestfs-a232e62dcf508517a32b9a8d7e4529e827be721b.tar.gz
libguestfs-a232e62dcf508517a32b9a8d7e4529e827be721b.tar.xz
libguestfs-a232e62dcf508517a32b9a8d7e4529e827be721b.zip
fish: '-i' option automatically handles whole-disk encryption.
This feature is also available in guestmount because of the shared option parsing code. You don't need to do anything to enable it, just using -i will attempt decryption of encrypted partitions. Only works for simple Fedora whole-disk encryption. It's a work-in-progress to make it work for other types of encryption.
Diffstat (limited to 'fish/inspect.c')
-rw-r--r--fish/inspect.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/fish/inspect.c b/fish/inspect.c
index 8e56553d..cc3916b1 100644
--- a/fish/inspect.c
+++ b/fish/inspect.c
@@ -22,10 +22,14 @@
#include <stdlib.h>
#include <string.h>
+#include "c-ctype.h"
+
#include "guestfs.h"
#include "options.h"
+static void do_decrypt (void);
+
/* Global that saves the root device between inspect_mount and
* print_inspect_prompt.
*/
@@ -71,6 +75,8 @@ compare_keys (const void *p1, const void *p2)
void
inspect_mount (void)
{
+ do_decrypt ();
+
char **roots = guestfs_inspect_os (g);
if (roots == NULL)
exit (EXIT_FAILURE);
@@ -139,3 +145,73 @@ print_inspect_prompt (void)
free_strings (mountpoints);
}
+
+/* Make a LUKS map name from the partition name,
+ * eg "/dev/vda2" => "luksvda2"
+ */
+static void
+make_mapname (const char *device, char *mapname, size_t len)
+{
+ size_t i = 0;
+
+ if (len < 5)
+ abort ();
+ strcpy (mapname, "luks");
+ mapname += 4;
+ len -= 4;
+
+ if (STRPREFIX (device, "/dev/"))
+ i = 5;
+
+ for (; device[i] != '\0' && len >= 1; ++i) {
+ if (c_isalnum (device[i])) {
+ *mapname++ = device[i];
+ len--;
+ }
+ }
+
+ *mapname = '\0';
+}
+
+/* Simple implementation of decryption: look for any crypto_LUKS
+ * partitions and decrypt them, then rescan for VGs. This only works
+ * for Fedora whole-disk encryption. WIP to make this work for other
+ * encryption schemes.
+ */
+static void
+do_decrypt (void)
+{
+ char **partitions = guestfs_list_partitions (g);
+ if (partitions == NULL)
+ exit (EXIT_FAILURE);
+
+ int need_rescan = 0;
+ size_t i;
+ for (i = 0; partitions[i] != NULL; ++i) {
+ char *type = guestfs_vfs_type (g, partitions[i]);
+ if (type && STREQ (type, "crypto_LUKS")) {
+ char mapname[32];
+ make_mapname (partitions[i], mapname, sizeof mapname);
+
+ char *key = read_key (partitions[i]);
+ /* XXX Should we call guestfs_luks_open_ro if readonly flag
+ * is set? This might break 'mount_ro'.
+ */
+ if (guestfs_luks_open (g, partitions[i], key, mapname) == -1)
+ exit (EXIT_FAILURE);
+
+ free (key);
+
+ need_rescan = 1;
+ }
+ }
+
+ free_strings (partitions);
+
+ if (need_rescan) {
+ if (guestfs_vgscan (g) == -1)
+ exit (EXIT_FAILURE);
+ if (guestfs_vg_activate_all (g, 1) == -1)
+ exit (EXIT_FAILURE);
+ }
+}