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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 181 - (hide annotations)
Tue Mar 14 11:01:22 2006 UTC (18 years, 11 months ago) by twoaday
File size: 26886 byte(s)
2006-03-12  Timo Schulz  <ts@g10code.de>
 
        * wptGPG.cpp (gnupg_load_config): Search for 'ask-cert-expire'.
        * wptKeyPropsDlg.cpp (display_key_info): Automatically update
        sym algorithm preferences if needed.
        * wptKeysignDlg.cpp (date_is_today): New.
        (keysign_dlg_proc): Only allow to set cert expire date if
        the option was found.
        * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Allow to set
        'ask-cert-expire'.
         


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26