diff --git a/AUTHORS b/AUTHORS index 8a87e949..5cc9c295 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,5 @@ Program: gpgme -Maintainer: +Maintainer: wk@g10gnupg.org FSF diff --git a/NEWS b/NEWS index c5bb19a2..6d21d0e7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ + + * New function gpgme_get_op_info which can be used to get the micalg + parameter needed for MOSS. + Noteworthy changes in version 0.2.2 (2001-06-12) ------------------------------------------------ diff --git a/TODO b/TODO index 7724065b..c24446fd 100644 --- a/TODO +++ b/TODO @@ -11,5 +11,4 @@ another flag or a callback? * There is no status response if we have no usable recipients - must - add one to gpg so that gpgme_encrypt does return with an error. - + add one to gpg so that gpgme_encrypt does return with an error. \ No newline at end of file diff --git a/complus/README b/complus/README index 30fc30d9..7dc3bb1d 100644 --- a/complus/README +++ b/complus/README @@ -63,7 +63,7 @@ Using Gpgcom Gpgcom currently support only encryption but will be extended to the full range of operations GnuPG provides. The 2 examples should goive yopu a hint on how to use it. We suggest that you always set armor to -true, so that the returned text is a string. IF you don't use armor, +true, so that the returned text is a string. If you don't use armor, the "ciphertext" property will return an array with the binary message. diff --git a/complus/vbtest.vbs b/complus/vbtest.vbs index 7ea346da..8246b456 100644 --- a/complus/vbtest.vbs +++ b/complus/vbtest.vbs @@ -13,7 +13,7 @@ gpg.textmode = true gpg.plaintext = "This is the secret message." 'or: InputBox('Enter message:") ' Set the Recipient. You may also use a keyID or an fingerprint -gpg.addrecipient "alice" +gpg.AddRecipient "alice" ' And encrypt the stuff gpg.encrypt diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 8ca3caa0..5dc5dfe4 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,10 +1,18 @@ +2001-08-28 Werner Koch + + * gpgme.c, gpgme.h (gpgme_get_op_info): New. + (_gpgme_set_op_info): New. + (_gpgme_release_result): Reset the op_info here. + * sign.c (append_xml_siginfo): New. + (sign_status_handler): Store the sig create information. + 2001-07-31 Werner Koch * encrypt.c (gpgme_op_encrypt): Hack to detect no valid recipients. 2001-07-30 Werner Koch - * gpgme.c (gpgme_get_armor,gpgme_get_texmode): New. + * gpgme.c (gpgme_get_armor,gpgme_get_textmode): New. * rungpg.c (build_argv): Disable armor comments * w32-io.c (build_commandline): Need to add quotes here diff --git a/gpgme/context.h b/gpgme/context.h index a1992697..662889f9 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -75,6 +75,7 @@ struct gpgme_context_s { } result; GpgmeData notation; /* last signature notation */ + GpgmeData op_info; /* last operation info */ GpgmeKey tmp_key; /* used by keylist.c */ volatile int key_cond; /* something new is available */ diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index b473feb6..1140c4c8 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -99,6 +99,7 @@ _gpgme_release_result ( GpgmeCtx c ) c->result.verify = NULL; c->result_type = RESULT_TYPE_NONE; + _gpgme_set_op_info (c, NULL); } @@ -137,6 +138,57 @@ gpgme_get_notation ( GpgmeCtx c ) return _gpgme_data_get_as_string ( c->notation ); } + +/** + * gpgme_get_op_info: + * @c: the context + * @reserved: + * + * Return information about the last information. The caller has to + * free the string. NULL is returned if there is not previous + * operation available or the operation has not yet finished. + * + * Here is a sample information we return: + + + + 17 + 2 + pgp-sha1 + 01 + 9222222 + 121212121212121212 + + + * + * Return value: NULL for no info available or an XML string + **/ +char * +gpgme_get_op_info ( GpgmeCtx c, int reserved ) +{ + if (!c || reserved) + return NULL; /*invalid value */ + + return _gpgme_data_get_as_string (c->op_info); +} + +/* + * Store the data object with the operation info in the + * context. Caller should not use that object anymore. + */ +void +_gpgme_set_op_info (GpgmeCtx c, GpgmeData info) +{ + assert (c); + + gpgme_data_release (c->op_info); + c->op_info = NULL; + + if (info) + c->op_info = info; +} + + /** * gpgme_set_armor: * @c: the contect diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index d4082d2f..7d5fde9e 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -183,8 +183,7 @@ GpgmeKey gpgme_signers_enum (const GpgmeCtx c, int seq); const char *gpgme_get_sig_status (GpgmeCtx c, int idx, GpgmeSigStat *r_stat, time_t *r_created ); GpgmeError gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key); - - +char *gpgme_get_op_info (GpgmeCtx c, int reserved); /* Functions to handle recipients */ diff --git a/gpgme/key.c b/gpgme/key.c index 966675e3..a4649df3 100644 --- a/gpgme/key.c +++ b/gpgme/key.c @@ -116,8 +116,8 @@ void _gpgme_key_cache_add (GpgmeKey key) { struct subkey_s *k; -#warning debug code - if (!key || getenv("gpgme_no_cache") ) + + if (!key) return; /* FIXME: add locking */ @@ -609,7 +609,7 @@ gpgme_key_get_as_xml ( GpgmeKey key ) /*add_tag_and_time (d, "expires", key->expires );*/ _gpgme_data_append_string (d, " \n"); - /* Now the user IDs. We are listing the last one firs becuase this is + /* Now the user IDs. We are listing the last one first because this is * the primary one. */ for (u = key->uids; u && u->next; u = u->next ) ; diff --git a/gpgme/ops.h b/gpgme/ops.h index 668a18d2..20a551bb 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -26,6 +26,7 @@ /*-- gpgme.c --*/ void _gpgme_release_result ( GpgmeCtx c ); +void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info); /*-- wait.c --*/ GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c, diff --git a/gpgme/sign.c b/gpgme/sign.c index f71e0d64..b92ea806 100644 --- a/gpgme/sign.c +++ b/gpgme/sign.c @@ -29,6 +29,15 @@ #include "context.h" #include "ops.h" +#define SKIP_TOKEN_OR_RETURN(a) do { \ + while (*(a) && *(a) != ' ') (a)++; \ + while (*(a) == ' ') (a)++; \ + if (!*(a)) \ + return; /* oops */ \ +} while (0) + + + struct sign_result_s { int no_passphrase; @@ -37,18 +46,99 @@ struct sign_result_s { char *userid_hint; char *passphrase_info; int bad_passphrase; + GpgmeData xmlinfo; }; void _gpgme_release_sign_result ( SignResult res ) { + gpgme_data_release (res->xmlinfo); xfree (res->userid_hint); xfree (res->passphrase_info); xfree (res); } +/* 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 */ + } + 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; + } + + _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; + } + 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"); +} + + static void sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) @@ -68,6 +158,11 @@ sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) 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: @@ -98,10 +193,8 @@ sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args ) 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; - /* parse the line and save the information - * - */ break; default: @@ -242,7 +335,7 @@ gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out, } _gpgme_data_set_mode (out, GPGME_DATA_MODE_IN ); - /* Tell the gpg object about the data */ + /* tell the gpg object about the data */ _gpgme_gpg_add_data ( c->gpg, in, 0 ); _gpgme_gpg_add_data ( c->gpg, out, 1 ); @@ -295,6 +388,7 @@ gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out, GpgmeSigMode mode ) err = mk_error (No_Passphrase); else if (!c->result.sign->okay) err = mk_error (No_Data); /* Hmmm: choose a better error? */ + } c->pending = 0; } diff --git a/tests/t-sign.c b/tests/t-sign.c index f57a1eaa..65822c9d 100644 --- a/tests/t-sign.c +++ b/tests/t-sign.c @@ -32,6 +32,19 @@ exit (1); } \ } while(0) +static void +print_op_info (GpgmeCtx c) +{ + char *s = gpgme_get_op_info (c, 0); + + if (!s) + puts (""); + else { + puts (s); + free (s); + } +} + static void print_data ( GpgmeData dh ) { @@ -95,6 +108,7 @@ main (int argc, char **argv ) fail_if_err (err); fflush (NULL); fputs ("Begin Result:\n", stdout ); + print_op_info (ctx); print_data (out); fputs ("End Result.\n", stdout ); gpgme_data_release (out); @@ -106,6 +120,7 @@ main (int argc, char **argv ) err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_DETACH ); fail_if_err (err); fflush (NULL); + print_op_info (ctx); fputs ("Begin Result:\n", stdout ); print_data (out); fputs ("End Result.\n", stdout ); @@ -119,6 +134,7 @@ main (int argc, char **argv ) err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_CLEAR ); fail_if_err (err); fflush (NULL); + print_op_info (ctx); fputs ("Begin Result:\n", stdout ); print_data (out); fputs ("End Result.\n", stdout );