diff options
author | Marcus Brinkmann <[email protected]> | 2001-11-16 00:20:11 +0000 |
---|---|---|
committer | Marcus Brinkmann <[email protected]> | 2001-11-16 00:20:11 +0000 |
commit | 550bc31b44b631368af398fb083f55bc2ffdae6b (patch) | |
tree | 0aa9f1c0caf6b10b73bfba0e1d864261ae5f0897 /gpgme/passphrase.c | |
parent | 2001-11-15 Marcus Brinkmann <[email protected]> (diff) | |
download | gpgme-550bc31b44b631368af398fb083f55bc2ffdae6b.tar.gz gpgme-550bc31b44b631368af398fb083f55bc2ffdae6b.zip |
2001-11-16 Marcus Brinkmann <[email protected]>
* passphrase.c: New file.
* Makefile.am (libgpgme_la_SOURCES): Add passphrase.c.
* ops.h (_gpgme_passphrase_result): Add prototypes from
passphrase.c.
* types.h: Likewise.
* context.h: Add member passphrase to result.
* gpgme.c (_gpgme_release_result): Release passphrase member.
* decrypt.c: Some formatting and variable name changes (like
CTX instead C).
(struct decrypt_result_s): Remove members now found in
passphrase result.
(_gpgme_release_decrypt_result): Don't release removed members.
(decrypt_status_handler): Call _gpgme_passphrase_status_handler,
and don't handle the cases catched there.
(command_handler): Removed.
(gpgme_op_decrypt_start): Don't set command handler, but invoke
_gpgme_passphrase_start which does it.
(gpgme_op_decrypt): Invoke _gpgme_passphrase_result and drop the
cases covered by it.
* sign.c Some formatting and variable name changes (like
CTX instead C).
(struct sign_result_s): Remove members now found in
passphrase result.
(_gpgme_release_sign_result): Don't release removed members.
(sign_status_handler): Call _gpgme_passphrase_status_handler,
and don't handle the cases catched there.
(command_handler): Removed.
(gpgme_op_sign_start): Don't set command handler, but invoke
_gpgme_passphrase_start which does it.
(gpgme_op_sign): Invoke _gpgme_passphrase_result and drop the
cases covered by it.
Diffstat (limited to '')
-rw-r--r-- | gpgme/passphrase.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/gpgme/passphrase.c b/gpgme/passphrase.c new file mode 100644 index 00000000..0ecea6dd --- /dev/null +++ b/gpgme/passphrase.c @@ -0,0 +1,187 @@ +/* passphrase.c - passphrase functions + * Copyright (C) 2000 Werner Koch (dd9jn) + * Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "util.h" +#include "context.h" +#include "ops.h" + +struct passphrase_result_s +{ + int no_passphrase; + void *last_pw_handle; + char *userid_hint; + char *passphrase_info; + int bad_passphrase; +}; + +void +_gpgme_release_passphrase_result (PassphraseResult result) +{ + if (!result) + return; + xfree (result->passphrase_info); + xfree (result->userid_hint); + xfree (result); +} + +void +_gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) +{ + if (ctx->out_of_core) + return; + + if (!ctx->result.passphrase) + { + ctx->result.passphrase = xtrycalloc (1, sizeof *ctx->result.passphrase); + if (!ctx->result.passphrase) + { + ctx->out_of_core = 1; + return; + } + } + + switch (code) + { + case STATUS_USERID_HINT: + xfree (ctx->result.passphrase->userid_hint); + if (!(ctx->result.passphrase->userid_hint = xtrystrdup (args)) ) + ctx->out_of_core = 1; + break; + + case STATUS_BAD_PASSPHRASE: + ctx->result.passphrase->bad_passphrase++; + break; + + case STATUS_GOOD_PASSPHRASE: + ctx->result.passphrase->bad_passphrase = 0; + break; + + case STATUS_NEED_PASSPHRASE: + case STATUS_NEED_PASSPHRASE_SYM: + xfree (ctx->result.passphrase->passphrase_info); + ctx->result.passphrase->passphrase_info = xtrystrdup (args); + if (!ctx->result.passphrase->passphrase_info) + ctx->out_of_core = 1; + break; + + case STATUS_MISSING_PASSPHRASE: + DEBUG0 ("missing passphrase - stop\n");; + ctx->result.passphrase->no_passphrase = 1; + break; + + default: + /* Ignore all other codes. */ + break; + } +} + +static const char * +command_handler (void *opaque, GpgStatusCode code, const char *key) +{ + GpgmeCtx ctx = opaque; + + if (!ctx->result.passphrase) + { + ctx->result.passphrase = xtrycalloc (1, sizeof *ctx->result.passphrase); + if (!ctx->result.passphrase) + { + ctx->out_of_core = 1; + return NULL; + } + } + + if (!code) + { + /* We have been called for cleanup. */ + if (ctx->passphrase_cb) + { + /* Fixme: Take the key in account. */ + ctx->passphrase_cb (ctx->passphrase_cb_value, NULL, + &ctx->result.passphrase->last_pw_handle); + } + return NULL; + } + + if (!key || !ctx->passphrase_cb) + return NULL; + + if (code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter")) + { + const char *userid_hint = ctx->result.passphrase->userid_hint; + const char *passphrase_info = ctx->result.passphrase->passphrase_info; + int bad_passphrase = ctx->result.passphrase->bad_passphrase; + char *buf; + const char *s; + + ctx->result.passphrase->bad_passphrase = 0; + if (!userid_hint) + userid_hint = "[User ID hint missing]"; + if (!passphrase_info) + passphrase_info = "[passphrase info missing]"; + buf = xtrymalloc (20 + strlen (userid_hint) + + strlen (passphrase_info) + 3); + if (!buf) + { + ctx->out_of_core = 1; + return NULL; + } + sprintf (buf, "%s\n%s\n%s", + bad_passphrase ? "TRY_AGAIN":"ENTER", + userid_hint, passphrase_info); + + s = ctx->passphrase_cb (ctx->passphrase_cb_value, + buf, &ctx->result.passphrase->last_pw_handle); + xfree (buf); + return s; + } + + return NULL; +} + +GpgmeError +_gpgme_passphrase_start (GpgmeCtx ctx) +{ + GpgmeError err = 0; + + if (ctx->passphrase_cb) + err = _gpgme_gpg_set_command_handler (ctx->gpg, command_handler, ctx); + return err; +} + +GpgmeError +_gpgme_passphrase_result (GpgmeCtx ctx) +{ + GpgmeError err = 0; + + if (!ctx->result.passphrase) + err = mk_error (General_Error); + else if (ctx->out_of_core) + err = mk_error (Out_Of_Core); + else if (ctx->result.passphrase->no_passphrase) + err = mk_error (No_Passphrase); + return err; +} |