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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 195 - (hide annotations)
Mon Apr 3 17:10:47 2006 UTC (18 years, 11 months ago) by twoaday
File size: 25748 byte(s)
Prepare new release.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26