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

Contents of /trunk/Src/wptKeylist.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 26992 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26