mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
g13: Second chunk of code to support dm-crypt.
* g13/be-dmcrypt.c, g13/be-dmcrypt.h: New. * g13/Makefile.am (g13_SOURCES): Add them. * g13/backend.c: Include be-dmcrypt.h and call-syshelp.h. (no_such_backend): Rename to _no_such_backend and provide replacement macro. (be_is_supported_conttype): Support DM-Crypt. (be_take_lock_for_create): Call set_segvice for DM-Crypt. (be_create_new_keys): Make it a dummy for DM-Crypt. (be_create_container): Call be_dmcrypt_create_container. (be_mount_container): call be_dmcrypt_mount_container. * g13/g13-syshelp.c (main): Enable verbose mode. * g13/g13tuple.c (get_tupledesc_data): New. * g13/g13tuple.h (unref_tupledesc): New. * g13/g13.h (server_control_): Add field "recipients". * g13/g13.c (main): Fix setting of recipients via cmdline. (g13_deinit_default_ctrl): Release recipients list. (g13_request_shutdown): New. Replace all direct update of shutdown_pending by calls this function. * g13/server.c (server_local_s): Remove field recipients which is now part of CTRL. (reset_notify, cmd_recipient, cmd_create): Adjust for this change. * g13/create.c (encrypt_keyblob): Rename to g13_encrypt_keyblob. (g13_create_container): Support DM-Crypt. * g13/mount.c (parse_header): Allow for meta data copies. (g13_mount_container): Support DM-Crypt. * g13/sh-cmd.c (cmd_create): Make it work. (cmd_mount): New. * g13/sh-dmcrypt.c (sh_dmcrypt_create_container): Make it work. (sh_dmcrypt_mount_container): New. -- With this patch we can now create an encrypted partition and partly mount it (i.e. setup keys and create the mapped device). We do not yet create a file system or mount that file system Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
13f745b50d
commit
b0e6ab1109
18 changed files with 955 additions and 125 deletions
|
@ -44,21 +44,56 @@ struct call_syshelp_s
|
|||
};
|
||||
|
||||
|
||||
/* Fork off the syshelp tool if this has not already been done. */
|
||||
/* Parameter used with the CREATE command. */
|
||||
struct create_parm_s
|
||||
{
|
||||
assuan_context_t ctx;
|
||||
ctrl_t ctrl;
|
||||
membuf_t plaintext;
|
||||
unsigned int expect_plaintext:1;
|
||||
unsigned int got_plaintext:1;
|
||||
};
|
||||
|
||||
|
||||
/* Parameter used with the MOUNT command. */
|
||||
struct mount_parm_s
|
||||
{
|
||||
assuan_context_t ctx;
|
||||
ctrl_t ctrl;
|
||||
const void *keyblob;
|
||||
size_t keybloblen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Fork off the syshelp tool if this has not already been done. On
|
||||
success stores the current Assuan context for the syshelp tool at
|
||||
R_CTX. */
|
||||
static gpg_error_t
|
||||
start_syshelp (ctrl_t ctrl)
|
||||
start_syshelp (ctrl_t ctrl, assuan_context_t *r_ctx)
|
||||
{
|
||||
gpg_error_t err;
|
||||
assuan_context_t ctx;
|
||||
assuan_fd_t no_close_list[3];
|
||||
int i;
|
||||
|
||||
if (ctrl->syshelp_local->assctx)
|
||||
*r_ctx = NULL;
|
||||
|
||||
if (ctrl->syshelp_local && (*r_ctx = ctrl->syshelp_local->assctx))
|
||||
return 0; /* Already set. */
|
||||
|
||||
if (opt.verbose)
|
||||
log_info ("starting a new syshelp\n");
|
||||
|
||||
if (!ctrl->syshelp_local)
|
||||
{
|
||||
ctrl->syshelp_local = xtrycalloc (1, sizeof *ctrl->syshelp_local);
|
||||
if (!ctrl->syshelp_local)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
if (es_fflush (NULL))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
|
@ -79,38 +114,40 @@ start_syshelp (ctrl_t ctrl)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Call userv to start g13-syshelp. This userv script needs tpo be
|
||||
installed under the name "gnupg-g13-syshelp":
|
||||
|
||||
if ( glob service-user root
|
||||
)
|
||||
reset
|
||||
suppress-args
|
||||
execute /home/wk/b/gnupg/g13/g13-syshelp -v
|
||||
else
|
||||
error Nothing to do for this service-user
|
||||
fi
|
||||
quit
|
||||
*/
|
||||
/* Call userv to start g13-syshelp. This userv script needs to be
|
||||
* installed under the name "gnupg-g13-syshelp":
|
||||
*
|
||||
* if ( glob service-user root
|
||||
* )
|
||||
* reset
|
||||
* suppress-args
|
||||
* execute /home/wk/b/gnupg/g13/g13-syshelp -v
|
||||
* else
|
||||
* error Nothing to do for this service-user
|
||||
* fi
|
||||
* quit
|
||||
*/
|
||||
{
|
||||
const char *argv[3];
|
||||
const char *argv[4];
|
||||
|
||||
argv[0] = "userv";
|
||||
argv[1] = "gnupg-g13-syshelp";
|
||||
argv[2] = NULL;
|
||||
argv[1] = "root";
|
||||
argv[2] = "gnupg-g13-syshelp";
|
||||
argv[3] = NULL;
|
||||
|
||||
err = assuan_pipe_connect (ctx, "/usr/bin/userv", argv,
|
||||
no_close_list, NULL, NULL, 0);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
log_error ("can't connect to '%s' - : %s\n",
|
||||
"g13-syshelp", gpg_strerror (err));
|
||||
log_error ("can't connect to '%s': %s %s\n",
|
||||
"g13-syshelp", gpg_strerror (err), gpg_strsource (err));
|
||||
log_info ("(is userv and its gnupg-g13-syshelp script installed?)\n");
|
||||
assuan_release (ctx);
|
||||
return err;
|
||||
}
|
||||
ctrl->syshelp_local->assctx = ctx;
|
||||
|
||||
*r_ctx = ctrl->syshelp_local->assctx = ctx;
|
||||
|
||||
if (DBG_IPC)
|
||||
log_debug ("connection to g13-syshelp established\n");
|
||||
|
@ -129,5 +166,243 @@ call_syshelp_release (ctrl_t ctrl)
|
|||
{
|
||||
assuan_release (ctrl->syshelp_local->assctx);
|
||||
ctrl->syshelp_local->assctx = NULL;
|
||||
xfree (ctrl->syshelp_local);
|
||||
ctrl->syshelp_local = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Send the DEVICE command to the syshelper. FNAME is the name of the
|
||||
device. */
|
||||
gpg_error_t
|
||||
call_syshelp_set_device (ctrl_t ctrl, const char *fname)
|
||||
{
|
||||
gpg_error_t err;
|
||||
assuan_context_t ctx;
|
||||
char *line = NULL;
|
||||
|
||||
err = start_syshelp (ctrl, &ctx);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
line = xtryasprintf ("DEVICE %s", fname);
|
||||
if (!line)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
leave:
|
||||
xfree (line);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
create_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct create_parm_s *parm = opaque;
|
||||
|
||||
if (has_leading_keyword (line, "PLAINTEXT_FOLLOWS"))
|
||||
parm->expect_plaintext = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
create_data_cb (void *opaque, const void *data, size_t datalen)
|
||||
{
|
||||
struct create_parm_s *parm = opaque;
|
||||
gpg_error_t err = 0;
|
||||
|
||||
if (!parm->expect_plaintext)
|
||||
{
|
||||
log_error ("status line for data missing\n");
|
||||
err = gpg_error (GPG_ERR_UNEXPECTED);
|
||||
}
|
||||
else if (data)
|
||||
{
|
||||
put_membuf (&parm->plaintext, data, datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
parm->expect_plaintext = 0;
|
||||
parm->got_plaintext = 1;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
create_inq_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct create_parm_s *parm = opaque;
|
||||
gpg_error_t err;
|
||||
|
||||
if (has_leading_keyword (line, "ENCKEYBLOB"))
|
||||
{
|
||||
void *plaintext;
|
||||
size_t plaintextlen;
|
||||
|
||||
if (!parm->got_plaintext)
|
||||
err = gpg_error (GPG_ERR_UNEXPECTED);
|
||||
else if (!(plaintext = get_membuf (&parm->plaintext, &plaintextlen)))
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
void *ciphertext;
|
||||
size_t ciphertextlen;
|
||||
|
||||
log_printhex ("plain", plaintext, plaintextlen);
|
||||
err = g13_encrypt_keyblob (parm->ctrl,
|
||||
plaintext, plaintextlen,
|
||||
&ciphertext, &ciphertextlen);
|
||||
wipememory (plaintext, plaintextlen);
|
||||
xfree (plaintext);
|
||||
if (err)
|
||||
log_error ("error encrypting keyblob: %s\n", gpg_strerror (err));
|
||||
else
|
||||
{
|
||||
err = assuan_send_data (parm->ctx, ciphertext, ciphertextlen);
|
||||
xfree (ciphertext);
|
||||
if (err)
|
||||
log_error ("sending ciphertext to g13-syshelp failed: %s\n",
|
||||
gpg_strerror (err));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Run the CREATE command on the current device. CONTTYPES gives the
|
||||
requested content type for the new container. */
|
||||
gpg_error_t
|
||||
call_syshelp_run_create (ctrl_t ctrl, int conttype)
|
||||
{
|
||||
gpg_error_t err;
|
||||
assuan_context_t ctx;
|
||||
struct create_parm_s parm;
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
|
||||
err = start_syshelp (ctrl, &ctx);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* tty_get ("waiting for debugger"); */
|
||||
/* tty_kill_prompt (); */
|
||||
|
||||
parm.ctx = ctx;
|
||||
parm.ctrl = ctrl;
|
||||
init_membuf (&parm.plaintext, 512);
|
||||
if (conttype == CONTTYPE_DM_CRYPT)
|
||||
{
|
||||
err = assuan_transact (ctx, "CREATE dm-crypt",
|
||||
create_data_cb, &parm,
|
||||
create_inq_cb, &parm,
|
||||
create_status_cb, &parm);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error ("invalid backend type %d given\n", conttype);
|
||||
err = GPG_ERR_INTERNAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (get_membuf (&parm.plaintext, NULL));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
mount_status_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct mount_parm_s *parm = opaque;
|
||||
|
||||
/* Nothing right now. */
|
||||
(void)parm;
|
||||
(void)line;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
mount_inq_cb (void *opaque, const char *line)
|
||||
{
|
||||
struct mount_parm_s *parm = opaque;
|
||||
gpg_error_t err;
|
||||
|
||||
if (has_leading_keyword (line, "KEYBLOB"))
|
||||
{
|
||||
int setconfidential = !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL);
|
||||
|
||||
if (setconfidential)
|
||||
assuan_begin_confidential (parm->ctx);
|
||||
err = assuan_send_data (parm->ctx, parm->keyblob, parm->keybloblen);
|
||||
if (setconfidential)
|
||||
assuan_end_confidential (parm->ctx);
|
||||
if (err)
|
||||
log_error ("sending keyblob to g13-syshelp failed: %s\n",
|
||||
gpg_strerror (err));
|
||||
}
|
||||
else
|
||||
err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Run the MOUNT command on the current device. CONTTYPES gives the
|
||||
requested content type for the new container. MOUNTPOINT the
|
||||
desired mount point or NULL for default. */
|
||||
gpg_error_t
|
||||
call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint,
|
||||
tupledesc_t tuples)
|
||||
{
|
||||
gpg_error_t err;
|
||||
assuan_context_t ctx;
|
||||
struct mount_parm_s parm;
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
|
||||
err = start_syshelp (ctrl, &ctx);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* tty_get ("waiting for debugger"); */
|
||||
/* tty_kill_prompt (); */
|
||||
|
||||
parm.ctx = ctx;
|
||||
parm.ctrl = ctrl;
|
||||
if (conttype == CONTTYPE_DM_CRYPT)
|
||||
{
|
||||
ref_tupledesc (tuples);
|
||||
parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen);
|
||||
err = assuan_transact (ctx, "MOUNT dm-crypt",
|
||||
NULL, NULL,
|
||||
mount_inq_cb, &parm,
|
||||
mount_status_cb, &parm);
|
||||
unref_tupledesc (tuples);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)mountpoint; /* Not used. */
|
||||
log_error ("invalid backend type %d given\n", conttype);
|
||||
err = GPG_ERR_INTERNAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
leave:
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue