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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide annotations)
Fri Oct 28 07:15:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 25701 byte(s)
A lot of bug fixes. See ChangeLog.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26