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

Annotation of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations)
Wed Jul 27 11:17:22 2005 UTC (19 years, 7 months ago) by twoaday
File size: 25578 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * wptMainProc.cpp (winpt_main_proc): Take care for shutdown
        messages and make sure WinPT make a keyring backup in this case.
        * wptGPGME.cpp (keycache_reload): Do not rebuild the signature
        cache each time. Just do it on startup.
        * wptKeyManager.cpp (km_key_is_v3): Use new ATTR_VERSION.
        * wptKeyEditDlgs.cpp (keyedit_main_dlg_proc): Assume the v3 flag
        was set by the calling function.
        * wptKeyGenDlg.cpp (keygen_wizard_dlg_proc): Ask for backups.
        (keygen_dlg_proc): Only add the generated key to the keycache
        and do not reload the entire cache.
        * wptKeyManager.cpp (km_delete_keys): Store the number of keys
        because in each loop iteration it will be new calculated.
        * wptListView.cpp (listview_del_items): Likewise.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Directly add the
        generated key to the list instead of reloading the entire cache.
        * wptKeyEditDlgs.cpp (parse_preflist): Support fpr SHAnnn.


1 twoaday 2 /* wptKeylist.cpp - Keylist element
2     * Copyright (C) 2001-2004 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    
22     #include <windows.h>
23     #include <commctrl.h>
24     #include <time.h>
25    
26     #include "wptCommonCtl.h"
27     #include "wptTypes.h"
28     #include "wptGPG.h"
29     #include "wptKeylist.h"
30     #include "wptKeyManager.h"
31     #include "wptW32API.h"
32     #include "wptNLS.h"
33     #include "wptErrors.h"
34     #include "wptUTF8.h"
35     #include "wptRegistry.h"
36    
37     static struct listview_column_s klist_enc[] = {
38     {0, 242, (char *)_("User ID")},
39     {1, 80, (char *)_("Key ID")},
40     {3, 46, (char *)_("Size")},
41     {4, 50, (char *)_("Cipher")},
42     {5, 70, (char *)_("Validity")},
43     {0, 0, NULL}
44     };
45     #define KLIST_ENC_ITEMS (DIM(klist_enc) -1)
46    
47     static struct listview_column_s klist[] = {
48     {0, 242, (char *)_("User ID")},
49     {1, 78, (char *)_("Key ID")},
50     {2, 52, (char *)_("Type")},
51     {3, 68, (char *)_("Size")},
52     {4, 66, (char *)_("Cipher")},
53     {5, 70, (char *)_("Validity")},
54     {6, 40, (char *)_("Trust")},
55     {7, 72, (char *) _("Creation")},
56     {0, 0, NULL}
57     };
58     #define KLIST_ITEMS (DIM(klist) - 1)
59    
60     struct key_array_s {
61     char keyid[32];
62     int checked;
63     };
64    
65     static int find_secret_key( gpgme_key_t key );
66    
67    
68     static key_array_s*
69     key_array_new( size_t items )
70     {
71     key_array_s *ka;
72     size_t j;
73    
74     if( items == 0 )
75     return NULL;
76     ka = new key_array_s[items + 1];
77     if( ka == NULL )
78     return NULL;
79     for ( j = 0; j < items; j++ )
80     ka[j].checked = 0;
81     return ka;
82     } /* key_array_new */
83    
84    
85     static void
86     key_array_release( key_array_s *ka )
87     {
88     free_if_alloc( ka );
89     } /* key_array_release */
90    
91    
92     static int
93     key_array_search( key_array_s *ka, size_t items, const char *keyid )
94     {
95     size_t j;
96    
97     /* fixme: we need a faster search method */
98     for( j = 0; j < items; j++ ) {
99     if( !strcmp( keyid, ka[j].keyid ) )
100     return 1;
101     }
102    
103     return 0;
104     } /* key_array_search */
105    
106    
107     const char*
108     get_key_algo( gpgme_key_t key, int keyidx )
109     {
110     static char algo_id[128];
111     int n, algo_main, algo_sub;
112    
113     if( keyidx > 0 ) {
114     algo_main = gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, keyidx-1 );
115     _snprintf( algo_id, sizeof algo_id-1, "%s",
116     gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo_main ) );
117     return algo_id;
118     }
119     algo_main = gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, 0 );
120     n = gpgme_key_count_items( key, GPGME_ATTR_KEYID );
121     if( n > 1 ) {
122     algo_sub = gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, n-1 );
123     _snprintf( algo_id, sizeof algo_id - 1, "%s/%s",
124     gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo_main ),
125     gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo_sub ) );
126     return algo_id;
127     }
128     return gpgme_key_expand_attr( GPGME_ATTR_ALGO, algo_main );
129     } /* get_key_algo */
130    
131    
132     const char*
133     get_key_created( long timestamp )
134     {
135     static char timebuf[128];
136     struct tm *warp;
137    
138     if( timestamp == 0 || timestamp == -1 )
139     return "????-??-??";
140     warp = localtime( &timestamp );
141     _snprintf( timebuf, sizeof timebuf - 1, "%04d-%02d-%02d",
142     warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );
143     return timebuf;
144     } /* get_key_created */
145    
146    
147     const char*
148     get_key_expire_date( long timestamp )
149     {
150     static char timebuf[64];
151     struct tm *warp;
152    
153     if( !timestamp )
154     return _("Never");
155     warp = localtime( &timestamp );
156     _snprintf( timebuf, sizeof timebuf -1, "%04d-%02d-%02d",
157     warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );
158     return timebuf;
159     } /* get_key_expire_date */
160    
161    
162     const char *
163     get_key_type( gpgme_key_t key )
164     {
165     int valid = gpgme_key_get_ulong_attr( key, GPGME_ATTR_VALIDITY, NULL, 0 );
166     if( find_secret_key( key ) || valid == GPGME_VALIDITY_ULTIMATE )
167     return _("Key Pair");
168     return _("Public Key");
169     } /* get_key_type */
170    
171    
172     const char *
173     get_key_size( gpgme_key_t key, int keyidx )
174     {
175     static char size_id[64];
176     int n, size_main, size_sub;
177    
178     if( keyidx > 0 ) {
179     size_main = gpgme_key_get_ulong_attr( key, GPGME_ATTR_LEN, NULL, keyidx-1 );
180     _snprintf( size_id, sizeof size_id-1, "%d", size_main );
181     return size_id;
182     }
183     size_main = gpgme_key_get_ulong_attr( key, GPGME_ATTR_LEN, NULL, 0 );
184     n = gpgme_key_count_items( key, GPGME_ATTR_KEYID );
185     if( n > 1 ) {
186     size_sub = gpgme_key_get_ulong_attr( key, GPGME_ATTR_LEN, NULL, n-1 );
187 twoaday 20 _snprintf( size_id, sizeof (size_id) - 1, "%d/%d", size_main, size_sub );
188 twoaday 2 return size_id;
189     }
190 twoaday 20 _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main );
191 twoaday 2 return size_id;
192     } /* get_key_size */
193    
194    
195     const char *
196     get_key_fpr( gpgme_key_t key )
197     {
198     static char fpr_md[64];
199     const char * fpr;
200 twoaday 20 char t[16], tmp[40];
201 twoaday 2 size_t i;
202    
203 twoaday 20 memset (fpr_md, 0, sizeof (fpr_md));
204     fpr = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
205     if (!fpr || !*fpr) {
206     memset (tmp, '0', 40);
207     fpr = tmp;
208 twoaday 2 }
209 twoaday 20 for (i = 0; i < strlen (fpr) / 4; i++) {
210     sprintf (t, "%c%c%c%c ", fpr[4*i], fpr[4*i+1], fpr[4*i+2], fpr[4*i+3]);
211     strcat (fpr_md, t);
212     }
213 twoaday 2 return fpr_md;
214     } /* get_key_fpr */
215    
216    
217    
218     static const char *
219     get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)
220     {
221     if (key)
222     val = gpgme_key_get_ulong_attr (key, GPGME_ATTR_OTRUST, NULL, uididx);
223     switch (val) {
224     case GPGME_TRUST_UNKNOWN:
225     case GPGME_TRUST_DONTKNOW:
226     return "None";
227     case GPGME_TRUST_NEVER:
228     return "Never";
229     case GPGME_TRUST_MARGINAL:
230     return "Marginal";
231     case GPGME_TRUST_FULLY:
232     case GPGME_TRUST_ULTIMATE:
233     return "Full";
234     }
235     return "";
236     }
237    
238    
239     const char *
240     get_key_trust (gpgme_key_t key, int uididx, int listmode)
241     {
242     return get_key_trust2 (key, 0, uididx, listmode);
243     }
244    
245    
246     const char *
247     get_key_trust_str (int val)
248     {
249     return get_key_trust2 (NULL, val, 0, 0);
250     }
251    
252    
253     char*
254     get_key_status( gpgme_key_t key, int uididx, int listmode )
255     {
256     char fmt[128], * p;
257     const char * attr;
258     int i = 0;
259     u32 key_attr =0;
260    
261     if( uididx < 0 || gpgme_key_count_items( key, GPGME_ATTR_USERID ) > uididx )
262     uididx = 0;
263     memset( fmt, 0, sizeof fmt );
264     if( listmode ) {
265     fmt[i++] = '[';
266     if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_REVOKED, NULL, 0 ) )
267     fmt[i++] = 'R';
268     if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_EXPIRED, NULL, 0 ) )
269     fmt[i++] = 'E';
270     if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_DISABLED, NULL, 0 ) )
271     fmt[i++] = 'D';
272     fmt[i++] = ']';
273     fmt[i++] = ' ';
274     }
275     key_attr = gpgme_key_get_ulong_attr( key, GPGME_ATTR_VALIDITY, NULL, uididx );
276     attr = gpgme_key_expand_attr( GPGME_ATTR_VALIDITY, key_attr );
277     p = new char[strlen( fmt ) + 1 + strlen( attr ) + 2];
278     sprintf( p, "%s%s", fmt, attr );
279     return p;
280     } /* get_key_status */
281    
282    
283     static inline int
284     int_cmp( int a, int b )
285     {
286     if( a == b ) return 0;
287     else if( a > b ) return 1;
288     else return -1;
289     return 0;
290     }
291    
292    
293     static int CALLBACK
294     keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
295     {
296     static char tmpa[128], tmpb[128];
297     gpgme_key_t a, b;
298     const char *aa = NULL, *bb = NULL;
299     long ta, tb;
300     int na = 0, nb = 0;
301     int cmpresult = 0;
302    
303     a = (gpgme_key_t)first;
304     b = (gpgme_key_t)second;
305    
306     switch( sortby & ~KEYLIST_SORT_DESC ) {
307     case GPGME_ATTR_USERID:
308     aa = gpgme_key_get_string_attr( a, GPGME_ATTR_USERID, NULL, 0 );
309     bb = gpgme_key_get_string_attr( b, GPGME_ATTR_USERID, NULL, 0 );
310     cmpresult = strcmpi( aa? aa : "", bb? bb : "" );
311     break;
312    
313     case GPGME_ATTR_KEYID:
314     aa = gpgme_key_get_string_attr( a, GPGME_ATTR_KEYID, NULL, 0) + 8;
315     bb = gpgme_key_get_string_attr( b, GPGME_ATTR_KEYID, NULL, 0) + 8;
316     cmpresult = strcmpi( aa? aa : "", bb? bb : "" );
317     break;
318    
319     case GPGME_ATTR_VALIDITY:
320     na = gpgme_key_get_ulong_attr( a, GPGME_ATTR_VALIDITY, NULL, 0 );
321     nb = gpgme_key_get_ulong_attr( b, GPGME_ATTR_VALIDITY, NULL, 0 );
322     cmpresult = int_cmp( na, nb );
323     break;
324    
325     case GPGME_ATTR_OTRUST:
326     na = gpgme_key_get_ulong_attr (a, GPGME_ATTR_OTRUST, NULL, 0);
327     nb = gpgme_key_get_ulong_attr (b, GPGME_ATTR_OTRUST, NULL, 0);
328     cmpresult = int_cmp (na, nb);
329     break;
330    
331     case GPGME_ATTR_IS_SECRET:
332     aa = gpgme_key_get_string_attr( a, GPGME_ATTR_KEYID, NULL, 0 );
333     bb = gpgme_key_get_string_attr( b, GPGME_ATTR_KEYID, NULL, 0 );
334     get_seckey( aa, &a );
335     get_seckey( bb, &b );
336     if( a )
337     na = gpgme_key_get_ulong_attr( a, GPGME_ATTR_IS_SECRET, NULL, 0 );
338     if( b )
339     nb = gpgme_key_get_ulong_attr( b, GPGME_ATTR_IS_SECRET, NULL, 0 );
340     cmpresult = int_cmp( na, nb );
341     break;
342    
343     case GPGME_ATTR_LEN:
344     na = gpgme_key_get_ulong_attr( a, GPGME_ATTR_LEN, NULL, 0 );
345     nb = gpgme_key_get_ulong_attr( b, GPGME_ATTR_LEN, NULL, 0 );
346     cmpresult = int_cmp( na, nb );
347     break;
348    
349     case GPGME_ATTR_CREATED:
350     ta = gpgme_key_get_ulong_attr( a, GPGME_ATTR_CREATED, NULL, 0 );
351     tb = gpgme_key_get_ulong_attr( b, GPGME_ATTR_CREATED, NULL, 0 );
352     strcpy( tmpa, get_key_created( ta ) ); aa = tmpa;
353     strcpy( tmpb, get_key_created( tb ) ); bb = tmpb;
354     cmpresult = strcmpi( aa? aa : "", bb? bb : "" );
355     break;
356    
357     case GPGME_ATTR_ALGO:
358     aa = gpgme_key_get_string_attr (a, GPGME_ATTR_ALGO, NULL, 0);
359     bb = gpgme_key_get_string_attr (b, GPGME_ATTR_ALGO, NULL, 0);
360     cmpresult = strcmpi (aa? aa : "", bb? bb : "");
361     break;
362    
363     default:
364     aa = gpgme_key_get_string_attr( a, GPGME_ATTR_USERID, NULL, 0 );
365     bb = gpgme_key_get_string_attr( b, GPGME_ATTR_USERID, NULL, 0 );
366     cmpresult = strcmpi( aa? aa : "", bb? bb : "" );
367     break;
368     }
369     if (sortby & KEYLIST_SORT_DESC)
370     return (~cmpresult + 1);
371     else
372     return cmpresult;
373     } /* keylist_cmp_cb */
374    
375    
376     static const char*
377     calc_validity( gpg_group_t grp )
378     {
379     int level = 0, valid;
380     gpg_member_t mbr;
381     gpgme_key_t key;
382    
383     for( mbr = grp->list; mbr; mbr = mbr->next ) {
384     if( get_pubkey( mbr->name, &key ) )
385     continue;
386     valid = gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_VALIDITY, NULL, 0 );
387     switch( valid ) {
388     case GPGME_VALIDITY_MARGINAL:
389     case GPGME_VALIDITY_NEVER:
390     case GPGME_VALIDITY_UNDEFINED:
391     return gpgme_key_expand_attr( GPGME_ATTR_VALIDITY, valid );
392     }
393     }
394     return gpgme_key_expand_attr( GPGME_ATTR_VALIDITY, GPGME_VALIDITY_FULL );
395     } /* calc_validity */
396    
397    
398     int
399     keylist_add_groups( listview_ctrl_t lv )
400     {
401     gpg_optfile_t gh;
402     gpg_group_t grp;
403     const char *valid;
404    
405     gh = km_groupdb_open( );
406     if( !gh )
407     return WPTERR_FILE_OPEN;
408    
409     for( grp = gh->grp; grp; grp = grp->next ) {
410     valid = calc_validity( grp );
411     listview_add_item( lv, " " );
412     listview_add_sub_item( lv, 0, 0, grp->name );
413     listview_add_sub_item( lv, 0, 1, "gpg_group_t" );
414     listview_add_sub_item( lv, 0, 2, "" );
415     listview_add_sub_item( lv, 0, 3, "Unknown" );
416     listview_add_sub_item( lv, 0, 4, valid?valid : "Unknown" );
417     }
418     return 0;
419     } /* keylist_add_groups */
420    
421    
422     static int
423     keylist_build( listview_ctrl_t *r_lv, HWND ctrl, int mode )
424     {
425     listview_ctrl_t lv;
426     listview_column_t col;
427     int j, n = 0;
428     int kl_nolist = 0, rc = 0;
429    
430     rc = listview_new( &lv );
431     if( rc )
432     return rc;
433    
434     lv->ctrl = ctrl;
435     if( (mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN) ) {
436     col = klist_enc;
437     n = KLIST_ENC_ITEMS;
438     }
439     else if( (mode & KEYLIST_SIGN) ) {
440     col = klist_enc;
441     n = KLIST_ENC_ITEMS - 1;
442     }
443     else {
444     col = klist;
445     n = KLIST_ITEMS;
446     }
447    
448     for( j = 0; j < n; j++ )
449     listview_add_column( lv, &col[j] );
450     listview_set_ext_style( lv );
451     *r_lv = lv;
452    
453     return 0;
454     } /* keylist_build */
455    
456    
457     static void
458 twoaday 20 keylist_load_keycache (listview_ctrl_t lv, int mode,
459     gpgme_keycache_t pubkc, gpgme_keycache_t seckc)
460 twoaday 2 {
461     gpgme_error_t err = GPGME_No_Error;
462     gpgme_key_t key, skey;
463     const char * keyid;
464    
465     if( pubkc && seckc ) {
466     gpgme_keycache_rewind( pubkc );
467     while( !gpgme_keycache_next_key( pubkc, 0, &key ) ) {
468     keyid = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, 0 );
469     if( keyid && !gpgme_keycache_find_key( seckc, keyid, 0, &skey ) )
470 twoaday 20 keylist_add_key (lv, mode, key);
471 twoaday 2 }
472     }
473 twoaday 20 else if (pubkc) {
474     gpgme_keycache_rewind (pubkc);
475     while (!err) {
476     err = gpgme_keycache_next_key (pubkc, 0, &key);
477     if (!err)
478     keylist_add_key (lv, mode, key);
479 twoaday 2 }
480     }
481     } /* keylist_load_keycache */
482    
483    
484     listview_ctrl_t
485     keylist_load( HWND ctrl, gpgme_keycache_t pubkc, gpgme_keycache_t seckc,
486     int mode, int sortby )
487     {
488     listview_ctrl_t lv;
489     int rc = 0;
490    
491     rc = keylist_build( &lv, ctrl, mode );
492     if( rc )
493     return NULL;
494     keylist_load_keycache( lv, mode, pubkc, seckc );
495     keylist_sort( lv, sortby );
496     if( (mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN) )
497     keylist_add_groups( lv );
498     return lv;
499     } /* keylist_load */
500    
501    
502     int
503     keylist_reload( listview_ctrl_t lv, gpgme_keycache_t pubkc, int mode, int sortby )
504     {
505     listview_del_all( lv );
506     keylist_load_keycache( lv, mode, pubkc, NULL );
507     keylist_sort( lv, sortby );
508     return 0;
509     } /* keylist_reload */
510    
511    
512     void
513     keylist_delete( listview_ctrl_t lv )
514     {
515     if( lv ) {
516     listview_release( lv );
517     }
518     } /* keylist_delete */
519    
520    
521     static int
522     find_secret_key( gpgme_key_t key )
523     {
524     const char * keyid;
525     gpgme_key_t skey;
526    
527     keyid = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, 0 );
528     if( !keyid )
529     return 0;
530     get_seckey( keyid, &skey );
531     return skey? 1 : 0;
532     } /* find_secret_key */
533    
534    
535     static int
536     do_addkey( listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list )
537     {
538     LV_ITEM lvi;
539     gpgme_key_t seckey;
540     char fmt[128];
541     const char *attr;
542     u32 key_attr;
543     int idx = 0;
544    
545     /* we check the pubkey algorithm here to make sure that no ElGamal
546     sign+encrypt key is used in _any_ mode */
547     if( list != 1 && gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, 0 )
548     == GPGME_PK_ELG_ES )
549     return 0;
550    
551     if( listview_add_item( lv, " " ) )
552     return WPTERR_GENERAL;
553    
554     attr = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
555     memset( &lvi, 0, sizeof lvi );
556     lvi.mask = LVIF_TEXT | LVIF_PARAM;
557     lvi.pszText = (char *)attr;
558     lvi.lParam = (LPARAM )key;
559     if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
560     return WPTERR_GENERAL;
561    
562     if( uididx == -1 ) {
563     /* request the primary user-id of the key. */
564     attr = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
565     uididx = 0;
566     }
567     else {
568     if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_UID_REVOKED, NULL, uididx ) || uididx < 0 )
569     uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */
570     attr = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, uididx );
571     }
572     if( attr == NULL || strlen( attr ) < 5 ) { /* normal userids are >= 5 chars */
573     attr = _("Invalid User ID");
574     listview_add_sub_item( lv, 0, idx++, attr );
575     }
576     else {
577     char * uid = utf8_to_wincp (attr, strlen (attr));
578     if( uid ) {
579     listview_add_sub_item( lv, 0, idx++, uid );
580     free( uid );
581     }
582     }
583     attr = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, keyidx );
584     if( attr ) {
585     _snprintf( fmt, sizeof fmt -1, "0x%s", attr + 8 );
586     listview_add_sub_item( lv, 0, idx++, fmt );
587     }
588    
589     if( list > 0 ) {
590     attr = find_secret_key( key )? "pub/sec" : "pub";
591     if( strchr( attr, '/' ) ) {
592     const char * kid;
593     kid = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, 0 );
594     get_seckey( kid, &seckey );
595     if( gpgme_key_get_ulong_attr( seckey, GPGME_ATTR_DIVERT_CARD, NULL, 0 ) )
596     attr = "pub/crd";
597     }
598     listview_add_sub_item( lv, 0, idx++, attr );
599     }
600     if( lv->cols >= 2 ) {
601     attr = get_key_size( key, list==-1? keyidx+1 : 0 );
602     if( attr )
603     listview_add_sub_item( lv, 0, idx++, attr );
604     }
605     if( lv->cols >= 3 ) {
606     attr = get_key_algo( key, list==-1? keyidx+1 : 0 );
607     if( attr )
608     listview_add_sub_item( lv, 0, idx++, attr );
609     }
610     if( lv->cols >= 4 ) {
611     char * status = get_key_status( key, uididx, list>0? 1 : 0 );
612     if( !status )
613     return WPTERR_GENERAL;
614     listview_add_sub_item( lv, 0, idx++, status );
615     free_if_alloc( status );
616     }
617     if (lv->cols >= 5) {
618     const char * s = get_key_trust (key, uididx, list>0? 1 : 0);
619     listview_add_sub_item (lv, 0, idx++, s);
620     }
621     if( lv->cols >= 6 ) {
622     key_attr = gpgme_key_get_ulong_attr( key, GPGME_ATTR_CREATED, NULL, keyidx );
623     if( key_attr ) {
624     attr = gpgme_key_expand_attr( GPGME_ATTR_CREATED, key_attr );
625     listview_add_sub_item( lv, 0, idx++, attr );
626     }
627     }
628    
629     return 0;
630     } /* do_addkey */
631    
632    
633 twoaday 20 int
634 twoaday 2 keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)
635     {
636     int uids, rc = 0, i, n = 0;
637    
638 twoaday 20 for (i = 0; i < gpgme_key_count_items (key, GPGME_ATTR_KEYID); i++) {
639     if (gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_INVALID, NULL, i))
640 twoaday 2 continue; /* Don't use invalid keys */
641    
642 twoaday 20 if (mode & KEYLIST_ALL) {
643     uids = gpgme_key_count_items (key, GPGME_ATTR_USERID);
644     rc = do_addkey (lv, key, uids, i, 0);
645 twoaday 2 if( rc )
646     return rc;
647     }
648 twoaday 20 else if (mode & KEYLIST_LIST)
649     return do_addkey (lv, key, -1, i, 1);
650     else if (mode & KEYLIST_ENCRYPT) {
651 twoaday 2 if (gpgme_key_get_cability (key, GPGME_ATTR_CAN_ENCRYPT, i)
652     && gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_USABLE, NULL, i))
653     {
654     if (mode & KEYLIST_FLAG_FILE ) {
655     rc = do_addkey( lv, key, -1, i, -1 );
656     if( rc )
657     return rc;
658     }
659     else {
660     for( uids = 0; uids < gpgme_key_count_items( key, GPGME_ATTR_USERID ); uids++ ) {
661     rc = do_addkey( lv, key, uids, i, -1 );
662     if( rc )
663     return rc;
664     }
665     }
666     }
667     }
668 twoaday 20 else if (mode & KEYLIST_ENCRYPT_MIN) {
669 twoaday 2 if( gpgme_key_get_cability (key, GPGME_ATTR_CAN_ENCRYPT, i)
670     && gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_USABLE, NULL, i))
671     {
672     rc = do_addkey (lv, key, -1, i, -1);
673     return rc;
674     }
675     }
676 twoaday 20 else if (mode & KEYLIST_SIGN) {
677 twoaday 2 if ( gpgme_key_get_cability( key, GPGME_ATTR_CAN_SIGN, i )
678     && find_secret_key( key )
679     && gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_USABLE, NULL, i))
680     {
681     rc = do_addkey (lv, key, -1, i, -1);
682     if( rc )
683     return rc;
684     }
685     }
686     }
687    
688     return rc;
689     } /* keylist_add_key */
690    
691    
692     int
693     keylist_sort (listview_ctrl_t lv, int sortby)
694     {
695     return listview_sort_items( lv, sortby, keylist_cmp_cb );
696     } /* keylist_sort */
697    
698    
699     static int
700     key_check_validity (const char *validity)
701     {
702     if (strstr (validity, "Unknown")
703     || strstr (validity, "Undefined")
704     || strstr (validity, "Never"))
705     return 0;
706     return 1;
707     } /* key_check_validity */
708    
709    
710     gpgme_recipients_t
711     keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)
712     {
713     int count = 0, force_trust = 0;
714     int n, j, ka_pos = 0, rc = 0;
715     char keyid[32], valid[32], id[100];
716     key_array_s *ka = NULL;
717     gpgme_error_t err;
718     gpgme_recipients_t rset;
719    
720     err = gpgme_recipients_new( &rset );
721     if( err )
722     BUG( NULL );
723    
724     n = listview_count_items( lv, 0 );
725     ka = key_array_new( n );
726     if ( !ka )
727     BUG( NULL );
728    
729     for( j = 0; j < n; j++ ) {
730     if( listview_get_item_state( lv, j ) || n == 1 ) {
731     listview_get_item_text( lv, j, 1, keyid, sizeof keyid - 1 );
732     listview_get_item_text( lv, j, 4, valid, sizeof valid -1 );
733     listview_get_item_text( lv, j, 0, id, sizeof id-1 );
734     if( !strncmp( keyid, "gpg_group_t", 5 ) ) {
735     listview_get_item_text( lv, j, 0, id, sizeof id -1 );
736     rc = km_groupdb_expand_recipients( id, rset );
737     if( rc )
738     force_trust++;
739     }
740     else if( !key_check_validity( valid )
741     && !key_array_search( ka, ka_pos, keyid ) ) {
742     char *warn = new char[512+strlen (id) + 1];
743     if (!warn)
744     BUG (0);
745     sprintf (warn,
746     _("It is NOT certain that the key belongs to the person\n"
747     "named in the user ID. If you *really* know what you are\n"
748     "doing, you may answer the next question with yes\n"
749     "\n"
750     "Use \"%s\" anyway?"), id);
751 twoaday 20 if (reg_prefs.always_trust)
752 twoaday 2 rc = IDYES;
753     else
754     rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);
755 twoaday 20 if (rc == IDYES) {
756 twoaday 2 gpgme_recipients_add_name_with_validity (rset, keyid, GPGME_VALIDITY_FULL);
757     force_trust++;
758     ka[ka_pos].checked = 1;
759     strcpy (ka[ka_pos++].keyid, keyid);
760     }
761     free_if_alloc (warn);
762     }
763     else {
764     listview_get_item_text( lv, j, 1, keyid, sizeof keyid -1 );
765     gpgme_recipients_add_name( rset, keyid );
766     count++;
767     }
768     }
769     }
770 twoaday 20 key_array_release (ka);
771     if (r_force_trust)
772 twoaday 2 *r_force_trust = force_trust;
773 twoaday 20 if (r_count)
774 twoaday 2 *r_count = count;
775     return rset;
776     } /* keylist_get_recipients */
777    
778    
779     static int
780     keylist_get_keyflags (const char *buf, size_t buflen)
781     {
782     int c = 0, flags = 0;
783    
784     if( *buf != '[' )
785     return KEYFLAG_NONE;
786     while (buf && c != ']')
787     {
788     c = *buf++;
789     if (c == 'R')
790     flags |= KEYFLAG_REVOKED;
791     if (c == 'E')
792     flags |= KEYFLAG_EXPIRED;
793     if (c == 'D')
794     flags |= KEYFLAG_DISABLED;
795     }
796    
797     return flags;
798     } /* keylist_get_keyflags */
799    
800    
801     gpgme_recipients_t
802     keylist_enum_recipients (listview_ctrl_t lv, int listype)
803     {
804     gpgme_recipients_t rset;
805     int i, n, id;
806     char keyid[32], t[128], t2[128];
807    
808     if( gpgme_recipients_new( &rset ) )
809     BUG( NULL );
810    
811     n = listview_count_items( lv, 0 );
812     for( i = 0; i < n; i++ ) {
813     if( !listview_get_item_state( lv, i ) )
814     continue;
815     listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
816     switch( listype ) {
817     case KEYLIST_LIST:
818     listview_get_item_text( lv, i, 5, t, sizeof t - 1 );
819     if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) {
820     _snprintf( t2, sizeof t2 -1,
821     _("KeyID %s.\nDo you really want to export a revoked key?"), keyid );
822     id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO );
823     if( id == IDNO )
824     continue;
825     }
826     break;
827     }
828     gpgme_recipients_add_name( rset, keyid );
829     }
830     return rset;
831     } /* keylist_enum_recipients */
832    
833    
834     void
835     seclist_destroy (keylist_t * list)
836     {
837     keylist_t l2;
838     while (*list) {
839     l2 = (*list)->next;
840     safe_free (*list);
841     *list = l2;
842     }
843     list = NULL;
844     } /* seclist_destroy */
845    
846    
847     void
848     seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)
849     {
850     gpgme_keycache_t kc = NULL;
851     gpgme_key_t key = NULL;
852     HWND kb;
853     keylist_t list=NULL, l, l2;
854     gpgme_attr_t name_attr = GPGME_ATTR_USERID;
855     long pos = 0;
856    
857     SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
858     kb = GetDlgItem (dlg, ctlid);
859     kc = keycache_get_ctx (0);
860     if (!kc)
861     BUG (0);
862     gpgme_keycache_rewind (kc);
863    
864     if (flags & KEYLIST_FLAG_SHORT)
865     name_attr = GPGME_ATTR_NAME;
866     while (!gpgme_keycache_next_key (kc, 1, &key)) {
867     char * inf = NULL, * uid = NULL;
868     const char * id;
869     const char * keyid;
870     int algo;
871     size_t size = 0;
872    
873     id = gpgme_key_get_string_attr (key, name_attr, NULL, 0);
874     keyid = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0);
875     algo = gpgme_key_get_ulong_attr (key, GPGME_ATTR_ALGO, NULL, 0);
876     if (!id || !keyid)
877     continue; /* fixme: error? */
878     if (!gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_USABLE, NULL, 0))
879     continue;
880    
881     uid = utf8_to_wincp (id, strlen (id));
882     size = strlen( uid ) + strlen( keyid ) + 32;
883     inf = new char[size+1];
884     if( !inf )
885     BUG( NULL );
886     _snprintf(inf, size, _("%s (%s/0x%s)"), uid,
887     gpgme_key_expand_attr (GPGME_ATTR_ALGO, algo), keyid + 8);
888    
889     combox_add_string (kb, inf);
890     free_if_alloc (inf);
891     free (uid);
892     l = (struct keylist_s *)calloc (1, sizeof * l);
893     if (!l)
894     BUG (0);
895     l->key = key;
896     if (!list)
897     list = l;
898     else
899     {
900     for( l2 = list; l2->next; l2 = l2->next )
901     ;
902     l2->next = l;
903     }
904     }
905     for( pos = 0, l2=list; pos < SendMessage( kb, CB_GETCOUNT, 0, 0 ); pos++, l2=l2->next )
906     SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key );
907     SendMessage( kb, CB_SETCURSEL, 0, 0 );
908     *ret_list = list;
909     } /* seclist_init */
910    
911    
912     int
913     seclist_select_key (HWND dlg, int ctlid, gpgme_key_t * ret_key)
914     {
915     int pos;
916     DWORD k = 0;
917    
918     pos = SendDlgItemMessage( dlg, ctlid, CB_GETCURSEL, 0, 0 );
919     if( pos == CB_ERR ) {
920     msg_box( dlg, _("No key was selected."), _("Secret Key List"), MB_ERR );
921     *ret_key = NULL;
922     }
923     else {
924     k = SendDlgItemMessage( dlg, ctlid, CB_GETITEMDATA, pos, 0 );
925     *ret_key = (gpgme_key_t)k;
926     }
927     return k? 0 : -1;
928 twoaday 20 } /* seclist_dlg_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26