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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 128 - (hide annotations)
Mon Dec 19 13:05:59 2005 UTC (19 years, 2 months ago) by twoaday
File size: 25783 byte(s)
2005-12-17  Timo Schulz  <ts@g10code.com>
 
        * wptUTF8.cpp: Removed unused charset array.
        * wptSigList.cpp (siglist_build): Increase size for 'class'
        column.
        * wptGPG.cpp (get_gnupg_path): Simplified.
        * WinPT.cpp (load_gpg_env): New.
        (check_crypto_engine): Return type is now bool.
        * wptRegistry.cpp (is_gpg4win_installed): New.
        * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): More consistent
        dialog design.
        * wptKeyManagerDlg.cpp (translate_menu_strings): New.
        (translate_popupmenu_strings): New.
        * wptKeyEditDlgs.cpp (is_jpg_file): New.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26