--- trunk/Src/wptKeyCache.cpp 2006/03/22 12:39:02 188 +++ trunk/Src/wptKeyCache.cpp 2006/05/03 14:34:08 209 @@ -1,14 +1,14 @@ /* wptKeyCache.cpp- Caching for the pub- and the secring * Copyright (C) 2001-2006 Timo Schulz * - * This file is part of MyGPGME. + * This file is part of WinPT. * - * MyGPGME is free software; you can redistribute it and/or modify + * WinPT 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. * - * MyGPGME is distributed in the hope that it will be useful, + * WinPT 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. @@ -37,6 +37,10 @@ #include "wptW32API.h" #include "wptGPG.h" #include "wptTypes.h" +#include "wptCommonCtl.h" +#include "wptContext.h" +#include "wptKeyEdit.h" +#include "wptUTF8.h" /* Attribute list which holds the image data. */ @@ -57,8 +61,8 @@ attr_list_t n; while (ctx) { n = ctx->next; - free (ctx->fpr); - free (ctx->d); + safe_free (ctx->fpr); + safe_free (ctx->d); ctx = n; } } @@ -250,8 +254,83 @@ } +static void +keycache_decode_uid (struct keycache_s *ctx) +{ + gpgme_user_id_t u; + struct native_uid_s *n, *t; + + for (u = ctx->key->uids; u; u = u->next) { + n = (struct native_uid_s*)calloc (1, sizeof *n); + if (!n) + BUG (0); + if (is_8bit_string (u->uid)) { + n->malloced = 1; + n->uid = utf8_to_native (u->uid); + if (u->name != NULL) + n->name = utf8_to_native (u->name); + if (u->email != NULL) + n->email = strdup (u->email); + if (u->comment != NULL) + n->comment = utf8_to_native (u->comment); + } + else { + n->malloced = 0; + n->uid = u->uid; + n->name = u->name; + n->comment = u->comment; + n->email = u->email; + } + n->signatures = u->signatures; + n->validity = u->validity; + n->revoked = u->revoked; + if (!ctx->uids) + ctx->uids = n; + else { + for (t = ctx->uids; t->next; t=t->next) + ; + t->next = n; + } + } +} + + +/* Store utf8 decoded user IDs in the code to avoid in-place decoding. */ +static void +keycache_decode_uids (gpg_keycache_t ctx) +{ + struct keycache_s *c; + + for (c = ctx->item; c; c = c->next) + keycache_decode_uid (c); +} + + +static void +free_native_uids (struct native_uid_s **r_n) +{ + struct native_uid_s *t; + struct native_uid_s *n = *r_n; + + while (n != NULL) { + t = n->next; + if (n->malloced) { + safe_free (n->uid); + safe_free (n->name); + safe_free (n->comment); + safe_free (n->email); + safe_free (n->uid); + } + safe_free (n); + n = t; + } + *r_n = NULL; +} + + + /* Merge the information from the keyrings into the key cache structure. */ -gpgme_error_t +static gpgme_error_t keycache_prepare2 (gpg_keycache_t ctx, const char *kid, const char *pubring, const char *secring) { @@ -284,7 +363,6 @@ strcpy (keyid, ""); key_seen = 1; } - if (pkt->pkttype == PKT_SIGNATURE && pkt->pkt.signature->sig_class == 0x1F) { if (pkt->pkt.signature->numrevkeys == 0) @@ -298,7 +376,9 @@ goto next; c->gloflags.has_desig_rev = 1; } - if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1 ) { + if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1 && c != NULL) { + if (c->sym_prefs) /* only use the prefs from the primary uid. */ + goto next; sym_prefs = gpg_parse_sig_subpkt (pkt->pkt.signature->hashed, SIGSUBPKT_PREF_SYM, &nsym); if (!sym_prefs) @@ -376,11 +456,15 @@ c2 = c->next; gpgme_key_release (c->key); c->key = NULL; + if (c->rev != NULL) + gpg_desig_rev_release (c->rev); + c->rev = NULL; safe_free (c->pref_keyserver); safe_free (c->sym_prefs); safe_free (c->attrib.d); safe_free (c->card_type); - free (c); + free_native_uids (&c->uids); + safe_free (c); } safe_free (ctx); } @@ -552,7 +636,7 @@ err = gpgme_new (&gctx); if (err) return err; - gpgme_set_keylist_mode (gctx, GPGME_KEYLIST_MODE_SIGS); + gpgme_set_keylist_mode (gctx, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/); err = gpgme_get_key (gctx, keyid, &key, is_sec); gpgme_release (gctx); if (err) @@ -587,7 +671,15 @@ } if (c) c->flags = KC_FLAG_ADD; + + } + + /* refresh utf8 user ID list. */ + if (c != NULL) { + free_native_uids (&c->uids); + keycache_decode_uid (c); } + return 0; } @@ -645,7 +737,8 @@ if (err) return err; - gpgme_set_keylist_mode (c, GPGME_KEYLIST_MODE_SIGS); + /* XXX: GPGME_KEYLIST_MODE_SIG_NOTATIONS causes an internal error! */ + gpgme_set_keylist_mode (c, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/); err = gpgme_op_keylist_start (c, pattern, secret); while(!err) { err = gpgme_op_keylist_next (c, &key); @@ -658,6 +751,7 @@ if (gpgme_err_code (err) == GPG_ERR_EOF) err = gpg_error (GPG_ERR_NO_ERROR); keycache_update_photos (ctx); + keycache_decode_uids (ctx); /* XXX: make sure the progress dialog is closed. */ gpgme_op_keylist_end (c); gpgme_release (c); @@ -772,7 +866,8 @@ if (flags && ctx->tmp->pubpart == NULL) flags = 0; *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key; - *c = ctx->tmp = ctx->tmp->next; + *c = ctx->tmp; + ctx->tmp = ctx->tmp->next; ctx->pos++; return 0; @@ -786,12 +881,19 @@ gpg_keycache_next_key (gpg_keycache_t ctx, int flags, gpgme_key_t *r_key) { struct keycache_s *c=NULL; - gpgme_error_t err = 0; + gpgme_error_t err; err = keycache_next_key (ctx, flags, &c, r_key); return err; } +gpgme_error_t +gpg_keycache_next_key2 (gpg_keycache_t ctx, int flags, + struct keycache_s **c, gpgme_key_t *r_key) +{ + return keycache_next_key (ctx, flags, c, r_key); +} + /* Search for a key with the pattern @pattern and mark this key as the default signing key if found. @@ -839,7 +941,7 @@ decode_subpacket (const char *subpkt_data, int *type, char **out, WORD *outlen) { - char tmp[128], *p = tmp, *val; + char tmp[128], *val; char *enc = NULL; size_t pos = 0, i=0; @@ -894,7 +996,7 @@ (*out)[i++] = enc[pos]; } (*out)[i] = 0; - free (enc); + safe_free (enc); return 0; } @@ -931,4 +1033,3 @@ safe_free (val); return err; } -