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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 164 - (hide annotations)
Fri Jan 20 09:19:15 2006 UTC (19 years, 1 month ago) by twoaday
File size: 23968 byte(s)
2006-01-20  Timo Schulz  <ts@g10code.com>
 
        * wptKeyCache.cpp (w32_tmpfile): New.
        (parse_attr_data): Use it here.
        * wptGPGUtil.cpp (gpg_get_photoid_data): Reset @ndata var.
         
2006-01-19  Timo Schulz  <ts@g10code.com>
 
        * wptClipVerifyDlg.cpp (clip_verify_dlg_proc): Do not
        reload the entire cache, just update the key.
        * wptFileVerifyDlg.cpp (file_verify_dlg_proc): Likewise.
        * wptKeyPropsDlg.cpp (keyprops_dlg_proc): Set update flag.
        * wptKeyRevokersDlg.cpp (key_revokers_dlg_proc): Likewise.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Update key
        if need after showing the properties.
        * wptGPGMEData.cpp (gpg_data_putc): Fix off-by-one bug.
        * wptKeyManager.cpp (km_import_file): New param. Changed
        all callers.
        (km_import_clip): Likewise.
        (delete_keys_from_cache): Delete secret part if available.
        * wptClipImportDlg.cpp (print_import_status): If there
        are too many new keys, use reload code.
         


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     /* Import keys from the clipboard. */
429     int
430 twoaday 164 km_clip_import (HWND dlg, int *r_newkeys)
431 werner 36 {
432     gpgme_error_t err;
433     int pgptype;
434     int id;
435 twoaday 164 int new_keys = 0, has_data = 0;
436 werner 36
437     if (!gpg_clip_istext_avail (&has_data) && !has_data) {
438 twoaday 121 msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY),
439     _("Key Manager"), MB_ERR);
440 werner 36 return WPTERR_CLIP_ISEMPTY;
441     }
442     err = gpg_clip_is_secured (&pgptype, &has_data);
443     if (err)
444     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
445     if (!has_data) {
446 twoaday 121 msg_box (dlg, _("No valid OpenPGP data found."),
447     _("Key Manager"), MB_ERR);
448 twoaday 161 return WPTERR_NODATA;
449 werner 36 }
450     if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
451 twoaday 121 msg_box (dlg, _("No valid OpenPGP keys found."),
452     _("Key Manager"), MB_ERR);
453 twoaday 161 return WPTERR_NODATA;
454 werner 36 }
455     if (pgptype & PGP_DASH_ESCAPED) {
456     id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
457     "Do you want to extract the key?"),
458     _("Key Manager"), MB_YESNO);
459     if (id == IDYES)
460     extract_dash_escaped_key ();
461     else
462     msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
463     _("Key Manager"), MB_INFO);
464     }
465    
466 twoaday 164 new_keys = dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
467 twoaday 150 clip_import_dlg_proc, 0,
468     _("Key Import"), IDS_WINPT_IMPORT);
469 twoaday 164 if (r_newkeys)
470     *r_newkeys = new_keys;
471     if (!new_keys)
472 twoaday 161 return WPTERR_NODATA;
473 werner 36 return 0;
474     }
475    
476    
477     /* Import a key from the http URL @url. */
478     int
479     km_http_import (HWND dlg, const char *url)
480     {
481     http_hd_t hd;
482     FILE *fp;
483     char *p;
484     char tmpfile[500];
485     int statcode;
486     int rc = 0;
487    
488     if (strncmp (url, "http://", 7)) {
489     log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
490     return WPTERR_GENERAL;
491     }
492    
493     GetTempPath (sizeof (tmpfile)-128, tmpfile);
494     p = make_filename (tmpfile, "winpt_file_http", "tmp");
495     if (!p)
496     BUG (0);
497     fp = fopen (p, "wb");
498     if (!fp) {
499     free_if_alloc (p);
500 twoaday 121 log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p,
501     winpt_strerror (WPTERR_FILE_CREAT));
502 werner 36 return WPTERR_FILE_CREAT;
503     }
504    
505     /* parse URL */
506     rc = http_send_request2 (url, &hd);
507     if (!rc)
508     rc = http_parse_response (hd, &statcode);
509     if (!rc)
510     rc = http_parse_data (hd, fp);
511     http_hd_free (hd);
512     fclose (fp);
513     if (rc) {
514     msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
515     rc = WPTERR_GENERAL;
516     }
517 twoaday 164 km_file_import (dlg, p, NULL);
518 werner 48 remove (p);
519 werner 36 free_if_alloc (p);
520     return rc;
521     }
522    
523    
524     /* Import a key from the given file @fname.
525     On success an import statistics dialog is shown. */
526     int
527 twoaday 164 km_file_import (HWND dlg, const char *fname, int *r_newkeys)
528 werner 36 {
529     gpgme_data_t keydata = NULL;
530     gpgme_ctx_t ctx;
531     gpgme_error_t err;
532     fm_state_s fm_stat;
533     gpgme_import_result_t res;
534 twoaday 150 int no_data = 0;
535 werner 36
536     memset (&fm_stat, 0, sizeof (fm_stat));
537     fm_stat.opaque = m_strdup (fname);
538    
539     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
540     file_import_dlg_proc, (LPARAM)&fm_stat,
541     _("File Import"), IDS_WINPT_IMPORT);
542     if (fm_stat.cancel == 1) {
543     free_if_alloc (fm_stat.opaque);
544     return WPTERR_GENERAL;
545     }
546    
547     err = gpgme_new (&ctx);
548     if (err)
549     BUG (NULL);
550     err = gpgme_data_new_from_file (&keydata, fname, 1);
551     if (err) {
552     msg_box (dlg, _("Could not read key-data from file."),
553     _("Key Manager"), MB_ERR);
554     goto leave;
555     }
556    
557 twoaday 130 op_begin ();
558 werner 36 err = gpgme_op_import (ctx, keydata);
559 twoaday 130 op_end ();
560 werner 36 if (err) {
561     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
562     goto leave;
563     }
564    
565     res = gpgme_op_import_result (ctx);
566 twoaday 150 if (res->unchanged == res->considered)
567     no_data = 1;
568 twoaday 164 if (r_newkeys)
569     *r_newkeys = res->considered - res->unchanged;
570 werner 36 if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
571     res->new_revocations = 1;
572     if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
573     res->secret_imported = 1;
574    
575 twoaday 123 /* XXX: if we import a key pair but the secret key comes first,
576     no_{valid}_user_id is 1 even so the public key, which comes
577     later is valid and self-signed. */
578 werner 36 print_import_status (res);
579     if (res->no_user_id > 0) {
580     msg_box (dlg, _("Key without a self signature was dectected!\n"
581     "(This key is NOT usable for encryption, etc)\n"
582     "\n"
583     "Cannot import these key(s)!"), _("Import"), MB_INFO);
584     }
585    
586     leave:
587     gpgme_data_release (keydata);
588     gpgme_release (ctx);
589     free_if_alloc (fm_stat.opaque);
590 twoaday 150 if (no_data)
591 twoaday 161 return WPTERR_NODATA;
592 werner 36 return (int)err;
593     }
594    
595    
596     /* Mark the keys in @rset as deleted in the keycache. */
597     static void
598     delete_keys_from_cache (gpgme_key_t *rset, size_t n)
599     {
600     gpg_keycache_t pub = keycache_get_ctx (1);
601 twoaday 164 gpg_keycache_t sec = keycache_get_ctx (0);
602     gpgme_key_t sk;
603 werner 36 int i=0;
604    
605 twoaday 164 while (n-- > 0) {
606     if (!get_seckey (rset[i]->subkeys->keyid, &sk))
607     gpg_keycache_delete_key (sec, sk->subkeys->keyid);
608     gpg_keycache_delete_key (pub, rset[i]->subkeys->keyid);
609     i++;
610     }
611 werner 36 }
612    
613    
614     /* Delete all selected keys from the list view @lv. */
615     int
616     km_delete_keys (listview_ctrl_t lv, HWND dlg)
617     {
618     gpgme_error_t err;
619     gpgme_ctx_t ctx;
620 twoaday 128 gpgme_key_t *rset;
621     gpgme_key_t key;
622     char *p;
623 werner 36 int with_seckey=0, seckey_type=0, confirm=0;
624     int i, rc, n, k_pos=0;
625    
626     if (listview_get_curr_pos (lv) == -1) {
627     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
628 twoaday 121 return -1;
629 werner 36 }
630    
631     if (listview_count_items (lv, 1) > 8) {
632     i = msg_box (NULL, _("Do you really want to confirm each key?"),
633     _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
634     if (i == IDCANCEL)
635     return 0;
636     if (i != IDNO)
637     confirm = 1;
638     }
639     else
640     confirm = 1;
641    
642 twoaday 133 /* n = total amount of keys, i is the selected amount. */
643 werner 36 n = listview_count_items (lv, 0);
644 twoaday 133 i = listview_count_items (lv, 1);
645     rset = (gpgme_key_t *)calloc (i+1, sizeof (gpgme_key_t));
646 werner 36 if (!rset)
647     BUG (NULL);
648 twoaday 121 for (i = 0; i < n; i++) {
649 twoaday 128 if (listview_get_item_state(lv, i)) {
650     key = (gpgme_key_t)listview_get_item2 (lv, i);
651     if (!key)
652     BUG (NULL);
653 werner 36 seckey_type = km_check_for_seckey (lv, i, NULL);
654     if (confirm && !seckey_type) {
655 twoaday 150 p = km_key_get_info (key, 0);
656 twoaday 133 rc = log_box (_("Key Manager"), MB_YESNO|MB_ICONWARNING,
657 werner 36 _("Do you really want to delete this key?\n\n"
658 twoaday 128 "%s"), p);
659     if (rc == IDYES)
660     rset[k_pos++] = key;
661 werner 36 with_seckey = 0;
662 twoaday 128 free_if_alloc (p);
663 werner 36 }
664     else if (confirm) {
665 twoaday 150 p = km_key_get_info (key, 1);
666 twoaday 121 rc = log_box (_("Key Manager"), MB_YESNO|MB_ICONWARNING,
667 werner 36 _("Do you really want to delete this KEY PAIR?\n\n"
668     "Please remember that you are not able to decrypt\n"
669     "messages you stored with this key any longer.\n"
670     "\n"
671 twoaday 128 "%s"), p);
672 twoaday 133 if (rc == IDYES) {
673 werner 36 if (seckey_type == 2)
674 twoaday 121 msg_box (dlg, _("The actual secret key is stored on a smartcard.\n"
675 werner 36 "Only the public key and the secret key \n"
676 twoaday 121 "placeholder will be deleted.\n"),
677     _("Key Manager"), MB_OK);
678 twoaday 128 rset[k_pos++] = key;
679 werner 36 }
680     with_seckey = 1;
681 twoaday 128 free_if_alloc (p);
682 werner 36 }
683     else {
684     with_seckey = 1;
685 twoaday 128 rset[k_pos++] = key;
686 werner 36 }
687     }
688     }
689    
690     if (k_pos == 0) {
691     free (rset);
692     return 0;
693     }
694    
695     err = gpgme_new (&ctx);
696     if (err)
697     BUG (NULL);
698 twoaday 128 n = k_pos;
699 twoaday 130 op_begin ();
700 werner 36 for (i=0; i < k_pos; i++) {
701     err = gpgme_op_delete (ctx, rset[i], with_seckey);
702     if (err)
703     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
704     else
705     n--;
706     }
707 twoaday 130 op_end ();
708 werner 36 if (n == 0)
709 twoaday 121 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
710 werner 36 gpgme_release (ctx);
711 twoaday 150 listview_del_sel_items (lv);
712 werner 36 delete_keys_from_cache (rset, k_pos);
713     free (rset);
714    
715     return (int)err;
716     }
717    
718    
719 twoaday 121 /* Send the select key in @lv to the keyserver @host:@port. */
720 werner 36 int
721 twoaday 121 km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char *host, u16 port)
722 werner 36 {
723 twoaday 128 gpgme_key_t key;
724 werner 36 int id;
725    
726 twoaday 121 id = listview_get_curr_pos (lv);
727     if (id == -1) {
728 werner 36 msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
729     return WPTERR_GENERAL;
730     }
731    
732 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, id);
733     if (!key)
734     BUG (NULL);
735 werner 36 id = log_box (_("Key Manager"), MB_YESNO,
736     _("Do you really want to send '%s' to keyserver %s?"),
737 twoaday 128 key->subkeys->keyid+8, host);
738     if (id == IDYES)
739     hkp_send_key (dlg, host, port, key->subkeys->keyid+8);
740 werner 36
741     return 0;
742 twoaday 121 }
743 werner 36
744    
745 twoaday 77 /* Send the selected key in @lv via MAPI to a mail recipient. */
746 werner 36 int
747 twoaday 77 km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg)
748 werner 36 {
749     gpgme_key_t key;
750     gpgme_ctx_t ctx=NULL;
751 twoaday 77 gpgme_data_t out;
752 werner 36 gpgme_error_t rc;
753 twoaday 128 char tmp[128];
754 twoaday 121 char *fname;
755 twoaday 129 char *name;
756 werner 36 int pos;
757    
758 twoaday 121 if (listview_count_items (lv, 1) > 1) {
759 twoaday 77 msg_box (dlg, _("Please only select one key."),
760     _("Key Manager"), MB_INFO|MB_OK);
761 werner 36 return WPTERR_GENERAL;
762     }
763 twoaday 77 pos = listview_get_curr_pos (lv);
764     if (pos == -1) {
765     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
766 werner 36 return WPTERR_GENERAL;
767     }
768 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
769     if (!key)
770 twoaday 77 BUG (NULL);
771 werner 36
772 twoaday 121 GetTempPath (sizeof (tmp)-1, tmp);
773     if (tmp[strlen (tmp)-1] == '\\')
774     tmp[strlen (tmp)-1] = 0;
775 twoaday 129 name = utf8_to_wincp2 (key->uids->name);
776     fname = make_filename (tmp, name, "asc");
777 twoaday 121 for (pos=0; pos < (int)strlen (fname); pos++) {
778     if (fname[pos] == ' ')
779     fname[pos] = '_';
780     }
781    
782 twoaday 77 rc = gpgme_new (&ctx);
783 werner 36 if (rc)
784 twoaday 77 BUG (NULL);
785     rc = gpgme_data_new (&out);
786     if (rc)
787     BUG (NULL);
788    
789     gpgme_set_armor (ctx, 1);
790     rc = gpgme_op_export (ctx, key->subkeys->keyid, 0, out);
791 twoaday 133 if (rc) {
792     gpgme_data_release (out);
793 werner 36 msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
794 twoaday 133 }
795     else {
796     gpg_data_release_and_set_file (out, fname);
797 twoaday 128 mapi_send_pubkey (key->subkeys->keyid+8, fname);
798 twoaday 133 }
799 werner 36
800     gpgme_release (ctx);
801 twoaday 129 safe_free (name);
802 twoaday 121 free_if_alloc (fname);
803 werner 36 return rc;
804     }
805    
806    
807     static void
808 twoaday 133 km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos, int flags)
809 werner 36 {
810 twoaday 128 gpgme_key_t key;
811 werner 36 int idx;
812    
813     if (pos != 0)
814     idx = pos;
815     else
816     idx = listview_get_curr_pos (lv);
817 twoaday 121 if (idx != -1) {
818 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, idx);
819 twoaday 133 if (!key)
820     BUG (0);
821 twoaday 121 hkp_recv_key (dlg, default_keyserver, default_keyserver_port,
822 twoaday 133 key->subkeys->keyid+8, 0, flags);
823 werner 36 }
824     }
825    
826    
827 twoaday 133 /* Refresh the selected keys from the default keyserver. */
828 werner 36 void
829     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
830     {
831 twoaday 133 int cnt, id, i;
832 werner 36
833 twoaday 128 if (kserver_check_inet_connection ()) {
834 werner 36 msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
835     _("Key Manager"), MB_ERR);
836     return;
837     }
838 twoaday 133
839     cnt = listview_count_items (lv, 0);
840     if (listview_count_items (lv, 1) == cnt) {
841     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"),
842 twoaday 121 _("Key Manager"), MB_YESNO);
843 werner 36 if (id == IDNO)
844     return;
845     }
846 twoaday 133 if (listview_count_items (lv, 1) == 1)
847     km_refresh_one_key (lv, dlg, listview_get_curr_pos (lv), 0);
848 werner 36 else {
849 twoaday 133 for (i=0; i < cnt; i++) {
850 werner 36 if (listview_get_item_state (lv, i))
851 twoaday 133 km_refresh_one_key (lv, dlg, i, KM_KS_REFRESH);
852 werner 36 }
853     }
854 twoaday 121 }
855 werner 36
856    
857     void
858     km_set_clip_info (const char *uid)
859     {
860     char buf[256];
861    
862 twoaday 129 key_get_clip_info (uid, buf, sizeof (buf)-1);
863 werner 36 set_clip_text (NULL, buf, strlen (buf));
864 twoaday 121 }
865 werner 36
866    
867    
868     /* Return TRUE if the key in the list @lv at pos @pos is an
869     old version 3 key. */
870     int
871     km_key_is_v3 (listview_ctrl_t lv, int pos)
872     {
873     gpgme_key_t pk;
874    
875 twoaday 128 pk = (gpgme_key_t)listview_get_item2 (lv, pos);
876     if (!pk)
877 werner 36 BUG (NULL);
878     if (strlen (pk->subkeys->fpr) == 32 &&
879     pk->subkeys->pubkey_algo == GPGME_PK_RSA)
880     return -1;
881     return 0;
882     }
883    
884    
885     /* Set trust of selected key in @lv (at @pos) to ultimate. */
886     int
887     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
888     {
889 twoaday 128 gpgme_error_t err;
890     gpgme_key_t key;
891 werner 36 GpgKeyEdit *ke;
892    
893 twoaday 128 key = (gpgme_key_t)listview_get_item2 (lv, pos);
894     if (!key)
895     BUG (NULL);
896     ke = new GpgKeyEdit (key->subkeys->keyid);
897 werner 36 if (!ke)
898     BUG (0);
899    
900     err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
901     if (err)
902     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
903     else
904     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
905    
906     delete ke;
907     return (int)err;
908     }
909    
910    
911     void
912     km_find_key (HWND dlg, listview_ctrl_t lv)
913     {
914     int oldpos = listview_get_curr_pos (lv);
915     int n;
916     char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
917     if (name == NULL)
918     return;
919     if (oldpos < 0)
920     oldpos = 0;
921     n = listview_find (lv, name);
922     if (n != -1) {
923     listview_select_one (lv, n);
924     listview_scroll (lv, oldpos, n);
925     }
926     else {
927     const char *s = _("String pattern \"%s\" not found.");
928     char *p = new char[strlen (s) + strlen (name) + 2];
929     if (!p)
930     BUG (0);
931     sprintf (p, s, name);
932     msg_box (dlg, p, _("Key Manager"), MB_INFO);
933     free_if_alloc (p);
934     }
935     free_if_alloc (name);
936     }
937 twoaday 129
938    
939     /* Return a user-friendly name for a key derrived from
940     name. If @is_secret is 1, a secret key name will be generated. */
941     char*
942     km_gen_export_filename (const char *keyid, int is_secret)
943     {
944     gpgme_key_t key;
945     char *p, *uid;
946    
947     if (get_pubkey (keyid, &key))
948     return m_strdup (keyid);
949     uid = utf8_to_wincp2 (key->uids->name);
950     if (!uid)
951     return m_strdup (keyid);
952     p = new char[strlen (uid) + 8 + 16];
953     if (!p)
954     BUG (0);
955     sprintf (p, "%s%s.asc", uid, is_secret? "_sec" : "");
956     for (size_t i=0; i < strlen (p); i++) {
957     if (p[i] == ' ' || p[i] == ':' || p[i] == '?' || p[i] == '|')
958     p[i] = '_';
959     }
960     safe_free (uid);
961     return p;
962     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26