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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (hide annotations)
Mon Oct 31 14:04:59 2005 UTC (19 years, 4 months ago) by werner
File size: 29501 byte(s)
Minor changes; compiles now but gettext is still missing.

1 werner 36 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2     * Copyright (C) 2001-2005 Timo Schulz
3     * 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     #ifdef HAVE_CONFIG_H
22     #include <config.h>
23     #endif
24    
25     #include <windows.h>
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    
50    
51     /* Return a user friendly key representation in @buf of
52     the key given by @keyid. */
53     static void
54     key_get_clip_info (const char *keyid, char *buf, size_t buflen)
55     {
56     gpgme_key_t pk;
57    
58     if (get_pubkey (keyid, &pk))
59     BUG (NULL);
60     _snprintf (buf, buflen-1,
61     "pub %04d%s/%s %s %s\r\n"
62     " Primary key fingerprint: %s\r\n",
63     pk->subkeys->length,
64     get_key_pubalgo (pk->subkeys->pubkey_algo),
65     pk->subkeys->keyid+8,
66     get_key_created (pk->subkeys->timestamp),
67     pk->uids->uid,
68     get_key_fpr (pk));
69     }
70    
71    
72     #if 0
73     /* Quoted the user-id given by @uid. If @uid is already
74     quoted @uid is returned without any modifications.
75     Return value: quoted @uid. */
76     char*
77     km_quote_uid (const char *uid)
78     {
79     char *q;
80    
81     if (*uid == '"' && uid[strlen (uid)-1] == '"')
82     return m_strdup (uid);
83     q = new char[strlen (uid) + 4];
84     if (!q)
85     BUG (NULL);
86     _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
87     return q;
88     }
89     #endif
90    
91    
92     /* Check if list view @lv contains a secret key at position @pos.
93     If utrust is valid, set it to 1 if the key is valid -1 otherwise.
94     Return value: 1 normal key, 2 smart card key. */
95     int
96     km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
97     {
98     char t[32], t2[64];
99     int type = 0;
100    
101     if (utrust)
102     *utrust = 0;
103     listview_get_item_text (lv, pos, 5, t, DIM (t)-1);
104     listview_get_item_text (lv, pos, 2, t2, DIM (t2)-1);
105     if (!strcmp (t2, "pub/sec"))
106     type = 1;
107     else if (!strcmp (t2, "pub/crd"))
108     type = 2;
109     if ((strstr (t, "Expired") || strstr (t, "Revoked")) && utrust)
110     *utrust = -1;
111     else if (stristr (t, "Ultimate") && utrust)
112     *utrust = 1;
113     return type;
114     }
115    
116    
117     /* Check if the key at position @pos is protected with a passwd. */
118     int
119     km_check_if_protected (listview_ctrl_t lv, int pos)
120     {
121     gpgme_key_t key;
122     winpt_key_s k;
123    
124     key = (gpgme_key_t)listview_get_item2 (lv, pos);
125     if (!key)
126     return 1; /* assume yes */
127     winpt_get_pubkey (key->subkeys->keyid, &k);
128     return k.is_protected;
129     }
130    
131    
132     int
133     km_check_key_status (listview_ctrl_t lv, int pos)
134     {
135     int flags = km_get_key_status (lv, pos);
136    
137     if (flags & KM_FLAG_EXPIRED) {
138     msg_box (lv->ctrl, _("This key has expired!\n"
139     "Key check failed."), _("Key Manager"), MB_ERR);
140     return -1;
141     }
142     else if (flags & KM_FLAG_REVOKED) {
143     msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
144     "Key check failed."), _("Key Manager"), MB_ERR);
145     return -1;
146     }
147    
148     return 0;
149     } /* km_check_key_status */
150    
151    
152     int
153     km_get_key_status (listview_ctrl_t lv, int pos)
154     {
155     gpgme_key_t key;
156     int flags = 0;
157    
158     if (pos == -1)
159     return 0;
160     key = (gpgme_key_t)listview_get_item2 (lv, pos);
161     if (key == NULL)
162     return 0;
163    
164     if (key->expired)
165     flags |= KM_FLAG_EXPIRED;
166     if (key->revoked)
167     flags |= KM_FLAG_REVOKED;
168     if (key->disabled)
169     flags |= KM_FLAG_DISABLED;
170     return flags;
171     } /* km_get_key_status */
172    
173    
174     /* Interface to enable or disable a key (@enable = 1 then enable).
175     The key is retrieved from a list control @lv at the pos @pos. */
176     int
177     km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
178     {
179     GpgKeyEdit *ke;
180     gpgme_error_t err;
181     char keyid[32];
182    
183     listview_get_item_text (lv, pos, 1, keyid, DIM (keyid)-1);
184    
185     ke = new GpgKeyEdit (keyid);
186     if (!ke)
187     BUG (NULL);
188    
189     err = enable? ke->enable () : ke->disable ();
190     if (!err) {
191     show_msg (dlg, 1500, _("Key status changed."));
192     keycache_set_reload (1); /* XXX: set update flag */
193     }
194     else
195     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
196     delete ke;
197     return err? WPTERR_GENERAL : 0;
198     }
199    
200    
201    
202     /* Create a string that contain all keyids from
203     the key list @rset separated by a space. */
204     char*
205     gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
206     {
207     char *p;
208     int i;
209    
210     if (!n)
211     return NULL;
212     p = (char *)calloc (1, n*(16+1)+n+2);
213     if (!p)
214     BUG (NULL);
215     for (i=0; i < n; i++) {
216     strcat (p, rset[i]->subkeys->keyid);
217     strcat (p, " ");
218     }
219     return p;
220     }
221    
222    
223     /* Export the keys given in @rset to the clipboard.
224     Return value: 0 on success. */
225     static gpgme_error_t
226     gpg_clip_export (gpgme_key_t *rset, int n)
227     {
228     gpgme_error_t err = 0;
229     gpgme_ctx_t ctx = NULL;
230     gpgme_data_t keydata = NULL;
231     char *patt=NULL;
232    
233     err = gpgme_new (&ctx);
234     if (err)
235     return err;
236     gpgme_set_armor (ctx, 1);
237     err = gpgme_data_new (&keydata);
238     if (err)
239     goto leave;
240    
241     patt = gpg_keylist_to_pattern (rset, n);
242     if (!patt) {
243     err = gpg_error (GPG_ERR_ENOMEM);
244     goto leave;
245     }
246    
247     err = gpgme_op_export (ctx, patt, 0, keydata);
248     if (err)
249     goto leave;
250    
251     gpg_data_release_and_set_clipboard (keydata, 1);
252    
253     leave:
254     if (patt)
255     free (patt);
256     gpgme_release (ctx);
257     return err;
258     }
259    
260    
261     /* Export the selected keys in @lv to the clipboard. */
262     int
263     km_clip_export (HWND dlg, listview_ctrl_t lv)
264     {
265     gpgme_error_t err;
266     gpgme_key_t *rset;
267     char buf[256];
268     int n=0;
269     int rc=0;
270    
271     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
272     if (!n) {
273     msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
274     rc = WPTERR_GENERAL;
275     goto leave;
276     }
277    
278     err = gpg_clip_export (rset, n);
279     if (err) {
280     msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
281     rc = WPTERR_GENERAL;
282     goto leave;
283     }
284     if (n == 1) {
285     key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
286     set_clip_text2 (NULL, buf, strlen (buf), 0);
287     }
288    
289     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
290    
291     leave:
292     free (rset);
293     return rc;
294     } /* km_clip_export */
295    
296    
297     /* Export the selected secret key from @lv into @fname.
298     It is only allowed to export a single secret key. */
299     int
300     km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
301     {
302     gpgme_key_t *rset;
303     gpgme_error_t err;
304     int n = 0;
305    
306     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
307     if (!n) {
308     msg_box (dlg, _("No key was selected for export."),
309     _("Key Manager"), MB_ERR);
310     return WPTERR_GENERAL;
311     }
312     if (n > 1) {
313     msg_box (dlg, _("Only one secret key can be exported."),
314     _("Key Manager"), MB_ERR);
315     free (rset);
316     return 0; /* we checked this before, so we just quit */
317     }
318    
319     err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
320     if (err)
321     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
322     else
323     log_box (_("Key Manager"), MB_OK,
324     _("Secret key successfully saved in '%s'."), fname);
325    
326     free (rset);
327     return err? WPTERR_GENERAL : 0;
328     }
329    
330    
331     int
332     km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
333     {
334     gpgme_key_t *rset;
335     gpgme_data_t keydata;
336     gpgme_error_t err;
337     gpgme_ctx_t ctx;
338     char *patt;
339     int n;
340    
341     rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
342     if (!n) {
343     msg_box (dlg, _("No key was selected for export."),
344     _("Key Manager"), MB_ERR);
345     return WPTERR_GENERAL;
346     }
347    
348     err = gpgme_data_new (&keydata);
349     if (err)
350     BUG (NULL);
351     err = gpgme_new (&ctx);
352     if (err)
353     BUG (NULL);
354     gpgme_set_armor (ctx, 1);
355    
356     /*gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);*/
357     patt = gpg_keylist_to_pattern (rset, n);
358    
359     err = gpgme_op_export( ctx, patt, 0, keydata);
360     if( err ) {
361     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
362     goto leave;
363     }
364    
365     log_box( _("Key Manager"), MB_OK,
366     _("Key(s) successfully saved in '%s'."), fname );
367    
368     leave:
369     err = gpg_data_release_and_set_file( keydata, fname );
370     if (err)
371     log_box (_("Key Manager"), MB_OK,
372     _("Could not save data to '%s'."), fname);
373     gpgme_release (ctx);
374     free (patt);
375     return (int)err;
376     } /* km_file_export */
377    
378    
379     static int
380     extract_dash_escaped_key (void)
381     {
382     gpgme_data_t inp, plain;
383     gpgme_error_t err;
384    
385     err = gpg_data_new_from_clipboard (&inp, 0);
386     if (err) {
387     msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
388     return -1;
389     }
390     gpg_data_extract_plaintext (inp, &plain);
391     gpg_data_release_and_set_clipboard (plain, 0);
392     gpgme_data_release (inp);
393    
394     return 0;
395     } /* extract_dash_escaped_key */
396    
397    
398     /* Import keys from the clipboard. */
399     int
400     km_clip_import (HWND dlg)
401     {
402     gpgme_error_t err;
403     int pgptype;
404     int id;
405     int has_data = 0;
406    
407     if (!gpg_clip_istext_avail (&has_data) && !has_data) {
408     msg_box( dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), _("Key Manager"), MB_ERR);
409     return WPTERR_CLIP_ISEMPTY;
410     }
411     err = gpg_clip_is_secured (&pgptype, &has_data);
412     if (err)
413     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
414     if (!has_data) {
415     msg_box (dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR);
416     return WPTERR_GENERAL;
417     }
418     if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
419     msg_box (dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR);
420     return WPTERR_GENERAL;
421     }
422     if (pgptype & PGP_DASH_ESCAPED) {
423     id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
424     "Do you want to extract the key?"),
425     _("Key Manager"), MB_YESNO);
426     if (id == IDYES)
427     extract_dash_escaped_key ();
428     else
429     msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
430     _("Key Manager"), MB_INFO);
431     }
432    
433     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
434     clip_import_dlg_proc, NULL,
435     _("Key Import"), IDS_WINPT_IMPORT);
436    
437     return 0;
438     }
439    
440    
441     /* Import a key from the http URL @url. */
442     int
443     km_http_import (HWND dlg, const char *url)
444     {
445     http_hd_t hd;
446     FILE *fp;
447     char *p;
448     char tmpfile[500];
449     int statcode;
450     int rc = 0;
451    
452     if (strncmp (url, "http://", 7)) {
453     log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
454     return WPTERR_GENERAL;
455     }
456    
457     GetTempPath (sizeof (tmpfile)-128, tmpfile);
458     p = make_filename (tmpfile, "winpt_file_http", "tmp");
459     if (!p)
460     BUG (0);
461     fp = fopen (p, "wb");
462     if (!fp) {
463     free_if_alloc (p);
464     log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
465     return WPTERR_FILE_CREAT;
466     }
467    
468     /* parse URL */
469     rc = http_send_request2 (url, &hd);
470     if (!rc)
471     rc = http_parse_response (hd, &statcode);
472     if (!rc)
473     rc = http_parse_data (hd, fp);
474     http_hd_free (hd);
475     fclose (fp);
476     if (rc) {
477     msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
478     rc = WPTERR_GENERAL;
479     }
480     km_file_import (dlg, p);
481     unlink (p);
482     free_if_alloc (p);
483     return rc;
484     }
485    
486    
487     /* Import a key from the given file @fname.
488     On success an import statistics dialog is shown. */
489     int
490     km_file_import (HWND dlg, const char *fname)
491     {
492     gpgme_data_t keydata = NULL;
493     gpgme_ctx_t ctx;
494     gpgme_error_t err;
495     fm_state_s fm_stat;
496     gpgme_import_result_t res;
497    
498     memset (&fm_stat, 0, sizeof (fm_stat));
499     fm_stat.opaque = m_strdup (fname);
500    
501     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
502     file_import_dlg_proc, (LPARAM)&fm_stat,
503     _("File Import"), IDS_WINPT_IMPORT);
504     if (fm_stat.cancel == 1) {
505     free_if_alloc (fm_stat.opaque);
506     return WPTERR_GENERAL;
507     }
508    
509     err = gpgme_new (&ctx);
510     if (err)
511     BUG (NULL);
512     err = gpgme_data_new_from_file (&keydata, fname, 1);
513     if (err) {
514     msg_box (dlg, _("Could not read key-data from file."),
515     _("Key Manager"), MB_ERR);
516     goto leave;
517     }
518    
519     SetCursor (LoadCursor (NULL, IDC_WAIT));
520     err = gpgme_op_import (ctx, keydata);
521     SetCursor (LoadCursor (NULL, IDC_ARROW));
522     if (err) {
523     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
524     goto leave;
525     }
526    
527     res = gpgme_op_import_result (ctx);
528     if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
529     res->new_revocations = 1;
530     if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
531     res->secret_imported = 1;
532    
533     print_import_status (res);
534     if (res->no_user_id > 0) {
535     msg_box (dlg, _("Key without a self signature was dectected!\n"
536     "(This key is NOT usable for encryption, etc)\n"
537     "\n"
538     "Cannot import these key(s)!"), _("Import"), MB_INFO);
539     }
540    
541     leave:
542     gpgme_data_release (keydata);
543     gpgme_release (ctx);
544     free_if_alloc (fm_stat.opaque);
545     return (int)err;
546     }
547    
548    
549     /* Mark the keys in @rset as deleted in the keycache. */
550     static void
551     delete_keys_from_cache (gpgme_key_t *rset, size_t n)
552     {
553     gpg_keycache_t pub = keycache_get_ctx (1);
554     int i=0;
555    
556     while (n-- > 0)
557     gpg_keycache_delete_key (pub, rset[i++]->subkeys->keyid);
558     }
559    
560    
561     /* Delete all selected keys from the list view @lv. */
562     int
563     km_delete_keys (listview_ctrl_t lv, HWND dlg)
564     {
565     gpgme_error_t err;
566     gpgme_ctx_t ctx;
567     gpgme_key_t *rset, k;
568     char keyid[32], uid[256], date[64], keylen[64];
569     int with_seckey=0, seckey_type=0, confirm=0;
570     int i, rc, n, k_pos=0;
571    
572     if (listview_get_curr_pos (lv) == -1) {
573     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
574     return WPTERR_GENERAL;
575     }
576    
577     if (listview_count_items (lv, 1) > 8) {
578     i = msg_box (NULL, _("Do you really want to confirm each key?"),
579     _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
580     if (i == IDCANCEL)
581     return 0;
582     if (i != IDNO)
583     confirm = 1;
584     }
585     else
586     confirm = 1;
587    
588     n = listview_count_items (lv, 0);
589     rset = (gpgme_key_t *)calloc (n+1, sizeof (gpgme_key_t));
590     if (!rset)
591     BUG (NULL);
592     for( i = 0; i < n; i++ ) {
593     if( listview_get_item_state( lv, i ) ) {
594     listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
595     listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
596     listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
597     listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
598     seckey_type = km_check_for_seckey (lv, i, NULL);
599     if (confirm && !seckey_type) {
600     rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
601     _("Do you really want to delete this key?\n\n"
602     "pub %s %s %s\n"
603     " \"%s\""), keylen, keyid, date, uid );
604     if (rc == IDYES) {
605     get_pubkey (keyid, &k);
606     rset[k_pos++] = k;
607     }
608     with_seckey = 0;
609     }
610     else if (confirm) {
611     rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
612     _("Do you really want to delete this KEY PAIR?\n\n"
613     "Please remember that you are not able to decrypt\n"
614     "messages you stored with this key any longer.\n"
615     "\n"
616     "pub/sec %s %s %s\n"
617     " \"%s\""), keylen, keyid, date, uid );
618     if( rc == IDYES ) {
619     if (seckey_type == 2)
620     msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
621     "Only the public key and the secret key \n"
622     "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
623     get_pubkey (keyid, &k);
624     rset[k_pos++] = k;
625     }
626     with_seckey = 1;
627     }
628     else {
629     with_seckey = 1;
630     get_pubkey (keyid, &k);
631     rset[k_pos++] = k;
632     }
633     }
634     }
635    
636     if (k_pos == 0) {
637     free (rset);
638     return 0;
639     }
640    
641     err = gpgme_new (&ctx);
642     if (err)
643     BUG (NULL);
644     n=k_pos;
645     for (i=0; i < k_pos; i++) {
646     err = gpgme_op_delete (ctx, rset[i], with_seckey);
647     if (err)
648     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
649     else
650     n--;
651     }
652     if (n == 0)
653     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
654     gpgme_release (ctx);
655     listview_del_items (lv);
656     delete_keys_from_cache (rset, k_pos);
657     free (rset);
658    
659     return (int)err;
660     }
661    
662    
663     int
664     km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
665     {
666     char keyid[32];
667     const char *t;
668     int id;
669    
670     id = listview_get_curr_pos( lv );
671     if( id == -1 ) {
672     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
673     return WPTERR_GENERAL;
674     }
675    
676     listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
677     id = log_box (_("Key Manager"), MB_YESNO,
678     _("Do you really want to send '%s' to keyserver %s?"),
679     keyid, host);
680     if (id == IDYES) {
681     t = keyid;
682     if (!strncmp (keyid, "0x", 2))
683     t += 2;
684     hkp_send_key (dlg, host, port, t);
685     }
686    
687     return 0;
688     } /* km_send_to_keyserver */
689    
690    
691     int
692     km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
693     {
694     #if 0 /*FIXME*/
695     gpgme_key_t key;
696     gpgme_ctx_t ctx=NULL;
697     gpgme_recipients_t rset=NULL;
698     gpgme_error_t rc;
699     const char * s;
700     char keyid[32], tmp[192+256], * p =NULL;
701     int pos;
702    
703     if( listview_count_items( lv, 1 ) > 1 ) {
704     msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
705     return WPTERR_GENERAL;
706     }
707     pos = listview_get_curr_pos( lv );
708     if( pos == -1 ) {
709     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
710     return WPTERR_GENERAL;
711     }
712     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
713     if( get_pubkey( keyid, &key ) )
714     BUG( NULL );
715     s = key->uids->name;
716     GetTempPath (sizeof tmp-1, tmp);
717     strncat (tmp, s, sizeof tmp-200);
718     strncat (tmp, ".asc", sizeof tmp-200);
719     p = fm_quote_file (tmp);
720    
721     rc = gpgme_recipients_new (&rset);
722     if (!rc)
723     rc = gpgme_recipients_add_name (rset, keyid);
724     if (!rc)
725     rc = gpgme_new (&ctx);
726     if (!rc) {
727     gpgme_set_armor (ctx, 1);
728     rc = gpgme_op_file_export (ctx, rset, p);
729     }
730     if (rc)
731     msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
732     else
733     mapi_send_pubkey (keyid, tmp);
734    
735     free_if_alloc (p);
736     gpgme_recipients_release (rset);
737     gpgme_release (ctx);
738     return rc;
739     #endif
740     return 0;
741     }
742    
743    
744     static void
745     km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
746     {
747     int idx;
748     char keyid[32];
749     const char *t;
750    
751     if (pos != 0)
752     idx = pos;
753     else
754     idx = listview_get_curr_pos (lv);
755     if (idx != -1)
756     {
757     listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
758     t = keyid;
759     if (!strncmp (keyid, "0x", 2))
760     t += 2;
761     hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
762     }
763     }
764    
765    
766     void
767     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
768     {
769     int idx, id, i;
770    
771     if (kserver_check_inet_connection ())
772     {
773     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
774     _("Key Manager"), MB_ERR);
775     return;
776     }
777     idx = listview_count_items (lv, 0);
778     if (listview_count_items (lv, 1) == idx) {
779     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
780     if (id == IDNO)
781     return;
782     for (i = 0; i < idx; i++)
783     km_refresh_one_key (lv, dlg, i);
784     }
785     else if (idx == 1)
786     km_refresh_one_key (lv, dlg, 0);
787     else {
788     for (i=0; i < listview_count_items (lv, 0); i++) {
789     if (listview_get_item_state (lv, i))
790     km_refresh_one_key (lv, dlg, i);
791     }
792     }
793     } /* km_refresh_from_keyserver */
794    
795    
796     void
797     km_set_clip_info (const char *uid)
798     {
799     char buf[256];
800    
801     key_get_clip_info (uid, buf, 255);
802     set_clip_text (NULL, buf, strlen (buf));
803     } /* km_set_clip_info */
804    
805    
806    
807     /* Return TRUE if the key in the list @lv at pos @pos is an
808     old version 3 key. */
809     int
810     km_key_is_v3 (listview_ctrl_t lv, int pos)
811     {
812     gpgme_key_t pk;
813     char keyid[32];
814    
815     listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
816     if (get_pubkey (keyid, &pk))
817     BUG (NULL);
818     if (strlen (pk->subkeys->fpr) == 32 &&
819     pk->subkeys->pubkey_algo == GPGME_PK_RSA)
820     return -1;
821     return 0;
822     }
823    
824    
825     /* Update the default key entry in the status bar for dialog @dlg. */
826     void
827     km_update_default_key_str (HWND dlg)
828     {
829     char *keyid, defkeyinf[512];
830     const char *fmt;
831    
832     /* XXX: also show the name? */
833     keyid = get_gnupg_default_key ();
834     if (!keyid)
835     BUG (0);
836     if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
837     || (keyid[0] == '0' && keyid[1] == 'x') )
838     fmt = _("Default Key: %s");
839     else
840     fmt = _("Default Key: 0x%s");
841     _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
842     SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
843     free_if_alloc (keyid);
844     }
845    
846    
847     /* Count all keys and show from @lv results in the status bar @sb. */
848     void
849     km_complete_status_bar (HWND sb, listview_ctrl_t lv)
850     {
851     char txt_sec[128], txt_pub[128];
852     int nkeys = 0, nsec = 0, i;
853    
854     nkeys = listview_count_items (lv, 0);
855     for (i = 0; i < nkeys; i++) {
856     if (km_check_for_seckey (lv, i, NULL))
857     nsec++;
858     }
859     _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
860     _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
861     SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
862     SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
863     }
864    
865    
866     /* Set trust of selected key in @lv (at @pos) to ultimate. */
867     int
868     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
869     {
870     GpgKeyEdit *ke;
871     gpgme_error_t err;
872     char keyid[32];
873    
874     listview_get_item_text (lv, pos, 1, keyid, 31);
875    
876     ke = new GpgKeyEdit (keyid);
877     if (!ke)
878     BUG (0);
879    
880     err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
881     if (err)
882     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
883     else
884     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
885    
886     delete ke;
887     return (int)err;
888     }
889    
890    
891     void
892     km_find_key (HWND dlg, listview_ctrl_t lv)
893     {
894     int oldpos = listview_get_curr_pos (lv);
895     int n;
896     char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
897     if (name == NULL)
898     return;
899     if (oldpos < 0)
900     oldpos = 0;
901     n = listview_find (lv, name);
902     if (n != -1) {
903     listview_select_one (lv, n);
904     listview_scroll (lv, oldpos, n);
905     }
906     else {
907     const char *s = _("String pattern \"%s\" not found.");
908     char *p = new char[strlen (s) + strlen (name) + 2];
909     if (!p)
910     BUG (0);
911     sprintf (p, s, name);
912     msg_box (dlg, p, _("Key Manager"), MB_INFO);
913     free_if_alloc (p);
914     }
915     free_if_alloc (name);
916     }
917    
918    
919    
920     void
921     km_dump_key (gpgme_key_t key)
922     {
923     #if _DEBUG
924     log_box ("DEBUG", MB_OK,
925     "%d %d %s %d\n%s", key->subkeys->length,
926     key->subkeys->pubkey_algo,
927     key->subkeys->keyid,
928     key->subkeys->timestamp,
929     key->uids->uid);
930     #endif
931     }
932    
933     #if 0
934     gpg_optfile_t
935     km_groupdb_open (void)
936     {
937     gpg_optfile_t opt;
938     char * optfile;
939     int err = 0;
940    
941     optfile = get_gnupg_cfgfile();
942     if( !optfile )
943     BUG( NULL );
944     if( parse_gpg_options( optfile, &opt ) )
945     err = 1;
946     free_if_alloc( optfile );
947     return err? NULL : opt;
948     } /* km_groupdb_open */
949    
950    
951     int
952     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
953     {
954     gpg_keycache_t kc;
955     gpgme_key_t pk;
956     gpg_optfile_t opt;
957     gpg_group_t grp;
958     gpg_member_t mbr;
959     int no_trust = 0, n;
960    
961     kc = keycache_get_ctx( 1 );
962     if( !kc )
963     BUG( NULL );
964    
965     opt = km_groupdb_open( );
966     if( !opt )
967     return WPTERR_FILE_OPEN;
968    
969     grp = find_group( opt, name );
970     if( !grp )
971     return WPTERR_GENERAL;
972    
973     /* we are paranoid and check that all group members exist in the
974     key cache. there is no need that it is really the real key, but
975     an entry should be available. the rest is up to GPG. */
976     for( mbr = grp->list; mbr; mbr = mbr->next ) {
977     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
978     BUG( NULL );
979     n = count_userids (pk);
980     while( n-- ) {
981     gpgme_user_id_t u = get_nth_userid (pk, n);
982     const char * s = u->uid;
983     if( s && stristr( s, mbr->name )
984     && u->validity < 3 )
985     no_trust++;
986     }
987     }
988    
989     gpgme_recipients_add_name( rset, name );
990     release_gpg_options( opt );
991    
992     return no_trust;
993     } /* km_groupdb_expand_recipients */
994    
995    
996     static HTREEITEM
997     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
998     {
999     TVINSERTSTRUCT tvis;
1000     HTREEITEM node;
1001    
1002     memset( &tvis, 0, sizeof tvis );
1003     tvis.hParent = parent;
1004     tvis.hInsertAfter = TVI_LAST;
1005     tvis.item.mask = TVIF_TEXT;
1006     tvis.item.pszText = (char *)text;
1007     node = TreeView_InsertItem( tree, &tvis );
1008     return node;
1009     } /* km_tv_insert_item */
1010    
1011    
1012     int
1013     km_groups_new( km_group_t *r_gc, HWND ctrl )
1014     {
1015     km_group_t gc;
1016    
1017     gc = new km_group_s;
1018     if (!gc)
1019     BUG (NULL);
1020     gc->tree = ctrl;
1021     gc->gh = km_groupdb_open ();
1022     *r_gc = gc;
1023     return 0;
1024     } /* km_groups_new */
1025    
1026    
1027     void
1028     km_groups_sync( km_group_t gc )
1029     {
1030     char * optfile;
1031    
1032     optfile = get_gnupg_cfgfile ();
1033     if( !optfile )
1034     BUG( NULL );
1035     commit_gpg_options( optfile, gc->gh );
1036     free_if_alloc( optfile );
1037     gc->need_sync = 0;
1038     } /* km_groups_sync */
1039    
1040    
1041     void
1042     km_groups_release (km_group_t gc)
1043     {
1044     if( gc ) {
1045     /* xxx: this reset the default key (sync=1) */
1046     gc->need_sync=0;
1047     if (gc->need_sync)
1048     km_groups_sync (gc);
1049     if (gc->gh)
1050     release_gpg_options( gc->gh );
1051     gc->gh = NULL;
1052     gc->tree = NULL;
1053     delete gc;
1054     }
1055     } /* km_groups_release */
1056    
1057    
1058     int
1059     km_groups_load( km_group_t gc )
1060     {
1061     HTREEITEM n;
1062     gpg_group_t grp, g;
1063     gpg_member_t mbr;
1064     u32 gid = 0;
1065    
1066     if( !gc->gh )
1067     return 0;
1068     grp = gc->gh->grp;
1069     if( !grp )
1070     return 0; /* no groups */
1071    
1072     for( g = grp; g; g = g->next ) {
1073     n = km_tv_insert_item( gc->tree, NULL, g->name );
1074     for( mbr = g->list; mbr; mbr = mbr->next ) {
1075     if( mbr->used && mbr->name )
1076     km_tv_insert_item( gc->tree, n, mbr->name );
1077     }
1078     }
1079     DragAcceptFiles( gc->tree, TRUE );
1080     gc->need_sync = 0;
1081     return 0;
1082     } /* km_groups_load */
1083    
1084    
1085     int
1086     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1087     {
1088     TVITEM tvi;
1089     char uid[128], valid[64], text[128];
1090     int i_valid;
1091    
1092     memset( &tvi, 0, sizeof tvi );
1093     tvi.hItem = TreeView_GetSelection( gc->tree );
1094     tvi.pszText = text;
1095     tvi.cchTextMax = sizeof text -1;
1096     tvi.mask = TVIF_TEXT;
1097     TreeView_GetItem( gc->tree, &tvi );
1098    
1099    
1100     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1101     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1102    
1103     if( strstr( valid, "Ultimate" ) )
1104     i_valid = 5;
1105     else if( !strstr( valid, "Full" ) )
1106     i_valid = 4;
1107     else if( !strstr( valid, "Marginal" ) )
1108     i_valid = 3;
1109     else
1110     i_valid = 0;
1111    
1112     /* we can't add the full name. one way would be to use the first
1113     text until a space appears.
1114     group_add_entry(&gc->gh, gid, i_valid, uid);
1115     treeview_add_item(gc->tree, tvi.hItem, uid);
1116     */
1117     gc->need_sync = 1;
1118    
1119     return 0;
1120     } /* km_groups_add */
1121    
1122    
1123     static int
1124     km_groups_del_main( km_group_t gc )
1125     {
1126     TVITEM tvi;
1127     char text[128];
1128     int id;
1129    
1130     memset( &tvi, 0, sizeof tvi );
1131     tvi.hItem = TreeView_GetSelection( gc->tree );
1132     tvi.pszText = text;
1133     tvi.cchTextMax = sizeof text -1;
1134     tvi.mask = TVIF_TEXT;
1135     TreeView_GetItem( gc->tree, &tvi );
1136    
1137     id = log_box( _("Key Manager"), MB_INFO_ASK,
1138     _("Do you really want to delete this group?\n\n%s"), text);
1139     if( id == IDNO )
1140     return 0;
1141     delete_group( gc->gh, text );
1142     TreeView_DeleteItem( gc->tree, &tvi );
1143     gc->need_sync = 1;
1144    
1145     return 0;
1146     } /* km_groups_del */
1147    
1148    
1149     static int
1150     km_groups_del_entry( km_group_t gc )
1151     {
1152     TVITEM tvi;
1153     HTREEITEM root;
1154     int id;
1155     char text[128], info[256];
1156     gpg_group_t grp = NULL;
1157    
1158     memset( &tvi, 0, sizeof tvi );
1159     tvi.hItem = TreeView_GetSelection( gc->tree );
1160     tvi.pszText = text;
1161     tvi.cchTextMax = sizeof text-1;
1162     tvi.mask = TVIF_TEXT;
1163     TreeView_GetItem( gc->tree, &tvi );
1164    
1165     _snprintf( info, sizeof info -1,
1166     _("Do you really want to delete this entry?\n\n%s"), text );
1167    
1168     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1169     if( id == IDNO )
1170     return 0;
1171    
1172     root = TreeView_GetParent( gc->tree, tvi.hItem );
1173     if( root ) {
1174     }
1175    
1176     delete_member( gc->gh, /*fixme*/NULL, text );
1177     TreeView_DeleteItem( gc->tree, &tvi );
1178     gc->need_sync = 1;
1179     return 0;
1180     } /* km_groups_del_entry */
1181    
1182    
1183     int
1184     km_groups_del( km_group_t gc )
1185     {
1186     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1187     return km_groups_del_entry( gc );
1188     else
1189     return km_groups_del_main( gc );
1190     } /* km_groups_del */
1191     #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26