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
device. */

View File

@ -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,

View File

@ -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;

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[] =
"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 },