gpg,sm: New option --with-key-screening.
[gnupg.git] / g13 / call-syshelp.c
index 0e69e9c..8a50c3f 100644 (file)
@@ -14,7 +14,7 @@
  * 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, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 
 #include "g13.h"
 #include <assuan.h>
-#include "i18n.h"
+#include "../common/i18n.h"
 #include "g13tuple.h"
 #include "keyblob.h"
-#include "membuf.h"
+#include "../common/membuf.h"
 #include "create.h"
+#include "call-syshelp.h"
 
 
 /* Local data for this module.  A pointer to this is stored in the
@@ -172,6 +173,114 @@ call_syshelp_release (ctrl_t ctrl)
 }
 
 
+\f
+/* Staus callback for call_syshelp_find_device.  */
+static gpg_error_t
+finddevice_status_cb (void *opaque, const char *line)
+{
+  char **r_blockdev = opaque;
+  char *p;
+
+  if ((p = has_leading_keyword (line, "BLOCKDEV")) && *p && !*r_blockdev)
+    {
+      *r_blockdev = xtrystrdup (p);
+      if (!*r_blockdev)
+        return gpg_error_from_syserror ();
+    }
+
+  return 0;
+}
+
+
+/* Send the FINDDEVICE command to the syshelper.  On success the name
+ * of the block device is stored at R_BLOCKDEV. */
+gpg_error_t
+call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  char *line = NULL;
+  char *blockdev = NULL;  /* The result.  */
+
+  *r_blockdev = NULL;
+
+  err = start_syshelp (ctrl, &ctx);
+  if (err)
+    goto leave;
+
+  line = xtryasprintf ("FINDDEVICE %s", name);
+  if (!line)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL,
+                         finddevice_status_cb, &blockdev);
+  if (err)
+    goto leave;
+  if (!blockdev)
+    {
+      log_error ("status line for successful FINDDEVICE missing\n");
+      err = gpg_error (GPG_ERR_UNEXPECTED);
+      goto leave;
+    }
+  *r_blockdev = blockdev;
+  blockdev = NULL;
+
+ leave:
+  xfree (blockdev);
+  xfree (line);
+  return err;
+}
+
+
+\f
+static gpg_error_t
+getkeyblob_data_cb (void *opaque, const void *data, size_t datalen)
+{
+  membuf_t *mb = opaque;
+
+  if (data)
+    put_membuf (mb, data, datalen);
+
+  return 0;
+}
+
+
+/* Send the GTEKEYBLOB command to the syshelper.  On success the
+ * encrypted keyblpob is stored at (R_ENCKEYBLOB,R_ENCKEYBLOBLEN).  */
+gpg_error_t
+call_syshelp_get_keyblob (ctrl_t ctrl,
+                          void **r_enckeyblob, size_t *r_enckeybloblen)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  membuf_t mb;
+
+  *r_enckeyblob = NULL;
+  *r_enckeybloblen = 0;
+  init_membuf (&mb, 512);
+
+  err = start_syshelp (ctrl, &ctx);
+  if (err)
+    goto leave;
+
+  err = assuan_transact (ctx, "GETKEYBLOB",
+                         getkeyblob_data_cb, &mb,
+                         NULL, NULL, NULL, NULL);
+  if (err)
+    goto leave;
+  *r_enckeyblob = get_membuf (&mb, r_enckeybloblen);
+  if (!*r_enckeyblob)
+    err = gpg_error_from_syserror ();
+
+ leave:
+  xfree (get_membuf (&mb, NULL));
+  return err;
+}
+
+
+\f
 /* Send the DEVICE command to the syshelper.  FNAME is the name of the
    device.  */
 gpg_error_t
@@ -337,6 +446,7 @@ mount_status_cb (void *opaque, const char *line)
 }
 
 
+/* Inquire callback for MOUNT and RESUME.  */
 static gpg_error_t
 mount_inq_cb (void *opaque, const char *line)
 {
@@ -363,9 +473,11 @@ mount_inq_cb (void *opaque, const char *line)
 }
 
 
-/* Run the MOUNT command on the current device.  CONTTYPES gives the
-   requested content type for the new container.  MOUNTPOINT the
-   desired mount point or NULL for default.  */
+/*
+ * Run the MOUNT command on the current device.  CONTTYPES gives the
+ * requested content type for the new container.  MOUNTPOINT the
+ * desired mount point or NULL for default.
+ */
 gpg_error_t
 call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint,
                         tupledesc_t tuples)
@@ -406,3 +518,114 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint,
  leave:
   return err;
 }
+
+
+\f
+/*
+ * Run the UMOUNT command on the current device.  CONTTYPES gives the
+ * content type of the container (fixme: Do we really need this?).
+ */
+gpg_error_t
+call_syshelp_run_umount (ctrl_t ctrl, int conttype)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+
+  err = start_syshelp (ctrl, &ctx);
+  if (err)
+    goto leave;
+
+  if (conttype == CONTTYPE_DM_CRYPT)
+    {
+      err = assuan_transact (ctx, "UMOUNT dm-crypt",
+                             NULL, NULL,
+                             NULL, NULL,
+                             NULL, NULL);
+    }
+  else
+    {
+      log_error ("invalid backend type %d given\n", conttype);
+      err = GPG_ERR_INTERNAL;
+      goto leave;
+    }
+
+ leave:
+  return err;
+}
+
+
+\f
+/*
+ * Run the SUSPEND command on the current device.  CONTTYPES gives the
+ * requested content type for the new container.
+ */
+gpg_error_t
+call_syshelp_run_suspend (ctrl_t ctrl, int conttype)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+
+  err = start_syshelp (ctrl, &ctx);
+  if (err)
+    goto leave;
+
+  if (conttype == CONTTYPE_DM_CRYPT)
+    {
+      err = assuan_transact (ctx, "SUSPEND dm-crypt",
+                             NULL, NULL,
+                             NULL, NULL,
+                             NULL, NULL);
+    }
+  else
+    {
+      log_error ("invalid backend type %d given\n", conttype);
+      err = GPG_ERR_INTERNAL;
+      goto leave;
+    }
+
+ leave:
+  return err;
+}
+
+
+\f
+/* Run the RESUME command on the current device.  CONTTYPES gives the
+   requested content type for the container.  */
+gpg_error_t
+call_syshelp_run_resume (ctrl_t ctrl, int conttype, tupledesc_t tuples)
+{
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct mount_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
+
+  err = start_syshelp (ctrl, &ctx);
+  if (err)
+    goto leave;
+
+  /* tty_get ("waiting for debugger"); */
+  /* tty_kill_prompt (); */
+
+  parm.ctx = ctx;
+  parm.ctrl = ctrl;
+  if (conttype == CONTTYPE_DM_CRYPT)
+    {
+      ref_tupledesc (tuples);
+      parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen);
+      err = assuan_transact (ctx, "RESUME dm-crypt",
+                             NULL, NULL,
+                             mount_inq_cb, &parm,
+                             NULL, NULL);
+      unref_tupledesc (tuples);
+    }
+  else
+    {
+      log_error ("invalid backend type %d given\n", conttype);
+      err = GPG_ERR_INTERNAL;
+      goto leave;
+    }
+
+ leave:
+  return err;
+}