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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (hide annotations)
Mon Apr 17 09:12:50 2006 UTC (18 years, 10 months ago) by twoaday
File size: 27345 byte(s)
2006-04-16  Timo Schulz  <ts@g10code.de>
 
        * wptHTTP.cpp (getErrorCode): New.
        (connect): Store winsock error code.
        * wptGPGMEData.cpp (is_armor_header): New.
        * wptGPG.cpp (check_gnupg_engine): Free context.
        (gnupg_backup_keyrings): Do not use global vars.
        * wptGPGUtil.cpp (gpg_export_seckey): Export in ascii format.
         
2006-04-15  Timo Schulz  <ts@g10code.de>
 
        * wptKeyManager.cpp (km_get_key): New.
        (km_key_show_revoc_info): New.
        * wptKeyRevokeDlg.cpp (key_revoke_dlg): Cleanups.
        (on_init_dialog): New.
        * wptKeyManagerDlg.cpp (key_manager_dlg_proc): Factour
        out some common code and use km_get_key() instead.
        * wptKeyEditDlgs.cpp (do_init_keylist): Change second
        param type. Change all callers.
        * wptKeyEdit.cpp (addNotation): New.
        * wptKeyEditCB.cpp (editkey_command_handler): Remove 'step'
        param everywhere. Change all callers.


