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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77 - (hide annotations)
Mon Nov 14 15:01:01 2005 UTC (19 years, 3 months ago) by twoaday
File size: 29427 byte(s)
2005-11-12  Timo Schulz  <ts@g10code.com>
 
        Fix more GCC warnings.
 
2005-11-10  Timo Schulz  <ts@g10code.com>
 
        * wptClipSignDlg.cpp (one_key_proc): Use
        release_gpg_passphrase_cb() to free the context.
        * wptListView.cpp (listview_deselect_all): New.
        * wptMAPI.cpp (mapi_send_pubkey): Works again.
        * wptFileManagerDlg.cpp (file_manager_dlg_proc): Support encrypt &
        zip.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Fix passphrase
        caching for signing operations.
        * wptKeyManager.cpp (km_send_to_mail_recipient): Works again.
        * wptFileManager.cpp (fm_send_file): Likewise.
        (fm_encrypt_into_zip): New.
         

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 <commctrl.h>
27     #include <stdio.h>
28    
29     #include "gpgme.h"
30 werner 47 #include "resource.h"
31 werner 36 #include "wptTypes.h"
32     #include "wptW32API.h"
33     #include "wptVersion.h"
34     #include "wptCommonCtl.h"
35     #include "wptNLS.h"
36     #include "wptErrors.h"
37     #include "wptContext.h"
38     #include "wptGPG.h"
39     #include "wptKeylist.h"
40     #include "wptFileManager.h"
41     #include "wptDlgs.h"
42     #include "wptKeyserver.h"
43     #include "wptKeyManager.h"
44     #include "wptKeylist.h"
45     #include "wptHTTP.h"
46     #include "wptKeyEdit.h"
47     #include "wptImport.h"
48 werner 48 #include "wptCrypto.h"
49 werner 36
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 twoaday 77 clip_import_dlg_proc, 0,
435 werner 36 _("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 werner 48 remove (p);
482 werner 36 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 twoaday 77 /* Send the selected key in @lv via MAPI to a mail recipient. */
692 werner 36 int
693 twoaday 77 km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg)
694 werner 36 {
695     gpgme_key_t key;
696     gpgme_ctx_t ctx=NULL;
697 twoaday 77 gpgme_data_t out;
698 werner 36 gpgme_error_t rc;
699 twoaday 77 const char *s;
700     char keyid[32], tmp[192+256];
701 werner 36 int pos;
702    
703 twoaday 77 if (listview_count_items (lv, 1 ) > 1) {
704     msg_box (dlg, _("Please only select one key."),
705     _("Key Manager"), MB_INFO|MB_OK);
706 werner 36 return WPTERR_GENERAL;
707     }
708 twoaday 77 pos = listview_get_curr_pos (lv);
709     if (pos == -1) {
710     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
711 werner 36 return WPTERR_GENERAL;
712     }
713 twoaday 77 listview_get_item_text(lv, pos, 1, keyid, sizeof keyid-1);
714     if (get_pubkey (keyid, &key))
715     BUG (NULL);
716 werner 36 s = key->uids->name;
717     GetTempPath (sizeof tmp-1, tmp);
718     strncat (tmp, s, sizeof tmp-200);
719     strncat (tmp, ".asc", sizeof tmp-200);
720    
721 twoaday 77 rc = gpgme_new (&ctx);
722 werner 36 if (rc)
723 twoaday 77 BUG (NULL);
724     rc = gpgme_data_new (&out);
725     if (rc)
726     BUG (NULL);
727    
728     gpgme_set_armor (ctx, 1);
729     rc = gpgme_op_export (ctx, key->subkeys->keyid, 0, out);
730     if (rc)
731 werner 36 msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
732     else
733     mapi_send_pubkey (keyid, tmp);
734    
735 twoaday 77 gpg_data_release_and_set_file (out, tmp);
736 werner 36 gpgme_release (ctx);
737     return rc;
738     }
739    
740    
741     static void
742     km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
743     {
744     int idx;
745     char keyid[32];
746     const char *t;
747    
748     if (pos != 0)
749     idx = pos;
750     else
751     idx = listview_get_curr_pos (lv);
752     if (idx != -1)
753     {
754     listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
755     t = keyid;
756     if (!strncmp (keyid, "0x", 2))
757     t += 2;
758     hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
759     }
760     }
761    
762    
763     void
764     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
765     {
766     int idx, id, i;
767    
768     if (kserver_check_inet_connection ())
769     {
770     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
771     _("Key Manager"), MB_ERR);
772     return;
773     }
774     idx = listview_count_items (lv, 0);
775     if (listview_count_items (lv, 1) == idx) {
776     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
777     if (id == IDNO)
778     return;
779     for (i = 0; i < idx; i++)
780     km_refresh_one_key (lv, dlg, i);
781     }
782     else if (idx == 1)
783     km_refresh_one_key (lv, dlg, 0);
784     else {
785     for (i=0; i < listview_count_items (lv, 0); i++) {
786     if (listview_get_item_state (lv, i))
787     km_refresh_one_key (lv, dlg, i);
788     }
789     }
790     } /* km_refresh_from_keyserver */
791    
792    
793     void
794     km_set_clip_info (const char *uid)
795     {
796     char buf[256];
797    
798     key_get_clip_info (uid, buf, 255);
799     set_clip_text (NULL, buf, strlen (buf));
800     } /* km_set_clip_info */
801    
802    
803    
804     /* Return TRUE if the key in the list @lv at pos @pos is an
805     old version 3 key. */
806     int
807     km_key_is_v3 (listview_ctrl_t lv, int pos)
808     {
809     gpgme_key_t pk;
810     char keyid[32];
811    
812     listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
813     if (get_pubkey (keyid, &pk))
814     BUG (NULL);
815     if (strlen (pk->subkeys->fpr) == 32 &&
816     pk->subkeys->pubkey_algo == GPGME_PK_RSA)
817     return -1;
818     return 0;
819     }
820    
821    
822     /* Update the default key entry in the status bar for dialog @dlg. */
823     void
824     km_update_default_key_str (HWND dlg)
825     {
826     char *keyid, defkeyinf[512];
827     const char *fmt;
828    
829     /* XXX: also show the name? */
830     keyid = get_gnupg_default_key ();
831     if (!keyid)
832 twoaday 66 return;
833 werner 36 if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
834     || (keyid[0] == '0' && keyid[1] == 'x') )
835     fmt = _("Default Key: %s");
836     else
837     fmt = _("Default Key: 0x%s");
838     _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
839     SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
840     free_if_alloc (keyid);
841     }
842    
843    
844     /* Count all keys and show from @lv results in the status bar @sb. */
845     void
846     km_complete_status_bar (HWND sb, listview_ctrl_t lv)
847     {
848     char txt_sec[128], txt_pub[128];
849     int nkeys = 0, nsec = 0, i;
850    
851     nkeys = listview_count_items (lv, 0);
852     for (i = 0; i < nkeys; i++) {
853     if (km_check_for_seckey (lv, i, NULL))
854     nsec++;
855     }
856     _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
857     _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
858     SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
859     SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
860     }
861    
862    
863     /* Set trust of selected key in @lv (at @pos) to ultimate. */
864     int
865     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
866     {
867     GpgKeyEdit *ke;
868     gpgme_error_t err;
869     char keyid[32];
870    
871     listview_get_item_text (lv, pos, 1, keyid, 31);
872    
873     ke = new GpgKeyEdit (keyid);
874     if (!ke)
875     BUG (0);
876    
877     err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
878     if (err)
879     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
880     else
881     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
882    
883     delete ke;
884     return (int)err;
885     }
886    
887    
888     void
889     km_find_key (HWND dlg, listview_ctrl_t lv)
890     {
891     int oldpos = listview_get_curr_pos (lv);
892     int n;
893     char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
894     if (name == NULL)
895     return;
896     if (oldpos < 0)
897     oldpos = 0;
898     n = listview_find (lv, name);
899     if (n != -1) {
900     listview_select_one (lv, n);
901     listview_scroll (lv, oldpos, n);
902     }
903     else {
904     const char *s = _("String pattern \"%s\" not found.");
905     char *p = new char[strlen (s) + strlen (name) + 2];
906     if (!p)
907     BUG (0);
908     sprintf (p, s, name);
909     msg_box (dlg, p, _("Key Manager"), MB_INFO);
910     free_if_alloc (p);
911     }
912     free_if_alloc (name);
913     }
914    
915    
916    
917     void
918     km_dump_key (gpgme_key_t key)
919     {
920     #if _DEBUG
921     log_box ("DEBUG", MB_OK,
922     "%d %d %s %d\n%s", key->subkeys->length,
923     key->subkeys->pubkey_algo,
924     key->subkeys->keyid,
925     key->subkeys->timestamp,
926     key->uids->uid);
927     #endif
928     }
929    
930     #if 0
931     gpg_optfile_t
932     km_groupdb_open (void)
933     {
934     gpg_optfile_t opt;
935     char * optfile;
936     int err = 0;
937    
938     optfile = get_gnupg_cfgfile();
939     if( !optfile )
940     BUG( NULL );
941     if( parse_gpg_options( optfile, &opt ) )
942     err = 1;
943     free_if_alloc( optfile );
944     return err? NULL : opt;
945     } /* km_groupdb_open */
946    
947    
948     int
949     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
950     {
951     gpg_keycache_t kc;
952     gpgme_key_t pk;
953     gpg_optfile_t opt;
954     gpg_group_t grp;
955     gpg_member_t mbr;
956     int no_trust = 0, n;
957    
958     kc = keycache_get_ctx( 1 );
959     if( !kc )
960     BUG( NULL );
961    
962     opt = km_groupdb_open( );
963     if( !opt )
964     return WPTERR_FILE_OPEN;
965    
966     grp = find_group( opt, name );
967     if( !grp )
968     return WPTERR_GENERAL;
969    
970     /* we are paranoid and check that all group members exist in the
971     key cache. there is no need that it is really the real key, but
972     an entry should be available. the rest is up to GPG. */
973     for( mbr = grp->list; mbr; mbr = mbr->next ) {
974     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
975     BUG( NULL );
976     n = count_userids (pk);
977     while( n-- ) {
978     gpgme_user_id_t u = get_nth_userid (pk, n);
979     const char * s = u->uid;
980     if( s && stristr( s, mbr->name )
981     && u->validity < 3 )
982     no_trust++;
983     }
984     }
985    
986     gpgme_recipients_add_name( rset, name );
987     release_gpg_options( opt );
988    
989     return no_trust;
990     } /* km_groupdb_expand_recipients */
991    
992    
993     static HTREEITEM
994     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
995     {
996     TVINSERTSTRUCT tvis;
997     HTREEITEM node;
998    
999     memset( &tvis, 0, sizeof tvis );
1000     tvis.hParent = parent;
1001     tvis.hInsertAfter = TVI_LAST;
1002     tvis.item.mask = TVIF_TEXT;
1003     tvis.item.pszText = (char *)text;
1004     node = TreeView_InsertItem( tree, &tvis );
1005     return node;
1006     } /* km_tv_insert_item */
1007    
1008    
1009     int
1010     km_groups_new( km_group_t *r_gc, HWND ctrl )
1011     {
1012     km_group_t gc;
1013    
1014     gc = new km_group_s;
1015     if (!gc)
1016     BUG (NULL);
1017     gc->tree = ctrl;
1018     gc->gh = km_groupdb_open ();
1019     *r_gc = gc;
1020     return 0;
1021     } /* km_groups_new */
1022    
1023    
1024     void
1025     km_groups_sync( km_group_t gc )
1026     {
1027     char * optfile;
1028    
1029     optfile = get_gnupg_cfgfile ();
1030     if( !optfile )
1031     BUG( NULL );
1032     commit_gpg_options( optfile, gc->gh );
1033     free_if_alloc( optfile );
1034     gc->need_sync = 0;
1035     } /* km_groups_sync */
1036    
1037    
1038     void
1039     km_groups_release (km_group_t gc)
1040     {
1041     if( gc ) {
1042     /* xxx: this reset the default key (sync=1) */
1043     gc->need_sync=0;
1044     if (gc->need_sync)
1045     km_groups_sync (gc);
1046     if (gc->gh)
1047     release_gpg_options( gc->gh );
1048     gc->gh = NULL;
1049     gc->tree = NULL;
1050     delete gc;
1051     }
1052     } /* km_groups_release */
1053    
1054    
1055     int
1056     km_groups_load( km_group_t gc )
1057     {
1058     HTREEITEM n;
1059     gpg_group_t grp, g;
1060     gpg_member_t mbr;
1061     u32 gid = 0;
1062    
1063     if( !gc->gh )
1064     return 0;
1065     grp = gc->gh->grp;
1066     if( !grp )
1067     return 0; /* no groups */
1068    
1069     for( g = grp; g; g = g->next ) {
1070     n = km_tv_insert_item( gc->tree, NULL, g->name );
1071     for( mbr = g->list; mbr; mbr = mbr->next ) {
1072     if( mbr->used && mbr->name )
1073     km_tv_insert_item( gc->tree, n, mbr->name );
1074     }
1075     }
1076     DragAcceptFiles( gc->tree, TRUE );
1077     gc->need_sync = 0;
1078     return 0;
1079     } /* km_groups_load */
1080    
1081    
1082     int
1083     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1084     {
1085     TVITEM tvi;
1086     char uid[128], valid[64], text[128];
1087     int i_valid;
1088    
1089     memset( &tvi, 0, sizeof tvi );
1090     tvi.hItem = TreeView_GetSelection( gc->tree );
1091     tvi.pszText = text;
1092     tvi.cchTextMax = sizeof text -1;
1093     tvi.mask = TVIF_TEXT;
1094     TreeView_GetItem( gc->tree, &tvi );
1095    
1096    
1097     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1098     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1099    
1100     if( strstr( valid, "Ultimate" ) )
1101     i_valid = 5;
1102     else if( !strstr( valid, "Full" ) )
1103     i_valid = 4;
1104     else if( !strstr( valid, "Marginal" ) )
1105     i_valid = 3;
1106     else
1107     i_valid = 0;
1108    
1109     /* we can't add the full name. one way would be to use the first
1110     text until a space appears.
1111     group_add_entry(&gc->gh, gid, i_valid, uid);
1112     treeview_add_item(gc->tree, tvi.hItem, uid);
1113     */
1114     gc->need_sync = 1;
1115    
1116     return 0;
1117     } /* km_groups_add */
1118    
1119    
1120     static int
1121     km_groups_del_main( km_group_t gc )
1122     {
1123     TVITEM tvi;
1124     char text[128];
1125     int id;
1126    
1127     memset( &tvi, 0, sizeof tvi );
1128     tvi.hItem = TreeView_GetSelection( gc->tree );
1129     tvi.pszText = text;
1130     tvi.cchTextMax = sizeof text -1;
1131     tvi.mask = TVIF_TEXT;
1132     TreeView_GetItem( gc->tree, &tvi );
1133    
1134     id = log_box( _("Key Manager"), MB_INFO_ASK,
1135     _("Do you really want to delete this group?\n\n%s"), text);
1136     if( id == IDNO )
1137     return 0;
1138     delete_group( gc->gh, text );
1139     TreeView_DeleteItem( gc->tree, &tvi );
1140     gc->need_sync = 1;
1141    
1142     return 0;
1143     } /* km_groups_del */
1144    
1145    
1146     static int
1147     km_groups_del_entry( km_group_t gc )
1148     {
1149     TVITEM tvi;
1150     HTREEITEM root;
1151     int id;
1152     char text[128], info[256];
1153     gpg_group_t grp = NULL;
1154    
1155     memset( &tvi, 0, sizeof tvi );
1156     tvi.hItem = TreeView_GetSelection( gc->tree );
1157     tvi.pszText = text;
1158     tvi.cchTextMax = sizeof text-1;
1159     tvi.mask = TVIF_TEXT;
1160     TreeView_GetItem( gc->tree, &tvi );
1161    
1162     _snprintf( info, sizeof info -1,
1163     _("Do you really want to delete this entry?\n\n%s"), text );
1164    
1165     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1166     if( id == IDNO )
1167     return 0;
1168    
1169     root = TreeView_GetParent( gc->tree, tvi.hItem );
1170     if( root ) {
1171     }
1172    
1173     delete_member( gc->gh, /*fixme*/NULL, text );
1174     TreeView_DeleteItem( gc->tree, &tvi );
1175     gc->need_sync = 1;
1176     return 0;
1177     } /* km_groups_del_entry */
1178    
1179    
1180     int
1181     km_groups_del( km_group_t gc )
1182     {
1183     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1184     return km_groups_del_entry( gc );
1185     else
1186     return km_groups_del_main( gc );
1187     } /* km_groups_del */
1188     #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26