aboutsummaryrefslogtreecommitdiffstats
path: root/g13
diff options
context:
space:
mode:
Diffstat (limited to 'g13')
-rw-r--r--g13/call-syshelp.c46
-rw-r--r--g13/call-syshelp.h3
-rw-r--r--g13/mount.c50
-rw-r--r--g13/sh-cmd.c47
4 files changed, 132 insertions, 14 deletions
diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c
index d0f1b0070..952d8de77 100644
--- a/g13/call-syshelp.c
+++ b/g13/call-syshelp.c
@@ -235,6 +235,52 @@ call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev)
+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;
+}
+
+
+
/* Send the DEVICE command to the syshelper. FNAME is the name of the
device. */
gpg_error_t
diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h
index 14deb7d18..aa4b692f4 100644
--- a/g13/call-syshelp.h
+++ b/g13/call-syshelp.h
@@ -25,6 +25,9 @@
void call_syshelp_release (ctrl_t ctrl);
gpg_error_t call_syshelp_find_device (ctrl_t ctrl,
const char *name, char **r_blockdev);
+gpg_error_t call_syshelp_get_keyblob (ctrl_t ctrl,
+ void **r_enckeyblob,
+ size_t *r_enckeybloblen);
gpg_error_t call_syshelp_set_device (ctrl_t ctrl, const char *fname);
gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype);
gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype,
diff --git a/g13/mount.c b/g13/mount.c
index 951a85917..d6825859d 100644
--- a/g13/mount.c
+++ b/g13/mount.c
@@ -38,6 +38,7 @@
#include "host2net.h"
#include "server.h" /*(g13_keyblob_decrypt)*/
#include "../common/sysutils.h"
+#include "call-syshelp.h"
/* Mount the container with name FILENAME at MOUNTPOINT. */
@@ -46,7 +47,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
{
gpg_error_t err;
dotlock_t lock;
- int needs_syshelp;
+ int needs_syshelp = 0;
void *enckeyblob = NULL;
size_t enckeybloblen;
void *keyblob = NULL;
@@ -57,16 +58,28 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
int conttype;
unsigned int rid;
char *mountpoint_buffer = NULL;
+ char *blockdev_buffer = NULL;
/* A quick check to see whether the container exists. */
- if (access (filename, R_OK))
+ if (access (filename, F_OK))
return gpg_error_from_syserror ();
/* Decide whether we need to use the g13-syshelp because we can't
use lock files for them. This is most likely the case for device
files; thus we test for this. FIXME: The correct solution would
be to call g13-syshelp to match the file against the g13tab. */
- needs_syshelp = !strncmp (filename, "/dev/", 5);
+ err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer);
+ if (!err)
+ {
+ needs_syshelp = 1;
+ filename = blockdev_buffer;
+ }
+ else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
+ {
+ log_error ("error finding device '%s': %s <%s>\n",
+ filename, gpg_strerror (err), gpg_strsource (err));
+ return err;
+ }
if (!mountpoint)
{
@@ -105,20 +118,27 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
}
/* Check again that the file exists. */
- {
- struct stat sb;
+ if (!needs_syshelp)
+ {
+ struct stat sb;
- if (stat (filename, &sb))
- {
- err = gpg_error_from_syserror ();
- goto leave;
- }
- }
+ if (stat (filename, &sb))
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ }
/* Read the encrypted keyblob. */
- /* Fixme: Should we move this to syshelp for dm-crypt or do we
- assume that the encrypted device is world readable? */
- err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen);
+ if (needs_syshelp)
+ {
+ err = call_syshelp_set_device (ctrl, filename);
+ if (err)
+ goto leave;
+ err = call_syshelp_get_keyblob (ctrl, &enckeyblob, &enckeybloblen);
+ }
+ else
+ err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen);
if (err)
goto leave;
@@ -186,6 +206,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
xfree (enckeyblob);
dotlock_destroy (lock);
xfree (mountpoint_buffer);
+ xfree (blockdev_buffer);
return err;
}
@@ -203,6 +224,7 @@ g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
if (!filename && !mountpoint)
return gpg_error (GPG_ERR_ENOENT);
+
err = mountinfo_find_mount (filename, mountpoint, &rid);
if (err)
return err;
diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c
index e00bb774c..10b1ba93b 100644
--- a/g13/sh-cmd.c
+++ b/g13/sh-cmd.c
@@ -383,6 +383,52 @@ cmd_create (assuan_context_t ctx, char *line)
}
+static const char hlp_getkeyblob[] =
+ "GETKEYBLOB\n"
+ "\n"
+ "Return the encrypted keyblob of the current device.";
+static gpg_error_t
+cmd_getkeyblob (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ void *enckeyblob = NULL;
+ size_t enckeybloblen;
+
+ line = skip_options (line);
+
+ if (!ctrl->server_local->devicename
+ || !ctrl->server_local->devicefp
+ || !ctrl->devti)
+ {
+ err = set_error (GPG_ERR_ENOENT, "No device has been set");
+ goto leave;
+ }
+
+ err = sh_is_empty_partition (ctrl->server_local->devicename);
+ if (!err)
+ {
+ err = gpg_error (GPG_ERR_ENODEV);
+ assuan_set_error (ctx, err, "Partition is empty");
+ goto leave;
+ }
+ err = 0;
+
+ err = g13_keyblob_read (ctrl->server_local->devicename,
+ &enckeyblob, &enckeybloblen);
+ if (err)
+ goto leave;
+
+ err = assuan_send_data (ctx, enckeyblob, enckeybloblen);
+ if (!err)
+ err = assuan_send_data (ctx, NULL, 0); /* Flush */
+
+ leave:
+ xfree (enckeyblob);
+ return leave_cmd (ctx, err);
+}
+
+
static const char hlp_mount[] =
"MOUNT <type>\n"
"\n"
@@ -667,6 +713,7 @@ register_commands (assuan_context_t ctx, int fail_all)
{ "FINDDEVICE", cmd_finddevice, hlp_finddevice },
{ "DEVICE", cmd_device, hlp_device },
{ "CREATE", cmd_create, hlp_create },
+ { "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob },
{ "MOUNT", cmd_mount, hlp_mount },
{ "SUSPEND", cmd_suspend,hlp_suspend},
{ "RESUME", cmd_resume, hlp_resume },