From 550bc31b44b631368af398fb083f55bc2ffdae6b Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 16 Nov 2001 00:20:11 +0000 Subject: [PATCH] 2001-11-16 Marcus Brinkmann * 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. --- gpgme/ChangeLog | 36 ++++ gpgme/Makefile.am | 1 + gpgme/context.h | 1 + gpgme/decrypt.c | 258 +++++++++---------------- gpgme/gpgme.c | 1 + gpgme/ops.h | 12 +- gpgme/passphrase.c | 187 ++++++++++++++++++ gpgme/sign.c | 463 ++++++++++++++++++--------------------------- gpgme/types.h | 4 + 9 files changed, 508 insertions(+), 455 deletions(-) create mode 100644 gpgme/passphrase.c diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 1f0d21b..253d8c3 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,39 @@ +2001-11-16 Marcus Brinkmann + + * 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. + 2001-11-15 Marcus Brinkmann * decrypt.c (command_handler): Fix last change. diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 36029b7..5a7fb4c 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -41,6 +41,7 @@ libgpgme_la_SOURCES = \ decrypt.c \ verify.c \ sign.c \ + passphrase.c \ key.c key.h \ keylist.c \ trustlist.c \ diff --git a/gpgme/context.h b/gpgme/context.h index 9a00499..c2a0bca 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -67,6 +67,7 @@ struct gpgme_context_s { DecryptResult decrypt; SignResult sign; EncryptResult encrypt; + PassphraseResult passphrase; } result; GpgmeData notation; /* last signature notation */ diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c index 2fb9052..4b38cf6 100644 --- a/gpgme/decrypt.c +++ b/gpgme/decrypt.c @@ -31,13 +31,8 @@ struct decrypt_result_s { - int no_passphrase; int okay; int failed; - void *last_pw_handle; - char *userid_hint; - char *passphrase_info; - int bad_passphrase; }; void @@ -45,8 +40,6 @@ _gpgme_release_decrypt_result (DecryptResult result) { if (!result) return; - xfree (result->passphrase_info); - xfree (result->userid_hint); xfree (result); } @@ -63,220 +56,139 @@ create_result_struct (GpgmeCtx ctx) static void decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) { - if ( ctx->out_of_core ) - return; - if (! ctx->result.decrypt) - { - if (create_result_struct (ctx)) - { - ctx->out_of_core = 1; - return; - } - } + _gpgme_passphrase_status_handler (ctx, code, args); - switch (code) { - case STATUS_EOF: - break; - - case STATUS_USERID_HINT: - xfree (ctx->result.decrypt->userid_hint); - if (!(ctx->result.decrypt->userid_hint = xtrystrdup (args)) ) - ctx->out_of_core = 1; - break; - - case STATUS_BAD_PASSPHRASE: - ctx->result.decrypt->bad_passphrase++; - break; - - case STATUS_GOOD_PASSPHRASE: - ctx->result.decrypt->bad_passphrase = 0; - break; - - case STATUS_NEED_PASSPHRASE: - case STATUS_NEED_PASSPHRASE_SYM: - xfree (ctx->result.decrypt->passphrase_info); - if (!(ctx->result.decrypt->passphrase_info = xtrystrdup (args)) ) - ctx->out_of_core = 1; - break; - - case STATUS_MISSING_PASSPHRASE: - DEBUG0 ("missing passphrase - stop\n");; - ctx->result.decrypt->no_passphrase = 1; - break; - - case STATUS_DECRYPTION_OKAY: - ctx->result.decrypt->okay = 1; - break; - - case STATUS_DECRYPTION_FAILED: - ctx->result.decrypt->failed = 1; - break; - + if (ctx->out_of_core) + return; - default: - /* ignore all other codes */ - break; + if (! ctx->result.decrypt) + { + if (create_result_struct (ctx)) + { + ctx->out_of_core = 1; + return; + } } -} + switch (code) + { + case STATUS_EOF: + break; -static const char * -command_handler (void *opaque, GpgStatusCode code, const char *key) -{ - GpgmeCtx c = opaque; - - if (! c->result.decrypt) - { - if (create_result_struct (c)) - { - c->out_of_core = 1; - return NULL; - } - } + case STATUS_DECRYPTION_OKAY: + ctx->result.decrypt->okay = 1; + break; - if ( !code ) { - /* We have been called for cleanup */ - if ( c->passphrase_cb ) { - /* Fixme: take the key in account */ - c->passphrase_cb (c->passphrase_cb_value, NULL, - &c->result.decrypt->last_pw_handle ); - } + case STATUS_DECRYPTION_FAILED: + ctx->result.decrypt->failed = 1; + break; - return NULL; + default: + /* Ignore all other codes. */ + break; } - - if ( !key || !c->passphrase_cb ) - return NULL; - - if ( code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter") ) { - const char *userid_hint = c->result.decrypt->userid_hint; - const char *passphrase_info = c->result.decrypt->passphrase_info; - int bad_passphrase = c->result.decrypt->bad_passphrase; - char *buf; - const char *s; - - c->result.decrypt->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) { - c->out_of_core = 1; - return NULL; - } - sprintf (buf, "%s\n%s\n%s", - bad_passphrase? "TRY_AGAIN":"ENTER", - userid_hint, passphrase_info ); - - s = c->passphrase_cb (c->passphrase_cb_value, - buf, &c->result.decrypt->last_pw_handle ); - xfree (buf); - return s; - } - - return NULL; } - GpgmeError -gpgme_op_decrypt_start ( GpgmeCtx c, - GpgmeData ciph, GpgmeData plain ) +gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain) { - int rc = 0; - int i; + GpgmeError err = 0; + int i; - fail_on_pending_request( c ); - c->pending = 1; + fail_on_pending_request (ctx); + ctx->pending = 1; - _gpgme_release_result (c); - c->out_of_core = 0; + _gpgme_release_result (ctx); + ctx->out_of_core = 0; - /* do some checks */ + /* Do some checks. */ - /* create a process object */ - _gpgme_gpg_release ( c->gpg ); - rc = _gpgme_gpg_new ( &c->gpg ); - if (rc) - goto leave; + /* Create a process object. */ + _gpgme_gpg_release (ctx->gpg); + err = _gpgme_gpg_new (&ctx->gpg); + if (err) + goto leave; - _gpgme_gpg_set_status_handler ( c->gpg, decrypt_status_handler, c ); - if (c->passphrase_cb) { - rc = _gpgme_gpg_set_command_handler ( c->gpg, command_handler, c ); - if (rc) - goto leave; - } + _gpgme_gpg_set_status_handler (ctx->gpg, decrypt_status_handler, ctx); + + err = _gpgme_passphrase_start (ctx); + if (err) + goto leave; - /* build the commandline */ - _gpgme_gpg_add_arg ( c->gpg, "--decrypt" ); - for ( i=0; i < c->verbosity; i++ ) - _gpgme_gpg_add_arg ( c->gpg, "--verbose" ); + /* Build the commandline. */ + _gpgme_gpg_add_arg (ctx->gpg, "--decrypt"); + for (i = 0; i < ctx->verbosity; i++) + _gpgme_gpg_add_arg (ctx->gpg, "--verbose"); - /* Check the supplied data */ - if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) { - rc = mk_error (No_Data); - goto leave; + /* Check the supplied data. */ + if (!ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE) + { + err = mk_error (No_Data); + goto leave; } - _gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT ); + _gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT); - if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) { - rc = mk_error (Invalid_Value); - goto leave; + if (gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE) + { + err = mk_error (Invalid_Value); + goto leave; } - _gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN ); + _gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN); - /* Tell the gpg object about the data */ - _gpgme_gpg_add_arg ( c->gpg, "--output" ); - _gpgme_gpg_add_arg ( c->gpg, "-" ); - _gpgme_gpg_add_data ( c->gpg, plain, 1 ); - _gpgme_gpg_add_data ( c->gpg, ciph, 0 ); + /* Tell the gpg object about the data. */ + _gpgme_gpg_add_arg (ctx->gpg, "--output"); + _gpgme_gpg_add_arg (ctx->gpg, "-"); + _gpgme_gpg_add_data (ctx->gpg, plain, 1); + _gpgme_gpg_add_data (ctx->gpg, ciph, 0); - /* and kick off the process */ - rc = _gpgme_gpg_spawn ( c->gpg, c ); + /* And kick off the process. */ + err = _gpgme_gpg_spawn (ctx->gpg, ctx); leave: - if (rc) { - c->pending = 0; - _gpgme_gpg_release ( c->gpg ); c->gpg = NULL; + if (err) + { + ctx->pending = 0; + _gpgme_gpg_release (ctx->gpg); + ctx->gpg = NULL; } - return rc; + return err; } - /** * gpgme_op_decrypt: - * @c: The context + * @ctx: The context * @in: ciphertext input * @out: plaintext output * * This function decrypts @in to @out. - * Other parameters are take from the context @c. + * Other parameters are take from the context @ctx. * The function does wait for the result. * * Return value: 0 on success or an errorcode. **/ GpgmeError -gpgme_op_decrypt (GpgmeCtx c, GpgmeData in, GpgmeData out) +gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out) { - GpgmeError err = gpgme_op_decrypt_start (c, in, out); + GpgmeError err = gpgme_op_decrypt_start (ctx, in, out); if (!err) { - gpgme_wait (c, 1); - if (!c->result.decrypt) + gpgme_wait (ctx, 1); + if (!ctx->result.decrypt) err = mk_error (General_Error); - else if (c->out_of_core) + else if (ctx->out_of_core) err = mk_error (Out_Of_Core); else { - if (c->result.decrypt->no_passphrase) - err = mk_error (No_Passphrase); - else if (c->result.decrypt->failed) - err = mk_error (Decryption_Failed); - else if (!c->result.decrypt->okay) - err = mk_error (No_Data); + err = _gpgme_passphrase_result (ctx); + if (! err) + { + if (ctx->result.decrypt->failed) + err = mk_error (Decryption_Failed); + else if (!ctx->result.decrypt->okay) + err = mk_error (No_Data); + } } - c->pending = 0; + ctx->pending = 0; } return err; } diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 8c0b704..2e010bc 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -88,6 +88,7 @@ _gpgme_release_result (GpgmeCtx c) _gpgme_release_decrypt_result (c->result.decrypt); _gpgme_release_sign_result (c->result.sign); _gpgme_release_encrypt_result (c->result.encrypt); + _gpgme_release_passphrase_result (c->result.passphrase); memset (&c->result, 0, sizeof (c->result)); _gpgme_set_op_info (c, NULL); } diff --git a/gpgme/ops.h b/gpgme/ops.h index 638e781..2186d93 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -23,6 +23,7 @@ #define OPS_H #include "types.h" +#include "rungpg.h" /*-- gpgme.c --*/ void _gpgme_release_result ( GpgmeCtx c ); @@ -79,10 +80,11 @@ void _gpgme_release_sign_result ( SignResult res ); /*-- encrypt.c --*/ void _gpgme_release_encrypt_result ( EncryptResult res ); +/*-- passphrase.c --*/ +void _gpgme_release_passphrase_result (PassphraseResult result); +void _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, + char *args); +GpgmeError _gpgme_passphrase_start (GpgmeCtx ctx); +GpgmeError _gpgme_passphrase_result (GpgmeCtx ctx); #endif /* OPS_H */ - - - - - diff --git a/gpgme/passphrase.c b/gpgme/passphrase.c new file mode 100644 index 0000000..0ecea6d --- /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 +#include +#include +#include +#include + +#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; +} diff --git a/gpgme/sign.c b/gpgme/sign.c index 2f0de1d..dc53b7b 100644 --- a/gpgme/sign.c +++ b/gpgme/sign.c @@ -38,12 +38,7 @@ struct sign_result_s { - int no_passphrase; int okay; - void *last_pw_handle; - char *userid_hint; - char *passphrase_info; - int bad_passphrase; GpgmeData xmlinfo; }; @@ -53,311 +48,230 @@ _gpgme_release_sign_result (SignResult result) if (!result) return; gpgme_data_release (result->xmlinfo); - xfree (result->userid_hint); - xfree (result->passphrase_info); xfree (result); } -/* parse the args and save the information +/* Parse the args and save the information * * in an XML structure. With args of NULL the xml structure is closed. */ static void append_xml_siginfo (GpgmeData *rdh, char *args) { - GpgmeData dh; - char helpbuf[100]; - int i; - char *s; - unsigned long ul; - - if ( !*rdh ) { - if (gpgme_data_new (rdh)) { - return; /* fixme: We are ignoring out-of-core */ + GpgmeData dh; + char helpbuf[100]; + int i; + char *s; + unsigned long ul; + + if (!*rdh) + { + if (gpgme_data_new (rdh)) + { + return; /* fixme: We are ignoring out-of-core */ } - dh = *rdh; - _gpgme_data_append_string (dh, "\n"); + dh = *rdh; + _gpgme_data_append_string (dh, "\n"); } - else { - dh = *rdh; - _gpgme_data_append_string (dh, " \n"); + else + { + dh = *rdh; + _gpgme_data_append_string (dh, " \n"); } - if (!args) { /* just close the XML containter */ - _gpgme_data_append_string (dh, "\n"); - return; + if (!args) + { + /* Just close the XML containter. */ + _gpgme_data_append_string (dh, "\n"); + return; } - _gpgme_data_append_string (dh, " \n"); + _gpgme_data_append_string (dh, " \n"); - _gpgme_data_append_string (dh, - *args == 'D'? " \n": - *args == 'C'? " \n": - *args == 'S'? " \n":""); - SKIP_TOKEN_OR_RETURN (args); - - sprintf (helpbuf, " %d\n", atoi (args)); - _gpgme_data_append_string (dh, helpbuf); - SKIP_TOKEN_OR_RETURN (args); - - i = atoi (args); - sprintf (helpbuf, " %d\n", atoi (args)); - _gpgme_data_append_string (dh, helpbuf); - switch (i) { - case 1: s = "pgp-md5"; break; - case 2: s = "pgp-sha1"; break; - case 3: s = "pgp-ripemd160"; break; - case 5: s = "pgp-md2"; break; - case 6: s = "pgp-tiger192"; break; - case 7: s = "pgp-haval-5-160"; break; - case 8: s = "pgp-sha256"; break; - case 9: s = "pgp-sha384"; break; - case 10: s = "pgp-sha512"; break; - default: s = "pgp-unknown"; break; + _gpgme_data_append_string (dh, + *args == 'D' ? " \n" : + *args == 'C' ? " \n" : + *args == 'S' ? " \n" : ""); + SKIP_TOKEN_OR_RETURN (args); + + sprintf (helpbuf, " %d\n", atoi (args)); + _gpgme_data_append_string (dh, helpbuf); + SKIP_TOKEN_OR_RETURN (args); + + i = atoi (args); + sprintf (helpbuf, " %d\n", atoi (args)); + _gpgme_data_append_string (dh, helpbuf); + switch (i) + { + case 1: s = "pgp-md5"; break; + case 2: s = "pgp-sha1"; break; + case 3: s = "pgp-ripemd160"; break; + case 5: s = "pgp-md2"; break; + case 6: s = "pgp-tiger192"; break; + case 7: s = "pgp-haval-5-160"; break; + case 8: s = "pgp-sha256"; break; + case 9: s = "pgp-sha384"; break; + case 10: s = "pgp-sha512"; break; + default: s = "pgp-unknown"; break; } - sprintf (helpbuf, " %s\n", s); - _gpgme_data_append_string (dh,helpbuf); - SKIP_TOKEN_OR_RETURN (args); + sprintf (helpbuf, " %s\n", s); + _gpgme_data_append_string (dh,helpbuf); + SKIP_TOKEN_OR_RETURN (args); - sprintf (helpbuf, " %.2s\n", args); - _gpgme_data_append_string (dh, helpbuf); - SKIP_TOKEN_OR_RETURN (args); - - ul = strtoul (args, NULL, 10); - sprintf (helpbuf, " %lu\n", ul); - _gpgme_data_append_string (dh, helpbuf); - SKIP_TOKEN_OR_RETURN (args); - - /* count the length of the finperprint */ - for (i=0; args[i] && args[i] != ' '; i++) - ; - _gpgme_data_append_string (dh, " "); - _gpgme_data_append (dh, args, i); - _gpgme_data_append_string (dh, "\n"); + sprintf (helpbuf, " %.2s\n", args); + _gpgme_data_append_string (dh, helpbuf); + SKIP_TOKEN_OR_RETURN (args); + + ul = strtoul (args, NULL, 10); + sprintf (helpbuf, " %lu\n", ul); + _gpgme_data_append_string (dh, helpbuf); + SKIP_TOKEN_OR_RETURN (args); + + /* Count the length of the finperprint. */ + for (i = 0; args[i] && args[i] != ' '; i++) + ; + _gpgme_data_append_string (dh, " "); + _gpgme_data_append (dh, args, i); + _gpgme_data_append_string (dh, "\n"); } - - static void sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args) { - if (ctx->out_of_core) - return; - if (!ctx->result.sign) - { - ctx->result.sign = xtrycalloc (1, sizeof *ctx->result.sign); - if (!ctx->result.sign) - { - ctx->out_of_core = 1; - return; - } - } - - switch (code) { - case STATUS_EOF: - if (ctx->result.sign->okay) { - append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL); - _gpgme_set_op_info (ctx, ctx->result.sign->xmlinfo); - ctx->result.sign->xmlinfo = NULL; - } - break; - - case STATUS_USERID_HINT: - xfree (ctx->result.sign->userid_hint); - if (!(ctx->result.sign->userid_hint = xtrystrdup (args)) ) - ctx->out_of_core = 1; - break; - - case STATUS_BAD_PASSPHRASE: - ctx->result.sign->bad_passphrase++; - break; - - case STATUS_GOOD_PASSPHRASE: - ctx->result.sign->bad_passphrase = 0; - break; - - case STATUS_NEED_PASSPHRASE: - case STATUS_NEED_PASSPHRASE_SYM: - xfree (ctx->result.sign->passphrase_info); - if (!(ctx->result.sign->passphrase_info = xtrystrdup (args)) ) - ctx->out_of_core = 1; - break; - - case STATUS_MISSING_PASSPHRASE: - DEBUG0 ("missing passphrase - stop\n"); - ctx->result.sign->no_passphrase = 1; - break; - - case STATUS_SIG_CREATED: - /* fixme: we have no error return for multiple signatures */ - append_xml_siginfo (&ctx->result.sign->xmlinfo, args); - ctx->result.sign->okay =1; - break; - - default: - break; + if (ctx->out_of_core) + return; + if (!ctx->result.sign) + { + ctx->result.sign = xtrycalloc (1, sizeof *ctx->result.sign); + if (!ctx->result.sign) + { + ctx->out_of_core = 1; + return; + } } -} -static const char * -command_handler ( void *opaque, GpgStatusCode code, const char *key ) -{ - GpgmeCtx c = opaque; - - if (!c->result.sign) - { - c->result.sign = xtrycalloc (1, sizeof *c->result.sign); - if (!c->result.sign) - { - c->out_of_core = 1; - return NULL; - } - } - - if ( !code ) { - /* We have been called for cleanup */ - if ( c->passphrase_cb ) { - /* Fixme: take the key in account */ - c->passphrase_cb (c->passphrase_cb_value, 0, - &c->result.sign->last_pw_handle ); + switch (code) + { + case STATUS_EOF: + if (ctx->result.sign->okay) + { + append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL); + _gpgme_set_op_info (ctx, ctx->result.sign->xmlinfo); + ctx->result.sign->xmlinfo = NULL; } - - return NULL; - } + break; - if ( !key || !c->passphrase_cb ) - return NULL; - - if ( code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter") ) { - const char *userid_hint = c->result.sign->userid_hint; - const char *passphrase_info = c->result.sign->passphrase_info; - int bad_passphrase = c->result.sign->bad_passphrase; - char *buf; - const char *s; - - c->result.sign->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) { - c->out_of_core = 1; - return NULL; - } - sprintf (buf, "%s\n%s\n%s", - bad_passphrase? "TRY_AGAIN":"ENTER", - userid_hint, passphrase_info ); + case STATUS_SIG_CREATED: + /* FIXME: We have no error return for multiple signatures. */ + append_xml_siginfo (&ctx->result.sign->xmlinfo, args); + ctx->result.sign->okay =1; + break; - s = c->passphrase_cb (c->passphrase_cb_value, - buf, &c->result.sign->last_pw_handle ); - xfree (buf); - return s; + default: + break; } - - return NULL; } - GpgmeError -gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out, - GpgmeSigMode mode ) +gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out, + GpgmeSigMode mode) { - int rc = 0; - int i; - GpgmeKey key; - - fail_on_pending_request( c ); - c->pending = 1; + GpgmeError err = 0; + int i; + GpgmeKey key; - _gpgme_release_result (c); - c->out_of_core = 0; + fail_on_pending_request (ctx); + ctx->pending = 1; + _gpgme_release_result (ctx); + ctx->out_of_core = 0; - if ( mode != GPGME_SIG_MODE_NORMAL - && mode != GPGME_SIG_MODE_DETACH - && mode != GPGME_SIG_MODE_CLEAR ) - return mk_error (Invalid_Value); + if (mode != GPGME_SIG_MODE_NORMAL + && mode != GPGME_SIG_MODE_DETACH + && mode != GPGME_SIG_MODE_CLEAR) + return mk_error (Invalid_Value); - /* create a process object */ - _gpgme_gpg_release (c->gpg); - c->gpg = NULL; - rc = _gpgme_gpg_new ( &c->gpg ); - if (rc) - goto leave; - - _gpgme_gpg_set_status_handler ( c->gpg, sign_status_handler, c ); - if (c->passphrase_cb) { - rc = _gpgme_gpg_set_command_handler ( c->gpg, command_handler, c ); - if (rc) - goto leave; + /* Create a process object. */ + _gpgme_gpg_release (ctx->gpg); + ctx->gpg = NULL; + err = _gpgme_gpg_new (&ctx->gpg); + if (err) + goto leave; + + _gpgme_gpg_set_status_handler (ctx->gpg, sign_status_handler, ctx); + + err = _gpgme_passphrase_start (ctx); + if (err) + goto leave; + + /* Build the commandline. */ + if (mode == GPGME_SIG_MODE_CLEAR) + _gpgme_gpg_add_arg (ctx->gpg, "--clearsign"); + else + { + _gpgme_gpg_add_arg (ctx->gpg, "--sign"); + if (mode == GPGME_SIG_MODE_DETACH) + _gpgme_gpg_add_arg (ctx->gpg, "--detach"); + if (ctx->use_armor) + _gpgme_gpg_add_arg (ctx->gpg, "--armor"); + if (ctx->use_textmode) + _gpgme_gpg_add_arg (ctx->gpg, "--textmode"); } - - /* build the commandline */ - if ( mode == GPGME_SIG_MODE_CLEAR ) { - _gpgme_gpg_add_arg ( c->gpg, "--clearsign" ); - } - else { - _gpgme_gpg_add_arg ( c->gpg, "--sign" ); - if ( mode == GPGME_SIG_MODE_DETACH ) - _gpgme_gpg_add_arg ( c->gpg, "--detach" ); - if ( c->use_armor ) - _gpgme_gpg_add_arg ( c->gpg, "--armor" ); - if ( c->use_textmode ) - _gpgme_gpg_add_arg ( c->gpg, "--textmode" ); - } - for (i=0; i < c->verbosity; i++) - _gpgme_gpg_add_arg ( c->gpg, "--verbose" ); - for (i=0; (key = gpgme_signers_enum (c, i)); i++ ) { - const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, - NULL, 0); - if (s) { - _gpgme_gpg_add_arg (c->gpg, "-u"); - _gpgme_gpg_add_arg (c->gpg, s); - } + for (i = 0; i < ctx->verbosity; i++) + _gpgme_gpg_add_arg (ctx->gpg, "--verbose"); + for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++) + { + const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, + NULL, 0); + if (s) + { + _gpgme_gpg_add_arg (ctx->gpg, "-u"); + _gpgme_gpg_add_arg (ctx->gpg, s); + } gpgme_key_unref (key); } - - /* Check the supplied data */ - if ( gpgme_data_get_type (in) == GPGME_DATA_TYPE_NONE ) { - rc = mk_error (No_Data); - goto leave; + /* Check the supplied data. */ + if (gpgme_data_get_type (in) == GPGME_DATA_TYPE_NONE) + { + err = mk_error (No_Data); + goto leave; } - _gpgme_data_set_mode (in, GPGME_DATA_MODE_OUT ); - if ( !out || gpgme_data_get_type (out) != GPGME_DATA_TYPE_NONE ) { - rc = mk_error (Invalid_Value); - goto leave; + _gpgme_data_set_mode (in, GPGME_DATA_MODE_OUT); + if (!out || gpgme_data_get_type (out) != GPGME_DATA_TYPE_NONE) + { + err = mk_error (Invalid_Value); + goto leave; } - _gpgme_data_set_mode (out, GPGME_DATA_MODE_IN ); - - /* tell the gpg object about the data */ - _gpgme_gpg_add_data ( c->gpg, in, 0 ); - _gpgme_gpg_add_data ( c->gpg, out, 1 ); + _gpgme_data_set_mode (out, GPGME_DATA_MODE_IN); - /* and kick off the process */ - rc = _gpgme_gpg_spawn ( c->gpg, c ); + /* Tell the gpg object about the data. */ + _gpgme_gpg_add_data (ctx->gpg, in, 0); + _gpgme_gpg_add_data (ctx->gpg, out, 1); + /* And kick off the process. */ + err = _gpgme_gpg_spawn (ctx->gpg, ctx); + leave: - if (rc) { - c->pending = 0; - _gpgme_gpg_release ( c->gpg ); c->gpg = NULL; + if (err) + { + ctx->pending = 0; + _gpgme_gpg_release (ctx->gpg); + ctx->gpg = NULL; } - return rc; + return err; } - /** * gpgme_op_sign: - * @c: The context + * @ctx: The context * @in: Data to be signed * @out: Detached signature * @mode: Signature creation mode * * Create a detached signature for @in and write it to @out. * The data will be signed using either the default key or the ones - * defined through @c. + * defined through @ctx. * The defined modes for signature create are: * * GPGME_SIG_MODE_NORMAL (or 0) @@ -370,31 +284,26 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out, * Return value: 0 on success or an error code. **/ GpgmeError -gpgme_op_sign (GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode) +gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode) { - GpgmeError err = gpgme_op_sign_start ( c, in, out, mode ); - if ( !err ) { - gpgme_wait (c, 1); - if (!c->result.sign) - err = mk_error (General_Error); - else if (c->out_of_core) - err = mk_error (Out_Of_Core); - else { - if (c->result.sign->no_passphrase) - err = mk_error (No_Passphrase); - else if (!c->result.sign->okay) + GpgmeError err = gpgme_op_sign_start (ctx, in, out, mode); + if (!err) + { + gpgme_wait (ctx, 1); + if (!ctx->result.sign) + err = mk_error (General_Error); + else if (ctx->out_of_core) + err = mk_error (Out_Of_Core); + else + { + err = _gpgme_passphrase_result (ctx); + if (! err) + { + if (!ctx->result.sign->okay) err = mk_error (No_Data); /* Hmmm: choose a better error? */ - } - c->pending = 0; + } + } + ctx->pending = 0; } - return err; + return err; } - - - - - - - - - diff --git a/gpgme/types.h b/gpgme/types.h index 774e30e..895d923 100644 --- a/gpgme/types.h +++ b/gpgme/types.h @@ -65,6 +65,10 @@ typedef struct sign_result_s *SignResult; struct encrypt_result_s; typedef struct encrypt_result_s *EncryptResult; +/*-- passphrase.c --*/ +struct passphrase_result_s; +typedef struct passphrase_result_s *PassphraseResult; + /*-- key.c --*/ -- 2.26.2