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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 30164 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 twoaday 2 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 twoaday 19 * Copyright (C) 2001-2005 Timo Schulz
3 twoaday 2 *
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 twoaday 22 km_quote_uid (const char *uid)
68 twoaday 2 {
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 twoaday 22 km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
79 twoaday 2 {
80 twoaday 16 char t[32], t2[64];
81     int type = 0;
82 twoaday 2
83 twoaday 22 if (utrust)
84     *utrust = 0;
85     listview_get_item_text (lv, pos, 5, t, DIM (t)-1);
86     listview_get_item_text (lv, pos, 2, t2, DIM (t2)-1);
87 twoaday 2 if (!strcmp (t2, "pub/sec"))
88     type = 1;
89     else if (!strcmp (t2, "pub/crd"))
90     type = 2;
91 twoaday 22 if ((strstr (t, "Expired") || strstr (t, "Revoked")) && utrust)
92     *utrust = -1;
93     else if (stristr (t, "Ultimate") && utrust)
94 twoaday 2 *utrust = 1;
95     return type;
96     } /* km_check_for_seckey */
97    
98    
99     int
100 twoaday 22 km_check_if_protected (listview_ctrl_t lv, int pos)
101 twoaday 2 {
102     gpgme_key_t key;
103 twoaday 22
104     key = (gpgme_key_t)listview_get_item2 (lv, pos);
105     if (key == NULL)
106     return 1; /* assume yes */
107     return gpgme_key_get_ulong_attr (key, GPGME_ATTR_IS_PROTECTED, NULL, 0);
108 twoaday 2 } /* km_check_if_protected */
109    
110    
111     int
112     km_check_key_status (listview_ctrl_t lv, int pos)
113     {
114 twoaday 22 int flags = km_get_key_status (lv, pos);
115 twoaday 2
116 twoaday 22 if (flags & KM_FLAG_EXPIRED) {
117     msg_box (lv->ctrl, _("This key has expired!\n"
118     "Key check failed."), _("Key Manager"), MB_ERR);
119     return -1;
120 twoaday 2 }
121 twoaday 22 else if (flags & KM_FLAG_REVOKED) {
122     msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
123     "Key check failed."), _("Key Manager"), MB_ERR);
124     return -1;
125     }
126 twoaday 2
127     return 0;
128     } /* km_check_key_status */
129    
130    
131     int
132 twoaday 22 km_get_key_status (listview_ctrl_t lv, int pos)
133 twoaday 2 {
134 twoaday 22 gpgme_key_t key;
135     int flags = 0;
136 twoaday 2
137 twoaday 22 if (pos == -1)
138 twoaday 2 return 0;
139 twoaday 22 key = (gpgme_key_t)listview_get_item2 (lv, pos);
140     if (key == NULL)
141     return 0;
142     if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_EXPIRED, NULL, 0))
143     flags |= KM_FLAG_EXPIRED;
144     if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_REVOKED, NULL, 0))
145     flags |= KM_FLAG_REVOKED;
146     if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_DISABLED, NULL, 0))
147     flags |= KM_FLAG_DISABLED;
148 twoaday 2 return flags;
149     } /* km_get_key_status */
150    
151    
152     int
153 twoaday 19 km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
154 twoaday 2 {
155     gpgme_ctx_t ctx;
156     gpgme_editkey_t ek;
157     gpgme_error_t err;
158     int edit_id;
159     char keyid[32];
160    
161 twoaday 22 listview_get_item_text (lv, pos, 1, keyid, DIM (keyid)-1);
162     err = gpgme_editkey_new (&ek);
163     if (err)
164     BUG (NULL);
165     if (enable) {
166 twoaday 19 gpgme_editkey_enable_set (ek);
167 twoaday 2 edit_id = GPGME_EDITKEY_ENABLE;
168     }
169     else {
170 twoaday 19 gpgme_editkey_disable_set (ek);
171 twoaday 2 edit_id = GPGME_EDITKEY_DISABLE;
172     }
173 twoaday 19 err = gpgme_new (&ctx);
174 twoaday 2 if( err )
175     BUG( NULL );
176 twoaday 19 gpgme_set_edit_ctx (ctx, ek, edit_id);
177     err = gpgme_op_editkey (ctx, keyid);
178 twoaday 2 if( !err ) {
179     show_msg( dlg, 1500, _("Key status changed.") );
180     keycache_set_reload( 1 );
181     }
182     else
183     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
184    
185 twoaday 19 gpgme_release (ctx);
186     gpgme_editkey_release (ek);
187 twoaday 2 return err? WPTERR_GENERAL : 0;
188     } /* km_enable_disable_key */
189    
190    
191     int
192     km_clip_export (HWND dlg, listview_ctrl_t lv)
193     {
194     gpgme_error_t err;
195     gpgme_recipients_t rset;
196     int rc, id = 0, n = 0;
197    
198     rset = keylist_enum_recipients (lv, KEYLIST_LIST);
199     n = gpgme_recipients_count (rset);
200     if (!n) {
201     msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
202     rc = WPTERR_GENERAL;
203     goto leave;
204     }
205    
206     err = gpgme_op_clip_export (rset);
207     if (err) {
208     msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
209     rc = WPTERR_GENERAL;
210     goto leave;
211     }
212     if (n == 1) {
213     const char *s;
214     char buf[256];
215     s = gpgme_recipients_get_name (rset, 0);
216     km_get_clip_info (s, buf, 255);
217     set_clip_text2 (NULL, buf, strlen (buf), 0);
218     }
219    
220     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
221    
222     leave:
223     gpgme_recipients_release (rset);
224     return rc;
225     } /* km_clip_export */
226    
227    
228     int
229 twoaday 22 km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
230 twoaday 2 {
231     gpgme_recipients_t rset;
232     gpgme_data_t keydata;
233     gpgme_error_t err;
234     gpgme_ctx_t ctx;
235     size_t n = 0;
236    
237 twoaday 22 rset = keylist_enum_recipients (lv, KEYLIST_LIST);
238     n = gpgme_recipients_count (rset);
239     if (!n) {
240 twoaday 2 msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );
241     return WPTERR_GENERAL;
242     }
243 twoaday 22 if (n > 1) {
244 twoaday 2 msg_box( dlg, _("Only one secret key can be exported."), _("Key Manager"), MB_ERR );
245     return 0; /* we checked this before, so we just quit */
246     }
247     err = gpgme_data_new( &keydata );
248     if( err )
249     BUG( dlg );
250     err = gpgme_new( &ctx );
251     if( err )
252     BUG( dlg );
253 twoaday 22 gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
254     gpgme_control (ctx, GPGME_CTRL_WITH_SECRET_KEY, 1);
255     gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);
256 twoaday 2
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 twoaday 22 gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
298 twoaday 2 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 twoaday 19 extract_dash_escaped_key (void)
322 twoaday 2 {
323     gpgme_data_t inp, plain;
324     gpgme_error_t err;
325    
326     err = gpgme_data_new_from_clipboard (&inp);
327 twoaday 19 if (err) {
328     msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
329 twoaday 2 return -1;
330     }
331 twoaday 19 gpgme_data_extract_plaintext (inp, &plain);
332     gpgme_data_release (inp);
333     gpgme_data_release_and_set_clipboard (plain);
334 twoaday 2
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 twoaday 19 gpgme_pgptype_t pgptype;
344 twoaday 2 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 twoaday 19 if( !(pgptype & GPGME_PGP_PUBKEY) && !(pgptype & GPGME_PGP_SECKEY) ) {
359 twoaday 2 msg_box( dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR );
360     return WPTERR_GENERAL;
361     }
362 twoaday 19 if( pgptype & GPGME_PGP_DASH_ESCAPED ) {
363 twoaday 2 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 twoaday 22 if (id == IDYES)
367     extract_dash_escaped_key ();
368 twoaday 2 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 twoaday 22 GetTempPath (sizeof (tmpdir)-1, tmpdir);
396     p = make_filename (tmpdir, "winpt_file_http", "tmp");
397 twoaday 2 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 twoaday 22 msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
416 twoaday 2 return WPTERR_GENERAL;
417     }
418     km_file_import (dlg, p);
419 twoaday 22 // XXX: delete file
420 twoaday 2 free_if_alloc (p);
421     return 0;
422     }
423    
424 twoaday 22
425 twoaday 2 int
426 twoaday 22 km_file_import (HWND dlg, const char * fname)
427 twoaday 2 {
428     gpgme_data_t keydata = NULL;
429     gpgme_ctx_t ctx;
430 twoaday 22 gpgme_error_t err;
431     gpgme_recipients_t keys = NULL;
432 twoaday 2 fm_state_s fm_stat;
433     int import_res[14];
434    
435 twoaday 22 memset (&fm_stat, 0, sizeof (fm_stat));
436     fm_stat.opaque = m_strdup (fname);
437 twoaday 2
438 twoaday 22 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
439 twoaday 2 file_import_dlg_proc, (LPARAM)&fm_stat,
440 twoaday 22 _("File Import"), IDS_WINPT_IMPORT);
441     if (fm_stat.cancel == 1 ) {
442     free_if_alloc (fm_stat.opaque);
443 twoaday 2 return WPTERR_GENERAL;
444 twoaday 22 }
445 twoaday 2
446     err = gpgme_new( &ctx );
447     if( err )
448     BUG( dlg );
449     gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );
450     err = gpgme_data_new_from_file (&keydata, fname);
451     if( err ) {
452     msg_box( dlg, _("Could not read key-data from file."), _("Key Manager"), MB_ERR );
453     goto leave;
454     }
455    
456     err = gpgme_op_import( ctx, NULL, keydata );
457     if( err ) {
458     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
459     goto leave;
460     }
461 twoaday 22
462     gpgme_get_import_status (ctx, import_res, &keys);
463     print_import_status (import_res, fm_stat.implist_revcert);
464     if (import_res[GPGME_IMPSTAT_NOSELFSIG] > 0) {
465     msg_box (dlg, _("Key without a self signature was dectected!\n"
466 twoaday 2 "(This key is NOT usable for encryption, etc)\n"
467     "\n"
468 twoaday 22 "Cannot import these key(s)!"), _("Import"), MB_INFO);
469 twoaday 2 }
470 twoaday 22
471     leave:
472     gpgme_recipients_release (keys);
473     gpgme_data_release (keydata);
474     gpgme_release (ctx);
475     free_if_alloc (fm_stat.opaque);
476 twoaday 2 return (int)err;
477     } /* km_file_import */
478    
479    
480     static void
481     delete_keys_from_cache (gpgme_recipients_t rset)
482     {
483     gpgme_keycache_t pub = keycache_get_ctx (1);
484 twoaday 22 void *ctx =NULL;
485     const char *s;
486 twoaday 2
487     gpgme_recipients_enum_open (rset, &ctx);
488     while ((s = gpgme_recipients_enum_read (rset, &ctx)))
489     gpgme_keycache_delete_key (pub, s);
490     gpgme_recipients_enum_close (rset, &ctx);
491     } /* delete_keys_from_cache */
492    
493    
494     int
495     km_delete_keys (listview_ctrl_t lv, HWND dlg)
496     {
497     gpgme_error_t err;
498     gpgme_recipients_t rset;
499     char keyid[32], uid[256], date[64], keylen[64];
500 twoaday 22 int with_seckey=0, seckey_type=0, confirm=0;
501 twoaday 20 int i, rc, n;
502 twoaday 2
503 twoaday 22 if (listview_get_curr_pos (lv) == -1) {
504     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
505 twoaday 2 return WPTERR_GENERAL;
506     }
507 twoaday 22
508     if (listview_count_items (lv, 1) > 8) {
509     i = msg_box (NULL, _("Do you really want to confirm each key?"), _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
510     if (i == IDCANCEL)
511     return 0;
512     if (i != IDNO)
513     confirm = 1;
514     }
515     else
516     confirm = 1;
517 twoaday 2 err = gpgme_recipients_new (&rset);
518     if (err)
519     BUG (0);
520 twoaday 20 n = listview_count_items (lv, 0);
521     for( i = 0; i < n; i++ ) {
522 twoaday 2 if( listview_get_item_state( lv, i ) ) {
523     listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
524     listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
525     listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
526     listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
527 twoaday 22 seckey_type = km_check_for_seckey (lv, i, NULL);
528     if (confirm && !seckey_type) {
529 twoaday 2 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
530     _("Do you really want to delete this key?\n\n"
531     "pub %s %s %s\n"
532     " \"%s\""), keylen, keyid, date, uid );
533 twoaday 22 if (rc == IDYES)
534     gpgme_recipients_add_name(rset, keyid);
535 twoaday 2 with_seckey = 0;
536     }
537 twoaday 22 else if (confirm) {
538 twoaday 2 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
539     _("Do you really want to delete this KEY PAIR?\n\n"
540     "Please remember that you are not able to decrypt\n"
541     "messages you stored with this key any longer.\n"
542     "\n"
543     "pub/sec %s %s %s\n"
544     " \"%s\""), keylen, keyid, date, uid );
545     if( rc == IDYES ) {
546     if( seckey_type == 2 )
547     msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
548     "Only the public key and the secret key \n"
549     "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
550     gpgme_recipients_add_name( rset, keyid );
551     }
552     with_seckey = 1;
553     }
554 twoaday 22 else {
555     with_seckey = 1;
556     gpgme_recipients_add_name (rset, keyid);
557     }
558 twoaday 2 }
559     }
560    
561     if (!gpgme_recipients_count (rset)) {
562     gpgme_recipients_release (rset);
563     return 0;
564     }
565    
566     err = gpgme_op_delete_keys (rset, with_seckey);
567     if (err) {
568     if (err == GPGME_Invalid_Key)
569     msg_box (dlg, _("No such key."), _("Key Manager"), MB_INFO);
570     else if (err == GPGME_Conflict)
571     msg_box (dlg, _("Must delete secret key first."), _("Key Manager"), MB_INFO);
572     else
573     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
574     return FALSE;
575     }
576     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
577     listview_del_items (lv);
578     delete_keys_from_cache (rset);
579     gpgme_recipients_release (rset);
580    
581     return (int)err;
582     } /* km_delete_keys */
583    
584    
585     int
586     km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
587     {
588     char keyid[32];
589     const char *t;
590     int id;
591    
592     id = listview_get_curr_pos( lv );
593     if( id == -1 ) {
594     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
595     return WPTERR_GENERAL;
596     }
597    
598     listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
599     id = log_box (_("Key Manager"), MB_YESNO,
600     _("Do you really want to send '%s' to keyserver %s?"),
601     keyid, host);
602     if (id == IDYES) {
603     t = keyid;
604     if (!strncmp (keyid, "0x", 2))
605     t += 2;
606     hkp_send_key (dlg, host, port, t);
607     }
608    
609     return 0;
610     } /* km_send_to_keyserver */
611    
612    
613     int
614     km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
615     {
616     gpgme_key_t key;
617     gpgme_ctx_t ctx=NULL;
618     gpgme_recipients_t rset=NULL;
619     gpgme_error_t rc;
620     const char * s;
621     char keyid[32], tmp[192+256], * p =NULL;
622     int pos;
623    
624     if( listview_count_items( lv, 1 ) > 1 ) {
625     msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
626     return WPTERR_GENERAL;
627     }
628     pos = listview_get_curr_pos( lv );
629     if( pos == -1 ) {
630     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
631     return WPTERR_GENERAL;
632     }
633     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
634     if( get_pubkey( keyid, &key ) )
635     BUG( NULL );
636     s = gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, 0 );
637     GetTempPath (sizeof tmp-1, tmp);
638     strncat (tmp, s, sizeof tmp-200);
639     strncat (tmp, ".asc", sizeof tmp-200);
640     p = fm_quote_file (tmp);
641    
642     rc = gpgme_recipients_new( &rset );
643     if( !rc )
644     rc = gpgme_recipients_add_name( rset, keyid );
645     if( !rc )
646     rc = gpgme_new( &ctx );
647     if( !rc ) {
648     gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
649     rc = gpgme_op_file_export( ctx, rset, p );
650     }
651     if( rc )
652     msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );
653     else
654     mapi_send_pubkey (keyid, tmp);
655     free_if_alloc( p );
656     gpgme_recipients_release( rset );
657     gpgme_release( ctx );
658     return rc;
659     }
660    
661    
662     static void
663     km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
664     {
665     int idx;
666     char keyid[32];
667     const char *t;
668    
669     if (pos != 0)
670     idx = pos;
671     else
672     idx = listview_get_curr_pos (lv);
673     if (idx != -1)
674     {
675     listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
676     t = keyid;
677     if (!strncmp (keyid, "0x", 2))
678     t += 2;
679     hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
680     }
681     }
682    
683    
684     void
685     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
686     {
687     int idx, id, i;
688    
689     if (kserver_check_inet_connection ())
690     {
691     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
692     _("Key Manager"), MB_ERR);
693     return;
694     }
695     idx = listview_count_items (lv, 0);
696     if (listview_count_items (lv, 1) == idx) {
697     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
698     if (id == IDNO)
699     return;
700     for (i = 0; i < idx; i++)
701     km_refresh_one_key (lv, dlg, i);
702     }
703     else if (idx == 1)
704     km_refresh_one_key (lv, dlg, 0);
705     else {
706     for (i=0; i < listview_count_items (lv, 0); i++) {
707     if (listview_get_item_state (lv, i))
708     km_refresh_one_key (lv, dlg, i);
709     }
710     }
711     } /* km_refresh_from_keyserver */
712    
713    
714     void
715     km_set_clip_info( const char *uid )
716     {
717     char buf[256];
718    
719     km_get_clip_info (uid, buf, 255);
720     set_clip_text( NULL, buf, strlen( buf ) );
721     } /* km_set_clip_info */
722    
723    
724    
725     int
726 twoaday 20 km_key_is_v3 (listview_ctrl_t lv, int pos)
727 twoaday 2 {
728     gpgme_key_t pk;
729     char keyid[32];
730    
731 twoaday 20 listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
732     if (get_pubkey (keyid, &pk))
733     BUG (NULL);
734     return gpgme_key_get_ulong_attr (pk, GPGME_ATTR_VERSION, NULL, 0);
735 twoaday 2 } /* km_key_is_v3 */
736    
737    
738     void
739     km_update_default_key_str (HWND dlg, int * ret_len)
740     {
741     char * keyid, defkeyinf[512];
742     const char * fmt;
743    
744     keyid = get_gnupg_default_key ();
745     if (!keyid)
746     BUG (0);
747     if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
748     || (keyid[0] == '0' && keyid[1] == 'x') )
749     fmt = _("Default Key: %s");
750     else
751     fmt = _("Default Key: 0x%s");
752     _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );
753     SetWindowText( dlg, defkeyinf );
754     *ret_len = strlen( defkeyinf );
755     free_if_alloc( keyid );
756     } /* km_return_default_key_str */
757    
758    
759     void
760     km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )
761     {
762     char text[384];
763     int nkeys = 0, nsec = 0, i;
764    
765     GetWindowText( sb, text, sizeof text -1 );
766     nkeys = listview_count_items( lv, 0 );
767     for( i = 0; i < nkeys; i++ ) {
768     if( km_check_for_seckey( lv, i, NULL ) )
769     nsec++;
770     }
771     _snprintf( text+startpos, sizeof text-1, " %d keys (%d secret keys)", nkeys, nsec );
772     SetWindowText( sb, text );
773     } /* km_complete_status_bar */
774    
775    
776 twoaday 22 int
777 twoaday 2 km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
778     {
779     gpgme_error_t err;
780     gpgme_ctx_t ctx;
781     gpgme_editkey_t ek;
782     char keyid[32];
783    
784     listview_get_item_text (lv, pos, 1, keyid, 31);
785     err = gpgme_new (&ctx);
786     if (err)
787     BUG (0);
788     err = gpgme_editkey_new (&ek);
789     if (err)
790     BUG (0);
791     gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);
792     gpgme_editkey_trust_set (ek, 5);
793    
794     err = gpgme_op_editkey (ctx, keyid);
795 twoaday 22
796 twoaday 2 if (err)
797     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
798 twoaday 22 else
799 twoaday 2 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
800    
801     gpgme_release (ctx);
802 twoaday 22 gpgme_editkey_release (ek);
803     return (int)err;
804 twoaday 2 }
805    
806    
807 twoaday 22 void
808     km_find_key (HWND dlg, listview_ctrl_t lv)
809     {
810     int oldpos = listview_get_curr_pos (lv);
811     int n;
812     char *name = get_input_dialog (dlg, "Search", "Search for:");
813     if (name == NULL)
814     return;
815     if (oldpos < 0)
816     oldpos = 0;
817     n = listview_find (lv, name);
818     if (n != -1) {
819     listview_select_one (lv, n);
820     listview_scroll (lv, oldpos, n);
821     }
822     else {
823     const char *s = _("String pattern \"%s\" not found.");
824     char *p = new char[strlen (s) + strlen (name) + 2];
825     if (!p)
826     BUG (0);
827     sprintf (p, s, name);
828     msg_box (dlg, p, _("Key Manager"), MB_INFO);
829     free_if_alloc (p);
830     }
831     free_if_alloc (name);
832     }
833    
834    
835    
836     void
837     km_dump_key (gpgme_key_t key)
838     {
839     #if _DEBUG
840     log_box ("DEBUG", MB_OK,
841     "%d %d %s %d\n%s",
842     gpgme_key_get_ulong_attr (key, GPGME_ATTR_LEN, NULL, 0),
843     gpgme_key_get_ulong_attr (key, GPGME_ATTR_ALGO, NULL, 0),
844     gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0),
845     gpgme_key_get_ulong_attr (key, GPGME_ATTR_CREATED, NULL, 0),
846     gpgme_key_get_string_attr (key, GPGME_ATTR_USERID, NULL, 0));
847     #endif
848     }
849    
850    
851 twoaday 2 gpg_optfile_t
852     km_groupdb_open( void )
853     {
854     gpg_optfile_t opt;
855     char * optfile;
856     int err = 0;
857    
858     optfile = get_gnupg_cfgfile();
859     if( !optfile )
860     BUG( NULL );
861     if( parse_gpg_options( optfile, &opt ) )
862     err = 1;
863     free_if_alloc( optfile );
864     return err? NULL : opt;
865     } /* km_groupdb_open */
866    
867    
868     int
869     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
870     {
871     gpgme_keycache_t kc;
872     gpgme_key_t pk;
873     gpg_optfile_t opt;
874     gpg_group_t grp;
875     gpg_member_t mbr;
876     int no_trust = 0, n;
877    
878     kc = keycache_get_ctx( 1 );
879     if( !kc )
880     BUG( NULL );
881    
882     opt = km_groupdb_open( );
883     if( !opt )
884     return WPTERR_FILE_OPEN;
885    
886     grp = find_group( opt, name );
887     if( !grp )
888     return WPTERR_GENERAL;
889    
890     /* we are paranoid and check that all group members exist in the
891     key cache. there is no need that it is really the real key, but
892     an entry should be available. the rest is up to GPG. */
893     for( mbr = grp->list; mbr; mbr = mbr->next ) {
894     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
895     BUG( NULL );
896     n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );
897     while( n-- ) {
898     const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );
899     if( s && stristr( s, mbr->name )
900     && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )
901     no_trust++;
902     }
903     }
904    
905     gpgme_recipients_add_name( rset, name );
906     release_gpg_options( opt );
907    
908     return no_trust;
909     } /* km_groupdb_expand_recipients */
910    
911    
912     static HTREEITEM
913     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
914     {
915     TVINSERTSTRUCT tvis;
916     HTREEITEM node;
917    
918     memset( &tvis, 0, sizeof tvis );
919     tvis.hParent = parent;
920     tvis.hInsertAfter = TVI_LAST;
921     tvis.item.mask = TVIF_TEXT;
922     tvis.item.pszText = (char *)text;
923     node = TreeView_InsertItem( tree, &tvis );
924     return node;
925     } /* km_tv_insert_item */
926    
927    
928     int
929     km_groups_new( km_group_t *r_gc, HWND ctrl )
930     {
931     km_group_t gc;
932    
933     gc = new km_group_s;
934     if (!gc)
935     BUG (NULL);
936     gc->tree = ctrl;
937     gc->gh = km_groupdb_open ();
938     *r_gc = gc;
939     return 0;
940     } /* km_groups_new */
941    
942    
943     void
944     km_groups_sync( km_group_t gc )
945     {
946     char * optfile;
947    
948     optfile = get_gnupg_cfgfile ();
949     if( !optfile )
950     BUG( NULL );
951     commit_gpg_options( optfile, gc->gh );
952     free_if_alloc( optfile );
953     gc->need_sync = 0;
954     } /* km_groups_sync */
955    
956    
957     void
958     km_groups_release (km_group_t gc)
959     {
960     if( gc ) {
961     /* xxx: this reset the default key (sync=1) */
962     gc->need_sync=0;
963     if (gc->need_sync)
964     km_groups_sync (gc);
965     if (gc->gh)
966     release_gpg_options( gc->gh );
967     gc->gh = NULL;
968     gc->tree = NULL;
969     delete gc;
970     }
971     } /* km_groups_release */
972    
973    
974     int
975     km_groups_load( km_group_t gc )
976     {
977     HTREEITEM n;
978     gpg_group_t grp, g;
979     gpg_member_t mbr;
980     u32 gid = 0;
981    
982     if( !gc->gh )
983     return 0;
984     grp = gc->gh->grp;
985     if( !grp )
986     return 0; /* no groups */
987    
988     for( g = grp; g; g = g->next ) {
989     n = km_tv_insert_item( gc->tree, NULL, g->name );
990     for( mbr = g->list; mbr; mbr = mbr->next ) {
991     if( mbr->used && mbr->name )
992     km_tv_insert_item( gc->tree, n, mbr->name );
993     }
994     }
995     DragAcceptFiles( gc->tree, TRUE );
996     gc->need_sync = 0;
997     return 0;
998     } /* km_groups_load */
999    
1000    
1001     int
1002     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1003     {
1004     TVITEM tvi;
1005     char uid[128], valid[64], text[128];
1006     int i_valid;
1007    
1008     memset( &tvi, 0, sizeof tvi );
1009     tvi.hItem = TreeView_GetSelection( gc->tree );
1010     tvi.pszText = text;
1011     tvi.cchTextMax = sizeof text -1;
1012     tvi.mask = TVIF_TEXT;
1013     TreeView_GetItem( gc->tree, &tvi );
1014    
1015    
1016     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1017     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1018    
1019     if( strstr( valid, "Ultimate" ) )
1020     i_valid = 5;
1021     else if( !strstr( valid, "Full" ) )
1022     i_valid = 4;
1023     else if( !strstr( valid, "Marginal" ) )
1024     i_valid = 3;
1025     else
1026     i_valid = 0;
1027    
1028     /* we can't add the full name. one way would be to use the first
1029     text until a space appears.
1030     group_add_entry(&gc->gh, gid, i_valid, uid);
1031     treeview_add_item(gc->tree, tvi.hItem, uid);
1032     */
1033     gc->need_sync = 1;
1034    
1035     return 0;
1036     } /* km_groups_add */
1037    
1038    
1039     static int
1040     km_groups_del_main( km_group_t gc )
1041     {
1042     TVITEM tvi;
1043     char text[128];
1044     int id;
1045    
1046     memset( &tvi, 0, sizeof tvi );
1047     tvi.hItem = TreeView_GetSelection( gc->tree );
1048     tvi.pszText = text;
1049     tvi.cchTextMax = sizeof text -1;
1050     tvi.mask = TVIF_TEXT;
1051     TreeView_GetItem( gc->tree, &tvi );
1052    
1053     id = log_box( _("Key Manager"), MB_INFO_ASK,
1054     _("Do you really want to delete this group?\n\n%s"), text);
1055     if( id == IDNO )
1056     return 0;
1057     delete_group( gc->gh, text );
1058     TreeView_DeleteItem( gc->tree, &tvi );
1059     gc->need_sync = 1;
1060    
1061     return 0;
1062     } /* km_groups_del */
1063    
1064    
1065     static int
1066     km_groups_del_entry( km_group_t gc )
1067     {
1068     TVITEM tvi;
1069     HTREEITEM root;
1070     int id;
1071     char text[128], info[256];
1072     gpg_group_t grp = NULL;
1073    
1074     memset( &tvi, 0, sizeof tvi );
1075     tvi.hItem = TreeView_GetSelection( gc->tree );
1076     tvi.pszText = text;
1077     tvi.cchTextMax = sizeof text-1;
1078     tvi.mask = TVIF_TEXT;
1079     TreeView_GetItem( gc->tree, &tvi );
1080    
1081     _snprintf( info, sizeof info -1,
1082     _("Do you really want to delete this entry?\n\n%s"), text );
1083    
1084     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1085     if( id == IDNO )
1086     return 0;
1087    
1088     root = TreeView_GetParent( gc->tree, tvi.hItem );
1089     if( root ) {
1090     }
1091    
1092     delete_member( gc->gh, /*fixme*/NULL, text );
1093     TreeView_DeleteItem( gc->tree, &tvi );
1094     gc->need_sync = 1;
1095     return 0;
1096     } /* km_groups_del_entry */
1097    
1098    
1099     int
1100     km_groups_del( km_group_t gc )
1101     {
1102     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1103     return km_groups_del_entry( gc );
1104     else
1105     return km_groups_del_main( gc );
1106     } /* km_groups_del */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26