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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (hide annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 25896 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26