g13: New option --no-mount.

* g13/g13.c (oNoMount): New.
(opts): Add --no-mount.
(main): Implement this.
* g13/g13-common.h (opt): Add field no_mount.
* common/status.h (STATUS_PLAINDEV): New.
* g13/sh-cmd.c (has_option): Uncomment.
(cmd_mount): Add option --no-mount and pass down.
* g13/sh-dmcrypt.c (sh_dmcrypt_mount_container): Add arg nomount and
emit PLAINDEV status line.
(sh_dmcrypt_umount_container): Rund findmnt before umount.
--

This option can be used to decrypt a device but not to mount it.  For
example to run fsck first.  A command or option to run fsck before a
mount will eventually be added.

The use of findmnt is needed so that we can easily remove a device
which has not been mounted.
This commit is contained in:
Werner Koch 2024-01-09 19:52:04 +01:00
parent 4ca017e43b
commit 6233a17ac9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
8 changed files with 76 additions and 43 deletions

View File

@ -152,6 +152,7 @@ enum
STATUS_TRUNCATED, STATUS_TRUNCATED,
STATUS_MOUNTPOINT, STATUS_MOUNTPOINT,
STATUS_BLOCKDEV, STATUS_BLOCKDEV,
STATUS_PLAINDEV, /* The decrypted virtual device. */
STATUS_PINENTRY_LAUNCHED, STATUS_PINENTRY_LAUNCHED,

View File

@ -433,10 +433,15 @@ static gpg_error_t
mount_status_cb (void *opaque, const char *line) mount_status_cb (void *opaque, const char *line)
{ {
struct mount_parm_s *parm = opaque; struct mount_parm_s *parm = opaque;
const char *s;
/* Nothing right now. */
(void)parm; (void)parm;
(void)line;
if ((s=has_leading_keyword (line, "PLAINDEV")))
{
if (opt.verbose || opt.no_mount)
log_info ("Device: %s\n", s);
}
return 0; return 0;
} }
@ -497,7 +502,10 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint,
{ {
ref_tupledesc (tuples); ref_tupledesc (tuples);
parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen);
err = assuan_transact (ctx, "MOUNT dm-crypt", err = assuan_transact (ctx,
(opt.no_mount
? "MOUNT --no-mount dm-crypt"
: "MOUNT dm-crypt"),
NULL, NULL, NULL, NULL,
mount_inq_cb, &parm, mount_inq_cb, &parm,
mount_status_cb, &parm); mount_status_cb, &parm);

View File

@ -81,6 +81,8 @@ struct
/* Name of the output file - FIXME: what is this? */ /* Name of the output file - FIXME: what is this? */
const char *outfile; const char *outfile;
int no_mount; /* Stop right before mounting a device. */
} opt; } opt;

View File

@ -584,7 +584,7 @@ g13_syshelp_i_know_what_i_am_doing (void)
if (gnupg_access (fname, F_OK)) if (gnupg_access (fname, F_OK))
{ {
log_info ("*******************************************************\n"); log_info ("*******************************************************\n");
log_info ("* The G13 support for DM-Crypt is new and not matured.\n"); log_info ("* The G13 support for DM-Crypt is not yet widely used.\n");
log_info ("* Bugs or improper use may delete all your disks!\n"); log_info ("* Bugs or improper use may delete all your disks!\n");
log_info ("* To confirm that you are ware of this risk, create\n"); log_info ("* To confirm that you are ware of this risk, create\n");
log_info ("* the file '%s'.\n", fname); log_info ("* the file '%s'.\n", fname);

View File

@ -85,7 +85,7 @@ gpg_error_t sh_is_empty_partition (const char *name);
gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, 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, int nomount);
gpg_error_t sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname); 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,

View File

