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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (hide annotations)
Mon Oct 17 08:49:30 2005 UTC (19 years, 4 months ago) by twoaday
File size: 26281 byte(s)
More bug fixes all over the place.
See ChangeLog for details.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26