1 werner 36 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 twoaday 133 * Copyright (C) 2001-2006 Timo Schulz
3 werner 36 * Copyright (C) 2005 g10 Code GmbH
4     *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or
8     * modify it under the terms of the GNU General Public License
9     * as published by the Free Software Foundation; either version 2
10     * of the License, or (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     * General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21 twoaday 121
22 werner 36 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24     #endif
25    
26     #include <windows.h>
27     #include <commctrl.h>
28 twoaday 200 #include <assert.h>
29 werner 36 #include <stdio.h>
30    
31     #include "gpgme.h"
32 werner 47 #include "resource.h"
33 werner 36 #include "wptTypes.h"
34     #include "wptW32API.h"
35     #include "wptVersion.h"
36     #include "wptCommonCtl.h"
37     #include "wptNLS.h"
38     #include "wptErrors.h"
39     #include "wptContext.h"
40     #include "wptGPG.h"
41     #include "wptKeylist.h"
42     #include "wptFileManager.h"
43     #include "wptDlgs.h"
44     #include "wptKeyserver.h"
45     #include "wptKeyManager.h"
46     #include "wptKeylist.h"
47     #include "wptHTTP.h"
48     #include "wptKeyEdit.h"
49     #include "wptImport.h"
50 werner 48 #include "wptCrypto.h"
51 twoaday 129 #include "wptUTF8.h"
52 twoaday 133 #include "wptGPGME.h"
53 werner 36
54    
55     /* Return a user friendly key representation in @buf of
56     the key given by @keyid. */
57     static void
58     key_get_clip_info (const char *keyid, char *buf, size_t buflen)
59     {
60     gpgme_key_t pk;
61 twoaday 129 char *uid;
62 werner 36
63     if (get_pubkey (keyid, &pk))
64     BUG (NULL);
65 twoaday 187 uid = utf8_to_native (pk->uids->uid);
66 werner 36 _snprintf (buf, buflen-1,
67     "pub %04d%s/%s %s %s\r\n"
68     " Primary key fingerprint: %s\r\n",
69     pk->subkeys->length,
70 twoaday 128 get_key_pubalgo2 (pk->subkeys->pubkey_algo),
71 werner 36 pk->subkeys->keyid+8,
72     get_key_created (pk->subkeys->timestamp),
73 twoaday 129 uid,
74 werner 36 get_key_fpr (pk));
75 twoaday 129 safe_free (uid);
76 werner 36 }
77    
78    
79 twoaday 128 /* Return a general description of the key @key. */
80 twoaday 150 char*
81     km_key_get_info (gpgme_key_t pk, int is_sec)
82 twoaday 128 {
83     const char *fmt = "%s %04d%s/0x%s %s\n \"%s\"";
84 twoaday 129 char *p, *uid;
85 twoaday 128 int n;
86    
87     n = strlen (fmt) + 8 + 2 + 16 + 12 + strlen (pk->uids->uid) + 32;
88     p = new char[n+1];
89     if (!p)
90     BUG (NULL);
91 twoaday 187 uid = utf8_to_native (pk->uids->uid);
92 twoaday 128 _snprintf (p, n, fmt, is_sec? "sec" : "pub",
93     pk->subkeys->length,
94     get_key_pubalgo2 (pk->subkeys->pubkey_algo),
95     pk->subkeys->keyid+8, get_key_created (pk->subkeys->timestamp),
96 twoaday 129 uid);
97     safe_free (uid);
98 twoaday 128 return p;
99     }
100    
101    
102 werner 36 /* Check if list view @lv contains a secret key at position @pos.
103     If utrust is valid, set it to 1 if the key is valid -1 otherwise.
104     Return value: 1 normal key, 2 smart card key. */
105     int
106     km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
107     {
108 twoaday 128 gpgme_key_t key;
109     winpt_key_s sk;
110 werner 36 int type = 0;
111    
112 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
113     if (!key)
114     BUG (NULL);
115 werner 36 if (utrust)
116     *utrust = 0;
117 twoaday 128 memset (&sk, 0, sizeof (sk));
118     if (!winpt_get_seckey (key->subkeys->keyid+8, &sk))
119 werner 36 type = 1;
120 twoaday 128 if (sk.ext && sk.ext->gloflags.divert_to_card)
121 werner 36 type = 2;
122 twoaday 128 if (utrust && (key->expired || key->revoked))
123 werner 36 *utrust = -1;
124 twoaday 128 else if (utrust && key->owner_trust == GPGME_VALIDITY_ULTIMATE)
125 werner 36 *utrust = 1;
126     return type;
127     }
128    
129    
130     /* Check if the key at position @pos is protected with a passwd. */
131     int
132     km_check_if_protected (listview_ctrl_t lv, int pos)
133     {
134     gpgme_key_t key;
135     winpt_key_s k;
136    
137     key = (gpgme_key_t)listview_get_item2 (lv, pos);
138     if (!key)
139     return 1; /* assume yes */
140     winpt_get_pubkey (key->subkeys->keyid, &k);
141     return k.is_protected;
142     }
143    
144    
145 twoaday 121 /* Check if the key has a good status.
146     Return value: 0 on success. */
147 werner 36 int
148     km_check_key_status (listview_ctrl_t lv, int pos)
149     {
150     int flags = km_get_key_status (lv, pos);
151    
152     if (flags & KM_FLAG_EXPIRED) {
153     msg_box (lv->ctrl, _("This key has expired!\n"
154     "Key check failed."), _("Key Manager"), MB_ERR);
155     return -1;
156     }
157     else if (flags & KM_FLAG_REVOKED) {
158     msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
159     "Key check failed."), _("Key Manager"), MB_ERR);
160     return -1;
161     }
162    
163     return 0;
164 twoaday 121 }
165 werner 36
166    
167 twoaday 121 /* Return all key flags ORed. */
168 werner 36 int
169     km_get_key_status (listview_ctrl_t lv, int pos)
170     {
171     gpgme_key_t key;
172     int flags = 0;
173    
174     if (pos == -1)
175     return 0;
176     key = (gpgme_key_t)listview_get_item2 (lv, pos);
177 twoaday 193 if (!key)
178 werner 36 return 0;
179    
180     if (key->expired)
181     flags |= KM_FLAG_EXPIRED;
182     if (key->revoked)
183     flags |= KM_FLAG_REVOKED;
184     if (key->disabled)
185     flags |= KM_FLAG_DISABLED;
186     return flags;
187 twoaday 121 }
188 werner 36
189    
190     /* Interface to enable or disable a key (@enable = 1 then enable).
191     The key is retrieved from a list control @lv at the pos @pos. */
192     int
193     km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
194     {
195 twoaday 128 gpgme_error_t err;
196     gpgme_key_t key;
197 werner 36 GpgKeyEdit *ke;
198    
199 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
200     if (!key)
201     BUG (NULL);
202     ke = new GpgKeyEdit (key->subkeys->keyid);
203 werner 36 if (!ke)
204     BUG (NULL);
205    
206     err = enable? ke->enable () : ke->disable ();
207 twoaday 121 if (!err)
208 werner 36 show_msg (dlg, 1500, _("Key status changed."));
209     else
210     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
211     delete ke;
212     return err? WPTERR_GENERAL : 0;
213     }
214    
215    
216    
217     /* Create a string that contain all keyids from
218     the key list @rset separated by a space. */
219     char*
220     gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
221     {
222     char *p;
223     int i;
224    
225     if (!n)
226     return NULL;
227     p = (char *)calloc (1, n*(16+1)+n+2);
228     if (!p)
229     BUG (NULL);
230     for (i=0; i < n; i++) {
231     strcat (p, rset[i]->subkeys->keyid);
232     strcat (p, " ");
233     }
234     return p;
235     }
236    
237    
238     /* Export the selected keys in @lv to the clipboard. */
239     int
240     km_clip_export (HWND dlg, listview_ctrl_t lv)
241     {
242     gpgme_error_t err;
243     gpgme_key_t *rset;
244 twoaday 193 GPGME *ctx;
245     char *patt=NULL;
246 werner 36 char buf[256];
247     int n=0;
248     int rc=0;
249    
250     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
251     if (!n) {
252 twoaday 121 msg_box (dlg, _("No key was selected for export."),
253     _("Key Manager"), MB_ERR);
254 twoaday 195 return WPTERR_GENERAL;
255 werner 36 }
256    
257 twoaday 193 patt = gpg_keylist_to_pattern (rset, n);
258    
259     ctx = new GPGME ();
260     if (!ctx)
261     BUG (0);
262     ctx->setArmor (true);
263     err = ctx->exportToClipboard (patt);
264 werner 36 if (err) {
265 twoaday 193 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
266 werner 36 rc = WPTERR_GENERAL;
267     goto leave;
268     }
269     if (n == 1) {
270     key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
271     set_clip_text2 (NULL, buf, strlen (buf), 0);
272     }
273    
274     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
275    
276     leave:
277 twoaday 193 safe_free (rset);
278     safe_free (patt);
279     delete ctx;
280 werner 36 return rc;
281 twoaday 121 }
282 werner 36
283    
284     /* Export the selected secret key from @lv into @fname.
285     It is only allowed to export a single secret key. */
286     int
287     km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
288     {
289     gpgme_key_t *rset;
290     gpgme_error_t err;
291     int n = 0;
292    
293     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
294     if (!n) {
295     msg_box (dlg, _("No key was selected for export."),
296     _("Key Manager"), MB_ERR);
297     return WPTERR_GENERAL;
298     }
299     if (n > 1) {
300     msg_box (dlg, _("Only one secret key can be exported."),
301     _("Key Manager"), MB_ERR);
302     free (rset);
303     return 0; /* we checked this before, so we just quit */
304     }
305    
306     err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
307     if (err)
308     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
309     else
310     log_box (_("Key Manager"), MB_OK,
311     _("Secret key successfully saved in '%s'."), fname);
312    
313     free (rset);
314     return err? WPTERR_GENERAL : 0;
315     }
316    
317    
318 twoaday 129 /* Export the selected recipients from @lv into the file @fname. */
319 werner 36 int
320 twoaday 129 km_file_export (HWND dlg, listview_ctrl_t lv, const char *fname)
321 werner 36 {
322 twoaday 133 GPGME *ctx;
323 werner 36 gpgme_key_t *rset;
324     gpgme_error_t err;
325     char *patt;
326     int n;
327    
328     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
329     if (!n) {
330     msg_box (dlg, _("No key was selected for export."),
331     _("Key Manager"), MB_ERR);
332     return WPTERR_GENERAL;
333     }
334 twoaday 133 patt = gpg_keylist_to_pattern (rset, n);
335 werner 36
336 twoaday 133 ctx = new GPGME ();
337     ctx->setArmor (true);
338     err = ctx->exportToFile (patt, fname);
339     if (err) {
340 twoaday 121 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
341 werner 36 goto leave;
342     }
343 twoaday 133 else
344     log_box (_("Key Manager"), MB_OK,
345     _("Key(s) successfully saved in '%s'."), fname);
346 werner 36
347     leave:
348 twoaday 133 delete ctx;
349     safe_free (patt);
350 werner 36 return (int)err;
351 twoaday 121 }
352 werner 36
353    
354 twoaday 121 /* Read a dash escaped key from the clipboard
355     unescape it and write it back. */
356 werner 36 static int
357     extract_dash_escaped_key (void)
358     {
359     gpgme_data_t inp, plain;
360     gpgme_error_t err;
361    
362     err = gpg_data_new_from_clipboard (&inp, 0);
363     if (err) {
364 twoaday 121 msg_box (NULL, gpgme_strerror (err), _("Key Manager"), MB_ERR);
365 werner 36 return -1;
366     }
367     gpg_data_extract_plaintext (inp, &plain);
368     gpg_data_release_and_set_clipboard (plain, 0);
369     gpgme_data_release (inp);
370    
371     return 0;
372 twoaday 121 }
373 werner 36
374    
375 twoaday 165 /* Import the PGP key data from the clipboard.
376     Return value: 0 on success. */
377     static gpgme_error_t
378     gpg_op_clip_import (gpgme_ctx_t ctx)
379     {
380     gpgme_error_t err = 0;
381     gpgme_data_t keydata = NULL;
382    
383     err = gpg_data_new_from_clipboard (&keydata, 0);
384     if (!err)
385     err = gpgme_op_import (ctx, keydata);
386    
387     gpgme_data_release (keydata);
388     return err;
389     }
390    
391 werner 36 /* Import keys from the clipboard. */
392     int
393 twoaday 165 km_clip_import (HWND dlg, int *r_newkeys, int *r_newsks)
394 werner 36 {
395     gpgme_error_t err;
396 twoaday 165 gpgme_ctx_t ctx = NULL;
397     gpgme_import_result_t res;
398     fm_state_s fm_stat;
399 werner 36 int pgptype;
400 twoaday 165 int id, has_data = 0;
401     int new_keys = 0, new_sks = 0;
402    
403 werner 36 if (!gpg_clip_istext_avail (&has_data) && !has_data) {
404 twoaday 121 msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY),
405     _("Key Manager"), MB_ERR);
406 werner 36 return WPTERR_CLIP_ISEMPTY;
407     }
408     err = gpg_clip_is_secured (&pgptype, &has_data);
409     if (err)
410     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
411     if (!has_data) {
412 twoaday 121 msg_box (dlg, _("No valid OpenPGP data found."),
413     _("Key Manager"), MB_ERR);
414 twoaday 161 return WPTERR_NODATA;
415 werner 36 }
416     if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
417 twoaday 121 msg_box (dlg, _("No valid OpenPGP keys found."),
418     _("Key Manager"), MB_ERR);
419 twoaday 161 return WPTERR_NODATA;
420 werner 36 }
421     if (pgptype & PGP_DASH_ESCAPED) {
422     id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
423     "Do you want to extract the key?"),
424     _("Key Manager"), MB_YESNO);
425     if (id == IDYES)
426     extract_dash_escaped_key ();
427     else
428     msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
429     _("Key Manager"), MB_INFO);
430     }
431    
432 twoaday 165 memset (&fm_stat, 0, sizeof (fm_stat));
433     fm_stat.opaque = m_strdup ("Clipboard");
434     fm_stat.import.is_clip = 1;
435     has_data = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
436     file_import_dlg_proc, (LPARAM)&fm_stat,
437 twoaday 150 _("Key Import"), IDS_WINPT_IMPORT);
438 twoaday 165 if (!has_data)
439     goto leave;
440    
441     err = gpgme_new (&ctx);
442     if (err)
443     BUG (NULL);
444     op_begin ();
445     err = gpg_op_clip_import (ctx);
446     op_end ();
447     if (err) {
448     msg_box (dlg, gpgme_strerror (err), _("Import"), MB_ERR);
449     goto leave;
450     }
451    
452     res = gpgme_op_import_result (ctx);
453     print_import_status (res);
454     new_keys = res->considered - res->unchanged;
455     new_sks = res->secret_imported - res->secret_unchanged;
456     if (res->no_user_id > 0) {
457     msg_box (dlg, _("Key without a self signature was dectected!\n"
458     "(This key is NOT usable for encryption, etc)\n"),
459     _("Import"), MB_WARN);
460     }
461    
462     leave:
463     if (ctx)
464     gpgme_release (ctx);
465     free_if_alloc (fm_stat.opaque);
466 twoaday 164 if (r_newkeys)
467     *r_newkeys = new_keys;
468 twoaday 165 if (r_newsks)
469     *r_newsks = new_sks;
470     if (!new_keys || !has_data)
471 twoaday 161 return WPTERR_NODATA;
472 twoaday 165 return (int)err;
473 werner 36 }
474    
475    
476     /* Import a key from the http URL @url. */
477     int
478     km_http_import (HWND dlg, const char *url)
479     {
480     FILE *fp;
481 twoaday 181 wHTTP *hd;
482 werner 36 char tmpfile[500];
483     int rc = 0;
484    
485     if (strncmp (url, "http://", 7)) {
486     log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
487     return WPTERR_GENERAL;
488     }
489    
490 twoaday 193 get_temp_name (tmpfile, sizeof (tmpfile)-1, "winpt_http.tmp");
491 twoaday 175 fp = fopen (tmpfile, "wb");
492 werner 36 if (!fp) {
493 twoaday 175 log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", tmpfile,
494 twoaday 121 winpt_strerror (WPTERR_FILE_CREAT));
495 werner 36 return WPTERR_FILE_CREAT;
496     }
497    
498 twoaday 181 hd = new wHTTP (url);
499     if (hd->getStatusCode () == HTTP_STAT_200)
500     hd->readData (fp);
501     else {
502     log_box (_("Key Import HTTP"), MB_ERR,
503     _("Could not fetch key from URL: %s"), url);
504 werner 36 rc = WPTERR_GENERAL;
505     }
506 twoaday 181
507     delete hd;
508     fclose (fp);
509     if (!rc)
510     km_file_import (dlg, tmpfile, NULL, NULL);
511 twoaday 175 DeleteFile (tmpfile);
512 werner 36 return rc;
513     }
514    
515    
516 twoaday 165 /* Import a key from the given file @fname, if @fname is
517     NULL use the common 'file open' dialog.
518 werner 36 On success an import statistics dialog is shown. */
519     int
520 twoaday 165 km_file_import (HWND dlg, const char *fname, int *r_newkeys, int *r_newsks)
521 werner 36 {
522     gpgme_data_t keydata = NULL;
523     gpgme_ctx_t ctx;
524     gpgme_error_t err;
525     fm_state_s fm_stat;
526     gpgme_import_result_t res;
527 twoaday 165 const char *name;
528 twoaday 150 int no_data = 0;
529 twoaday 165 int new_keys = 0, new_sks = 0;
530    
531     if (!fname) {
532     name = get_fileopen_dlg (dlg, _("Choose Name of the Key File"),
533     NULL, NULL);
534     if (!name)
535     return WPTERR_GENERAL;
536     }
537     else
538     name = fname;
539    
540 werner 36 memset (&fm_stat, 0, sizeof (fm_stat));
541 twoaday 165 fm_stat.opaque = m_strdup (name);
542 werner 36
543     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
544     file_import_dlg_proc, (LPARAM)&fm_stat,
545     _("File Import"), IDS_WINPT_IMPORT);
546     if (fm_stat.cancel == 1) {
547     free_if_alloc (fm_stat.opaque);
548     return WPTERR_GENERAL;
549     }
550    
551     err = gpgme_new (&ctx);
552     if (err)
553     BUG (NULL);
554 twoaday 165 err = gpgme_data_new_from_file (&keydata, name, 1);
555 werner 36 if (err) {
556     msg_box (dlg, _("Could not read key-data from file."),
557     _("Key Manager"), MB_ERR);
558     goto leave;
559     }
560    
561 twoaday 130 op_begin ();
562 werner 36 err = gpgme_op_import (ctx, keydata);
563 twoaday 130 op_end ();
564 werner 36 if (err) {
565     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
566     goto leave;
567     }
568    
569     res = gpgme_op_import_result (ctx);
570 twoaday 165 if (res->unchanged == res->considered &&
571     res->secret_unchanged == res->secret_imported)
572 twoaday 150 no_data = 1;
573 twoaday 165 new_keys = res->considered - res->unchanged;
574     new_sks = res->secret_imported - res->secret_unchanged;
575 werner 36 if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
576     res->new_revocations = 1;
577     if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
578     res->secret_imported = 1;
579    
580 twoaday 123 /* XXX: if we import a key pair but the secret key comes first,
581     no_{valid}_user_id is 1 even so the public key, which comes
582     later is valid and self-signed. */
583 werner 36 print_import_status (res);
584     if (res->no_user_id > 0) {
585     msg_box (dlg, _("Key without a self signature was dectected!\n"
586 twoaday 165 "(This key is NOT usable for encryption, etc)\n"),
587     _("Import"), MB_WARN);
588 werner 36 }
589    
590     leave:
591     gpgme_data_release (keydata);
592     gpgme_release (ctx);
593     free_if_alloc (fm_stat.opaque);
594 twoaday 165 if (r_newkeys)
595     *r_newkeys = new_keys;
596     if (r_newsks)
597     *r_newsks = new_sks;
598 twoaday 150 if (no_data)
599 twoaday 161 return WPTERR_NODATA;
600 werner 36 return (int)err;
601     }
602    
603    
604 twoaday 166 /* Import all dropped files. */
605     int
606     km_dropped_file_import (HWND dlg, HDROP hdrop,
607     int *r_newkeys, int *r_newsks)
608     {
609     char name[MAX_PATH+1];
610     UINT n = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
611     UINT i;
612     int newk=0, newsk=0, err=0;
613    
614     for (i=0; i < n; i++) {
615     DragQueryFile (hdrop, i, name, MAX_PATH);
616     err = km_file_import (dlg, name, &newk, &newsk);
617     *r_newkeys = (*r_newkeys) + newk;
618     *r_newsks = (*r_newsks) + newsk;
619     }
620 twoaday 167 DragFinish (hdrop);
621 twoaday 166 return err;
622     }
623    
624    
625 werner 36 /* Mark the keys in @rset as deleted in the keycache. */
626     static void
627     delete_keys_from_cache (gpgme_key_t *rset, size_t n)
628     {
629     gpg_keycache_t pub = keycache_get_ctx (1);
630 twoaday 164 gpg_keycache_t sec = keycache_get_ctx (0);
631     gpgme_key_t sk;
632 werner 36 int i=0;
633    
634 twoaday 164 while (n-- > 0) {
635     if (!get_seckey (rset[i]->subkeys->keyid, &sk))
636     gpg_keycache_delete_key (sec, sk->subkeys->keyid);
637     gpg_keycache_delete_key (pub, rset[i]->subkeys->keyid);
638     i++;
639     }
640 werner 36 }
641    
642    
643 twoaday 179 /* Check that the selected default secret key is still
644     available. If not, delete the entry in gpg.conf. */
645     static void
646     check_exist_default_key (void)
647     {
648     gpgme_key_t sk;
649     char *defkey;
650    
651     defkey = get_gnupg_default_key ();
652     if (defkey && get_seckey (defkey, &sk))
653     set_gnupg_default_key (NULL);
654     free_if_alloc (defkey);
655     }
656    
657    
658 werner 36 /* Delete all selected keys from the list view @lv. */
659     int
660     km_delete_keys (listview_ctrl_t lv, HWND dlg)
661     {
662     gpgme_error_t err;
663     gpgme_ctx_t ctx;
664 twoaday 128 gpgme_key_t *rset;
665     gpgme_key_t key;
666     char *p;
667 werner 36 int with_seckey=0, seckey_type=0, confirm=0;
668     int i, rc, n, k_pos=0;
669    
670     if (listview_get_curr_pos (lv) == -1) {
671     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
672 twoaday 121 return -1;
673 werner 36 }
674    
675     if (listview_count_items (lv, 1) > 8) {
676     i = msg_box (NULL, _("Do you really want to confirm each key?"),
677     _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
678     if (i == IDCANCEL)
679     return 0;
680     if (i != IDNO)
681     confirm = 1;
682     }
683     else
684     confirm = 1;
685    
686 twoaday 133 /* n = total amount of keys, i is the selected amount. */
687 werner 36 n = listview_count_items (lv, 0);
688 twoaday 133 i = listview_count_items (lv, 1);
689     rset = (gpgme_key_t *)calloc (i+1, sizeof (gpgme_key_t));
690 werner 36 if (!rset)
691     BUG (NULL);
692 twoaday 121 for (i = 0; i < n; i++) {
693 twoaday 128 if (listview_get_item_state(lv, i)) {
694     key = (gpgme_key_t)listview_get_item2 (lv, i);
695     if (!key)
696     BUG (NULL);
697 werner 36 seckey_type = km_check_for_seckey (lv, i, NULL);
698     if (confirm && !seckey_type) {
699 twoaday 150 p = km_key_get_info (key, 0);
700 twoaday 133 rc = log_box (_("Key Manager"), MB_YESNO|MB_ICONWARNING,
701 werner 36 _("Do you really want to delete this key?\n\n"
702 twoaday 128 "%s"), p);
703     if (rc == IDYES)
704     rset[k_pos++] = key;
705     free_if_alloc (p);
706 werner 36 }
707     else if (confirm) {
708 twoaday 150 p = km_key_get_info (key, 1);
709 twoaday 121 rc = log_box (_("Key Manager"), MB_YESNO|MB_ICONWARNING,
710 werner 36 _("Do you really want to delete this KEY PAIR?\n\n"
711     "Please remember that you are not able to decrypt\n"
712     "messages you stored with this key any longer.\n"
713     "\n"
714 twoaday 128 "%s"), p);
715 twoaday 133 if (rc == IDYES) {
716 werner 36 if (seckey_type == 2)
717 twoaday 121 msg_box (dlg, _("The actual secret key is stored on a smartcard.\n"
718 werner 36 "Only the public key and the secret key \n"
719 twoaday 121 "placeholder will be deleted.\n"),
720     _("Key Manager"), MB_OK);
721 twoaday 128 rset[k_pos++] = key;
722 werner 36 }
723     with_seckey = 1;
724 twoaday 128 free_if_alloc (p);
725 werner 36 }
726     else {
727     with_seckey = 1;
728 twoaday 128 rset[k_pos++] = key;
729 werner 36 }
730     }
731     }
732    
733     if (k_pos == 0) {
734     free (rset);
735     return 0;
736     }
737    
738     err = gpgme_new (&ctx);
739     if (err)
740     BUG (NULL);
741 twoaday 128 n = k_pos;
742 twoaday 130 op_begin ();
743 werner 36 for (i=0; i < k_pos; i++) {
744     err = gpgme_op_delete (ctx, rset[i], with_seckey);
745     if (err)
746     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
747     else
748     n--;
749     }
750 twoaday 130 op_end ();
751 werner 36 if (n == 0)
752 twoaday 179 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
753 werner 36 gpgme_release (ctx);
754 twoaday 150 listview_del_sel_items (lv);
755 werner 36 delete_keys_from_cache (rset, k_pos);
756     free (rset);
757 twoaday 179 if (with_seckey)
758     check_exist_default_key ();
759 werner 36 return (int)err;
760     }
761    
762    
763 twoaday 121 /* Send the select key in @lv to the keyserver @host:@port. */
764 werner 36 int
765 twoaday 181 km_send_to_keyserver (listview_ctrl_t lv, HWND dlg,
766     const char *host, WORD port)
767 werner 36 {
768 twoaday 128 gpgme_key_t key;
769 werner 36 int id;
770    
771 twoaday 121 id = listview_get_curr_pos (lv);
772     if (id == -1) {
773 werner 36 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
774     return WPTERR_GENERAL;
775     }
776    
777 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, id);
778     if (!key)
779     BUG (NULL);
780 werner 36 id = log_box (_("Key Manager"), MB_YESNO,
781 twoaday 195 _("Do you really want to send '0x%s' to keyserver %s?"),
782 twoaday 128 key->subkeys->keyid+8, host);
783     if (id == IDYES)
784     hkp_send_key (dlg, host, port, key->subkeys->keyid+8);
785 werner 36
786     return 0;
787 twoaday 121 }
788 werner 36
789    
790 twoaday 77 /* Send the selected key in @lv via MAPI to a mail recipient. */
791 werner 36 int
792 twoaday 77 km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg)
793 werner 36 {
794     gpgme_key_t key;
795     gpgme_error_t rc;
796 twoaday 175 GPGME *ctx;
797 twoaday 121 char *fname;
798 twoaday 129 char *name;
799 werner 36 int pos;
800 twoaday 175 int n;
801 werner 36
802 twoaday 121 if (listview_count_items (lv, 1) > 1) {
803 twoaday 77 msg_box (dlg, _("Please only select one key."),
804     _("Key Manager"), MB_INFO|MB_OK);
805 werner 36 return WPTERR_GENERAL;
806     }
807 twoaday 77 pos = listview_get_curr_pos (lv);
808     if (pos == -1) {
809     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
810 werner 36 return WPTERR_GENERAL;
811     }
812 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
813     if (!key)
814 twoaday 77 BUG (NULL);
815 werner 36
816 twoaday 187 name = utf8_to_native (key->uids->name);
817 twoaday 175 n = strlen (name)+1 + MAX_PATH + 5;
818     fname = new char[n+1];
819     get_temp_name (fname, n-5, name);
820 twoaday 121 for (pos=0; pos < (int)strlen (fname); pos++) {
821     if (fname[pos] == ' ')
822     fname[pos] = '_';
823     }
824 twoaday 175 strcat (fname, ".asc");
825     ctx = new GPGME ();
826     ctx->setArmor (true);
827     rc = ctx->exportToFile (key->subkeys->keyid, fname);
828 werner 36 if (rc)
829     msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
830 twoaday 175 else
831 twoaday 128 mapi_send_pubkey (key->subkeys->keyid+8, fname);
832 werner 36
833 twoaday 175 delete ctx;
834 twoaday 129 safe_free (name);
835 twoaday 121 free_if_alloc (fname);
836 werner 36 return rc;
837     }
838    
839    
840 twoaday 181 /* Refresh the selected key in the listview @lv at position @pos.
841     Legal flags are 0 = single key. */
842 werner 36 static void
843 twoaday 133 km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos, int flags)
844 werner 36 {
845 twoaday 181 winpt_key_s pk;
846 twoaday 128 gpgme_key_t key;
847 twoaday 181 const char *pref_kserv = default_keyserver;
848 twoaday 165 char keyid[16+1];
849     int idx, err = 0;
850 twoaday 181
851 werner 36 if (pos != 0)
852     idx = pos;
853     else
854     idx = listview_get_curr_pos (lv);
855 twoaday 121 if (idx != -1) {
856 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, idx);
857 twoaday 133 if (!key)
858     BUG (0);
859 twoaday 181 /* In single refresh mode, try to use the users preferred keyserver. */
860     if (flags == 0 &&
861     !winpt_get_pubkey (key->subkeys->keyid+8, &pk) &&
862 twoaday 193 !gpg_keycache_update_attr (pk.ext, KC_ATTR_PREFKSERV, 0)
863     && pk.ext->pref_keyserver)
864 twoaday 181 pref_kserv = pk.ext->pref_keyserver;
865 twoaday 165 _snprintf (keyid, sizeof (keyid)-1, "%s", key->subkeys->keyid+8);
866 twoaday 181 err = hkp_recv_key (dlg, pref_kserv, default_keyserver_port,
867 twoaday 165 keyid, 0, flags);
868     /* if we receive just a single key (no refresh mode), update it. */
869     if (!flags && !err)
870     keycache_update (0, keyid);
871 werner 36 }
872     }
873    
874    
875 twoaday 133 /* Refresh the selected keys from the default keyserver. */
876 werner 36 void
877     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
878     {
879 twoaday 175 int cnt, id, i;
880 twoaday 133
881     cnt = listview_count_items (lv, 0);
882     if (listview_count_items (lv, 1) == cnt) {
883     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"),
884 twoaday 121 _("Key Manager"), MB_YESNO);
885 werner 36 if (id == IDNO)
886     return;
887 twoaday 175 if (kserver_check_inet_connection ()) {
888     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
889     _("Key Manager"), MB_ERR);
890     return;
891     }
892 werner 36 }
893 twoaday 133 if (listview_count_items (lv, 1) == 1)
894     km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0);
895 werner 36 else {
896 twoaday 133 for (i=0; i < cnt; i++) {
897 werner 36 if (listview_get_item_state (lv, i))
898 twoaday 133 km_refresh_one_key (lv, dlg, i, KM_KS_REFRESH);
899 werner 36 }
900     }
901 twoaday 121 }
902 werner 36
903    
904     void
905     km_set_clip_info (const char *uid)
906     {
907     char buf[256];
908    
909 twoaday 129 key_get_clip_info (uid, buf, sizeof (buf)-1);
910 werner 36 set_clip_text (NULL, buf, strlen (buf));
911 twoaday 121 }
912 werner 36
913    
914    
915     /* Return TRUE if the key in the list @lv at pos @pos is an
916     old version 3 key. */
917     int
918     km_key_is_v3 (listview_ctrl_t lv, int pos)
919     {
920     gpgme_key_t pk;
921    
922 twoaday 128 pk = (gpgme_key_t)listview_get_item2 (lv, pos);
923     if (!pk)
924 werner 36 BUG (NULL);
925     if (strlen (pk->subkeys->fpr) == 32 &&
926     pk->subkeys->pubkey_algo == GPGME_PK_RSA)
927     return -1;
928     return 0;
929     }
930    
931    
932     /* Set trust of selected key in @lv (at @pos) to ultimate. */
933     int
934     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
935     {
936 twoaday 128 gpgme_error_t err;
937     gpgme_key_t key;
938 werner 36 GpgKeyEdit *ke;
939    
940 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
941     if (!key)
942     BUG (NULL);
943     ke = new GpgKeyEdit (key->subkeys->keyid);
944 werner 36 if (!ke)
945     BUG (0);
946    
947     err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
948     if (err)
949     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
950     else
951     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
952    
953     delete ke;
954     return (int)err;
955     }
956    
957    
958     void
959     km_find_key (HWND dlg, listview_ctrl_t lv)
960     {
961     int oldpos = listview_get_curr_pos (lv);
962     int n;
963     char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
964     if (name == NULL)
965     return;
966     if (oldpos < 0)
967     oldpos = 0;
968     n = listview_find (lv, name);
969     if (n != -1) {
970     listview_select_one (lv, n);
971     listview_scroll (lv, oldpos, n);
972     }
973     else {
974     const char *s = _("String pattern \"%s\" not found.");
975     char *p = new char[strlen (s) + strlen (name) + 2];
976     if (!p)
977     BUG (0);
978     sprintf (p, s, name);
979     msg_box (dlg, p, _("Key Manager"), MB_INFO);
980     free_if_alloc (p);
981     }
982     free_if_alloc (name);
983     }
984 twoaday 129
985    
986     /* Return a user-friendly name for a key derrived from
987     name. If @is_secret is 1, a secret key name will be generated. */
988     char*
989     km_gen_export_filename (const char *keyid, int is_secret)
990     {
991     gpgme_key_t key;
992     char *p, *uid;
993    
994     if (get_pubkey (keyid, &key))
995     return m_strdup (keyid);
996 twoaday 187 uid = utf8_to_native (key->uids->name);
997 twoaday 129 if (!uid)
998     return m_strdup (keyid);
999     p = new char[strlen (uid) + 8 + 16];
1000     if (!p)
1001     BUG (0);
1002     sprintf (p, "%s%s.asc", uid, is_secret? "_sec" : "");
1003     for (size_t i=0; i < strlen (p); i++) {
1004     if (p[i] == ' ' || p[i] == ':' || p[i] == '?' || p[i] == '|')
1005     p[i] = '_';
1006     }
1007     safe_free (uid);
1008     return p;
1009     }
1010 twoaday 200
1011    
1012     /* Retrieve the GPGME pointer from the selected list view
1013     item and return the WinPT specific key context. */
1014     int
1015     km_get_key (listview_ctrl_t lv, int pos, winpt_key_t k)
1016     {
1017     gpgme_key_t key;
1018    
1019     if (pos == -1)
1020     return -1;
1021     key = (gpgme_key_t)listview_get_item2 (lv, pos);
1022     if (!key)
1023     BUG (NULL);
1024     memset (k, 0, sizeof (*k));
1025     strncpy (k->tmp_keyid, key->subkeys->keyid+8, 8);
1026     k->keyid = k->tmp_keyid;
1027     k->is_protected = km_check_if_protected (lv, pos);
1028     k->key_pair = km_check_for_seckey (lv, pos, NULL);
1029     k->is_v3 = km_key_is_v3 (lv, pos);
1030     k->flags = km_get_key_status (lv, pos);
1031     k->ctx = key;
1032     k->uid = key->uids->uid;
1033     return 0;
1034     }
1035    
1036    
1037     /* Show details of the revocation of the key @k. */
1038     void
1039     km_key_show_revoc_info (winpt_key_t k)
1040     {
1041     const char *desc;
1042     char *val=NULL, *p;
1043     int len, reason;
1044     const char *reasons[] = {
1045     _("0. No reason specified"),
1046     _("1. Key has been compromised"),
1047     _("2. Key is superseded"),
1048     _("3. Key is no longer used"),
1049     NULL
1050     };
1051    
1052     /* spk:29:1:19:%00This key is kaputt */
1053     gpg_find_key_subpacket (k->keyid, 29, &val);
1054     if (!val || strlen (val) < 3) {
1055     safe_free (val);
1056     return;
1057     }
1058    
1059     len = atoi (val+9);
1060     p = strchr (val+9, ':');
1061     assert (p);
1062     p++;
1063     reason = atoi (p+1);
1064     if (strlen (p+1) > 0)
1065     desc = p+3;
1066     else
1067     desc = "none";
1068     log_box (_("Key Manager"), MB_OK,
1069     "Key revocation info for '%s':\n"
1070     "Reason for revocation: %s\n"
1071     "Description: %s\n",
1072     k->ctx->uids->name, reasons[reason % 4]+3,
1073     desc);
1074     safe_free (val);
1075     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26