/[winpt]/trunk/Src/wptKeylist.cpp
ViewVC logotype

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 167 - (hide annotations)
Thu Jan 26 10:17:17 2006 UTC (19 years, 1 month ago) by twoaday
File size: 26620 byte(s)
2006-01-25  Timo Schulz  <ts@g10code.com>
 
        * wptRegistry.cpp (get_reg_entry_gpg): Return NULL if
        the key exist with no value.
        * wptMDSumDlg.cpp (mdsum_dlg_proc): Translate string.
        * wptKeysignDlg.cpp (do_fill_seclist): Select the
        default key if possible.
        * wptFirstRunDlg.cpp (firstrun_dlg_proc): Directly
        return the choice.
        * wptKeylist.cpp (get_key_desc): New.
        (keylist_upd_key): Free memory.
        * wptKeyCache.cpp (gpg_keycache_get_default_key): New.
        (gpg_keycache_set_default_key): New.
        * WinPT.cpp (gpg_prefs_ok): New.
        (WinMain): Only start gpg prefs if needed.
         


1 werner 36 /* wptKeylist.cpp - Keylist element
2 twoaday 133 * Copyright (C) 2001-2006 Timo Schulz
3 werner 36 * Copyright (C) 2004 Andreas Jobs
4     *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or
8     * modify it under the terms of the GNU General Public License
9     * as published by the Free Software Foundation; either version 2
10     * of the License, or (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     * General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21 twoaday 128
22 werner 42 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24     #endif
25    
26 werner 36 #include <windows.h>
27     #include <commctrl.h>
28     #include <time.h>
29    
30     #include "wptCommonCtl.h"
31     #include "wptTypes.h"
32     #include "wptGPG.h"
33     #include "wptKeylist.h"
34     #include "wptKeyManager.h"
35     #include "wptW32API.h"
36     #include "wptNLS.h"
37     #include "wptErrors.h"
38     #include "wptUTF8.h"
39     #include "wptRegistry.h"
40     #include "wptContext.h"
41 twoaday 133 #include "wptVersion.h"
42     #include "resource.h"
43 werner 36
44     #define key_is_useable(key) (!(key)->revoked && !(key)->expired && !(key)->disabled)
45    
46     struct key_array_s {
47     char keyid[32];
48     int checked;
49     };
50    
51     static int find_secret_key (gpgme_key_t key);
52    
53    
54     static key_array_s*
55 twoaday 133 key_array_new (int items)
56 werner 36 {
57     key_array_s *ka;
58 twoaday 133 int j;
59 werner 36
60 twoaday 133 if (items == 0)
61 werner 36 return NULL;
62     ka = new key_array_s[items + 1];
63 twoaday 133 if (!ka)
64     BUG (NULL);
65     for (j = 0; j < items; j++)
66 werner 36 ka[j].checked = 0;
67     return ka;
68 twoaday 133 }
69 werner 36
70    
71     static void
72 twoaday 133 key_array_release (key_array_s *ka)
73 werner 36 {
74 twoaday 133 free_if_alloc (ka);
75     }
76 werner 36
77    
78 twoaday 133 /* Check if the keyid @keyid is in the key array @ka.
79     Return value: 1 if it exists, 0 otherwise. */
80 werner 36 static int
81 twoaday 133 key_array_search (key_array_s *ka, int items, const char *keyid)
82 werner 36 {
83 twoaday 133 int j;
84 werner 36
85 twoaday 133 for (j = 0; j < items; j++) {
86     if (!strcmp (keyid, ka[j].keyid ))
87 werner 36 return 1;
88     }
89     return 0;
90 twoaday 133 }
91 werner 36
92    
93     gpgme_user_id_t
94     get_nth_userid (gpgme_key_t key, int idx)
95     {
96     gpgme_user_id_t t;
97    
98     if (!key->uids)
99     return NULL;
100     t = key->uids;
101     while (idx-- && t->next)
102     t = t->next;
103     return t;
104     }
105    
106    
107     int
108     count_userids (gpgme_key_t key)
109     {
110     gpgme_user_id_t u;
111     int n = 1;
112    
113     u = key->uids;
114     if (!u)
115     return 0;
116     while (u->next) {
117     u = u->next;
118     n++;
119     }
120     return n;
121     }
122    
123    
124     gpgme_subkey_t
125     get_nth_key (gpgme_key_t key, int idx)
126     {
127     gpgme_subkey_t t;
128    
129     if (!key->subkeys)
130     return NULL;
131     t = key->subkeys;
132     while (idx-- && t->next)
133     t = t->next;
134     return t;
135     }
136    
137    
138     int
139     count_subkeys (gpgme_key_t key)
140     {
141     gpgme_subkey_t k;
142     int n = 1;
143    
144     k = key->subkeys;
145     if (!k)
146     return 0;
147     while (k->next) {
148     k = k->next;
149     n++;
150     }
151     return n;
152     }
153    
154    
155 twoaday 133 /* Return the self signature of the key @keyid.
156     If first is set, the first self sig will be returned. */
157 werner 36 gpgme_key_sig_t
158     get_selfsig (gpgme_user_id_t uid, const char *keyid, int first)
159     {
160     gpgme_key_sig_t s, self_sig=NULL;
161     long timestamp=0;
162 twoaday 133 int off = 0;
163 werner 36
164 twoaday 133 if (strlen (keyid) == 8)
165     off = 8;
166    
167 werner 36 for (s = uid->signatures; s; s = s->next) {
168 twoaday 133 if (!strcmp (s->keyid+off, keyid) && s->timestamp > timestamp) {
169 werner 36 self_sig = s;
170     timestamp = s->timestamp;
171     if (first)
172     break;
173     }
174     }
175     return self_sig;
176     }
177    
178    
179    
180     const char*
181     get_key_algo (gpgme_key_t key, int keyidx)
182     {
183     static char algo_id[128];
184     gpgme_subkey_t k;
185     char alg[32];
186     const char *subalg;
187     int n=0;
188    
189     if (keyidx > 0) {
190     k = get_nth_key (key, keyidx-1);
191     subalg = get_key_pubalgo (k->pubkey_algo);
192 twoaday 133 _snprintf (algo_id, DIM (algo_id)-1, "%s", subalg);
193 werner 36 return algo_id;
194     }
195     strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo));
196     n = count_subkeys (key);
197     if (n > 1) {
198     k = get_nth_key (key, n-1);
199     subalg = get_key_pubalgo (k->pubkey_algo);
200     _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg);
201     return algo_id;
202     }
203     return get_key_pubalgo (key->subkeys->pubkey_algo);
204 twoaday 133 }
205 werner 36
206    
207     const char*
208 twoaday 41 get_key_created (long timestamp)
209 werner 36 {
210     static char timebuf[128];
211 twoaday 133 struct tm *warp;
212 twoaday 129 const char *dat;
213 werner 36
214 twoaday 133 if (timestamp < 1)
215 werner 48 return "????" "-??" "-??";
216 twoaday 129 dat = get_locale_date (timestamp, timebuf, sizeof (timebuf)-1);
217     if (dat)
218     return dat;
219     warp = localtime (&timestamp);
220     _snprintf (timebuf, sizeof timebuf - 1, "%04d-%02d-%02d",
221     warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday);
222 werner 36 return timebuf;
223 twoaday 129 }
224 werner 36
225    
226 twoaday 41 /* Return a string presentation of the time @timestamp. */
227 werner 36 const char*
228     get_key_expire_date (long timestamp)
229     {
230     static char timebuf[64];
231     struct tm *warp;
232 twoaday 133 const char *dat;
233 werner 36
234 twoaday 133 if (timestamp == 0)
235 werner 36 return _("Never");
236 twoaday 133 dat = get_locale_date (timestamp, timebuf, sizeof (timebuf)-1);
237     if (dat)
238     return dat;
239     warp = localtime (&timestamp);
240 twoaday 41 _snprintf (timebuf, sizeof timebuf -1, "%04d-%02d-%02d",
241     warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday);
242 werner 36 return timebuf;
243 twoaday 41 }
244 werner 36
245    
246     const char*
247     get_key_type (gpgme_key_t key)
248     {
249     int type = find_secret_key (key);
250    
251     if (type == 1)
252     return _("Key Pair");
253     else if (type == 2)
254     return _("Key Pair (Card)");
255     return _("Public Key");
256 twoaday 129 }
257 werner 36
258    
259     const char*
260     get_key_size (gpgme_key_t key, int keyidx)
261     {
262     static char size_id[64];
263     gpgme_subkey_t k;
264     int n, size_main, size_sub;
265    
266     if (keyidx > 0) {
267     k = get_nth_key (key, keyidx-1);
268     size_main = k->length;
269     _snprintf (size_id, DIM (size_id)-1, "%d", size_main);
270     return size_id;
271     }
272     size_main = key->subkeys->length;
273     n = count_subkeys (key);
274     if (n > 1) {
275     k = get_nth_key (key, n-1);
276     size_sub = k->length;
277 twoaday 133 _snprintf (size_id, sizeof (size_id) - 1, "%d/%d",
278     size_main, size_sub);
279 werner 36 return size_id;
280     }
281     _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main );
282     return size_id;
283 twoaday 129 }
284 werner 36
285    
286     const char*
287 twoaday 129 get_key_pubalgo2 (gpgme_pubkey_algo_t alg)
288     {
289     switch (alg) {
290     case GPGME_PK_DSA: return "D";
291     case GPGME_PK_RSA: return "R";
292     case GPGME_PK_ELG: return "G";
293     default: return "?";
294     }
295     return "?";
296     }
297    
298 twoaday 133
299 twoaday 129 const char*
300 werner 36 get_key_pubalgo (gpgme_pubkey_algo_t alg)
301     {
302     switch (alg) {
303     case GPGME_PK_DSA: return "DSA";
304     case GPGME_PK_ELG:
305     case GPGME_PK_ELG_E: return "ELG";
306     case GPGME_PK_RSA: return "RSA";
307 twoaday 73 default: return "???";
308 werner 36 }
309     return "???";
310     }
311    
312 twoaday 133 const char*
313 werner 36 get_key_fpr (gpgme_key_t key)
314     {
315     static char fpr_md[64];
316     const char *fpr;
317     char t[16], tmp[40];
318     size_t i=0;
319    
320     memset (fpr_md, 0, sizeof (fpr_md));
321     fpr = key->subkeys->fpr;
322     if (!fpr || !*fpr) {
323     memset (tmp, '0', 40);
324     fpr = tmp;
325     }
326     if (strlen (fpr) == 32) {
327     strcat (fpr_md, " ");
328     for (i=0; i < strlen (fpr)/2; i++) {
329     sprintf (t, "%c%c ", fpr[2*i], fpr[2*i+1]);
330     strcat (fpr_md, t);
331     }
332     }
333     else {
334     strcat (fpr_md, " ");
335     for (i = 0; i < strlen (fpr) / 4; i++) {
336     sprintf (t, "%c%c%c%c ", fpr[4*i], fpr[4*i+1], fpr[4*i+2], fpr[4*i+3]);
337     strcat (fpr_md, t);
338     }
339     }
340     return fpr_md;
341 twoaday 129 }
342 werner 36
343    
344 twoaday 133 const char*
345 werner 36 get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)
346     {
347     if (key)
348     val = key->owner_trust; /* uididx?? */
349     switch (val) {
350     case GPGME_VALIDITY_UNKNOWN:
351     case GPGME_VALIDITY_UNDEFINED:
352 twoaday 88 return _("None");
353 werner 36 case GPGME_VALIDITY_NEVER:
354 twoaday 88 return _("Never");
355 werner 36 case GPGME_VALIDITY_MARGINAL:
356 twoaday 88 return _("Marginal");
357 werner 36 case GPGME_VALIDITY_FULL:
358     case GPGME_VALIDITY_ULTIMATE:
359 twoaday 88 return _("Full");
360 werner 36 }
361     return "";
362     }
363    
364    
365 twoaday 167 const char*
366 werner 36 get_key_trust (gpgme_key_t key, int uididx, int listmode)
367     {
368     return get_key_trust2 (key, 0, uididx, listmode);
369     }
370    
371    
372 twoaday 167 const char*
373 werner 36 get_key_trust_str (int val)
374     {
375     return get_key_trust2 (NULL, val, 0, 0);
376     }
377    
378    
379 twoaday 50 /* Return the status of the key @key. */
380 werner 36 char*
381     get_key_status (gpgme_key_t key, int uididx, int listmode)
382     {
383     gpgme_user_id_t u;
384 twoaday 50 const char *attr;
385 werner 36 u32 key_attr =0;
386    
387     if (uididx < 0 || count_userids (key) > uididx)
388     uididx = 0;
389     if (listmode) {
390 twoaday 105 const char *s;
391 werner 36 if (key->revoked)
392 werner 48 s = _("Revoked");
393 werner 36 else if (key->expired)
394 werner 48 s = _("Expired");
395 werner 36 else if (key->disabled)
396 werner 48 s = _("Disabled");
397 twoaday 105 else
398     s = "";
399 werner 36 /* if the key has a special status, we don't continue to figure out
400 twoaday 133 the user-id validities. */
401 werner 48 if (*s)
402     return m_strdup (s);
403 werner 36 }
404     u = get_nth_userid (key, uididx);
405     key_attr = u->validity;
406     attr = get_key_trust2 (NULL, key_attr, 0, 0);
407 twoaday 50 return m_strdup (attr);
408     }
409 werner 36
410    
411 twoaday 167 /* Return human readable description of the key @key. */
412     char*
413     get_key_desc (gpgme_key_t key)
414     {
415     gpgme_key_t sk;
416     const char *state, *alg, *type;
417     char *p;
418    
419     /* XXX: problems with the German translation. */
420     state = "";
421     if (key->disabled)
422     state = _("Disabled");
423     if (key->expired)
424     state = _("Expired");
425     if (key->revoked)
426     state = _("Revoked");
427     alg = "OpenPGP";
428     if (strlen (key->subkeys->fpr) == 32)
429     alg = "RSA Legacy";
430     type = _("public key");
431     if (!get_seckey (key->subkeys->keyid+8, &sk))
432     type = _("key pair");
433     p = new char[strlen (state) + strlen (alg) + strlen (type) + 4 + 1];
434     if (!p)
435     BUG (0);
436     sprintf (p, "%s %s %s", state, alg, type);
437     return p;
438     }
439    
440    
441 werner 36 /* Integer comparsion of @a and @b.
442     Return values: same as in strcmp. */
443     static inline int
444     int_cmp (int a, int b)
445     {
446     if (a == b) return 0;
447     else if (a > b) return 1;
448     else return -1;
449     return 0;
450     }
451    
452    
453     /* To allow to sort the keys, we need to take care of
454     the expired/revoke status also. */
455     static int
456     get_ext_validity (gpgme_key_t k)
457     {
458     if (k->revoked)
459     return GPGME_VALIDITY_ULTIMATE+1;
460     else if (k->expired)
461     return GPGME_VALIDITY_ULTIMATE+2;
462 twoaday 150 else if (k->disabled)
463     return GPGME_VALIDITY_ULTIMATE+3;
464 werner 36 return k->uids->validity;
465     }
466    
467    
468     /* List view sorting callback. */
469     static int CALLBACK
470     keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
471     {
472     gpgme_key_t a, b;
473     int cmpresult = 0;
474    
475     a = (gpgme_key_t)first;
476     b = (gpgme_key_t)second;
477     if (!a || !b)
478     BUG (NULL);
479    
480     switch (sortby & ~KEYLIST_SORT_DESC) {
481     case KEY_SORT_USERID:
482 twoaday 25 cmpresult = strcmpi (a->uids->uid, b->uids->uid);
483 werner 36 break;
484    
485     case KEY_SORT_KEYID:
486     cmpresult = strcmpi (a->subkeys->keyid+8,
487     b->subkeys->keyid+8);
488     break;
489    
490     case KEY_SORT_VALIDITY:
491     cmpresult = int_cmp (get_ext_validity (a),
492     get_ext_validity (b));
493     break;
494    
495     case KEY_SORT_OTRUST:
496     cmpresult = int_cmp (a->owner_trust, b->owner_trust);
497     break;
498    
499     case KEY_SORT_IS_SECRET:
500     get_seckey (a->subkeys->keyid, &a);
501     get_seckey (b->subkeys->keyid, &b);
502     cmpresult = int_cmp (a? a->secret : 0, b? b->secret : 0);
503     break;
504    
505     case KEY_SORT_LEN:
506     cmpresult = int_cmp (a->subkeys->length,
507     b->subkeys->length);
508     break;
509    
510     case KEY_SORT_CREATED:
511     cmpresult = int_cmp (a->subkeys->timestamp,
512     b->subkeys->timestamp);
513     break;
514    
515     case KEY_SORT_ALGO:
516     cmpresult = int_cmp (a->subkeys->pubkey_algo,
517     b->subkeys->pubkey_algo);
518     break;
519    
520     default:
521     cmpresult = strcmpi (a->uids->uid, b->uids->uid);
522     break;
523     }
524     if (sortby & KEYLIST_SORT_DESC)
525     return (~cmpresult + 1);
526     else
527     return cmpresult;
528     }
529    
530    
531     int
532 twoaday 133 keylist_add_groups (listview_ctrl_t lv)
533 werner 36 {
534     return 0;
535 twoaday 133 }
536 werner 36
537    
538     /* Create a listview for listing keys. Use the mode given in @mode
539     and the control is given in @ctrl. */
540     static int
541     keylist_build (listview_ctrl_t *r_lv, HWND ctrl, int mode)
542     {
543 twoaday 105 struct listview_column_s klist_enc[] = {
544     {0, 242, (char *)_("User ID")},
545     {1, 80, (char *)_("Key ID")},
546     {3, 46, (char *)_("Size")},
547     {4, 50, (char *)_("Cipher")},
548     {5, 70, (char *)_("Validity")},
549     {0, 0, NULL}
550     };
551     struct listview_column_s klist[] = {
552 twoaday 129 {0, 240, (char *)_("User ID")},
553 twoaday 105 {1, 78, (char *)_("Key ID")},
554     {2, 52, (char *)_("Type")},
555 twoaday 129 {3, 66, (char *)_("Size")},
556     {4, 60, (char *)_("Cipher")},
557     {5, 66, (char *)_("Validity")},
558     {6, 58, (char *)_("Trust")},
559 twoaday 105 {7, 72, (char *)_("Creation")},
560     {0, 0, NULL}
561     };
562 twoaday 133 HICON ico[2];
563 werner 36 listview_ctrl_t lv;
564     listview_column_t col;
565     int j, n = 0;
566 twoaday 73 int rc = 0;
567 werner 36
568     rc = listview_new (&lv);
569 twoaday 105 if (rc)
570 werner 36 return rc;
571    
572     lv->ctrl = ctrl;
573     if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN)) {
574     col = klist_enc;
575 twoaday 105 n = (DIM(klist_enc) -1);
576 werner 36 }
577     else if ((mode & KEYLIST_SIGN)) {
578     col = klist_enc;
579 twoaday 105 n = (DIM(klist_enc) - 1) - 1;
580 werner 36 }
581     else {
582     col = klist;
583 twoaday 105 n = (DIM(klist) - 1);
584 werner 36 }
585    
586 twoaday 133 for (j = 0; j < n; j++)
587     listview_add_column (lv, &col[j]);
588     listview_set_ext_style (lv);
589     ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY);
590     ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR);
591     listview_set_image_list (lv, ico, 2);
592 twoaday 150 listview_del_all_items (lv);
593 twoaday 133
594 werner 36 *r_lv = lv;
595     return 0;
596     }
597    
598    
599     static void
600     keylist_load_keycache (listview_ctrl_t lv, int mode,
601     gpg_keycache_t pubkc, gpg_keycache_t seckc)
602     {
603     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
604     gpgme_key_t key, skey;
605     const char * keyid;
606    
607     if (pubkc && seckc) {
608     gpg_keycache_rewind (pubkc);
609     while (!gpg_keycache_next_key (pubkc, 0, &key)) {
610     keyid = key->subkeys->keyid;
611     if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))
612     keylist_add_key (lv, mode, key);
613     }
614     }
615     else if (pubkc) {
616     gpg_keycache_rewind (pubkc);
617     while (!err) {
618     err = gpg_keycache_next_key (pubkc, 0, &key);
619     if (!err)
620     keylist_add_key (lv, mode, key);
621     }
622     }
623     }
624    
625    
626     /* Load the list view @ctrl with the keys from the cache.
627     Return value: list view context on success. */
628     listview_ctrl_t
629     keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,
630     int mode, int sortby)
631     {
632     listview_ctrl_t lv;
633     int rc = 0;
634    
635     rc = keylist_build (&lv, ctrl, mode);
636     if (rc)
637     return NULL;
638     keylist_load_keycache (lv, mode, pubkc, seckc);
639     keylist_sort (lv, sortby);
640     if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN))
641     keylist_add_groups (lv);
642     return lv;
643     }
644    
645    
646     /* Reload the given key list control @lv. */
647     int
648     keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby)
649     {
650 twoaday 150 listview_del_all_items (lv);
651 twoaday 161 keylist_load_keycache (lv, mode, pubkc, NULL);
652 werner 36 keylist_sort (lv, sortby);
653     return 0;
654     }
655    
656    
657     void
658     keylist_delete (listview_ctrl_t lv)
659     {
660     if (lv) {
661     listview_release (lv);
662     }
663     }
664    
665    
666     /* Return if there is a secret for @key.
667     0 means success. */
668     static int
669     find_secret_key (gpgme_key_t key)
670     {
671     const char *keyid;
672     winpt_key_s skey;
673    
674     memset (&skey, 0, sizeof (skey));
675     keyid = key->subkeys->keyid;
676     if (!keyid)
677     return 0;
678     winpt_get_seckey (keyid, &skey);
679     if (skey.ext && skey.ext->gloflags.divert_to_card)
680     return 2;
681     return skey.ctx? 1 : 0;
682     }
683    
684    
685     static int
686     do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list)
687     {
688     LV_ITEM lvi;
689     gpgme_user_id_t u;
690     gpgme_subkey_t k;
691     char fmt[128], *p;
692     const char *attr;
693     u32 key_attr;
694     int idx = 0;
695    
696     /* we check the pubkey algorithm here to make sure that no ElGamal
697     sign+encrypt key is used in _any_ mode */
698     if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {
699 twoaday 128 log_debug ("ElGamal (E+S) key found: %s (%s)\n",
700 werner 36 key->uids->name, key->subkeys->keyid);
701     return 0;
702     }
703    
704 twoaday 128 if (listview_add_item2 (lv, " ", (void *)key))
705 werner 36 return WPTERR_GENERAL;
706 twoaday 128
707 werner 36 attr = key->uids->uid;
708     memset (&lvi, 0, sizeof lvi);
709 twoaday 133 lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
710 werner 36 lvi.pszText = (char *)attr;
711 twoaday 133 lvi.iImage = find_secret_key (key)? 1 : 0;
712 werner 36 lvi.lParam = (LPARAM )key;
713 twoaday 128 if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
714 werner 36 return WPTERR_GENERAL;
715    
716     if (uididx == -1) { /* request the primary user-id of the key. */
717     attr = key->uids->uid;
718     uididx = 0;
719     }
720     else {
721     u = get_nth_userid (key, uididx);
722     if (!u || u->revoked || uididx < 0)
723 twoaday 133 uididx = 0;
724 werner 36 u = get_nth_userid (key, uididx);
725     attr = u->uid;
726     }
727 twoaday 133 if (attr == NULL || strlen (attr) < 5) { /* normal userids are > 5 chars */
728 werner 36 attr = _("Invalid User ID");
729     listview_add_sub_item (lv, 0, idx++, attr);
730     }
731     else {
732     char *uid = utf8_to_wincp (attr, strlen (attr));
733     if (uid) {
734     listview_add_sub_item (lv, 0, idx++, uid);
735     free (uid);
736     }
737     }
738     k = get_nth_key (key, keyidx);
739     if (k && k->keyid) {
740     _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8);
741     listview_add_sub_item( lv, 0, idx++, fmt );
742     }
743     if (list > 0) {
744     key_attr = find_secret_key (key);
745     if (!key_attr)
746     attr = "pub";
747     else
748     attr = key_attr == 1? "pub/sec" : "pub/crd";
749     listview_add_sub_item (lv, 0, idx++, attr);
750     }
751     if (lv->cols >= 2) {
752     attr = get_key_size (key, list == -1? keyidx+1 : 0);
753     if (attr)
754     listview_add_sub_item (lv, 0, idx++, attr);
755     }
756     if (lv->cols >= 3) {
757     attr = get_key_algo (key, list == -1? keyidx+1 : 0);
758     if (attr)
759     listview_add_sub_item( lv, 0, idx++, attr);
760     }
761 twoaday 167 if (lv->cols >= 4) {
762 werner 36 p = get_key_status( key, uididx, list > 0? 1 : 0 );
763     if (!p)
764     return WPTERR_GENERAL;
765     listview_add_sub_item (lv, 0, idx++, p);
766     free_if_alloc (p);
767     }
768     if (lv->cols >= 5) {
769     attr = get_key_trust (key, uididx, list > 0? 1 : 0);
770     listview_add_sub_item (lv, 0, idx++, attr);
771     }
772     if( lv->cols >= 6 ) {
773     k = get_nth_key (key, keyidx);
774     key_attr = k->timestamp;
775     if( key_attr ) {
776     attr = get_key_created (key_attr);
777     listview_add_sub_item( lv, 0, idx++, attr );
778     }
779     }
780    
781     return 0;
782     }
783    
784    
785 twoaday 129 /* Update a single column @col but for each element in the
786     listview @lv. */
787 werner 36 void
788 twoaday 129 keylist_upd_col (listview_ctrl_t lv, int col)
789     {
790     gpgme_key_t key;
791     const char *s;
792 twoaday 167 char buf[32], *p;
793 twoaday 129 int i;
794    
795     for (i=0; i < listview_count_items (lv, 0); i++) {
796     key = (gpgme_key_t)listview_get_item2 (lv, i);
797     if (!key)
798     continue;
799     switch (col) {
800     case KM_COL_KEYID:
801     _snprintf (buf, sizeof (buf)-1, "0x%s", key->subkeys->keyid+8);
802     listview_add_sub_item (lv, i, col, buf);
803     break;
804    
805     case KM_COL_CIPHER:
806     s = get_key_algo (key, 0);
807     listview_add_sub_item (lv, i, col, s);
808     break;
809    
810     case KM_COL_TYPE:
811     s = find_secret_key (key)? "pub/sec" : "pub";
812     listview_add_sub_item (lv, i, col, s);
813     break;
814    
815     case KM_COL_CREAT:
816     s = get_key_created (key->subkeys->timestamp);
817     listview_add_sub_item (lv, i, col, s);
818     break;
819 twoaday 167
820     case KM_COL_DESC:
821     p = get_key_desc (key);
822     listview_add_sub_item (lv, i, col, p);
823     free_if_alloc (p);
824     break;
825 twoaday 129 }
826     }
827     }
828    
829 twoaday 133
830 twoaday 129 /* Update the listview item at position @pos with the data from
831     the key @key. */
832     void
833 werner 36 keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)
834     {
835     const char *s;
836 twoaday 167 char *uid, *p;
837 werner 36 char tmp[32];
838    
839     listview_set_item2 (lv, pos, (void *)key);
840     /* the only mode we support is KYLIST_LIST in the Key Manager */
841    
842     s = key->uids->uid;
843 twoaday 129 if (s) {
844     uid = utf8_to_wincp2 (s);
845 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_UID, uid);
846 twoaday 129 free (uid);
847     }
848 werner 36
849     s = key->subkeys->keyid;
850     if (s) {
851     sprintf (tmp, "0x%s", s+8);
852 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_KEYID, tmp);
853 werner 36 }
854    
855     s = find_secret_key (key)? "pub/sec" : "pub";
856 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_TYPE, s);
857 werner 36
858     s = get_key_size (key, 0);
859     if (s)
860 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_SIZE, s);
861 werner 36
862     s = get_key_algo (key, 0);
863     if (s)
864 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_CIPHER, s);
865 werner 36
866 twoaday 167 p = get_key_status (key, 0, 1);
867     if (p) {
868     listview_add_sub_item (lv, pos, KM_COL_VALID, p);
869     free_if_alloc (p);
870     }
871 werner 36
872     s = get_key_trust (key, 0, 1);
873     if (s)
874 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_TRUST, s);
875 werner 36
876     long t = key->subkeys->timestamp;
877     s = get_key_created (t);
878     if (s)
879 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_CREAT, s);
880 werner 36 }
881    
882    
883     int
884     keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)
885     {
886 twoaday 73 int uids, rc = 0, i;
887 werner 36 gpgme_subkey_t k;
888    
889 twoaday 41 /* if the entire key is disabled, just return. */
890 twoaday 80 if (key->disabled && !(mode & KEYLIST_LIST))
891 twoaday 41 return 0;
892    
893 werner 36 for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) {
894     if (k->invalid) {
895     log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name);
896     continue; /* Don't use invalid keys */
897     }
898    
899     if (mode & KEYLIST_ALL) {
900     uids = count_userids (key);
901     rc = do_addkey (lv, key, uids, i, 0);
902 twoaday 128 if (rc)
903 werner 36 return rc;
904     }
905     else if (mode & KEYLIST_LIST)
906     return do_addkey (lv, key, -1, i, 1);
907     else if (mode & KEYLIST_ENCRYPT) {
908     if (k->can_encrypt && key_is_useable (k)) {
909     if (mode & KEYLIST_FLAG_FILE) {
910     rc = do_addkey (lv, key, -1, i, -1);
911     if (rc)
912     return rc;
913     }
914     else {
915 twoaday 128 for (uids = 0; uids < count_userids (key); uids++) {
916     rc = do_addkey (lv, key, uids, i, -1);
917     if (rc)
918 werner 36 return rc;
919     }
920     }
921     }
922     }
923     else if (mode & KEYLIST_ENCRYPT_MIN) {
924     if( k->can_encrypt && key_is_useable (k))
925     {
926     rc = do_addkey (lv, key, -1, i, -1);
927     return rc;
928     }
929     }
930     else if (mode & KEYLIST_SIGN) {
931 twoaday 41 if (k->can_sign
932     && find_secret_key (key)
933     && key_is_useable (k)) {
934 werner 36 rc = do_addkey (lv, key, -1, i, -1);
935 twoaday 41 if (rc)
936 werner 36 return rc;
937     }
938     }
939     }
940    
941     return rc;
942 twoaday 133 }
943 werner 36
944    
945     int
946     keylist_sort (listview_ctrl_t lv, int sortby)
947 twoaday 150 {
948 werner 36 return listview_sort_items (lv, sortby, keylist_cmp_cb);
949     }
950    
951    
952     /* Check that the validity @validity is at least >= marginal. */
953     static int
954 twoaday 133 key_check_validity (gpgme_key_t key)
955     {
956     gpgme_user_id_t u;
957    
958     for (u=key->uids; u; u =u->next) {
959     if (u->validity >= GPGME_VALIDITY_MARGINAL)
960     return -1;
961     }
962    
963     return 0;
964 werner 36 }
965    
966    
967     /* Extract all selected recipients from the list @lv and return them
968     as a vector. @r_force_trust is >= 1 if one of the recipients is not
969     fully trusted. @r_count returns the number of selected keys.
970     Return value: the key list on success, NULL otherwise. */
971     gpgme_key_t*
972     keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)
973     {
974 twoaday 133 key_array_s *ka = NULL;
975     gpgme_key_t *keybuf, key;
976 werner 36 int count = 0, force_trust = 0;
977     int n, j, ka_pos = 0, rc = 0;
978     int k_pos=0;
979    
980 twoaday 133 n = listview_count_items (lv, 0);
981 werner 36
982 twoaday 133 ka = key_array_new (n);
983 werner 36 if (!ka)
984     BUG (NULL);
985    
986     keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
987     if (!keybuf)
988     BUG (NULL);
989    
990 twoaday 133 for (j = 0; j < n; j++) {
991     if (listview_get_item_state (lv, j) || n == 1) {
992     key = (gpgme_key_t)listview_get_item2 (lv, j);
993     if (!key)
994     BUG (0);
995     if (!key_check_validity (key) &&
996     !key_array_search (ka, ka_pos, key->subkeys->keyid)) {
997     char *warn = new char[512+strlen (key->uids->uid) + 1];
998 werner 36 if (!warn)
999     BUG (0);
1000     sprintf (warn,
1001     _("It is NOT certain that the key belongs to the person\n"
1002     "named in the user ID. If you *really* know what you are\n"
1003     "doing, you may answer the next question with yes\n"
1004     "\n"
1005 twoaday 133 "Use \"%s\" anyway?"), key->uids->uid);
1006 werner 36 if (reg_prefs.always_trust)
1007     rc = IDYES;
1008     else
1009     rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);
1010     if (rc == IDYES) {
1011 twoaday 133 keybuf[k_pos++] = key;
1012 werner 36 force_trust++;
1013     ka[ka_pos].checked = 1;
1014 twoaday 133 strcpy (ka[ka_pos++].keyid, key->subkeys->keyid);
1015 werner 36 count++;
1016     }
1017     free_if_alloc (warn);
1018     }
1019     else {
1020 twoaday 133 keybuf[k_pos++] = key;
1021 werner 36 count++;
1022     }
1023     }
1024     }
1025     key_array_release (ka);
1026     if (r_force_trust)
1027     *r_force_trust = force_trust;
1028     if (r_count)
1029     *r_count = count;
1030     return keybuf;
1031     }
1032    
1033    
1034     static int
1035 twoaday 133 keylist_get_keyflags (gpgme_key_t key)
1036 werner 36 {
1037 twoaday 133 int flags = KEYFLAG_NONE;
1038 werner 36
1039 twoaday 133 if (key->revoked)
1040     flags |= KEYFLAG_REVOKED;
1041     if (key->expired)
1042     flags |= KEYFLAG_EXPIRED;
1043     if (key->disabled)
1044     flags |= KEYFLAG_DISABLED;
1045 werner 36
1046     return flags;
1047 twoaday 133 }
1048 werner 36
1049    
1050     gpgme_key_t*
1051     keylist_enum_recipients (listview_ctrl_t lv, int listype, int *r_count)
1052     {
1053 twoaday 133 gpgme_key_t *rset;
1054     gpgme_key_t key;
1055 werner 36 int i, n, id, k_pos=0;
1056    
1057     n = listview_count_items (lv, 0);
1058     if (!n)
1059     return 0;
1060     rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
1061     if (!rset)
1062     BUG (NULL);
1063 twoaday 133 for (i = 0; i < n; i++) {
1064     if (!listview_get_item_state (lv, i))
1065 werner 36 continue;
1066 twoaday 133 key = (gpgme_key_t)listview_get_item2 (lv, i);
1067     if (!key)
1068     BUG (0);
1069     switch (listype) {
1070 werner 36 case KEYLIST_LIST:
1071 twoaday 133 if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) {
1072     id = printf_box (_("Recipients"), MB_INFO|MB_YESNO,
1073     _("KeyID %s.\nDo you really want to export a revoked key?"),
1074     key->uids->uid);
1075     if (id == IDNO)
1076     continue;
1077 werner 36 }
1078     break;
1079     }
1080 twoaday 133 rset[k_pos++] = key;
1081 werner 36 }
1082     if (r_count)
1083     *r_count = k_pos;
1084     return rset;
1085 twoaday 133 }
1086 werner 36
1087    
1088     void
1089 twoaday 133 seclist_destroy (keylist_t *list)
1090 werner 36 {
1091     keylist_t l2;
1092     while (*list) {
1093     l2 = (*list)->next;
1094     safe_free (*list);
1095     *list = l2;
1096     }
1097     list = NULL;
1098 twoaday 133 }
1099 werner 36
1100    
1101     void
1102     seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)
1103     {
1104     gpg_keycache_t kc = NULL;
1105     gpgme_key_t key = NULL;
1106     HWND kb;
1107     keylist_t list=NULL, l, l2;
1108     long pos = 0;
1109    
1110     SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
1111     kb = GetDlgItem (dlg, ctlid);
1112     kc = keycache_get_ctx (0);
1113     if (!kc)
1114     BUG (0);
1115     gpg_keycache_rewind (kc);
1116    
1117     while (!gpg_keycache_next_key (kc, 1, &key)) {
1118 twoaday 41 char *inf = NULL, *uid = NULL;
1119     const char *id;
1120     const char *keyid;
1121 werner 36 int algo;
1122     size_t size = 0;
1123    
1124     if (flags & KEYLIST_FLAG_SHORT)
1125     id = key->uids->name;
1126     else
1127     id = key->uids->uid;
1128     keyid = key->subkeys->keyid;
1129     algo = key->subkeys->pubkey_algo;
1130     if (!id || !keyid)
1131     continue;
1132 twoaday 41 if (key->disabled || !key_is_useable (key->subkeys))
1133     continue;
1134 werner 36
1135     uid = utf8_to_wincp (id, strlen (id));
1136 twoaday 133 size = strlen (uid) + strlen (keyid) + 32;
1137 werner 36 inf = new char[size+1];
1138 twoaday 133 if (!inf)
1139     BUG (NULL);
1140     _snprintf (inf, size, "%s (%s/0x%s)", uid,
1141 werner 36 get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);
1142     combox_add_string (kb, inf);
1143     free_if_alloc (inf);
1144     free (uid);
1145     l = (struct keylist_s *)calloc (1, sizeof * l);
1146     if (!l)
1147     BUG (0);
1148     l->key = key;
1149     if (!list)
1150     list = l;
1151     else {
1152     for( l2 = list; l2->next; l2 = l2->next )
1153     ;
1154     l2->next = l;
1155     }
1156     }
1157 twoaday 133 for (pos = 0, l2=list; pos < SendMessage (kb, CB_GETCOUNT, 0, 0);
1158     pos++, l2=l2->next)
1159     SendMessage (kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key);
1160     SendMessage (kb, CB_SETCURSEL, 0, 0);
1161 werner 36 *ret_list = list;
1162     }
1163    
1164    
1165     /* Select a secret key from the combo box with the ID @ctlid.
1166     Return the code on success in @ret_key. */
1167     int
1168     seclist_select_key (HWND dlg, int ctlid, gpgme_key_t *ret_key)
1169     {
1170     int pos;
1171     DWORD k = 0;
1172    
1173     pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
1174     if (pos == CB_ERR) {
1175     msg_box (dlg, _("No key was selected."), _("Secret Key List"), MB_ERR);
1176     *ret_key = NULL;
1177     }
1178     else {
1179     k = SendDlgItemMessage (dlg, ctlid, CB_GETITEMDATA, pos, 0);
1180     *ret_key = (gpgme_key_t)k;
1181     }
1182     return k? 0 : -1;
1183     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26