g13: Consider g13tab for a mount command.

* g13/sh-cmd.c (cmd_getkeyblob): New.
(register_commands): Register it.
* g13/call-syshelp.c (getkeyblob_data_cb): New.
(call_syshelp_get_keyblob): New.
* g13/mount.c: Include callsyshelp.h.
(g13_mount_container): Ask syshelp whether the filename is managed by
g13tab.  Call syshelp to get the encrypted keyblob in this case.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-08-13 19:27:28 +02:00
parent 37e932658c
commit 7009206402
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 132 additions and 14 deletions

View File

@ -234,6 +234,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 /* Send the DEVICE command to the syshelper. FNAME is the name of the
device. */ device. */

View File

@ -25,6 +25,9 @@
void call_syshelp_release (ctrl_t ctrl); void call_syshelp_release (ctrl_t ctrl);
gpg_error_t call_syshelp_find_device (ctrl_t ctrl, gpg_error_t call_syshelp_find_device (ctrl_t ctrl,
const char *name, char **r_blockdev); 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_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_create (ctrl_t ctrl, int conttype);
gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype,

View File

@ -38,6 +38,7 @@
#include "host2net.h" #include "host2net.h"
#include "server.h" /*(g13_keyblob_decrypt)*/ #include "server.h" /*(g13_keyblob_decrypt)*/
#include "../common/sysutils.h" #include "../common/sysutils.h"
#include "call-syshelp.h"
/* Mount the container with name FILENAME at MOUNTPOINT. */ /* 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; gpg_error_t err;
dotlock_t lock; dotlock_t lock;
int needs_syshelp; int needs_syshelp = 0;
void *enckeyblob = NULL; void *enckeyblob = NULL;
size_t enckeybloblen; size_t enckeybloblen;
void *keyblob = NULL; void *keyblob = NULL;
@ -57,16 +58,28 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
int conttype; int conttype;
unsigned int rid; unsigned int rid;
char *mountpoint_buffer = NULL; char *mountpoint_buffer = NULL;
char *blockdev_buffer = NULL;
/* A quick check to see whether the container exists. */ /* A quick check to see whether the container exists. */
if (access (filename, R_OK)) if (access (filename, F_OK))
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
/* Decide whether we need to use the g13-syshelp because we can't /* 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 use lock files for them. This is most likely the case for device
files; thus we test for this. FIXME: The correct solution would files; thus we test for this. FIXME: The correct solution would
be to call g13-syshelp to match the file against the g13tab. */ 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) if (!mountpoint)
{ {
@ -105,20 +118,27 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
} }
/* Check again that the file exists. */ /* Check again that the file exists. */
{ if (!needs_syshelp)
struct stat sb; {
struct stat sb;
if (stat (filename, &sb)) if (stat (filename, &sb))
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
goto leave; goto leave;
} }
} }
/* Read the encrypted keyblob. */ /* Read the encrypted keyblob. */
/* Fixme: Should we move this to syshelp for dm-crypt or do we if (needs_syshelp)
assume that the encrypted device is world readable? */ {
err = g13_keyblob_read (filename, &enckeyblob, &enckeybloblen); 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) if (err)
goto leave; goto leave;
@ -186,6 +206,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
xfree (enckeyblob); xfree (enckeyblob);
dotlock_destroy (lock); dotlock_destroy (lock);
xfree (mountpoint_buffer); xfree (mountpoint_buffer);
xfree (blockdev_buffer);
return err; return err;
} }
@ -203,6 +224,7 @@ g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
if (!filename && !mountpoint) if (!filename && !mountpoint)
return gpg_error (GPG_ERR_ENOENT); return gpg_error (GPG_ERR_ENOENT);
err = mountinfo_find_mount (filename, mountpoint, &rid); err = mountinfo_find_mount (filename, mountpoint, &rid);
if (err) if (err)
return err; return err;

View File

@ -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[] = static const char hlp_mount[] =
"MOUNT <type>\n" "MOUNT <type>\n"
"\n" "\n"
@ -667,6 +713,7 @@ register_commands (assuan_context_t ctx, int fail_all)
{ "FINDDEVICE", cmd_finddevice, hlp_finddevice }, { "FINDDEVICE", cmd_finddevice, hlp_finddevice },
{ "DEVICE", cmd_device, hlp_device }, { "DEVICE", cmd_device, hlp_device },
{ "CREATE", cmd_create, hlp_create }, { "CREATE", cmd_create, hlp_create },
{ "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob },
{ "MOUNT", cmd_mount, hlp_mount }, { "MOUNT", cmd_mount, hlp_mount },
{ "SUSPEND", cmd_suspend,hlp_suspend}, { "SUSPEND", cmd_suspend,hlp_suspend},
{ "RESUME", cmd_resume, hlp_resume }, { "RESUME", cmd_resume, hlp_resume },