[Libguestfs] [PATCH 2/3] mllib: expose disk decrypt functionalities

Pino Toscano ptoscano at redhat.com
Mon Sep 19 17:12:45 UTC 2016


Expose via Common_utils the C functions & variables (part of guestfish)
that handle decryption of LUKS partitions, and the additional command
line arguments to tune the way they work.  This way it will be easy to
provide (basic) crypto support also in OCaml-based tools.

Related to: RHBZ#1362649
---
 mllib/Makefile.am      |  3 ++
 mllib/common_utils-c.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mllib/common_utils.ml  | 22 ++++++++++++++-
 mllib/common_utils.mli | 10 ++++++-
 4 files changed, 108 insertions(+), 2 deletions(-)
 create mode 100644 mllib/common_utils-c.c

diff --git a/mllib/Makefile.am b/mllib/Makefile.am
index e93771e..489529a 100644
--- a/mllib/Makefile.am
+++ b/mllib/Makefile.am
@@ -63,8 +63,11 @@ SOURCES_ML = \
 	exit.ml
 
 SOURCES_C = \
+	../fish/decrypt.c \
+	../fish/keys.c \
 	../fish/progress.c \
 	../fish/uri.c \
+	common_utils-c.c \
 	dev_t-c.c \
 	exit-c.c \
 	fsync-c.c \
diff --git a/mllib/common_utils-c.c b/mllib/common_utils-c.c
new file mode 100644
index 0000000..d674377
--- /dev/null
+++ b/mllib/common_utils-c.c
@@ -0,0 +1,75 @@
+/* libguestfs OCaml tools common code
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+#ifdef HAVE_CAML_UNIXSUPPORT_H
+#include <caml/unixsupport.h>
+#else
+#define Nothing ((value) 0)
+extern void unix_error (int errcode, char * cmdname, value arg) Noreturn;
+#endif
+
+#include <guestfs.h>
+
+#include "options.h"
+
+extern value guestfs_int_mllib_inspect_decrypt (value gv, value gpv);
+extern value guestfs_int_mllib_set_echo_keys (value unitv);
+extern value guestfs_int_mllib_set_keys_from_stdin (value unitv);
+
+/* Interface with the guestfish inspection and decryption code. */
+int echo_keys = 0;
+int keys_from_stdin = 0;
+
+value
+guestfs_int_mllib_inspect_decrypt (value gv, value gpv)
+{
+  CAMLparam2 (gv, gpv);
+  guestfs_h *g = (guestfs_h *) (intptr_t) Int64_val (gpv);
+
+  inspect_do_decrypt (g);
+
+  CAMLreturn (Val_unit);
+}
+
+/* NB: This is a "noalloc" call. */
+value
+guestfs_int_mllib_set_echo_keys (value unitv)
+{
+  echo_keys = 1;
+  return Val_unit;
+}
+
+/* NB: This is a "noalloc" call. */
+value
+guestfs_int_mllib_set_keys_from_stdin (value unitv)
+{
+  keys_from_stdin = 1;
+  return Val_unit;
+}
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 4e36d50..7cb8198 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -21,6 +21,10 @@ open Printf
 open Common_gettext.Gettext
 open Getopt.OptionName
 
+external c_inspect_decrypt : Guestfs.t -> int64 -> unit = "guestfs_int_mllib_inspect_decrypt"
+external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" "noalloc"
+external c_set_keys_from_stdin : unit -> unit = "guestfs_int_mllib_set_keys_from_stdin" "noalloc"
+
 module Char = struct
     include Char
 
@@ -591,7 +595,7 @@ let human_size i =
     )
   )
 
-let create_standard_options argspec ?anon_fun usage_msg =
+let create_standard_options argspec ?anon_fun ?(key_opts = false) usage_msg =
   (** Install an exit hook to check gc consistency for --debug-gc *)
   let set_debug_gc () =
     at_exit (fun () -> Gc.compact()) in
@@ -604,6 +608,14 @@ let create_standard_options argspec ?anon_fun usage_msg =
     [ L"color"; L"colors";
       L"colour"; L"colours" ], Getopt.Unit set_colours, s_"Use ANSI colour sequences even if not tty";
   ] @ argspec in
+  let argspec =
+    argspec @
+      (if key_opts then
+      [
+        [ L"echo-keys" ],       Getopt.Unit c_set_echo_keys,       s_"Don't turn off echo for passphrases";
+        [ L"keys-from-stdin" ], Getopt.Unit c_set_keys_from_stdin, s_"Read passphrases from stdin";
+      ]
+      else []) in
   Getopt.create argspec ?anon_fun usage_msg
 
 (* Compare two version strings intelligently. *)
@@ -998,3 +1010,11 @@ let is_btrfs_subvolume g fs =
   with Guestfs.Error msg as exn ->
     if g#last_errno () = Guestfs.Errno.errno_EINVAL then false
     else raise exn
+
+let inspect_decrypt g =
+  (* Note we pass original 'g' even though it is not used by the
+   * callee.  This is so that 'g' is kept as a root on the stack, and
+   * so cannot be garbage collected while we are in the c_edit_file
+   * function.
+   *)
+  c_inspect_decrypt g#ocaml_handle (Guestfs.c_pointer g#ocaml_handle)
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index de95f9d..68c0d54 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -260,10 +260,13 @@ val parse_resize : int64 -> string -> int64
 val human_size : int64 -> string
 (** Converts a size in bytes to a human-readable string. *)
 
-val create_standard_options : Getopt.speclist -> ?anon_fun:Getopt.anon_fun -> Getopt.usage_msg -> Getopt.t
+val create_standard_options : Getopt.speclist -> ?anon_fun:Getopt.anon_fun -> ?key_opts:bool -> Getopt.usage_msg -> Getopt.t
 (** Adds the standard libguestfs command line options to the specified ones,
     sorting them, and setting [long_options] to them.
 
+    [key_opts] specifies whether add the standard options related to
+    keys management, i.e. [--echo-keys] and [--keys-from-stdin].
+
     Returns a new [Getopt.t] handle. *)
 
 val compare_version : string -> string -> int
@@ -390,3 +393,8 @@ val which : string -> string
 (** Return the full path of the specified executable from [$PATH].
 
     Throw [Executable_not_found] if not available. *)
+
+val inspect_decrypt : Guestfs.guestfs -> unit
+(** 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. *)
-- 
2.7.4




More information about the Libguestfs mailing list