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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 205 - (hide annotations)
Thu Apr 27 12:46:03 2006 UTC (18 years, 10 months ago) by twoaday
File size: 27310 byte(s)
2006-04-27  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptKeyManager.cpp (km_get_key_ptr): New.
        * wptListview.cpp (listview_get_item_text): Drop utf8 support.
        * wptKeyCache.cpp (keycache_decode_uids): New.
        (free_native_uids): New.
        * wptKeyEdit.cpp (uid_inf_colon_handler): Do utf8 decodig here.
                                                                                
2006-04-26  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptKeylist.cpp (get_keyid_from_fpr): New.
        * wptDecryptClipDlg.cpp (clip_decrypt_dlg): Use it here.
        * wptVerifyList.cpp (verlist_add_sig): Likewise.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26