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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 109 - (hide annotations)
Fri Dec 2 07:32:13 2005 UTC (19 years, 3 months ago) by twoaday
File size: 25562 byte(s)
2005-12-01  Timo Schulz  <ts@g10code.com>
 
        * wptClipVerifyDlg.cpp (clipverify_dlg_proc): Use new semantic
        for get_gpg_sigstat().
        * wptGPGME.cpp (get_gpg_sigstat): New. It is now a function.
        As a macro strings will not be translated at runtime.
        * wptKeyserverDlg.cpp (hkp_recv_key): Properly detect if we
        need to update the cache. Thanks to Jan-Oliver.
        * wptKeyImportStatusDlg.cpp (import_status_dlg_proc): Localized.
         

Prepare a new release.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26