@ -103,6 +103,7 @@ enum cmd_and_opt_values {
oWithColons, oWithColons,
oDryRun, oDryRun,
oNoDetach, oNoDetach,
oNoMount,
oNoRandomSeedFile, oNoRandomSeedFile,
oFakedSystemTime oFakedSystemTime
@ -137,6 +138,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write log output to FILE")), ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write log output to FILE")),
ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"),
ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
ARGPARSE_s_n (oNoMount, "no-mount", N_("stop right before running mount")),
ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
@ -518,6 +520,8 @@ main (int argc, char **argv)
case oNoDetach: /*nodetach = 1; */break; case oNoDetach: /*nodetach = 1; */break;
case oNoMount: opt.no_mount = 1; break;
case oDebug: case oDebug:
if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags)) if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
{ {

View File

@ -83,17 +83,17 @@ skip_options (const char *line)
/* Check whether the option NAME appears in LINE. */ /* Check whether the option NAME appears in LINE. */
/* static int */ static int
/* has_option (const char *line, const char *name) */ has_option (const char *line, const char *name)
/* { */ {
/* const char *s; */ const char *s;
/* int n = strlen (name); */ int n = strlen (name);
/* s = strstr (line, name); */ s = strstr (line, name);
/* if (s && s >= skip_options (line)) */ if (s && s >= skip_options (line))
/* return 0; */ return 0;
/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */ return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
/* } */ }
/* Helper to print a message while leaving a command. */ /* Helper to print a message while leaving a command. */
@ -431,10 +431,11 @@ cmd_getkeyblob (assuan_context_t ctx, char *line)
static const char hlp_mount[] = static const char hlp_mount[] =
"MOUNT <type>\n" "MOUNT [--no-mount] <type>\n"
"\n" "\n"
"Mount an encrypted partition on the current device.\n" "Mount an encrypted partition on the current device.\n"
"<type> must be \"dm-crypt\" for now."; "<type> must be \"dm-crypt\" for now. Option --no-mount\n"
"stops right before calling the mount command.\n";
static gpg_error_t static gpg_error_t
cmd_mount (assuan_context_t ctx, char *line) cmd_mount (assuan_context_t ctx, char *line)
{ {
@ -443,6 +444,9 @@ cmd_mount (assuan_context_t ctx, char *line)
unsigned char *keyblob = NULL; unsigned char *keyblob = NULL;
size_t keybloblen; size_t keybloblen;
tupledesc_t tuples = NULL; tupledesc_t tuples = NULL;
int nomount;
nomount = has_option (line, "--no-mount");
line = skip_options (line); line = skip_options (line);
@ -493,7 +497,7 @@ cmd_mount (assuan_context_t ctx, char *line)
err = sh_dmcrypt_mount_container (ctrl, err = sh_dmcrypt_mount_container (ctrl,
ctrl->server_local->devicename, ctrl->server_local->devicename,
tuples); tuples, nomount);
leave: leave:
destroy_tupledesc (tuples); destroy_tupledesc (tuples);

View File

@ -220,7 +220,7 @@ mk_setup_area_prefix (size_t *r_length)
} }
/* Create a new g13 styloe DM-Crypt container on devoce DEVNAME. */ /* Create a new g13 style DM-Crypt container on device DEVNAME. */
gpg_error_t gpg_error_t
sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp)
{ {
@ -538,10 +538,11 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp)
/* Mount a DM-Crypt container on device DEVNAME taking keys and other /* Mount a DM-Crypt container on device DEVNAME taking keys and other
* meta data from KEYBLOB. */ * meta data from KEYBLOB. If NOMOUNT is set the actual mount command
* is not run. */
gpg_error_t gpg_error_t
sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
tupledesc_t keyblob) tupledesc_t keyblob, int nomount)
{ {
gpg_error_t err; gpg_error_t err;
char *targetname_abs = NULL; char *targetname_abs = NULL;
@ -696,8 +697,10 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname,
xfree (result); xfree (result);
result = NULL; result = NULL;
g13_status (ctrl, STATUS_PLAINDEV, targetname_abs, NULL);
/* Mount if a mountpoint has been given. */ /* Mount if a mountpoint has been given. */
if (ctrl->devti->mountpoint) if (!nomount && ctrl->devti->mountpoint)
{ {
const char *argv[3]; const char *argv[3];
@ -766,32 +769,43 @@ sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname)
goto leave; goto leave;
} }
/* Run the regular umount command. */ /* Run the regular umount command but first test with findmnt. */
{ {
const char *argv[2]; const char *argv[3];
argv[0] = targetname_abs; argv[0] = targetname_abs;
argv[1] = NULL; argv[1] = NULL;
log_debug ("now running \"umount %s\"\n", targetname_abs); log_debug ("now running \"findmnt %s\"\n", targetname_abs);
err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); err = gnupg_exec_tool ("/bin/findmnt", 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"; if (err)
argv[1] = targetname_abs; log_info ("Note: device was not mounted\n");
argv[2] = NULL; else
gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); {
} xfree (result);
goto leave; result = NULL;
}
if (result && *result) /* (We should not see output to stdout). */ argv[0] = targetname_abs;
log_info ("WARNING: umount returned data on stdout! (%s)\n", result); 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. */
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); xfree (result);
result = NULL; result = NULL;