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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 176 - (hide annotations)
Mon Feb 13 09:38:03 2006 UTC (19 years ago) by twoaday
File size: 26655 byte(s)


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 twoaday 174 int j, n = 0, ext_chk = 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 twoaday 176 if (mode & KEYLIST_ENCRYPT_MIN) {
574 werner 36 col = klist_enc;
575 twoaday 105 n = (DIM(klist_enc) -1);
576 twoaday 174 ext_chk = 1;
577 werner 36 }
578     else if ((mode & KEYLIST_SIGN)) {
579     col = klist_enc;
580 twoaday 105 n = (DIM(klist_enc) - 1) - 1;
581 twoaday 174 ext_chk = 1;
582 werner 36 }
583     else {
584     col = klist;
585 twoaday 105 n = (DIM(klist) - 1);
586 werner 36 }
587    
588 twoaday 133 for (j = 0; j < n; j++)
589 twoaday 174 listview_add_column (lv, &col[j]);
590 twoaday 133 listview_set_ext_style (lv);
591 twoaday 174 if (ext_chk)
592     listview_set_chkbox_style (lv);
593 twoaday 133 ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY);
594     ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR);
595     listview_set_image_list (lv, ico, 2);
596 twoaday 150 listview_del_all_items (lv);
597 twoaday 133
598 werner 36 *r_lv = lv;
599     return 0;
600     }
601    
602    
603     static void
604     keylist_load_keycache (listview_ctrl_t lv, int mode,
605     gpg_keycache_t pubkc, gpg_keycache_t seckc)
606     {
607     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
608     gpgme_key_t key, skey;
609     const char * keyid;
610    
611     if (pubkc && seckc) {
612     gpg_keycache_rewind (pubkc);
613     while (!gpg_keycache_next_key (pubkc, 0, &key)) {
614     keyid = key->subkeys->keyid;
615     if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))
616     keylist_add_key (lv, mode, key);
617     }
618     }
619     else if (pubkc) {
620     gpg_keycache_rewind (pubkc);
621     while (!err) {
622     err = gpg_keycache_next_key (pubkc, 0, &key);
623     if (!err)
624     keylist_add_key (lv, mode, key);
625     }
626     }
627     }
628    
629    
630     /* Load the list view @ctrl with the keys from the cache.
631     Return value: list view context on success. */
632     listview_ctrl_t
633     keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,
634     int mode, int sortby)
635     {
636     listview_ctrl_t lv;
637     int rc = 0;
638    
639     rc = keylist_build (&lv, ctrl, mode);
640     if (rc)
641     return NULL;
642     keylist_load_keycache (lv, mode, pubkc, seckc);
643     keylist_sort (lv, sortby);
644 twoaday 176 if (mode & KEYLIST_ENCRYPT_MIN)
645 werner 36 keylist_add_groups (lv);
646     return lv;
647     }
648    
649    
650     /* Reload the given key list control @lv. */
651     int
652     keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby)
653     {
654 twoaday 150 listview_del_all_items (lv);
655 twoaday 161 keylist_load_keycache (lv, mode, pubkc, NULL);
656 werner 36 keylist_sort (lv, sortby);
657     return 0;
658     }
659    
660    
661     void
662     keylist_delete (listview_ctrl_t lv)
663     {
664     if (lv) {
665     listview_release (lv);
666     }
667     }
668    
669    
670     /* Return if there is a secret for @key.
671     0 means success. */
672     static int
673     find_secret_key (gpgme_key_t key)
674     {
675     const char *keyid;
676     winpt_key_s skey;
677    
678     memset (&skey, 0, sizeof (skey));
679     keyid = key->subkeys->keyid;
680     if (!keyid)
681     return 0;
682     winpt_get_seckey (keyid, &skey);
683     if (skey.ext && skey.ext->gloflags.divert_to_card)
684     return 2;
685     return skey.ctx? 1 : 0;
686     }
687    
688    
689     static int
690     do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list)
691     {
692     LV_ITEM lvi;
693     gpgme_user_id_t u;
694     gpgme_subkey_t k;
695     char fmt[128], *p;
696     const char *attr;
697     u32 key_attr;
698     int idx = 0;
699    
700     /* we check the pubkey algorithm here to make sure that no ElGamal
701     sign+encrypt key is used in _any_ mode */
702     if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {
703 twoaday 128 log_debug ("ElGamal (E+S) key found: %s (%s)\n",
704 werner 36 key->uids->name, key->subkeys->keyid);
705     return 0;
706     }
707    
708 twoaday 128 if (listview_add_item2 (lv, " ", (void *)key))
709 werner 36 return WPTERR_GENERAL;
710 twoaday 128
711 werner 36 attr = key->uids->uid;
712     memset (&lvi, 0, sizeof lvi);
713 twoaday 133 lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
714 werner 36 lvi.pszText = (char *)attr;
715 twoaday 133 lvi.iImage = find_secret_key (key)? 1 : 0;
716 werner 36 lvi.lParam = (LPARAM )key;
717 twoaday 128 if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
718 werner 36 return WPTERR_GENERAL;
719    
720     if (uididx == -1) { /* request the primary user-id of the key. */
721     attr = key->uids->uid;
722     uididx = 0;
723     }
724     else {
725     u = get_nth_userid (key, uididx);
726     if (!u || u->revoked || uididx < 0)
727 twoaday 133 uididx = 0;
728 werner 36 u = get_nth_userid (key, uididx);
729     attr = u->uid;
730     }
731 twoaday 133 if (attr == NULL || strlen (attr) < 5) { /* normal userids are > 5 chars */
732 werner 36 attr = _("Invalid User ID");
733     listview_add_sub_item (lv, 0, idx++, attr);
734     }
735     else {
736     char *uid = utf8_to_wincp (attr, strlen (attr));
737     if (uid) {
738     listview_add_sub_item (lv, 0, idx++, uid);
739     free (uid);
740     }
741     }
742     k = get_nth_key (key, keyidx);
743     if (k && k->keyid) {
744     _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8);
745     listview_add_sub_item( lv, 0, idx++, fmt );
746     }
747     if (list > 0) {
748     key_attr = find_secret_key (key);
749     if (!key_attr)
750     attr = "pub";
751     else
752     attr = key_attr == 1? "pub/sec" : "pub/crd";
753     listview_add_sub_item (lv, 0, idx++, attr);
754     }
755     if (lv->cols >= 2) {
756     attr = get_key_size (key, list == -1? keyidx+1 : 0);
757     if (attr)
758     listview_add_sub_item (lv, 0, idx++, attr);
759     }
760     if (lv->cols >= 3) {
761     attr = get_key_algo (key, list == -1? keyidx+1 : 0);
762     if (attr)
763     listview_add_sub_item( lv, 0, idx++, attr);
764     }
765 twoaday 167 if (lv->cols >= 4) {
766 werner 36 p = get_key_status( key, uididx, list > 0? 1 : 0 );
767     if (!p)
768     return WPTERR_GENERAL;
769     listview_add_sub_item (lv, 0, idx++, p);
770     free_if_alloc (p);
771     }
772     if (lv->cols >= 5) {
773     attr = get_key_trust (key, uididx, list > 0? 1 : 0);
774     listview_add_sub_item (lv, 0, idx++, attr);
775     }
776     if( lv->cols >= 6 ) {
777     k = get_nth_key (key, keyidx);
778     key_attr = k->timestamp;
779     if( key_attr ) {
780     attr = get_key_created (key_attr);
781     listview_add_sub_item( lv, 0, idx++, attr );
782     }
783     }
784    
785     return 0;
786     }
787    
788    
789 twoaday 129 /* Update a single column @col but for each element in the
790     listview @lv. */
791 werner 36 void
792 twoaday 129 keylist_upd_col (listview_ctrl_t lv, int col)
793     {
794     gpgme_key_t key;
795     const char *s;
796 twoaday 167 char buf[32], *p;
797 twoaday 129 int i;
798    
799     for (i=0; i < listview_count_items (lv, 0); i++) {
800     key = (gpgme_key_t)listview_get_item2 (lv, i);
801     if (!key)
802     continue;
803     switch (col) {
804     case KM_COL_KEYID:
805     _snprintf (buf, sizeof (buf)-1, "0x%s", key->subkeys->keyid+8);
806     listview_add_sub_item (lv, i, col, buf);
807     break;
808    
809     case KM_COL_CIPHER:
810     s = get_key_algo (key, 0);
811     listview_add_sub_item (lv, i, col, s);
812     break;
813    
814     case KM_COL_TYPE:
815     s = find_secret_key (key)? "pub/sec" : "pub";
816     listview_add_sub_item (lv, i, col, s);
817     break;
818    
819     case KM_COL_CREAT:
820     s = get_key_created (key->subkeys->timestamp);
821     listview_add_sub_item (lv, i, col, s);
822     break;
823 twoaday 167
824     case KM_COL_DESC:
825     p = get_key_desc (key);
826     listview_add_sub_item (lv, i, col, p);
827     free_if_alloc (p);
828     break;
829 twoaday 129 }
830     }
831     }
832    
833 twoaday 133
834 twoaday 129 /* Update the listview item at position @pos with the data from
835     the key @key. */
836     void
837 werner 36 keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)
838     {
839     const char *s;
840 twoaday 167 char *uid, *p;
841 werner 36 char tmp[32];
842    
843     listview_set_item2 (lv, pos, (void *)key);
844     /* the only mode we support is KYLIST_LIST in the Key Manager */
845    
846     s = key->uids->uid;
847 twoaday 129 if (s) {
848     uid = utf8_to_wincp2 (s);
849 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_UID, uid);
850 twoaday 129 free (uid);
851     }
852 werner 36
853     s = key->subkeys->keyid;
854     if (s) {
855     sprintf (tmp, "0x%s", s+8);
856 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_KEYID, tmp);
857 werner 36 }
858    
859     s = find_secret_key (key)? "pub/sec" : "pub";
860 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_TYPE, s);
861 werner 36
862     s = get_key_size (key, 0);
863     if (s)
864 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_SIZE, s);
865 werner 36
866     s = get_key_algo (key, 0);
867     if (s)
868 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_CIPHER, s);
869 werner 36
870 twoaday 167 p = get_key_status (key, 0, 1);
871     if (p) {
872     listview_add_sub_item (lv, pos, KM_COL_VALID, p);
873     free_if_alloc (p);
874     }
875 werner 36
876     s = get_key_trust (key, 0, 1);
877     if (s)
878 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_TRUST, s);
879 werner 36
880     long t = key->subkeys->timestamp;
881     s = get_key_created (t);
882     if (s)
883 twoaday 167 listview_add_sub_item (lv, pos, KM_COL_CREAT, s);
884 werner 36 }
885    
886    
887     int
888     keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)
889     {
890 twoaday 73 int uids, rc = 0, i;
891 werner 36 gpgme_subkey_t k;
892    
893 twoaday 41 /* if the entire key is disabled, just return. */
894 twoaday 80 if (key->disabled && !(mode & KEYLIST_LIST))
895 twoaday 41 return 0;
896    
897 werner 36 for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) {
898     if (k->invalid) {
899     log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name);
900     continue; /* Don't use invalid keys */
901     }
902    
903     if (mode & KEYLIST_ALL) {
904     uids = count_userids (key);
905     rc = do_addkey (lv, key, uids, i, 0);
906 twoaday 128 if (rc)
907 werner 36 return rc;
908     }
909     else if (mode & KEYLIST_LIST)
910     return do_addkey (lv, key, -1, i, 1);
911     else if (mode & KEYLIST_ENCRYPT) {
912     if (k->can_encrypt && key_is_useable (k)) {
913     if (mode & KEYLIST_FLAG_FILE) {
914     rc = do_addkey (lv, key, -1, i, -1);
915     if (rc)
916     return rc;
917     }
918     else {
919 twoaday 128 for (uids = 0; uids < count_userids (key); uids++) {
920     rc = do_addkey (lv, key, uids, i, -1);
921     if (rc)
922 werner 36 return rc;
923     }
924     }
925     }
926     }
927     else if (mode & KEYLIST_ENCRYPT_MIN) {
928     if( k->can_encrypt && key_is_useable (k))
929     {
930     rc = do_addkey (lv, key, -1, i, -1);
931     return rc;
932     }
933     }
934     else if (mode & KEYLIST_SIGN) {
935 twoaday 41 if (k->can_sign
936     && find_secret_key (key)
937     && key_is_useable (k)) {
938 werner 36 rc = do_addkey (lv, key, -1, i, -1);
939 twoaday 41 if (rc)
940 werner 36 return rc;
941     }
942     }
943     }
944    
945     return rc;
946 twoaday 133 }
947 werner 36
948    
949     int
950     keylist_sort (listview_ctrl_t lv, int sortby)
951 twoaday 150 {
952 werner 36 return listview_sort_items (lv, sortby, keylist_cmp_cb);
953     }
954    
955    
956     /* Check that the validity @validity is at least >= marginal. */
957     static int
958 twoaday 133 key_check_validity (gpgme_key_t key)
959     {
960     gpgme_user_id_t u;
961    
962     for (u=key->uids; u; u =u->next) {
963     if (u->validity >= GPGME_VALIDITY_MARGINAL)
964     return -1;
965     }
966    
967     return 0;
968 werner 36 }
969    
970    
971     /* Extract all selected recipients from the list @lv and return them
972     as a vector. @r_force_trust is >= 1 if one of the recipients is not
973     fully trusted. @r_count returns the number of selected keys.
974     Return value: the key list on success, NULL otherwise. */
975     gpgme_key_t*
976     keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)
977     {
978 twoaday 133 key_array_s *ka = NULL;
979     gpgme_key_t *keybuf, key;
980 werner 36 int count = 0, force_trust = 0;
981     int n, j, ka_pos = 0, rc = 0;
982     int k_pos=0;
983    
984 twoaday 133 n = listview_count_items (lv, 0);
985 werner 36
986 twoaday 133 ka = key_array_new (n);
987 werner 36 if (!ka)
988     BUG (NULL);
989    
990     keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
991     if (!keybuf)
992     BUG (NULL);
993    
994 twoaday 133 for (j = 0; j < n; j++) {
995     if (listview_get_item_state (lv, j) || n == 1) {
996     key = (gpgme_key_t)listview_get_item2 (lv, j);
997     if (!key)
998     BUG (0);
999     if (!key_check_validity (key) &&
1000     !key_array_search (ka, ka_pos, key->subkeys->keyid)) {
1001     char *warn = new char[512+strlen (key->uids->uid) + 1];
1002 werner 36 if (!warn)
1003     BUG (0);
1004     sprintf (warn,
1005     _("It is NOT certain that the key belongs to the person\n"
1006     "named in the user ID. If you *really* know what you are\n"
1007     "doing, you may answer the next question with yes\n"
1008     "\n"
1009 twoaday 133 "Use \"%s\" anyway?"), key->uids->uid);
1010 werner 36 if (reg_prefs.always_trust)
1011     rc = IDYES;
1012     else
1013     rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);
1014     if (rc == IDYES) {
1015 twoaday 133 keybuf[k_pos++] = key;
1016 werner 36 force_trust++;
1017     ka[ka_pos].checked = 1;
1018 twoaday 133 strcpy (ka[ka_pos++].keyid, key->subkeys->keyid);
1019 werner 36 count++;
1020     }
1021     free_if_alloc (warn);
1022     }
1023     else {
1024 twoaday 133 keybuf[k_pos++] = key;
1025 werner 36 count++;
1026     }
1027     }
1028     }
1029     key_array_release (ka);
1030     if (r_force_trust)
1031     *r_force_trust = force_trust;
1032     if (r_count)
1033     *r_count = count;
1034     return keybuf;
1035     }
1036    
1037    
1038     static int
1039 twoaday 133 keylist_get_keyflags (gpgme_key_t key)
1040 werner 36 {
1041 twoaday 133 int flags = KEYFLAG_NONE;
1042 werner 36
1043 twoaday 133 if (key->revoked)
1044     flags |= KEYFLAG_REVOKED;
1045     if (key->expired)
1046     flags |= KEYFLAG_EXPIRED;
1047     if (key->disabled)
1048     flags |= KEYFLAG_DISABLED;
1049 werner 36
1050     return flags;
1051 twoaday 133 }
1052 werner 36
1053    
1054     gpgme_key_t*
1055     keylist_enum_recipients (listview_ctrl_t lv, int listype, int *r_count)
1056     {
1057 twoaday 133 gpgme_key_t *rset;
1058     gpgme_key_t key;
1059 werner 36 int i, n, id, k_pos=0;
1060    
1061     n = listview_count_items (lv, 0);
1062     if (!n)
1063     return 0;
1064     rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
1065     if (!rset)
1066     BUG (NULL);
1067 twoaday 133 for (i = 0; i < n; i++) {
1068     if (!listview_get_item_state (lv, i))
1069 werner 36 continue;
1070 twoaday 133 key = (gpgme_key_t)listview_get_item2 (lv, i);
1071     if (!key)
1072     BUG (0);
1073     switch (listype) {
1074 werner 36 case KEYLIST_LIST:
1075 twoaday 133 if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) {
1076     id = printf_box (_("Recipients"), MB_INFO|MB_YESNO,
1077     _("KeyID %s.\nDo you really want to export a revoked key?"),
1078     key->uids->uid);
1079     if (id == IDNO)
1080     continue;
1081 werner 36 }
1082     break;
1083     }
1084 twoaday 133 rset[k_pos++] = key;
1085 werner 36 }
1086     if (r_count)
1087     *r_count = k_pos;
1088     return rset;
1089 twoaday 133 }
1090 werner 36
1091    
1092     void
1093 twoaday 133 seclist_destroy (keylist_t *list)
1094 werner 36 {
1095     keylist_t l2;
1096     while (*list) {
1097     l2 = (*list)->next;
1098     safe_free (*list);
1099     *list = l2;
1100     }
1101     list = NULL;
1102 twoaday 133 }
1103 werner 36
1104    
1105     void
1106     seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)
1107     {
1108     gpg_keycache_t kc = NULL;
1109     gpgme_key_t key = NULL;
1110     HWND kb;
1111     keylist_t list=NULL, l, l2;
1112     long pos = 0;
1113    
1114     SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
1115     kb = GetDlgItem (dlg, ctlid);
1116     kc = keycache_get_ctx (0);
1117     if (!kc)
1118     BUG (0);
1119     gpg_keycache_rewind (kc);
1120    
1121     while (!gpg_keycache_next_key (kc, 1, &key)) {
1122 twoaday 41 char *inf = NULL, *uid = NULL;
1123     const char *id;
1124     const char *keyid;
1125 werner 36 int algo;
1126     size_t size = 0;
1127    
1128     if (flags & KEYLIST_FLAG_SHORT)
1129     id = key->uids->name;
1130     else
1131     id = key->uids->uid;
1132     keyid = key->subkeys->keyid;
1133     algo = key->subkeys->pubkey_algo;
1134     if (!id || !keyid)
1135     continue;
1136 twoaday 41 if (key->disabled || !key_is_useable (key->subkeys))
1137     continue;
1138 werner 36
1139     uid = utf8_to_wincp (id, strlen (id));
1140 twoaday 133 size = strlen (uid) + strlen (keyid) + 32;
1141 werner 36 inf = new char[size+1];
1142 twoaday 133 if (!inf)
1143     BUG (NULL);
1144     _snprintf (inf, size, "%s (%s/0x%s)", uid,
1145 werner 36 get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);
1146     combox_add_string (kb, inf);
1147     free_if_alloc (inf);
1148     free (uid);
1149     l = (struct keylist_s *)calloc (1, sizeof * l);
1150     if (!l)
1151     BUG (0);
1152     l->key = key;
1153     if (!list)
1154     list = l;
1155     else {
1156     for( l2 = list; l2->next; l2 = l2->next )
1157     ;
1158     l2->next = l;
1159     }
1160     }
1161 twoaday 133 for (pos = 0, l2=list; pos < SendMessage (kb, CB_GETCOUNT, 0, 0);
1162     pos++, l2=l2->next)
1163     SendMessage (kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key);
1164     SendMessage (kb, CB_SETCURSEL, 0, 0);
1165 werner 36 *ret_list = list;
1166     }
1167    
1168    
1169     /* Select a secret key from the combo box with the ID @ctlid.
1170     Return the code on success in @ret_key. */
1171     int
1172     seclist_select_key (HWND dlg, int ctlid, gpgme_key_t *ret_key)
1173     {
1174     int pos;
1175     DWORD k = 0;
1176    
1177     pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
1178     if (pos == CB_ERR) {
1179     msg_box (dlg, _("No key was selected."), _("Secret Key List"), MB_ERR);
1180     *ret_key = NULL;
1181     }
1182     else {
1183     k = SendDlgItemMessage (dlg, ctlid, CB_GETITEMDATA, pos, 0);
1184     *ret_key = (gpgme_key_t)k;
1185     }
1186     return k? 0 : -1;
1187     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26