summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g13/backend.c18
-rw-r--r--g13/backend.h1
-rw-r--r--g13/be-dmcrypt.c17
-rw-r--r--g13/be-dmcrypt.h1
-rw-r--r--g13/call-syshelp.c34
-rw-r--r--g13/call-syshelp.h1
-rw-r--r--g13/g13-syshelp.h1
-rw-r--r--g13/g13.c7
-rw-r--r--g13/mount.c58
-rw-r--r--g13/sh-cmd.c35
-rw-r--r--g13/sh-dmcrypt.c93
11 files changed, 244 insertions, 22 deletions
diff --git a/g13/backend.c b/g13/backend.c
index dd2176834..659c6b749 100644
--- a/g13/backend.c
+++ b/g13/backend.c
@@ -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. */
gpg_error_t
be_suspend_container (ctrl_t ctrl, int conttype, const char *fname)
diff --git a/g13/backend.h b/g13/backend.h
index 66d9cd593..d1cedb36f 100644
--- a/g13/backend.h
+++ b/g13/backend.h
@@ -39,6 +39,7 @@ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype,
const char *fname, const char *mountpoint,
tupledesc_t tuples,
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,
const char *fname);
gpg_error_t be_resume_container (ctrl_t ctrl, int conttype,
diff --git a/g13/be-dmcrypt.c b/g13/be-dmcrypt.c
index e5e9b332a..c65be0894 100644
--- a/g13/be-dmcrypt.c
+++ b/g13/be-dmcrypt.c
@@ -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. */
gpg_error_t
be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname)
diff --git a/g13/be-dmcrypt.h b/g13/be-dmcrypt.h
index d74e09f7c..189bfee7b 100644
--- a/g13/be-dmcrypt.h
+++ b/g13/be-dmcrypt.h
@@ -27,6 +27,7 @@ gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl,
const char *fname,
const char *mountpoint,
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_resume_container (ctrl_t ctrl, const char *fname,
tupledesc_t tuples);
diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c
index 952d8de77..76d181b67 100644
--- a/g13/call-syshelp.c
+++ b/g13/call-syshelp.c
@@ -522,6 +522,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
* requested content type for the new container.
*/
diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h
index aa4b692f4..0e110c903 100644
--- a/g13/call-syshelp.h
+++ b/g13/call-syshelp.h
@@ -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,
const char *mountpoint,
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_resume (ctrl_t ctrl, int conttype,
tupledesc_t tuples);
diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h
index dae2bd05c..618b41de5 100644
--- a/g13/g13-syshelp.h
+++ b/g13/g13-syshelp.h
@@ -86,6 +86,7 @@ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname,
estream_t devfp);
gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
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_resume_container (ctrl_t ctrl, const char *devname,
tupledesc_t keyblob);
diff --git a/g13/g13.c b/g13/g13.c
index 799fd6651..7744855c2 100644
--- a/g13/g13.c
+++ b/g13/g13.c
@@ -793,9 +793,10 @@ main ( int argc, char **argv)
{
if (argc != 1)
wrong_args ("--umount filename");
- err = GPG_ERR_NOT_IMPLEMENTED;
- log_error ("error unmounting container '%s': %s <%s>\n",
- *argv, gpg_strerror (err), gpg_strsource (err));
+ err = g13_umount_container (&ctrl, argv[0], NULL);
+ if (err)
+ log_error ("error unmounting container '%s': %s <%s>\n",
+ *argv, gpg_strerror (err), gpg_strsource (err));
}
break;
diff --git a/g13/mount.c b/g13/mount.c
index d6825859d..f4371cce5 100644
--- a/g13/mount.c
+++ b/g13/mount.c
@@ -64,10 +64,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
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. */
+ /* Decide whether we need to use the g13-syshelp. */
err = call_syshelp_find_device (ctrl, filename, &blockdev_buffer);
if (!err)
{
@@ -217,27 +214,50 @@ gpg_error_t
g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
{
gpg_error_t err;
- unsigned int rid;
- runner_t runner;
-
- (void)ctrl;
+ char *blockdev;
if (!filename && !mountpoint)
return gpg_error (GPG_ERR_ENOENT);
- err = mountinfo_find_mount (filename, mountpoint, &rid);
- if (err)
- return err;
-
- runner = runner_find_by_rid (rid);
- if (!runner)
+ /* Decide whether we need to use the g13-syshelp. */
+ err = call_syshelp_find_device (ctrl, filename, &blockdev);
+ if (!err)
+ {
+ /* Need to employ the syshelper to umount the file system. */
+ /* 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 ("runner %u not found\n", rid);
- return gpg_error (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;
- runner_cancel (runner);
- runner_release (runner);
+ err = mountinfo_find_mount (filename, mountpoint, &rid);
+ if (err)
+ return err;
- return 0;
+ 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);
+ }
+
+ xfree (blockdev);
+ return err;
}
diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c
index 20db8dce0..821491982 100644
--- a/g13/sh-cmd.c
+++ b/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[] =
"SUSPEND <type>\n"
"\n"
@@ -713,6 +747,7 @@ register_commands (assuan_context_t ctx, int fail_all)
{ "CREATE", cmd_create, hlp_create },
{ "GETKEYBLOB", cmd_getkeyblob, hlp_getkeyblob },
{ "MOUNT", cmd_mount, hlp_mount },
+ { "UMOUNT", cmd_umount, hlp_umount },
{ "SUSPEND", cmd_suspend,hlp_suspend},
{ "RESUME", cmd_resume, hlp_resume },
{ "INPUT", NULL },
diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c
index e0cd2e1a1..201f8569e 100644
--- a/g13/sh-dmcrypt.c
+++ b/g13/sh-dmcrypt.c
@@ -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. */
gpg_error_t
sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname)