mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
g13: Implement --umount for dm-crypt.
* g13/g13.c (main): Implement command --umount. * g13/mount.c (g13_umount_container): use the syshelper if needed. * g13/backend.c (be_umount_container): New. * g13/be-dmcrypt.c (be_dmcrypt_umount_container): New. * g13/call-syshelp.c (call_syshelp_run_umount): New. * g13/sh-cmd.c (cmd_umount): New. (register_commands): Register UMOUNT. * g13/sh-dmcrypt.c (sh_dmcrypt_umount_container): New. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
c9a0bccc77
commit
b781113cf1
@ -240,6 +240,24 @@ be_mount_container (ctrl_t ctrl, int conttype,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Dispatcher to the backend's umount function. */
|
||||||
|
gpg_error_t
|
||||||
|
be_umount_container (ctrl_t ctrl, int conttype, const char *fname)
|
||||||
|
{
|
||||||
|
switch (conttype)
|
||||||
|
{
|
||||||
|
case CONTTYPE_ENCFS:
|
||||||
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
case CONTTYPE_DM_CRYPT:
|
||||||
|
return be_dmcrypt_umount_container (ctrl, fname);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return no_such_backend (conttype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Dispatcher to the backend's suspend function. */
|
/* Dispatcher to the backend's suspend function. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
be_suspend_container (ctrl_t ctrl, int conttype, const char *fname)
|
be_suspend_container (ctrl_t ctrl, int conttype, const char *fname)
|
||||||
|
@ -39,6 +39,7 @@ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype,
|
|||||||
const char *fname, const char *mountpoint,
|
const char *fname, const char *mountpoint,
|
||||||
tupledesc_t tuples,
|
tupledesc_t tuples,
|
||||||
unsigned int *r_id);
|
unsigned int *r_id);
|
||||||
|
gpg_error_t be_umount_container (ctrl_t ctrl, int conttype, const char *fname);
|
||||||
gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype,
|
gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype,
|
||||||
const char *fname);
|
const char *fname);
|
||||||
gpg_error_t be_resume_container (ctrl_t ctrl, int conttype,
|
gpg_error_t be_resume_container (ctrl_t ctrl, int conttype,
|
||||||
|
@ -64,6 +64,23 @@ be_dmcrypt_mount_container (ctrl_t ctrl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unmount the container described by the filename FNAME. */
|
||||||
|
gpg_error_t
|
||||||
|
be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
err = call_syshelp_set_device (ctrl, fname);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
err = call_syshelp_run_umount (ctrl, CONTTYPE_DM_CRYPT);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Suspend the container described by the filename FNAME. */
|
/* Suspend the container described by the filename FNAME. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname)
|
be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname)
|
||||||
|
@ -27,6 +27,7 @@ gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl,
|
|||||||
const char *fname,
|
const char *fname,
|
||||||
const char *mountpoint,
|
const char *mountpoint,
|
||||||
tupledesc_t tuples);
|
tupledesc_t tuples);
|
||||||
|
gpg_error_t be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname);
|
||||||
gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname);
|
gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname);
|
||||||
gpg_error_t be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname,
|
gpg_error_t be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname,
|
||||||
tupledesc_t tuples);
|
tupledesc_t tuples);
|
||||||
|
@ -520,6 +520,40 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run the SUSPEND command on the current device. CONTTYPES gives the
|
* Run the SUSPEND command on the current device. CONTTYPES gives the
|
||||||
|
@ -33,6 +33,7 @@ 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,
|
||||||
const char *mountpoint,
|
const char *mountpoint,
|
||||||
tupledesc_t tuples);
|
tupledesc_t tuples);
|
||||||
|
gpg_error_t call_syshelp_run_umount (ctrl_t ctrl, int conttype);
|
||||||
gpg_error_t call_syshelp_run_suspend (ctrl_t ctrl, int conttype);
|
gpg_error_t call_syshelp_run_suspend (ctrl_t ctrl, int conttype);
|
||||||
gpg_error_t call_syshelp_run_resume (ctrl_t ctrl, int conttype,
|
gpg_error_t call_syshelp_run_resume (ctrl_t ctrl, int conttype,
|
||||||
tupledesc_t tuples);
|
tupledesc_t tuples);
|
||||||
|
@ -86,6 +86,7 @@ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname,
|
|||||||
estream_t devfp);
|
estream_t devfp);
|
||||||
gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
|
gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
|
||||||
tupledesc_t keyblob);
|
tupledesc_t keyblob);
|
||||||
|
gpg_error_t sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname);
|
||||||
gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname);
|
gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname);
|
||||||
gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname,
|
gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname,
|
||||||
tupledesc_t keyblob);
|
tupledesc_t keyblob);
|
||||||
|
@ -793,9 +793,10 @@ main ( int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
wrong_args ("--umount filename");
|
wrong_args ("--umount filename");
|
||||||
err = GPG_ERR_NOT_IMPLEMENTED;
|
err = g13_umount_container (&ctrl, argv[0], NULL);
|
||||||
log_error ("error unmounting container '%s': %s <%s>\n",
|
if (err)
|
||||||
*argv, gpg_strerror (err), gpg_strsource (err));
|
log_error ("error unmounting container '%s': %s <%s>\n",
|
||||||
|
*argv, gpg_strerror (err), gpg_strsource (err));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
60
g13/mount.c
60
g13/mount.c
@ -64,10 +64,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
|
|||||||
if (access (filename, F_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. */
|
||||||
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. */
|
|
||||||
err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer);
|
err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer);
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
@ -217,27 +214,50 @@ gpg_error_t
|
|||||||
g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
|
g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
unsigned int rid;
|
char *blockdev;
|
||||||
runner_t runner;
|
|
||||||
|
|
||||||
(void)ctrl;
|
|
||||||
|
|
||||||
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);
|
/* Decide whether we need to use the g13-syshelp. */
|
||||||
if (err)
|
err = call_syshelp_find_device (ctrl, filename, &blockdev);
|
||||||
return err;
|
if (!err)
|
||||||
|
|
||||||
runner = runner_find_by_rid (rid);
|
|
||||||
if (!runner)
|
|
||||||
{
|
{
|
||||||
log_error ("runner %u not found\n", rid);
|
/* Need to employ the syshelper to umount the file system. */
|
||||||
return gpg_error (GPG_ERR_NOT_FOUND);
|
/* FIXME: We should get the CONTTYPE from the blockdev. */
|
||||||
|
err = be_umount_container (ctrl, CONTTYPE_DM_CRYPT, blockdev);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
/* if (conttype == CONTTYPE_DM_CRYPT) */
|
||||||
|
g13_request_shutdown ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Not in g13tab - kill the runner process for this mount. */
|
||||||
|
unsigned int rid;
|
||||||
|
runner_t runner;
|
||||||
|
|
||||||
|
err = mountinfo_find_mount (filename, mountpoint, &rid);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
runner = runner_find_by_rid (rid);
|
||||||
|
if (!runner)
|
||||||
|
{
|
||||||
|
log_error ("runner %u not found\n", rid);
|
||||||
|
return gpg_error (GPG_ERR_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
runner_cancel (runner);
|
||||||
|
runner_release (runner);
|
||||||
}
|
}
|
||||||
|
|
||||||
runner_cancel (runner);
|
xfree (blockdev);
|
||||||
runner_release (runner);
|
return err;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
35
g13/sh-cmd.c
35
g13/sh-cmd.c
@ -500,6 +500,40 @@ cmd_mount (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char hlp_umount[] =
|
||||||
|
"UMOUNT <type>\n"
|
||||||
|
"\n"
|
||||||
|
"Unmount an encrypted partition and wipe the key.\n"
|
||||||
|
"<type> must be \"dm-crypt\" for now.";
|
||||||
|
static gpg_error_t
|
||||||
|
cmd_umount (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
|
||||||
|
line = skip_options (line);
|
||||||
|
|
||||||
|
if (strcmp (line, "dm-crypt"))
|
||||||
|
{
|
||||||
|
err = set_error (GPG_ERR_INV_ARG, "Type must be \"dm-crypt\"");
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_dmcrypt_umount_container (ctrl, ctrl->server_local->devicename);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
return leave_cmd (ctx, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_suspend[] =
|
static const char hlp_suspend[] =
|
||||||
"SUSPEND <type>\n"
|
"SUSPEND <type>\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -713,6 +747,7 @@ register_commands (assuan_context_t ctx, int fail_all)
|
|||||||
{ "CREATE", cmd_create, hlp_create },
|
{ "CREATE", cmd_create, hlp_create },
|
||||||
{ "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob },
|
{ "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob },
|
||||||
{ "MOUNT", cmd_mount, hlp_mount },
|
{ "MOUNT", cmd_mount, hlp_mount },
|
||||||
|
{ "UMOUNT", cmd_umount, hlp_umount },
|
||||||
{ "SUSPEND", cmd_suspend,hlp_suspend},
|
{ "SUSPEND", cmd_suspend,hlp_suspend},
|
||||||
{ "RESUME", cmd_resume, hlp_resume },
|
{ "RESUME", cmd_resume, hlp_resume },
|
||||||
{ "INPUT", NULL },
|
{ "INPUT", NULL },
|
||||||
|
@ -723,6 +723,99 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unmount a DM-Crypt container on device DEVNAME and wipe the keys. */
|
||||||
|
gpg_error_t
|
||||||
|
sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
char *targetname_abs = NULL;
|
||||||
|
char *result = NULL;
|
||||||
|
|
||||||
|
if (!ctrl->devti)
|
||||||
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
|
g13_syshelp_i_know_what_i_am_doing ();
|
||||||
|
|
||||||
|
/* Check that the device is used by device mapper. */
|
||||||
|
err = check_blockdev (devname, 1);
|
||||||
|
if (gpg_err_code (err) != GPG_ERR_EBUSY)
|
||||||
|
{
|
||||||
|
log_error ("device '%s' is not used by the device mapper: %s\n",
|
||||||
|
devname, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixme: Check that this is really a g13 partition. */
|
||||||
|
|
||||||
|
/* Device mapper needs a name for the device: Take it from the label
|
||||||
|
or use "0". */
|
||||||
|
targetname_abs = strconcat ("/dev/mapper/",
|
||||||
|
"g13-", ctrl->client.uname, "-",
|
||||||
|
ctrl->devti->label? ctrl->devti->label : "0",
|
||||||
|
NULL);
|
||||||
|
if (!targetname_abs)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the regular umount command. */
|
||||||
|
{
|
||||||
|
const char *argv[2];
|
||||||
|
|
||||||
|
argv[0] = targetname_abs;
|
||||||
|
argv[1] = NULL;
|
||||||
|
log_debug ("now running \"umount %s\"\n", targetname_abs);
|
||||||
|
err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL);
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("error running umount: %s\n", gpg_strerror (err));
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
/* Try to show some info about processes using the partition. */
|
||||||
|
const char *argv[3];
|
||||||
|
|
||||||
|
argv[0] = "-mv";
|
||||||
|
argv[1] = targetname_abs;
|
||||||
|
argv[2] = NULL;
|
||||||
|
gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL);
|
||||||
|
}
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (result && *result) /* (We should not see output to stdout). */
|
||||||
|
log_info ("WARNING: umount returned data on stdout! (%s)\n", result);
|
||||||
|
xfree (result);
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
/* Run the dmsetup remove command. */
|
||||||
|
{
|
||||||
|
const char *argv[3];
|
||||||
|
|
||||||
|
argv[0] = "remove";
|
||||||
|
argv[1] = targetname_abs;
|
||||||
|
argv[2] = NULL;
|
||||||
|
log_debug ("now running \"dmsetup remove %s\"\n", targetname_abs);
|
||||||
|
err = gnupg_exec_tool ("/sbin/dmsetup", argv, NULL, &result, NULL);
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("error running \"dmsetup remove %s\": %s\n",
|
||||||
|
targetname_abs, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (result && *result)
|
||||||
|
log_debug ("dmsetup result: %s\n", result);
|
||||||
|
xfree (result);
|
||||||
|
result = NULL;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (targetname_abs);
|
||||||
|
xfree (result);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Suspend a DM-Crypt container on device DEVNAME and wipe the keys. */
|
/* Suspend a DM-Crypt container on device DEVNAME and wipe the keys. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname)
|
sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user