aboutsummaryrefslogtreecommitdiffstats
path: root/g13/sh-cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'g13/sh-cmd.c')
-rw-r--r--g13/sh-cmd.c112
1 files changed, 108 insertions, 4 deletions
diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c
index 8a3006cab..6ba4cd8c8 100644
--- a/g13/sh-cmd.c
+++ b/g13/sh-cmd.c
@@ -172,9 +172,15 @@ cmd_device (assuan_context_t ctx, char *line)
tab_item_t ti;
estream_t fp = NULL;
- /* strcpy (line, "/dev/sdb1"); /\* FIXME *\/ */
line = skip_options (line);
+/* # warning hardwired to /dev/sdb1 ! */
+/* if (strcmp (line, "/dev/sdb1")) */
+/* { */
+/* err = gpg_error (GPG_ERR_ENOENT); */
+/* goto leave; */
+/* } */
+
/* Always close an open device stream of this session. */
xfree (ctrl->server_local->devicename);
ctrl->server_local->devicename = NULL;
@@ -239,9 +245,9 @@ cmd_create (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
gpg_error_t err = 0;
+ estream_t fp = NULL;
line = skip_options (line);
-
if (strcmp (line, "dm-crypt"))
{
err = set_error (GPG_ERR_INV_ARG, "Type must be \"dm-crypt\"");
@@ -259,23 +265,120 @@ cmd_create (assuan_context_t ctx, char *line)
err = sh_is_empty_partition (ctrl->server_local->devicename);
if (err)
{
+ if (gpg_err_code (err) == GPG_ERR_FALSE)
+ err = gpg_error (GPG_ERR_CONFLICT);
err = assuan_set_error (ctx, err, "Partition is not empty");
goto leave;
}
+ /* We need a writeable stream to create the container. */
+ fp = es_fopen (ctrl->server_local->devicename, "r+b");
+ if (!fp)
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error opening '%s': %s\n",
+ ctrl->server_local->devicename, gpg_strerror (err));
+ goto leave;
+ }
+ if (es_setvbuf (fp, NULL, _IONBF, 0))
+ {
+ err = gpg_error_from_syserror ();
+ log_error ("error setting '%s' to _IONBF: %s\n",
+ ctrl->server_local->devicename, gpg_strerror (err));
+ goto leave;
+ }
+
err = sh_dmcrypt_create_container (ctrl,
ctrl->server_local->devicename,
- ctrl->server_local->devicefp);
+ fp);
+ if (es_fclose (fp))
+ {
+ gpg_error_t err2 = gpg_error_from_syserror ();
+ log_error ("error closing '%s': %s\n",
+ ctrl->server_local->devicename, gpg_strerror (err2));
+ if (!err)
+ err = err2;
+ }
+ fp = NULL;
+ leave:
+ es_fclose (fp);
+ return leave_cmd (ctx, err);
+}
+static const char hlp_mount[] =
+ "MOUNT <type>\n"
+ "\n"
+ "Mount an encrypted partition on the current device.\n"
+ "<type> must be \"dm-crypt\" for now.";
+static gpg_error_t
+cmd_mount (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err = 0;
+ unsigned char *keyblob = NULL;
+ size_t keybloblen;
+ tupledesc_t tuples = NULL;
+
+ 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_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;
+
+ /* We expect that the client already decrypted the keyblob.
+ * Eventually we should move reading of the keyblob to here and ask
+ * the client to decrypt it. */
+ assuan_begin_confidential (ctx);
+ err = assuan_inquire (ctx, "KEYBLOB",
+ &keyblob, &keybloblen, 4 * 1024);
+ assuan_end_confidential (ctx);
+ if (err)
+ {
+ log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+ err = create_tupledesc (&tuples, keyblob, keybloblen);
+ if (!err)
+ keyblob = NULL;
+ else
+ {
+ if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
+ log_error ("unknown keyblob version received\n");
+ goto leave;
+ }
+
+ err = sh_dmcrypt_mount_container (ctrl,
+ ctrl->server_local->devicename,
+ tuples);
leave:
+ xfree (tuples);
+ destroy_tupledesc (tuples);
return leave_cmd (ctx, err);
}
-
static const char hlp_getinfo[] =
"GETINFO <what>\n"
"\n"
@@ -372,6 +475,7 @@ register_commands (assuan_context_t ctx, int fail_all)
} table[] = {
{ "DEVICE", cmd_device, hlp_device },
{ "CREATE", cmd_create, hlp_create },
+ { "MOUNT", cmd_mount, hlp_mount },
{ "INPUT", NULL },
{ "OUTPUT", NULL },
{ "GETINFO", cmd_getinfo, hlp_getinfo },