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

Contents of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (show annotations)
Fri May 20 08:39:15 2005 UTC (19 years, 9 months ago) by twoaday
File size: 28607 byte(s)
2005-05-09 Timo Schulz  <twoaday@freakmail.de>
                                                                                  
        * wptCommonDlg.cpp (http_file_dlg_proc): Renamed to..
        (http_dlg_proc): ..this.
        (get_keyserver_URL_dlg): New.
        (check_URL): New.
        * wptKeyEditDlgs.cpp (keyedit_set_pref_keyserver): New.
        (keyedit_main_dlg_proc): Avoid massive keycache reloads, just reload
        the single key.
        * wptKeyRevokersDlg.cpp (key_revokers_dlg_proc): Show the key properties
        of the selected desig. revoker.
        * wptVerifyList.cpp (verlist_build): Increase the column size of 'keyid'.
        * wptGPGME.cpp (keycache_update): New.
        * wptKeySigDlg.cpp (keysig_dlg_proc): Update the key if a signature
        was deleted.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Zeroing the key struct
        before we set any values.
                                                                                  

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26