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

Contents of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 28648 byte(s)
WinPT initial checkin.


1 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 * Copyright (C) 2001-2004 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 /* x-todo-status: OK */
21
22 #include <windows.h>
23 #include <commctrl.h>
24 #include <stdio.h>
25 #include <io.h>
26
27 #include "../resource.h"
28 #include "wptTypes.h"
29 #include "wptW32API.h"
30 #include "wptVersion.h"
31 #include "wptCommonCtl.h"
32 #include "wptNLS.h"
33 #include "wptErrors.h"
34 #include "wptGPG.h"
35 #include "wptContext.h"
36 #include "wptKeylist.h"
37 #include "wptFileManager.h"
38 #include "wptDlgs.h"
39 #include "wptKeyserver.h"
40 #include "wptKeyManager.h"
41 #include "wptKeylist.h"
42 #include "wptHTTP.h"
43
44
45 static void
46 km_get_clip_info (const char *uid, char *buf, size_t buflen)
47 {
48 gpgme_key_t pk;
49 unsigned long a, algo;
50
51 if (get_pubkey (uid, &pk))
52 BUG (0);
53
54 a = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_CREATED, NULL, 0);
55 algo = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_ALGO, NULL, 0);
56 _snprintf (buf, buflen-1,
57 "pub %04d%s/%s %s %s\r\n"
58 " Primary key fingerprint: %s\r\n",
59 gpgme_key_get_ulong_attr (pk, GPGME_ATTR_LEN, NULL, 0),
60 gpgme_key_expand_attr (GPGME_ATTR_ALGO_SHORT, algo),
61 gpgme_key_get_string_attr (pk, GPGME_ATTR_KEYID, NULL, 0) + 8,
62 gpgme_key_expand_attr (GPGME_ATTR_CREATED, a ),
63 gpgme_key_get_string_attr (pk, GPGME_ATTR_USERID, NULL, 0),
64 get_key_fpr (pk));
65 }
66
67
68 char*
69 km_quote_uid (const char * uid)
70 {
71 char * q = new char[strlen (uid) + 4];
72 if (!q)
73 BUG (NULL);
74 _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
75 return q;
76 } /* km_quote_uid */
77
78
79 int
80 km_check_for_seckey (listview_ctrl_t lv, int pos, int * utrust)
81 {
82 char t[128], t2[128];
83 int type=0;
84
85 listview_get_item_text (lv, pos, 5, t, sizeof t -1);
86 listview_get_item_text (lv, pos, 2, t2, sizeof t2 -1);
87 if (!strcmp (t2, "pub/sec"))
88 type = 1;
89 else if (!strcmp (t2, "pub/crd"))
90 type = 2;
91 if (stristr (t, "ultimate") && utrust)
92 *utrust = 1;
93 return type;
94 } /* km_check_for_seckey */
95
96
97 int
98 km_check_if_protected( listview_ctrl_t lv, int pos )
99 {
100 gpgme_key_t key;
101 char keyid[32];
102
103 listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
104 if( get_pubkey( keyid, &key ) )
105 BUG( NULL );
106 return gpgme_key_get_ulong_attr( key, GPGME_ATTR_IS_PROTECTED, NULL, 0 );
107 } /* km_check_if_protected */
108
109
110 int
111 km_check_key_status (listview_ctrl_t lv, int pos)
112 {
113 char t[128];
114 int i = 1;
115
116 listview_get_item_text( lv, pos, 5, t, sizeof t - 1 );
117 if( t[0] == '[' && t[1] == ']' )
118 return 1;
119 for( i = 0; t[i] != ']'; i++ ) {
120 if( t[i] == 'E' )
121 msg_box(lv->ctrl, _("This key has expired!\n"
122 "Key check failed."), _("Key Manager"), MB_ERR );
123 else if( t[i] == 'R' )
124 msg_box(lv->ctrl, _("This key has been revoked by its owner!\n"
125 "Key check failed."), _("Key Manager"), MB_ERR );
126 }
127
128 return 0;
129 } /* km_check_key_status */
130
131
132 int
133 km_get_key_status( listview_ctrl_t lv, int pos )
134 {
135 char t[128];
136 int i, flags = 0;
137
138 if( pos == -1 )
139 return 0;
140 listview_get_item_text( lv, pos, 5, t, sizeof t-1 );
141 for( i = 0; t[i] != ']'; i++ ) {
142 if( t[i] == 'E' )
143 flags |= KM_FLAG_EXPIRED;
144 if( t[i] == 'R' )
145 flags |= KM_FLAG_REVOKED;
146 if( t[i] == 'D' )
147 flags |= KM_FLAG_DISABLED;
148 }
149 return flags;
150 } /* km_get_key_status */
151
152
153 int
154 km_enable_disable_key( listview_ctrl_t lv, HWND dlg, int pos, int enable )
155 {
156 gpgme_ctx_t ctx;
157 gpgme_editkey_t ek;
158 gpgme_error_t err;
159 int edit_id;
160 char keyid[32];
161
162 listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
163 err = gpgme_editkey_new( &ek );
164 if( err )
165 BUG( NULL );
166 if( enable ) {
167 gpgme_editkey_enable_set( ek );
168 edit_id = GPGME_EDITKEY_ENABLE;
169 }
170 else {
171 gpgme_editkey_disable_set( ek );
172 edit_id = GPGME_EDITKEY_DISABLE;
173 }
174 err = gpgme_new( &ctx );
175 if( err )
176 BUG( NULL );
177 gpgme_set_edit_ctx( ctx, ek, edit_id );
178 err = gpgme_op_editkey( ctx, keyid );
179 if( !err ) {
180 show_msg( dlg, 1500, _("Key status changed.") );
181 keycache_set_reload( 1 );
182 }
183 else
184 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
185
186 gpgme_release( ctx );
187 gpgme_editkey_release( ek );
188 return err? WPTERR_GENERAL : 0;
189 } /* km_enable_disable_key */
190
191
192 int
193 km_clip_export (HWND dlg, listview_ctrl_t lv)
194 {
195 gpgme_error_t err;
196 gpgme_recipients_t rset;
197 int rc, id = 0, n = 0;
198
199 rset = keylist_enum_recipients (lv, KEYLIST_LIST);
200 n = gpgme_recipients_count (rset);
201 if (!n) {
202 msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
203 rc = WPTERR_GENERAL;
204 goto leave;
205 }
206
207 err = gpgme_op_clip_export (rset);
208 if (err) {
209 msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
210 rc = WPTERR_GENERAL;
211 goto leave;
212 }
213 if (n == 1) {
214 const char *s;
215 char buf[256];
216 s = gpgme_recipients_get_name (rset, 0);
217 km_get_clip_info (s, buf, 255);
218 set_clip_text2 (NULL, buf, strlen (buf), 0);
219 }
220
221 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
222
223 leave:
224 gpgme_recipients_release (rset);
225 return rc;
226 } /* km_clip_export */
227
228
229 int
230 km_privkey_export( HWND dlg, listview_ctrl_t lv, const char *fname )
231 {
232 gpgme_recipients_t rset;
233 gpgme_data_t keydata;
234 gpgme_error_t err;
235 gpgme_ctx_t ctx;
236 size_t n = 0;
237
238 rset = keylist_enum_recipients( lv, KEYLIST_LIST );
239 n = gpgme_recipients_count( rset );
240 if( !n ) {
241 msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );
242 return WPTERR_GENERAL;
243 }
244 if( n > 1 ) {
245 msg_box( dlg, _("Only one secret key can be exported."), _("Key Manager"), MB_ERR );
246 return 0; /* we checked this before, so we just quit */
247 }
248 err = gpgme_data_new( &keydata );
249 if( err )
250 BUG( dlg );
251 err = gpgme_new( &ctx );
252 if( err )
253 BUG( dlg );
254 gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
255 gpgme_control( ctx, GPGME_CTRL_WITH_SECRET_KEY, 1 );
256
257 err = gpgme_op_export( ctx, rset, keydata );
258 if( err ) {
259 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
260 goto leave;
261 }
262
263 log_box( _("Key Manager"), MB_OK,
264 _("Secret key successfully saved in '%s'."), fname );
265
266 leave:
267 err = gpgme_data_release_and_set_file( keydata, fname );
268 if( err )
269 log_box( _("Key Manager"), MB_OK,
270 _("Could not save data to '%s'."), fname );
271 gpgme_release( ctx );
272
273 return (int)err;
274 } /* km_privkey_export */
275
276
277 int
278 km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
279 {
280 gpgme_recipients_t rset;
281 gpgme_data_t keydata;
282 gpgme_error_t err;
283 gpgme_ctx_t ctx;
284
285 rset = keylist_enum_recipients( lv, KEYLIST_LIST );
286 if( !gpgme_recipients_count( rset ) ) {
287 msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );
288 return WPTERR_GENERAL;
289 }
290
291 err = gpgme_data_new( &keydata );
292 if( err )
293 BUG( dlg );
294 err = gpgme_new( &ctx );
295 if( err )
296 BUG( dlg );
297 gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
298 gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);
299
300 err = gpgme_op_export( ctx, rset, keydata );
301 if( err ) {
302 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
303 goto leave;
304 }
305
306 log_box( _("Key Manager"), MB_OK,
307 _("Key(s) successfully saved in '%s'."), fname );
308
309 leave:
310 err = gpgme_data_release_and_set_file( keydata, fname );
311 if( err )
312 log_box( _("Key Manager"), MB_OK,
313 _("Could not save data to '%s'."), fname );
314 gpgme_release( ctx );
315
316 return (int)err;
317 } /* km_file_export */
318
319
320 static int
321 extract_dash_escaped_key( void )
322 {
323 gpgme_data_t inp, plain;
324 gpgme_error_t err;
325
326 err = gpgme_data_new_from_clipboard (&inp);
327 if( err ) {
328 msg_box( NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
329 return -1;
330 }
331 gpgme_data_extract_plaintext( inp, &plain );
332 gpgme_data_release( inp );
333 gpgme_data_release_and_set_clipboard( plain );
334
335 return 0;
336 } /* extract_dash_escaped_key */
337
338
339 int
340 km_clip_import( HWND dlg )
341 {
342 gpgme_error_t err;
343 gpgme_cliptype_t pgptype;
344 int id;
345 int has_data = 0;
346
347 if( !gpgme_clip_istext_avail( &has_data ) && !has_data ) {
348 msg_box( dlg, winpt_strerror( WPTERR_CLIP_ISEMPTY ), _("Key Manager"), MB_ERR );
349 return WPTERR_CLIP_ISEMPTY;
350 }
351 err = gpgme_clip_is_secured( &pgptype, &has_data );
352 if( err )
353 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
354 if( !has_data ) {
355 msg_box( dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR );
356 return WPTERR_GENERAL;
357 }
358 if( !(pgptype & GPGME_CLIP_PUBKEY) && !(pgptype & GPGME_CLIP_SECKEY) ) {
359 msg_box( dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR );
360 return WPTERR_GENERAL;
361 }
362 if( pgptype & GPGME_CLIP_DASH_ESCAPED ) {
363 id = msg_box( dlg, _("The key you want to import is dash escacped.\n"
364 "Do you want to extract the key?"),
365 _("Key Manager"), MB_YESNO );
366 if( id == IDYES )
367 extract_dash_escaped_key( );
368 else
369 msg_box( dlg, _("Cannot import dash escaped OpenPGP keys."), _("Key Manager"), MB_INFO );
370 }
371
372 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
373 clip_import_dlg_proc, NULL,
374 _("Key Import"), IDS_WINPT_IMPORT );
375
376 return 0;
377 } /* km_clip_import */
378
379
380 int
381 km_http_import (HWND dlg, const char * url)
382 {
383 FILE * fp;
384 char * p;
385 char tmpdir[500];
386 http_hd_t hd;
387 int statcode;
388 int rc = 0;
389
390 if (strncmp (url, "http://", 7)) {
391 log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
392 return WPTERR_GENERAL;
393 }
394
395 GetTempPath (499, tmpdir);
396 p = make_filename (tmpdir, "file_http", "tmp");
397 if (!p)
398 BUG (0);
399 fp = fopen (p, "wb");
400 if (fp == NULL) {
401 free_if_alloc (p);
402 log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
403 return WPTERR_FILE_CREAT;
404 }
405 /* parse URL */
406 rc = http_send_request2 (url, &hd);
407 if (!rc)
408 rc = http_parse_response (hd, &statcode);
409 if (!rc)
410 rc = http_parse_data (hd, fp);
411 http_hd_free (hd);
412 fclose (fp);
413 if (rc) {
414 free_if_alloc (p);
415 msg_box (dlg, http_strerror (rc), _("Key Import HTTP"), MB_ERR);
416 return WPTERR_GENERAL;
417 }
418 km_file_import (dlg, p);
419 free_if_alloc (p);
420 return 0;
421 }
422
423 int
424 km_file_import( HWND dlg, const char * fname )
425 {
426 gpgme_data_t keydata = NULL;
427 gpgme_ctx_t ctx;
428 gpgme_error_t err;
429 fm_state_s fm_stat;
430 int import_res[14];
431
432 memset( &fm_stat, 0, sizeof fm_stat );
433 fm_stat.opaque = m_strdup( fname );
434
435 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
436 file_import_dlg_proc, (LPARAM)&fm_stat,
437 _("File Import"), IDS_WINPT_IMPORT );
438 if( fm_stat.cancel == 1 )
439 return WPTERR_GENERAL;
440
441 err = gpgme_new( &ctx );
442 if( err )
443 BUG( dlg );
444 gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );
445 err = gpgme_data_new_from_file (&keydata, fname);
446 if( err ) {
447 msg_box( dlg, _("Could not read key-data from file."), _("Key Manager"), MB_ERR );
448 goto leave;
449 }
450
451 err = gpgme_op_import( ctx, NULL, keydata );
452 if( err ) {
453 msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
454 goto leave;
455 }
456
457 gpgme_get_import_status( ctx, import_res, NULL );
458 print_import_status( import_res, fm_stat.implist_revcert );
459 if( import_res[GPGME_IMPSTAT_NOSELFSIG] > 0 ) {
460 msg_box( dlg, _("Key without a self signature was dectected!\n"
461 "(This key is NOT usable for encryption, etc)\n"
462 "\n"
463 "Cannot import these key(s)!"), _("Import"), MB_INFO );
464 }
465
466 leave:
467 gpgme_data_release( keydata );
468 gpgme_release( ctx );
469 free_if_alloc( fm_stat.opaque );
470 return (int)err;
471 } /* km_file_import */
472
473
474 static void
475 delete_keys_from_cache (gpgme_recipients_t rset)
476 {
477 gpgme_keycache_t pub = keycache_get_ctx (1);
478 void * ctx =NULL;
479 const char * s;
480
481 gpgme_recipients_enum_open (rset, &ctx);
482 while ((s = gpgme_recipients_enum_read (rset, &ctx)))
483 gpgme_keycache_delete_key (pub, s);
484 gpgme_recipients_enum_close (rset, &ctx);
485 } /* delete_keys_from_cache */
486
487
488 int
489 km_delete_keys (listview_ctrl_t lv, HWND dlg)
490 {
491 gpgme_error_t err;
492 gpgme_recipients_t rset;
493 char keyid[32], uid[256], date[64], keylen[64];
494 int with_seckey, seckey_type=0;
495 int i, rc;
496
497 if( listview_get_curr_pos( lv ) == -1 ) {
498 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
499 return WPTERR_GENERAL;
500 }
501
502 err = gpgme_recipients_new (&rset);
503 if (err)
504 BUG (0);
505
506 for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
507 if( listview_get_item_state( lv, i ) ) {
508 listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
509 listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
510 listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
511 listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
512 seckey_type = km_check_for_seckey( lv, i, NULL );
513 if( !seckey_type ) {
514 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
515 _("Do you really want to delete this key?\n\n"
516 "pub %s %s %s\n"
517 " \"%s\""), keylen, keyid, date, uid );
518 if( rc == IDYES )
519 gpgme_recipients_add_name( rset, keyid );
520 with_seckey = 0;
521 }
522 else {
523 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
524 _("Do you really want to delete this KEY PAIR?\n\n"
525 "Please remember that you are not able to decrypt\n"
526 "messages you stored with this key any longer.\n"
527 "\n"
528 "pub/sec %s %s %s\n"
529 " \"%s\""), keylen, keyid, date, uid );
530 if( rc == IDYES ) {
531 if( seckey_type == 2 )
532 msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
533 "Only the public key and the secret key \n"
534 "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
535 gpgme_recipients_add_name( rset, keyid );
536 }
537 with_seckey = 1;
538 }
539 }
540 }
541
542 if (!gpgme_recipients_count (rset)) {
543 gpgme_recipients_release (rset);
544 return 0;
545 }
546
547 err = gpgme_op_delete_keys (rset, with_seckey);
548 if (err) {
549 if (err == GPGME_Invalid_Key)
550 msg_box (dlg, _("No such key."), _("Key Manager"), MB_INFO);
551 else if (err == GPGME_Conflict)
552 msg_box (dlg, _("Must delete secret key first."), _("Key Manager"), MB_INFO);
553 else
554 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
555 return FALSE;
556 }
557 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
558 listview_del_items (lv);
559 if (keyring_check_last_access ())
560 keycache_set_reload (1);
561 delete_keys_from_cache (rset);
562 gpgme_recipients_release (rset);
563
564 return (int)err;
565 } /* km_delete_keys */
566
567
568 int
569 km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
570 {
571 char keyid[32];
572 const char *t;
573 int id;
574
575 id = listview_get_curr_pos( lv );
576 if( id == -1 ) {
577 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
578 return WPTERR_GENERAL;
579 }
580
581 listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
582 id = log_box (_("Key Manager"), MB_YESNO,
583 _("Do you really want to send '%s' to keyserver %s?"),
584 keyid, host);
585 if (id == IDYES) {
586 t = keyid;
587 if (!strncmp (keyid, "0x", 2))
588 t += 2;
589 hkp_send_key (dlg, host, port, t);
590 }
591
592 return 0;
593 } /* km_send_to_keyserver */
594
595
596 int
597 km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
598 {
599 gpgme_key_t key;
600 gpgme_ctx_t ctx=NULL;
601 gpgme_recipients_t rset=NULL;
602 gpgme_error_t rc;
603 const char * s;
604 char keyid[32], tmp[192+256], * p =NULL;
605 int pos;
606
607 if( listview_count_items( lv, 1 ) > 1 ) {
608 msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
609 return WPTERR_GENERAL;
610 }
611 pos = listview_get_curr_pos( lv );
612 if( pos == -1 ) {
613 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
614 return WPTERR_GENERAL;
615 }
616 listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
617 if( get_pubkey( keyid, &key ) )
618 BUG( NULL );
619 s = gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, 0 );
620 GetTempPath (sizeof tmp-1, tmp);
621 strncat (tmp, s, sizeof tmp-200);
622 strncat (tmp, ".asc", sizeof tmp-200);
623 p = fm_quote_file (tmp);
624
625 rc = gpgme_recipients_new( &rset );
626 if( !rc )
627 rc = gpgme_recipients_add_name( rset, keyid );
628 if( !rc )
629 rc = gpgme_new( &ctx );
630 if( !rc ) {
631 gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
632 rc = gpgme_op_file_export( ctx, rset, p );
633 }
634 if( rc )
635 msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );
636 else
637 mapi_send_pubkey (keyid, tmp);
638 free_if_alloc( p );
639 gpgme_recipients_release( rset );
640 gpgme_release( ctx );
641 return rc;
642 }
643
644
645 static void
646 km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
647 {
648 int idx;
649 char keyid[32];
650 const char *t;
651
652 if (pos != 0)
653 idx = pos;
654 else
655 idx = listview_get_curr_pos (lv);
656 if (idx != -1)
657 {
658 listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
659 t = keyid;
660 if (!strncmp (keyid, "0x", 2))
661 t += 2;
662 hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
663 }
664 }
665
666
667 void
668 km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
669 {
670 int idx, id, i;
671
672 if (kserver_check_inet_connection ())
673 {
674 msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
675 _("Key Manager"), MB_ERR);
676 return;
677 }
678 idx = listview_count_items (lv, 0);
679 if (listview_count_items (lv, 1) == idx) {
680 id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
681 if (id == IDNO)
682 return;
683 for (i = 0; i < idx; i++)
684 km_refresh_one_key (lv, dlg, i);
685 }
686 else if (idx == 1)
687 km_refresh_one_key (lv, dlg, 0);
688 else {
689 for (i=0; i < listview_count_items (lv, 0); i++) {
690 if (listview_get_item_state (lv, i))
691 km_refresh_one_key (lv, dlg, i);
692 }
693 }
694 } /* km_refresh_from_keyserver */
695
696
697 void
698 km_set_clip_info( const char *uid )
699 {
700 char buf[256];
701
702 km_get_clip_info (uid, buf, 255);
703 set_clip_text( NULL, buf, strlen( buf ) );
704 } /* km_set_clip_info */
705
706
707
708 int
709 km_key_is_v3( listview_ctrl_t lv, int pos )
710 {
711 gpgme_key_t pk;
712 const char * fpr;
713 unsigned long algo;
714 char keyid[32];
715
716 listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
717 if( get_pubkey( keyid, &pk ) )
718 BUG( NULL );
719 algo = gpgme_key_get_ulong_attr( pk, GPGME_ATTR_ALGO, NULL, 0 );
720 fpr = gpgme_key_get_string_attr( pk, GPGME_ATTR_FPR, NULL, 0 );
721 return strlen( fpr ) == 32 && algo == GPGME_PK_RSA? 1 : 0;
722 } /* km_key_is_v3 */
723
724
725 void
726 km_update_default_key_str (HWND dlg, int * ret_len)
727 {
728 char * keyid, defkeyinf[512];
729 const char * fmt;
730
731 keyid = get_gnupg_default_key ();
732 if (!keyid)
733 BUG (0);
734 if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
735 || (keyid[0] == '0' && keyid[1] == 'x') )
736 fmt = _("Default Key: %s");
737 else
738 fmt = _("Default Key: 0x%s");
739 _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );
740 SetWindowText( dlg, defkeyinf );
741 *ret_len = strlen( defkeyinf );
742 free_if_alloc( keyid );
743 } /* km_return_default_key_str */
744
745
746 void
747 km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )
748 {
749 char text[384];
750 int nkeys = 0, nsec = 0, i;
751
752 GetWindowText( sb, text, sizeof text -1 );
753 nkeys = listview_count_items( lv, 0 );
754 for( i = 0; i < nkeys; i++ ) {
755 if( km_check_for_seckey( lv, i, NULL ) )
756 nsec++;
757 }
758 _snprintf( text+startpos, sizeof text-1, " %d keys (%d secret keys)", nkeys, nsec );
759 SetWindowText( sb, text );
760 } /* km_complete_status_bar */
761
762
763 void
764 km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
765 {
766 gpgme_error_t err;
767 gpgme_ctx_t ctx;
768 gpgme_editkey_t ek;
769 char keyid[32];
770
771 listview_get_item_text (lv, pos, 1, keyid, 31);
772 err = gpgme_new (&ctx);
773 if (err)
774 BUG (0);
775 err = gpgme_editkey_new (&ek);
776 if (err)
777 BUG (0);
778 gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);
779 gpgme_editkey_trust_set (ek, 5);
780
781 err = gpgme_op_editkey (ctx, keyid);
782 if (err)
783 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
784 else {
785 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
786 keycache_set_reload (1);
787 }
788
789 gpgme_release (ctx);
790 gpgme_editkey_release (ek);
791 }
792
793
794 gpg_optfile_t
795 km_groupdb_open( void )
796 {
797 gpg_optfile_t opt;
798 char * optfile;
799 int err = 0;
800
801 optfile = get_gnupg_cfgfile();
802 if( !optfile )
803 BUG( NULL );
804 if( parse_gpg_options( optfile, &opt ) )
805 err = 1;
806 free_if_alloc( optfile );
807 return err? NULL : opt;
808 } /* km_groupdb_open */
809
810
811 int
812 km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
813 {
814 gpgme_keycache_t kc;
815 gpgme_key_t pk;
816 gpg_optfile_t opt;
817 gpg_group_t grp;
818 gpg_member_t mbr;
819 int no_trust = 0, n;
820
821 kc = keycache_get_ctx( 1 );
822 if( !kc )
823 BUG( NULL );
824
825 opt = km_groupdb_open( );
826 if( !opt )
827 return WPTERR_FILE_OPEN;
828
829 grp = find_group( opt, name );
830 if( !grp )
831 return WPTERR_GENERAL;
832
833 /* we are paranoid and check that all group members exist in the
834 key cache. there is no need that it is really the real key, but
835 an entry should be available. the rest is up to GPG. */
836 for( mbr = grp->list; mbr; mbr = mbr->next ) {
837 if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
838 BUG( NULL );
839 n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );
840 while( n-- ) {
841 const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );
842 if( s && stristr( s, mbr->name )
843 && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )
844 no_trust++;
845 }
846 }
847
848 gpgme_recipients_add_name( rset, name );
849 release_gpg_options( opt );
850
851 return no_trust;
852 } /* km_groupdb_expand_recipients */
853
854
855 static HTREEITEM
856 km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
857 {
858 TVINSERTSTRUCT tvis;
859 HTREEITEM node;
860
861 memset( &tvis, 0, sizeof tvis );
862 tvis.hParent = parent;
863 tvis.hInsertAfter = TVI_LAST;
864 tvis.item.mask = TVIF_TEXT;
865 tvis.item.pszText = (char *)text;
866 node = TreeView_InsertItem( tree, &tvis );
867 return node;
868 } /* km_tv_insert_item */
869
870
871 int
872 km_groups_new( km_group_t *r_gc, HWND ctrl )
873 {
874 km_group_t gc;
875
876 gc = new km_group_s;
877 if (!gc)
878 BUG (NULL);
879 gc->tree = ctrl;
880 gc->gh = km_groupdb_open ();
881 *r_gc = gc;
882 return 0;
883 } /* km_groups_new */
884
885
886 void
887 km_groups_sync( km_group_t gc )
888 {
889 char * optfile;
890
891 optfile = get_gnupg_cfgfile ();
892 if( !optfile )
893 BUG( NULL );
894 commit_gpg_options( optfile, gc->gh );
895 free_if_alloc( optfile );
896 gc->need_sync = 0;
897 } /* km_groups_sync */
898
899
900 void
901 km_groups_release (km_group_t gc)
902 {
903 if( gc ) {
904 /* xxx: this reset the default key (sync=1) */
905 gc->need_sync=0;
906 if (gc->need_sync)
907 km_groups_sync (gc);
908 if (gc->gh)
909 release_gpg_options( gc->gh );
910 gc->gh = NULL;
911 gc->tree = NULL;
912 delete gc;
913 }
914 } /* km_groups_release */
915
916
917 int
918 km_groups_load( km_group_t gc )
919 {
920 HTREEITEM n;
921 gpg_group_t grp, g;
922 gpg_member_t mbr;
923 u32 gid = 0;
924
925 if( !gc->gh )
926 return 0;
927 grp = gc->gh->grp;
928 if( !grp )
929 return 0; /* no groups */
930
931 for( g = grp; g; g = g->next ) {
932 n = km_tv_insert_item( gc->tree, NULL, g->name );
933 for( mbr = g->list; mbr; mbr = mbr->next ) {
934 if( mbr->used && mbr->name )
935 km_tv_insert_item( gc->tree, n, mbr->name );
936 }
937 }
938 DragAcceptFiles( gc->tree, TRUE );
939 gc->need_sync = 0;
940 return 0;
941 } /* km_groups_load */
942
943
944 int
945 km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
946 {
947 TVITEM tvi;
948 char uid[128], valid[64], text[128];
949 int i_valid;
950
951 memset( &tvi, 0, sizeof tvi );
952 tvi.hItem = TreeView_GetSelection( gc->tree );
953 tvi.pszText = text;
954 tvi.cchTextMax = sizeof text -1;
955 tvi.mask = TVIF_TEXT;
956 TreeView_GetItem( gc->tree, &tvi );
957
958
959 listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
960 listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
961
962 if( strstr( valid, "Ultimate" ) )
963 i_valid = 5;
964 else if( !strstr( valid, "Full" ) )
965 i_valid = 4;
966 else if( !strstr( valid, "Marginal" ) )
967 i_valid = 3;
968 else
969 i_valid = 0;
970
971 /* we can't add the full name. one way would be to use the first
972 text until a space appears.
973 group_add_entry(&gc->gh, gid, i_valid, uid);
974 treeview_add_item(gc->tree, tvi.hItem, uid);
975 */
976 gc->need_sync = 1;
977
978 return 0;
979 } /* km_groups_add */
980
981
982 static int
983 km_groups_del_main( km_group_t gc )
984 {
985 TVITEM tvi;
986 char text[128];
987 int id;
988
989 memset( &tvi, 0, sizeof tvi );
990 tvi.hItem = TreeView_GetSelection( gc->tree );
991 tvi.pszText = text;
992 tvi.cchTextMax = sizeof text -1;
993 tvi.mask = TVIF_TEXT;
994 TreeView_GetItem( gc->tree, &tvi );
995
996 id = log_box( _("Key Manager"), MB_INFO_ASK,
997 _("Do you really want to delete this group?\n\n%s"), text);
998 if( id == IDNO )
999 return 0;
1000 delete_group( gc->gh, text );
1001 TreeView_DeleteItem( gc->tree, &tvi );
1002 gc->need_sync = 1;
1003
1004 return 0;
1005 } /* km_groups_del */
1006
1007
1008 static int
1009 km_groups_del_entry( km_group_t gc )
1010 {
1011 TVITEM tvi;
1012 HTREEITEM root;
1013 int id;
1014 char text[128], info[256];
1015 gpg_group_t grp = NULL;
1016
1017 memset( &tvi, 0, sizeof tvi );
1018 tvi.hItem = TreeView_GetSelection( gc->tree );
1019 tvi.pszText = text;
1020 tvi.cchTextMax = sizeof text-1;
1021 tvi.mask = TVIF_TEXT;
1022 TreeView_GetItem( gc->tree, &tvi );
1023
1024 _snprintf( info, sizeof info -1,
1025 _("Do you really want to delete this entry?\n\n%s"), text );
1026
1027 id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1028 if( id == IDNO )
1029 return 0;
1030
1031 root = TreeView_GetParent( gc->tree, tvi.hItem );
1032 if( root ) {
1033 }
1034
1035 delete_member( gc->gh, /*fixme*/NULL, text );
1036 TreeView_DeleteItem( gc->tree, &tvi );
1037 gc->need_sync = 1;
1038 return 0;
1039 } /* km_groups_del_entry */
1040
1041
1042 int
1043 km_groups_del( km_group_t gc )
1044 {
1045 if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1046 return km_groups_del_entry( gc );
1047 else
1048 return km_groups_del_main( gc );
1049 } /* km_groups_del */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26