--- trunk/Src/wptKeylist.cpp 2005/11/08 07:15:13 73 +++ trunk/Src/wptKeylist.cpp 2006/06/15 11:37:53 228 @@ -1,5 +1,5 @@ /* wptKeylist.cpp - Keylist element - * Copyright (C) 2001-2005 Timo Schulz + * Copyright (C) 2001-2006 Timo Schulz * Copyright (C) 2004 Andreas Jobs * * This file is part of WinPT. @@ -18,6 +18,7 @@ * along with WinPT; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifdef HAVE_CONFIG_H #include #endif @@ -37,33 +38,11 @@ #include "wptUTF8.h" #include "wptRegistry.h" #include "wptContext.h" - +#include "wptVersion.h" +#include "resource.h" #define key_is_useable(key) (!(key)->revoked && !(key)->expired && !(key)->disabled) -static struct listview_column_s klist_enc[] = { - {0, 242, (char *)_("User ID")}, - {1, 80, (char *)_("Key ID")}, - {3, 46, (char *)_("Size")}, - {4, 50, (char *)_("Cipher")}, - {5, 70, (char *)_("Validity")}, - {0, 0, NULL} -}; -#define KLIST_ENC_ITEMS (DIM(klist_enc) -1) - -static struct listview_column_s klist[] = { - {0, 242, (char *)_("User ID")}, - {1, 78, (char *)_("Key ID")}, - {2, 52, (char *)_("Type")}, - {3, 68, (char *)_("Size")}, - {4, 66, (char *)_("Cipher")}, - {5, 70, (char *)_("Validity")}, - {6, 40, (char *)_("Trust")}, - {7, 72, (char *)_("Creation")}, - {0, 0, NULL} -}; -#define KLIST_ITEMS (DIM(klist) - 1) - struct key_array_s { char keyid[32]; int checked; @@ -73,42 +52,42 @@ static key_array_s* -key_array_new( size_t items ) +key_array_new (int items) { key_array_s *ka; - size_t j; + int j; - if( items == 0 ) + if (items == 0) return NULL; ka = new key_array_s[items + 1]; - if( ka == NULL ) - return NULL; - for ( j = 0; j < items; j++ ) + if (!ka) + BUG (NULL); + for (j = 0; j < items; j++) ka[j].checked = 0; return ka; -} /* key_array_new */ +} static void -key_array_release( key_array_s *ka ) +key_array_release (key_array_s *ka) { - free_if_alloc( ka ); -} /* key_array_release */ + free_if_alloc (ka); +} +/* Check if the keyid @keyid is in the key array @ka. + Return value: 1 if it exists, 0 otherwise. */ static int -key_array_search( key_array_s *ka, size_t items, const char *keyid ) +key_array_search (key_array_s *ka, int items, const char *keyid) { - size_t j; + int j; - /* fixme: we need a faster search method */ - for( j = 0; j < items; j++ ) { - if( !strcmp( keyid, ka[j].keyid ) ) + for (j = 0; j < items; j++) { + if (!strcmp (keyid, ka[j].keyid)) return 1; } - return 0; -} /* key_array_search */ +} gpgme_user_id_t @@ -173,14 +152,20 @@ } +/* Return the self signature of the key @keyid. + If first is set, the first self sig will be returned. */ gpgme_key_sig_t -get_selfsig (gpgme_user_id_t uid, const char *keyid, int first) +get_selfsig (gpgme_key_sig_t sigs, const char *keyid, int first) { gpgme_key_sig_t s, self_sig=NULL; long timestamp=0; + int off = 0; + + if (strlen (keyid) == 8) + off = 8; - for (s = uid->signatures; s; s = s->next) { - if (!strcmp (s->keyid+8, keyid) && s->timestamp > timestamp) { + for (s = sigs; s; s = s->next) { + if (!strcmp (s->keyid+off, keyid) && s->timestamp > timestamp) { self_sig = s; timestamp = s->timestamp; if (first) @@ -191,7 +176,6 @@ } - const char* get_key_algo (gpgme_key_t key, int keyidx) { @@ -204,19 +188,28 @@ if (keyidx > 0) { k = get_nth_key (key, keyidx-1); subalg = get_key_pubalgo (k->pubkey_algo); - _snprintf( algo_id, DIM (algo_id)-1, "%s", subalg); + _snprintf (algo_id, DIM (algo_id)-1, "%s", subalg); return algo_id; } strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo)); n = count_subkeys (key); if (n > 1) { - k = get_nth_key (key, n-1); + do { + k = get_nth_key (key, --n); + if (k->revoked || k->expired) + continue; + else + break; + } while (n > 0); subalg = get_key_pubalgo (k->pubkey_algo); - _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg); + if (k == key->subkeys) + _snprintf (algo_id, DIM (algo_id)-1, "%s", subalg); + else + _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg); return algo_id; } return get_key_pubalgo (key->subkeys->pubkey_algo); -} /* get_key_algo */ +} const char* @@ -224,14 +217,19 @@ { static char timebuf[128]; struct tm *warp; + const char *dat; - if (timestamp == 0 || timestamp == -1) + if (timestamp < 1) return "????" "-??" "-??"; - warp = localtime( ×tamp ); - _snprintf( timebuf, sizeof timebuf - 1, "%04d-%02d-%02d", - warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday ); + dat = get_locale_date (timestamp, timebuf, sizeof (timebuf)-1); + if (dat) + return dat; + /* Fallback if locate date conversion failed. */ + warp = localtime (×tamp); + _snprintf (timebuf, sizeof timebuf - 1, "%04d-%02d-%02d", + warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday); return timebuf; -} /* get_key_created */ +} /* Return a string presentation of the time @timestamp. */ @@ -240,10 +238,14 @@ { static char timebuf[64]; struct tm *warp; + const char *dat; - if( !timestamp ) + if (timestamp == 0) return _("Never"); - warp = localtime( ×tamp ); + dat = get_locale_date (timestamp, timebuf, sizeof (timebuf)-1); + if (dat) + return dat; + warp = localtime (×tamp); _snprintf (timebuf, sizeof timebuf -1, "%04d-%02d-%02d", warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday); return timebuf; @@ -260,7 +262,7 @@ else if (type == 2) return _("Key Pair (Card)"); return _("Public Key"); -} /* get_key_type */ +} const char* @@ -281,12 +283,26 @@ if (n > 1) { k = get_nth_key (key, n-1); size_sub = k->length; - _snprintf( size_id, sizeof (size_id) - 1, "%d/%d", size_main, size_sub ); + _snprintf (size_id, sizeof (size_id) - 1, "%d/%d", + size_main, size_sub); return size_id; } _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main ); return size_id; -} /* get_key_size */ +} + + +const char* +get_key_pubalgo2 (gpgme_pubkey_algo_t alg) +{ + switch (alg) { + case GPGME_PK_DSA: return "D"; + case GPGME_PK_RSA: return "R"; + case GPGME_PK_ELG: return "G"; + default: return "?"; + } + return "?"; +} const char* @@ -296,13 +312,16 @@ case GPGME_PK_DSA: return "DSA"; case GPGME_PK_ELG: case GPGME_PK_ELG_E: return "ELG"; - case GPGME_PK_RSA: return "RSA"; + case 0: /* XXX: do we still need this?? */ + case GPGME_PK_RSA: + case GPGME_PK_RSA_S: + case GPGME_PK_RSA_E: return "RSA"; default: return "???"; } return "???"; } -const char * +const char* get_key_fpr (gpgme_key_t key) { static char fpr_md[64]; @@ -331,10 +350,29 @@ } } return fpr_md; -} /* get_key_fpr */ +} -const char * +/* Extract the key ID from the fingerprint. + A long ID will be converted into a short ID. */ +const char* +get_keyid_from_fpr (const char *fpr) +{ + if (!fpr) + return "????????"; + if (strlen (fpr) == 40) + fpr += 32; + else if (strlen (fpr) == 32) + fpr += 24; + else if (strlen (fpr) == 16) + fpr += 8; + else + return "????????"; + return fpr; +} + + +const char* get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode) { if (key) @@ -342,27 +380,28 @@ switch (val) { case GPGME_VALIDITY_UNKNOWN: case GPGME_VALIDITY_UNDEFINED: - return "None"; + return _("None"); case GPGME_VALIDITY_NEVER: - return "Never"; + return _("Never"); case GPGME_VALIDITY_MARGINAL: - return "Marginal"; + return _("Marginal"); case GPGME_VALIDITY_FULL: + return _("Full"); case GPGME_VALIDITY_ULTIMATE: - return "Full"; + return _("Ultimate"); } return ""; } -const char * +const char* get_key_trust (gpgme_key_t key, int uididx, int listmode) { return get_key_trust2 (key, 0, uididx, listmode); } -const char * +const char* get_key_trust_str (int val) { return get_key_trust2 (NULL, val, 0, 0); @@ -380,19 +419,17 @@ if (uididx < 0 || count_userids (key) > uididx) uididx = 0; if (listmode) { - const char *s; - + const char *s; if (key->revoked) s = _("Revoked"); else if (key->expired) s = _("Expired"); else if (key->disabled) s = _("Disabled"); - else - s = ""; - + else + s = ""; /* if the key has a special status, we don't continue to figure out - what any user-id validities. */ + the user-id validities. */ if (*s) return m_strdup (s); } @@ -403,6 +440,36 @@ } +/* Return human readable description of the key @key. */ +char* +get_key_desc (gpgme_key_t key) +{ + gpgme_key_t sk; + const char *state, *alg, *type; + char *p; + + /* XXX: problems with the German translation. */ + state = ""; + if (key->disabled) + state = _("Disabled"); + if (key->expired) + state = _("Expired"); + if (key->revoked) + state = _("Revoked"); + alg = "OpenPGP"; + if (strlen (key->subkeys->fpr) == 32) + alg = "RSA Legacy"; + type = _("public key"); + if (!get_seckey (key->subkeys->keyid+8, &sk)) + type = _("key pair"); + p = new char[strlen (state) + strlen (alg) + strlen (type) + 4 + 1]; + if (!p) + BUG (0); + sprintf (p, "%s %s %s", state, alg, type); + return p; +} + + /* Integer comparsion of @a and @b. Return values: same as in strcmp. */ static inline int @@ -424,6 +491,8 @@ return GPGME_VALIDITY_ULTIMATE+1; else if (k->expired) return GPGME_VALIDITY_ULTIMATE+2; + else if (k->disabled) + return GPGME_VALIDITY_ULTIMATE+3; return k->uids->validity; } @@ -432,13 +501,16 @@ static int CALLBACK keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby) { + struct keycache_s *aa, *bb; gpgme_key_t a, b; int cmpresult = 0; - a = (gpgme_key_t)first; - b = (gpgme_key_t)second; - if (!a || !b) + aa = (struct keycache_s *)first; + bb = (struct keycache_s *)second; + if (!aa || !bb) BUG (NULL); + a = aa->key; + b = bb->key; switch (sortby & ~KEYLIST_SORT_DESC) { case KEY_SORT_USERID: @@ -491,53 +563,11 @@ } -/* Return the validity of the group @grp. */ -static const char* -calc_validity (gpg_group_t grp) -{ - int valid=0; - gpg_member_t mbr; - gpgme_key_t key; - - for (mbr = grp->list; mbr; mbr = mbr->next) { - if (get_pubkey (mbr->name, &key)) - continue; - valid = key->uids->validity; - switch (valid) { - case GPGME_VALIDITY_MARGINAL: - case GPGME_VALIDITY_NEVER: - case GPGME_VALIDITY_UNDEFINED: - return get_key_trust2 (NULL, valid, 0, 0); - } - } - return _("Full"); -} - - int -keylist_add_groups( listview_ctrl_t lv ) +keylist_add_groups (listview_ctrl_t lv) { -#if 0 - gpg_optfile_t gh; - gpg_group_t grp; - const char *valid; - - gh = km_groupdb_open( ); - if( !gh ) - return WPTERR_FILE_OPEN; - - for( grp = gh->grp; grp; grp = grp->next ) { - valid = calc_validity( grp ); - listview_add_item( lv, " " ); - listview_add_sub_item( lv, 0, 0, grp->name ); - listview_add_sub_item( lv, 0, 1, "gpg_group_t" ); - listview_add_sub_item( lv, 0, 2, "" ); - listview_add_sub_item( lv, 0, 3, "Unknown" ); - listview_add_sub_item( lv, 0, 4, valid?valid : "Unknown" ); - } -#endif return 0; -} /* keylist_add_groups */ +} /* Create a listview for listing keys. Use the mode given in @mode @@ -545,34 +575,57 @@ static int keylist_build (listview_ctrl_t *r_lv, HWND ctrl, int mode) { + struct listview_column_s klist_enc[] = { + {0, 242, (char *)_("User ID")}, + {1, 80, (char *)_("Key ID")}, + {3, 46, (char *)_("Size")}, + {4, 50, (char *)_("Cipher")}, + {5, 70, (char *)_("Validity")}, + {0, 0, NULL} + }; + struct listview_column_s klist[] = { + {0, 240, (char *)_("User ID")}, + {1, 78, (char *)_("Key ID")}, + {2, 52, (char *)_("Type")}, + {3, 66, (char *)_("Size")}, + {4, 60, (char *)_("Cipher")}, + {5, 66, (char *)_("Validity")}, + {6, 58, (char *)_("Trust")}, + {7, 72, (char *)_("Creation")}, + {0, 0, NULL} + }; + HICON ico[2]; listview_ctrl_t lv; listview_column_t col; - int j, n = 0; - int rc = 0; + int j, n = 0, ext_chk = 0; - rc = listview_new (&lv); - if( rc ) - return rc; - - lv->ctrl = ctrl; - if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN)) { + listview_new (&lv, ctrl); + if (mode & KEYLIST_ENCRYPT_MIN) { col = klist_enc; - n = KLIST_ENC_ITEMS; + n = (DIM (klist_enc) -1); + ext_chk = 1; } else if ((mode & KEYLIST_SIGN)) { col = klist_enc; - n = KLIST_ENC_ITEMS - 1; + n = (DIM (klist_enc) - 1) - 1; + ext_chk = 1; } else { col = klist; - n = KLIST_ITEMS; + n = (DIM (klist) - 1); } - for( j = 0; j < n; j++ ) - listview_add_column( lv, &col[j] ); - listview_set_ext_style( lv ); + for (j = 0; j < n; j++) + listview_add_column (lv, &col[j]); + listview_set_ext_style (lv); + if (ext_chk) + listview_set_chkbox_style (lv); + ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY); + ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR); + listview_set_image_list (lv, 22, 14, ico, 2); + listview_del_all_items (lv); + *r_lv = lv; - return 0; } @@ -583,22 +636,23 @@ { gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR); gpgme_key_t key, skey; - const char * keyid; + struct keycache_s *c; + const char *keyid; if (pubkc && seckc) { gpg_keycache_rewind (pubkc); - while (!gpg_keycache_next_key (pubkc, 0, &key)) { + while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) { keyid = key->subkeys->keyid; if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey)) - keylist_add_key (lv, mode, key); + keylist_add_key (lv, mode, c, key); } } else if (pubkc) { gpg_keycache_rewind (pubkc); while (!err) { - err = gpg_keycache_next_key (pubkc, 0, &key); + err = gpg_keycache_next_key2 (pubkc, 0, &c, &key); if (!err) - keylist_add_key (lv, mode, key); + keylist_add_key (lv, mode, c, key); } } } @@ -618,7 +672,7 @@ return NULL; keylist_load_keycache (lv, mode, pubkc, seckc); keylist_sort (lv, sortby); - if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN)) + if (mode & KEYLIST_ENCRYPT_MIN) keylist_add_groups (lv); return lv; } @@ -628,8 +682,8 @@ int keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby) { - listview_del_all (lv); - keylist_load_keycache( lv, mode, pubkc, NULL ); + listview_del_all_items (lv); + keylist_load_keycache (lv, mode, pubkc, NULL); keylist_sort (lv, sortby); return 0; } @@ -664,7 +718,8 @@ static int -do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list) +do_addkey (listview_ctrl_t lv, struct keycache_s *ctx, gpgme_key_t key, + int uididx, int keyidx, int list) { LV_ITEM lvi; gpgme_user_id_t u; @@ -677,50 +732,44 @@ /* we check the pubkey algorithm here to make sure that no ElGamal sign+encrypt key is used in _any_ mode */ if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) { - log_debug ("ElGamal (E+S) key found: %s (%s)\n", + log_debug ("ElGamal (E+S) key found: %s (%s)\n", key->uids->name, key->subkeys->keyid); return 0; } - - if (listview_add_item2 (lv, " ", (void *)key)) + if (listview_add_item2 (lv, " ", (void *)ctx)) return WPTERR_GENERAL; - - attr = key->uids->uid; + + attr = ctx->uids->uid; memset (&lvi, 0, sizeof lvi); - lvi.mask = LVIF_TEXT | LVIF_PARAM; + lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvi.pszText = (char *)attr; - lvi.lParam = (LPARAM )key; - if (ListView_SetItem( lv->ctrl, &lvi ) == FALSE) + lvi.iImage = find_secret_key (key)? 1 : 0; + lvi.lParam = (LPARAM )ctx; + if (ListView_SetItem (lv->ctrl, &lvi) == FALSE) return WPTERR_GENERAL; if (uididx == -1) { /* request the primary user-id of the key. */ - attr = key->uids->uid; + attr = ctx->uids->uid; uididx = 0; } else { u = get_nth_userid (key, uididx); if (!u || u->revoked || uididx < 0) - uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */ + uididx = 0; u = get_nth_userid (key, uididx); - /*attr = key->uids->uid; XXX*/ attr = u->uid; } - if (attr == NULL || strlen (attr) < 5) { /* normal userids are >= 5 chars */ + if (attr == NULL || strlen (attr) < 5) { /* normal userids are > 5 chars */ attr = _("Invalid User ID"); listview_add_sub_item (lv, 0, idx++, attr); } - else { - char *uid = utf8_to_wincp (attr, strlen (attr)); - if (uid) { - listview_add_sub_item (lv, 0, idx++, uid); - free (uid); - } - } + else + listview_add_sub_item (lv, 0, idx++, attr); k = get_nth_key (key, keyidx); if (k && k->keyid) { _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8); - listview_add_sub_item( lv, 0, idx++, fmt ); + listview_add_sub_item (lv, 0, idx++, fmt); } if (list > 0) { key_attr = find_secret_key (key); @@ -740,7 +789,7 @@ if (attr) listview_add_sub_item( lv, 0, idx++, attr); } - if( lv->cols >= 4 ) { + if (lv->cols >= 4) { p = get_key_status( key, uididx, list > 0? 1 : 0 ); if (!p) return WPTERR_GENERAL; @@ -764,59 +813,111 @@ } +/* Update a single column @col but for each element in the + listview @lv. */ void -keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key) +keylist_upd_col (listview_ctrl_t lv, int col) { + gpgme_key_t key; const char *s; + char buf[32], *p; + int i; + + for (i=0; i < listview_count_items (lv, 0); i++) { + key = km_get_key_ptr (lv, i, NULL); + if (!key) + continue; + switch (col) { + case KM_COL_KEYID: + _snprintf (buf, sizeof (buf)-1, "0x%s", key->subkeys->keyid+8); + listview_add_sub_item (lv, i, col, buf); + break; + + case KM_COL_CIPHER: + s = get_key_algo (key, 0); + listview_add_sub_item (lv, i, col, s); + break; + + case KM_COL_TYPE: + s = find_secret_key (key)? "pub/sec" : "pub"; + listview_add_sub_item (lv, i, col, s); + break; + + case KM_COL_CREAT: + s = get_key_created (key->subkeys->timestamp); + listview_add_sub_item (lv, i, col, s); + break; + + case KM_COL_DESC: + p = get_key_desc (key); + listview_add_sub_item (lv, i, col, p); + free_if_alloc (p); + break; + } + } +} + + +/* Update the listview item at position @pos with the data from + the key @key. */ +void +keylist_upd_key (listview_ctrl_t lv, int pos, + struct keycache_s *ctx, gpgme_key_t key) +{ + const char *s; + char *p; char tmp[32]; - listview_set_item2 (lv, pos, (void *)key); - /* the only mode we support is KYLIST_LIST in the Key Manager */ + listview_set_item2 (lv, pos, (void *)ctx); + /* the only mode we support is KEYLIST_LIST in the Key Manager */ - s = key->uids->uid; + s = ctx->uids->uid; if (s) - listview_add_sub_item (lv, pos, 0, s); + listview_add_sub_item (lv, pos, KM_COL_UID, s); s = key->subkeys->keyid; if (s) { sprintf (tmp, "0x%s", s+8); - listview_add_sub_item (lv, pos, 1, tmp); + listview_add_sub_item (lv, pos, KM_COL_KEYID, tmp); } s = find_secret_key (key)? "pub/sec" : "pub"; - listview_add_sub_item (lv, pos, 2, s); + listview_add_sub_item (lv, pos, KM_COL_TYPE, s); s = get_key_size (key, 0); if (s) - listview_add_sub_item (lv, pos, 3, s); + listview_add_sub_item (lv, pos, KM_COL_SIZE, s); s = get_key_algo (key, 0); if (s) - listview_add_sub_item (lv, pos, 4, s); + listview_add_sub_item (lv, pos, KM_COL_CIPHER, s); - s = get_key_status (key, 0, 1); - if (s) - listview_add_sub_item (lv, pos, 5, s); + p = get_key_status (key, 0, 1); + if (p) { + listview_add_sub_item (lv, pos, KM_COL_VALID, p); + free_if_alloc (p); + } s = get_key_trust (key, 0, 1); if (s) - listview_add_sub_item (lv, pos, 6, s); + listview_add_sub_item (lv, pos, KM_COL_TRUST, s); long t = key->subkeys->timestamp; s = get_key_created (t); if (s) - listview_add_sub_item (lv, pos, 7, s); + listview_add_sub_item (lv, pos, KM_COL_CREAT, s); } int -keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key) +keylist_add_key (listview_ctrl_t lv, int mode, + struct keycache_s *ctx, gpgme_key_t key) { int uids, rc = 0, i; gpgme_subkey_t k; /* if the entire key is disabled, just return. */ - if (key->disabled) + if (key->disabled && !(mode & KEYLIST_LIST)) return 0; for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) { @@ -827,23 +928,23 @@ if (mode & KEYLIST_ALL) { uids = count_userids (key); - rc = do_addkey (lv, key, uids, i, 0); - if( rc ) + rc = do_addkey (lv, ctx, key, uids, i, 0); + if (rc) return rc; } else if (mode & KEYLIST_LIST) - return do_addkey (lv, key, -1, i, 1); + return do_addkey (lv, ctx, key, -1, i, 1); else if (mode & KEYLIST_ENCRYPT) { if (k->can_encrypt && key_is_useable (k)) { if (mode & KEYLIST_FLAG_FILE) { - rc = do_addkey (lv, key, -1, i, -1); + rc = do_addkey (lv, ctx, key, -1, i, -1); if (rc) return rc; } else { - for( uids = 0; uids < count_userids (key); uids++ ) { - rc = do_addkey( lv, key, uids, i, -1 ); - if( rc ) + for (uids = 0; uids < count_userids (key); uids++) { + rc = do_addkey (lv, ctx, key, uids, i, -1); + if (rc) return rc; } } @@ -852,7 +953,7 @@ else if (mode & KEYLIST_ENCRYPT_MIN) { if( k->can_encrypt && key_is_useable (k)) { - rc = do_addkey (lv, key, -1, i, -1); + rc = do_addkey (lv, ctx, key, -1, i, -1); return rc; } } @@ -860,7 +961,7 @@ if (k->can_sign && find_secret_key (key) && key_is_useable (k)) { - rc = do_addkey (lv, key, -1, i, -1); + rc = do_addkey (lv, ctx, key, -1, i, -1); if (rc) return rc; } @@ -868,26 +969,28 @@ } return rc; -} /* keylist_add_key */ +} int keylist_sort (listview_ctrl_t lv, int sortby) -{ +{ return listview_sort_items (lv, sortby, keylist_cmp_cb); } /* Check that the validity @validity is at least >= marginal. */ static int -key_check_validity (const char *validity) -{ - if (strstr (validity, "Unknown") || - strstr (validity, "Undefined") || - strstr (validity, "Never") || - strstr (validity, "None")) - return 0; - return 1; +key_check_validity (gpgme_key_t key) +{ + gpgme_user_id_t u; + + for (u=key->uids; u; u =u->next) { + if (u->validity >= GPGME_VALIDITY_MARGINAL) + return -1; + } + + return 0; } @@ -898,31 +1001,31 @@ gpgme_key_t* keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count) { + key_array_s *ka = NULL; + keycache_s *c; + gpgme_key_t *keybuf, key; int count = 0, force_trust = 0; int n, j, ka_pos = 0, rc = 0; int k_pos=0; - char keyid[32], valid[32], id[100]; - key_array_s *ka = NULL; - gpgme_key_t *keybuf; - n = listview_count_items( lv, 0 ); + n = listview_count_items (lv, 0); - ka = key_array_new( n ); + ka = key_array_new (n); if (!ka) BUG (NULL); - keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t)); + keybuf = (gpgme_key_t*)calloc (n+1, sizeof (gpgme_key_t)); if (!keybuf) BUG (NULL); - for( j = 0; j < n; j++ ) { - if( listview_get_item_state (lv, j) || n == 1) { - listview_get_item_text (lv, j, 0, id, sizeof id-1); - listview_get_item_text (lv, j, 1, keyid, sizeof keyid - 1); - listview_get_item_text (lv, j, 4, valid, sizeof valid -1); - if( !key_check_validity (valid) - && !key_array_search( ka, ka_pos, keyid )) { - char *warn = new char[512+strlen (id) + 1]; + for (j = 0; j < n; j++) { + if (listview_get_item_state (lv, j) || n == 1) { + key = km_get_key_ptr (lv, j, &c); + if (!key) + BUG (0); + if (!key_check_validity (key) && + !key_array_search (ka, ka_pos, key->subkeys->keyid)) { + char *warn = new char[512+strlen (c->uids->uid) + 1]; if (!warn) BUG (0); sprintf (warn, @@ -930,27 +1033,22 @@ "named in the user ID. If you *really* know what you are\n" "doing, you may answer the next question with yes\n" "\n" - "Use \"%s\" anyway?"), id); + "Use \"%s\" anyway?"), c->uids->uid); if (reg_prefs.always_trust) rc = IDYES; else rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK); if (rc == IDYES) { - gpgme_key_t k; - get_pubkey (keyid, &k); - keybuf[k_pos++] = k; + keybuf[k_pos++] = key; force_trust++; ka[ka_pos].checked = 1; - strcpy (ka[ka_pos++].keyid, keyid); + strcpy (ka[ka_pos++].keyid, key->subkeys->keyid); count++; } free_if_alloc (warn); } else { - gpgme_key_t k; - listview_get_item_text( lv, j, 1, keyid, sizeof keyid -1 ); - get_pubkey (keyid, &k); - keybuf[k_pos++] = k; + keybuf[k_pos++] = key; count++; } } @@ -965,68 +1063,60 @@ static int -keylist_get_keyflags (const char *buf, size_t buflen) +keylist_get_keyflags (gpgme_key_t key) { - int c = 0, flags = 0; + int flags = KEYFLAG_NONE; - if( *buf != '[' ) - return KEYFLAG_NONE; - while (buf && c != ']') - { - c = *buf++; - if (c == 'R') - flags |= KEYFLAG_REVOKED; - if (c == 'E') - flags |= KEYFLAG_EXPIRED; - if (c == 'D') - flags |= KEYFLAG_DISABLED; - } + if (key->revoked) + flags |= KEYFLAG_REVOKED; + if (key->expired) + flags |= KEYFLAG_EXPIRED; + if (key->disabled) + flags |= KEYFLAG_DISABLED; return flags; -} /* keylist_get_keyflags */ +} gpgme_key_t* keylist_enum_recipients (listview_ctrl_t lv, int listype, int *r_count) { - gpgme_key_t* rset; - gpgme_key_t k; + struct keycache_s *c; + gpgme_key_t *rset; + gpgme_key_t key; int i, n, id, k_pos=0; - char keyid[32], t[128], t2[128]; n = listview_count_items (lv, 0); if (!n) return 0; - rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t)); + rset = (gpgme_key_t*)calloc (n+1, sizeof (gpgme_key_t)); if (!rset) BUG (NULL); - for( i = 0; i < n; i++ ) { - if( !listview_get_item_state( lv, i ) ) + for (i = 0; i < n; i++) { + if (!listview_get_item_state (lv, i)) continue; - listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 ); - switch( listype ) { + key = km_get_key_ptr (lv, i, &c); + switch (listype) { case KEYLIST_LIST: - listview_get_item_text( lv, i, 5, t, sizeof t - 1 ); - if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) { - _snprintf( t2, sizeof t2 -1, - _("KeyID %s.\nDo you really want to export a revoked key?"), keyid ); - id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO ); - if( id == IDNO ) - continue; + if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) { + id = printf_box (_("Recipients"), MB_INFO|MB_YESNO, + _("KeyID %s.\nDo you really want to export a revoked key?"), + c->uids->uid); + if (id == IDNO) + continue; } break; } - get_pubkey (keyid, &k); - rset[k_pos++] = k; + rset[k_pos++] = key; } if (r_count) *r_count = k_pos; return rset; -} /* keylist_enum_recipients */ +} void -seclist_destroy (keylist_t * list) +seclist_destroy (keylist_t *list) { keylist_t l2; while (*list) { @@ -1035,7 +1125,7 @@ *list = l2; } list = NULL; -} /* seclist_destroy */ +} void @@ -1072,12 +1162,12 @@ if (key->disabled || !key_is_useable (key->subkeys)) continue; - uid = utf8_to_wincp (id, strlen (id)); - size = strlen( uid ) + strlen( keyid ) + 32; + uid = utf8_to_native (id); + size = strlen (uid) + strlen (keyid) + 32; inf = new char[size+1]; - if( !inf ) - BUG( NULL ); - _snprintf (inf, size, "%s (%s/0x%s)", uid, + if (!inf) + BUG (NULL); + _snprintf (inf, size, "%s (%s/0x%s)", uid, get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8); combox_add_string (kb, inf); free_if_alloc (inf); @@ -1094,9 +1184,10 @@ l2->next = l; } } - for( pos = 0, l2=list; pos < SendMessage( kb, CB_GETCOUNT, 0, 0 ); pos++, l2=l2->next ) - SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key ); - SendMessage( kb, CB_SETCURSEL, 0, 0 ); + for (pos = 0, l2=list; pos < SendMessage (kb, CB_GETCOUNT, 0, 0); + pos++, l2=l2->next) + SendMessage (kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key); + SendMessage (kb, CB_SETCURSEL, 0, 0); *ret_list = list; }