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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide annotations)
Wed Jul 27 11:17:22 2005 UTC (19 years, 7 months ago) by twoaday
File size: 28431 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * wptMainProc.cpp (winpt_main_proc): Take care for shutdown
        messages and make sure WinPT make a keyring backup in this case.
        * wptGPGME.cpp (keycache_reload): Do not rebuild the signature
        cache each time. Just do it on startup.
        * wptKeyManager.cpp (km_key_is_v3): Use new ATTR_VERSION.
        * wptKeyEditDlgs.cpp (keyedit_main_dlg_proc): Assume the v3 flag
        was set by the calling function.
        * wptKeyGenDlg.cpp (keygen_wizard_dlg_proc): Ask for backups.
        (keygen_dlg_proc): Only add the generated key to the keycache
        and do not reload the entire cache.
        * wptKeyManager.cpp (km_delete_keys): Store the number of keys
        because in each loop iteration it will be new calculated.
        * wptListView.cpp (listview_del_items): Likewise.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Directly add the
        generated key to the list instead of reloading the entire cache.
        * wptKeyEditDlgs.cpp (parse_preflist): Support fpr SHAnnn.


1 twoaday 2 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 twoaday 19 * Copyright (C) 2001-2005 Timo Schulz
3 twoaday 2 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20     #include <windows.h>
21     #include <commctrl.h>
22     #include <stdio.h>
23     #include <io.h>
24    
25     #include "../resource.h"
26     #include "wptTypes.h"
27     #include "wptW32API.h"
28     #include "wptVersion.h"
29     #include "wptCommonCtl.h"
30     #include "wptNLS.h"
31     #include "wptErrors.h"
32     #include "wptGPG.h"
33     #include "wptContext.h"
34     #include "wptKeylist.h"
35     #include "wptFileManager.h"
36     #include "wptDlgs.h"
37     #include "wptKeyserver.h"
38     #include "wptKeyManager.h"
39     #include "wptKeylist.h"
40     #include "wptHTTP.h"
41    
42    
43     static void
44     km_get_clip_info (const char *uid, char *buf, size_t buflen)
45     {
46     gpgme_key_t pk;
47     unsigned long a, algo;
48    
49     if (get_pubkey (uid, &pk))
50     BUG (0);
51    
52     a = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_CREATED, NULL, 0);
53     algo = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_ALGO, NULL, 0);
54     _snprintf (buf, buflen-1,
55     "pub %04d%s/%s %s %s\r\n"
56     " Primary key fingerprint: %s\r\n",
57     gpgme_key_get_ulong_attr (pk, GPGME_ATTR_LEN, NULL, 0),
58     gpgme_key_expand_attr (GPGME_ATTR_ALGO_SHORT, algo),
59     gpgme_key_get_string_attr (pk, GPGME_ATTR_KEYID, NULL, 0) + 8,
60     gpgme_key_expand_attr (GPGME_ATTR_CREATED, a ),
61     gpgme_key_get_string_attr (pk, GPGME_ATTR_USERID, NULL, 0),
62     get_key_fpr (pk));
63     }
64    
65    
66     char*
67     km_quote_uid (const char * uid)
68     {
69     char * q = new char[strlen (uid) + 4];
70     if (!q)
71     BUG (NULL);
72     _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
73     return q;
74     } /* km_quote_uid */
75    
76    
77     int
78     km_check_for_seckey (listview_ctrl_t lv, int pos, int * utrust)
79     {
80 twoaday 16 char t[32], t2[64];
81     int type = 0;
82 twoaday 2
83 twoaday 16 listview_get_item_text (lv, pos, 5, t, sizeof (t) - 1);
84     listview_get_item_text (lv, pos, 2, t2, sizeof (t2) - 1);
85 twoaday 2 if (!strcmp (t2, "pub/sec"))
86     type = 1;
87     else if (!strcmp (t2, "pub/crd"))
88     type = 2;
89     if (stristr (t, "ultimate") && utrust)
90     *utrust = 1;
91     return type;
92     } /* km_check_for_seckey */
93    
94    
95     int
96     km_check_if_protected( listview_ctrl_t lv, int pos )
97     {
98     gpgme_key_t key;
99     char keyid[32];
100    
101     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
102     if( get_pubkey( keyid, &key ) )
103     BUG( NULL );
104     return gpgme_key_get_ulong_attr( key, GPGME_ATTR_IS_PROTECTED, NULL, 0 );
105     } /* km_check_if_protected */
106    
107    
108     int
109     km_check_key_status (listview_ctrl_t lv, int pos)
110     {
111     char t[128];
112     int i = 1;
113    
114     listview_get_item_text( lv, pos, 5, t, sizeof t - 1 );
115     if( t[0] == '[' && t[1] == ']' )
116     return 1;
117     for( i = 0; t[i] != ']'; i++ ) {
118     if( t[i] == 'E' )
119     msg_box(lv->ctrl, _("This key has expired!\n"
120     "Key check failed."), _("Key Manager"), MB_ERR );
121     else if( t[i] == 'R' )
122     msg_box(lv->ctrl, _("This key has been revoked by its owner!\n"
123     "Key check failed."), _("Key Manager"), MB_ERR );
124     }
125    
126     return 0;
127     } /* km_check_key_status */
128    
129    
130     int
131     km_get_key_status( listview_ctrl_t lv, int pos )
132     {
133     char t[128];
134     int i, flags = 0;
135    
136     if( pos == -1 )
137     return 0;
138     listview_get_item_text( lv, pos, 5, t, sizeof t-1 );
139     for( i = 0; t[i] != ']'; i++ ) {
140     if( t[i] == 'E' )
141     flags |= KM_FLAG_EXPIRED;
142     if( t[i] == 'R' )
143     flags |= KM_FLAG_REVOKED;
144     if( t[i] == 'D' )
145     flags |= KM_FLAG_DISABLED;
146     }
147     return flags;
148     } /* km_get_key_status */
149    
150    
151     int
152 twoaday 19 km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
153 twoaday 2 {
154     gpgme_ctx_t ctx;
155     gpgme_editkey_t ek;
156     gpgme_error_t err;
157     int edit_id;
158     char keyid[32];
159    
160 twoaday 19 listview_get_item_text( lv, pos, 1, keyid, DIM (keyid)-1 );
161 twoaday 2 err = gpgme_editkey_new( &ek );
162     if( err )
163     BUG( NULL );
164     if( enable ) {
165 twoaday 19 gpgme_editkey_enable_set (ek);
166 twoaday 2 edit_id = GPGME_EDITKEY_ENABLE;
167     }
168     else {
169 twoaday 19 gpgme_editkey_disable_set (ek);
170 twoaday 2 edit_id = GPGME_EDITKEY_DISABLE;
171     }
172 twoaday 19 err = gpgme_new (&ctx);
173 twoaday 2 if( err )
174     BUG( NULL );
175 twoaday 19 gpgme_set_edit_ctx (ctx, ek, edit_id);
176     err = gpgme_op_editkey (ctx, keyid);
177 twoaday 2 if( !err ) {
178     show_msg( dlg, 1500, _("Key status changed.") );
179     keycache_set_reload( 1 );
180     }
181     else
182     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
183    
184 twoaday 19 gpgme_release (ctx);
185     gpgme_editkey_release (ek);
186 twoaday 2 return err? WPTERR_GENERAL : 0;
187     } /* km_enable_disable_key */
188    
189    
190     int
191     km_clip_export (HWND dlg, listview_ctrl_t lv)
192     {
193     gpgme_error_t err;
194     gpgme_recipients_t rset;
195     int rc, id = 0, n = 0;
196    
197     rset = keylist_enum_recipients (lv, KEYLIST_LIST);
198     n = gpgme_recipients_count (rset);
199     if (!n) {
200     msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
201     rc = WPTERR_GENERAL;
202     goto leave;
203     }
204    
205     err = gpgme_op_clip_export (rset);
206     if (err) {
207     msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
208     rc = WPTERR_GENERAL;
209     goto leave;
210     }
211     if (n == 1) {
212     const char *s;
213     char buf[256];
214     s = gpgme_recipients_get_name (rset, 0);
215     km_get_clip_info (s, buf, 255);
216     set_clip_text2 (NULL, buf, strlen (buf), 0);
217     }
218    
219     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
220    
221     leave:
222     gpgme_recipients_release (rset);
223     return rc;
224     } /* km_clip_export */
225    
226    
227     int
228     km_privkey_export( HWND dlg, listview_ctrl_t lv, const char *fname )
229     {
230     gpgme_recipients_t rset;
231     gpgme_data_t keydata;
232     gpgme_error_t err;
233     gpgme_ctx_t ctx;
234     size_t n = 0;
235    
236     rset = keylist_enum_recipients( lv, KEYLIST_LIST );
237     n = gpgme_recipients_count( rset );
238     if( !n ) {
239     msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );
240     return WPTERR_GENERAL;
241     }
242     if( n > 1 ) {
243     msg_box( dlg, _("Only one secret key can be exported."), _("Key Manager"), MB_ERR );
244     return 0; /* we checked this before, so we just quit */
245     }
246     err = gpgme_data_new( &keydata );
247     if( err )
248     BUG( dlg );
249     err = gpgme_new( &ctx );
250     if( err )
251     BUG( dlg );
252     gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
253     gpgme_control( ctx, GPGME_CTRL_WITH_SECRET_KEY, 1 );
254    
255     err = gpgme_op_export( ctx, rset, keydata );
256     if( err ) {
257     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
258     goto leave;
259     }
260    
261     log_box( _("Key Manager"), MB_OK,
262     _("Secret key successfully saved in '%s'."), fname );
263    
264     leave:
265     err = gpgme_data_release_and_set_file( keydata, fname );
266     if( err )
267     log_box( _("Key Manager"), MB_OK,
268     _("Could not save data to '%s'."), fname );
269     gpgme_release( ctx );
270    
271     return (int)err;
272     } /* km_privkey_export */
273    
274    
275     int
276     km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
277     {
278     gpgme_recipients_t rset;
279     gpgme_data_t keydata;
280     gpgme_error_t err;
281     gpgme_ctx_t ctx;
282    
283     rset = keylist_enum_recipients( lv, KEYLIST_LIST );
284     if( !gpgme_recipients_count( rset ) ) {
285     msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );
286     return WPTERR_GENERAL;
287     }
288    
289     err = gpgme_data_new( &keydata );
290     if( err )
291     BUG( dlg );
292     err = gpgme_new( &ctx );
293     if( err )
294     BUG( dlg );
295     gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
296     gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);
297    
298     err = gpgme_op_export( ctx, rset, keydata );
299     if( err ) {
300     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
301     goto leave;
302     }
303    
304     log_box( _("Key Manager"), MB_OK,
305     _("Key(s) successfully saved in '%s'."), fname );
306    
307     leave:
308     err = gpgme_data_release_and_set_file( keydata, fname );
309     if( err )
310     log_box( _("Key Manager"), MB_OK,
311     _("Could not save data to '%s'."), fname );
312     gpgme_release( ctx );
313    
314     return (int)err;
315     } /* km_file_export */
316    
317    
318     static int
319 twoaday 19 extract_dash_escaped_key (void)
320 twoaday 2 {
321     gpgme_data_t inp, plain;
322     gpgme_error_t err;
323    
324     err = gpgme_data_new_from_clipboard (&inp);
325 twoaday 19 if (err) {
326     msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
327 twoaday 2 return -1;
328     }
329 twoaday 19 gpgme_data_extract_plaintext (inp, &plain);
330     gpgme_data_release (inp);
331     gpgme_data_release_and_set_clipboard (plain);
332 twoaday 2
333     return 0;
334     } /* extract_dash_escaped_key */
335    
336    
337     int
338     km_clip_import( HWND dlg )
339     {
340     gpgme_error_t err;
341 twoaday 19 gpgme_pgptype_t pgptype;
342 twoaday 2 int id;
343     int has_data = 0;
344    
345     if( !gpgme_clip_istext_avail( &has_data ) && !has_data ) {
346     msg_box( dlg, winpt_strerror( WPTERR_CLIP_ISEMPTY ), _("Key Manager"), MB_ERR );
347     return WPTERR_CLIP_ISEMPTY;
348     }
349     err = gpgme_clip_is_secured( &pgptype, &has_data );
350     if( err )
351     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
352     if( !has_data ) {
353     msg_box( dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR );
354     return WPTERR_GENERAL;
355     }
356 twoaday 19 if( !(pgptype & GPGME_PGP_PUBKEY) && !(pgptype & GPGME_PGP_SECKEY) ) {
357 twoaday 2 msg_box( dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR );
358     return WPTERR_GENERAL;
359     }
360 twoaday 19 if( pgptype & GPGME_PGP_DASH_ESCAPED ) {
361 twoaday 2 id = msg_box( dlg, _("The key you want to import is dash escacped.\n"
362     "Do you want to extract the key?"),
363     _("Key Manager"), MB_YESNO );
364     if( id == IDYES )
365     extract_dash_escaped_key( );
366     else
367     msg_box( dlg, _("Cannot import dash escaped OpenPGP keys."), _("Key Manager"), MB_INFO );
368     }
369    
370     dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
371     clip_import_dlg_proc, NULL,
372     _("Key Import"), IDS_WINPT_IMPORT );
373    
374     return 0;
375     } /* km_clip_import */
376    
377    
378     int
379     km_http_import (HWND dlg, const char * url)
380     {
381     FILE * fp;
382     char * p;
383     char tmpdir[500];
384     http_hd_t hd;
385     int statcode;
386     int rc = 0;
387    
388     if (strncmp (url, "http://", 7)) {
389     log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
390     return WPTERR_GENERAL;
391     }
392    
393     GetTempPath (499, tmpdir);
394     p = make_filename (tmpdir, "file_http", "tmp");
395     if (!p)
396     BUG (0);
397     fp = fopen (p, "wb");
398     if (fp == NULL) {
399     free_if_alloc (p);
400     log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
401     return WPTERR_FILE_CREAT;
402     }
403     /* parse URL */
404     rc = http_send_request2 (url, &hd);
405     if (!rc)
406     rc = http_parse_response (hd, &statcode);
407     if (!rc)
408     rc = http_parse_data (hd, fp);
409     http_hd_free (hd);
410     fclose (fp);
411     if (rc) {
412     free_if_alloc (p);
413     msg_box (dlg, http_strerror (rc), _("Key Import HTTP"), MB_ERR);
414     return WPTERR_GENERAL;
415     }
416     km_file_import (dlg, p);
417     free_if_alloc (p);
418     return 0;
419     }
420    
421     int
422     km_file_import( HWND dlg, const char * fname )
423     {
424     gpgme_data_t keydata = NULL;
425     gpgme_ctx_t ctx;
426     gpgme_error_t err;
427     fm_state_s fm_stat;
428     int import_res[14];
429    
430     memset( &fm_stat, 0, sizeof fm_stat );
431     fm_stat.opaque = m_strdup( fname );
432    
433     dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
434     file_import_dlg_proc, (LPARAM)&fm_stat,
435     _("File Import"), IDS_WINPT_IMPORT );
436     if( fm_stat.cancel == 1 )
437     return WPTERR_GENERAL;
438    
439     err = gpgme_new( &ctx );
440     if( err )
441     BUG( dlg );
442     gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );
443     err = gpgme_data_new_from_file (&keydata, fname);
444     if( err ) {
445     msg_box( dlg, _("Could not read key-data from file."), _("Key Manager"), MB_ERR );
446     goto leave;
447     }
448    
449     err = gpgme_op_import( ctx, NULL, keydata );
450     if( err ) {
451     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
452     goto leave;
453     }
454    
455     gpgme_get_import_status( ctx, import_res, NULL );
456     print_import_status( import_res, fm_stat.implist_revcert );
457     if( import_res[GPGME_IMPSTAT_NOSELFSIG] > 0 ) {
458     msg_box( dlg, _("Key without a self signature was dectected!\n"
459     "(This key is NOT usable for encryption, etc)\n"
460     "\n"
461     "Cannot import these key(s)!"), _("Import"), MB_INFO );
462     }
463    
464     leave:
465     gpgme_data_release( keydata );
466     gpgme_release( ctx );
467     free_if_alloc( fm_stat.opaque );
468     return (int)err;
469     } /* km_file_import */
470    
471    
472     static void
473     delete_keys_from_cache (gpgme_recipients_t rset)
474     {
475     gpgme_keycache_t pub = keycache_get_ctx (1);
476     void * ctx =NULL;
477     const char * s;
478    
479     gpgme_recipients_enum_open (rset, &ctx);
480     while ((s = gpgme_recipients_enum_read (rset, &ctx)))
481     gpgme_keycache_delete_key (pub, s);
482     gpgme_recipients_enum_close (rset, &ctx);
483     } /* delete_keys_from_cache */
484    
485    
486     int
487     km_delete_keys (listview_ctrl_t lv, HWND dlg)
488     {
489     gpgme_error_t err;
490     gpgme_recipients_t rset;
491     char keyid[32], uid[256], date[64], keylen[64];
492     int with_seckey, seckey_type=0;
493 twoaday 20 int i, rc, n;
494 twoaday 2
495     if( listview_get_curr_pos( lv ) == -1 ) {
496     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
497     return WPTERR_GENERAL;
498     }
499    
500     err = gpgme_recipients_new (&rset);
501     if (err)
502     BUG (0);
503 twoaday 20 n = listview_count_items (lv, 0);
504     for( i = 0; i < n; i++ ) {
505 twoaday 2 if( listview_get_item_state( lv, i ) ) {
506     listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
507     listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
508     listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
509     listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
510     seckey_type = km_check_for_seckey( lv, i, NULL );
511     if( !seckey_type ) {
512     rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
513     _("Do you really want to delete this key?\n\n"
514     "pub %s %s %s\n"
515     " \"%s\""), keylen, keyid, date, uid );
516     if( rc == IDYES )
517     gpgme_recipients_add_name( rset, keyid );
518     with_seckey = 0;
519     }
520     else {
521     rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
522     _("Do you really want to delete this KEY PAIR?\n\n"
523     "Please remember that you are not able to decrypt\n"
524     "messages you stored with this key any longer.\n"
525     "\n"
526     "pub/sec %s %s %s\n"
527     " \"%s\""), keylen, keyid, date, uid );
528     if( rc == IDYES ) {
529     if( seckey_type == 2 )
530     msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
531     "Only the public key and the secret key \n"
532     "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
533     gpgme_recipients_add_name( rset, keyid );
534     }
535     with_seckey = 1;
536     }
537     }
538     }
539    
540     if (!gpgme_recipients_count (rset)) {
541     gpgme_recipients_release (rset);
542     return 0;
543     }
544    
545     err = gpgme_op_delete_keys (rset, with_seckey);
546     if (err) {
547     if (err == GPGME_Invalid_Key)
548     msg_box (dlg, _("No such key."), _("Key Manager"), MB_INFO);
549     else if (err == GPGME_Conflict)
550     msg_box (dlg, _("Must delete secret key first."), _("Key Manager"), MB_INFO);
551     else
552     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
553     return FALSE;
554     }
555     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
556     listview_del_items (lv);
557     if (keyring_check_last_access ())
558     keycache_set_reload (1);
559     delete_keys_from_cache (rset);
560     gpgme_recipients_release (rset);
561    
562     return (int)err;
563     } /* km_delete_keys */
564    
565    
566     int
567     km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
568     {
569     char keyid[32];
570     const char *t;
571     int id;
572    
573     id = listview_get_curr_pos( lv );
574     if( id == -1 ) {
575     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
576     return WPTERR_GENERAL;
577     }
578    
579     listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
580     id = log_box (_("Key Manager"), MB_YESNO,
581     _("Do you really want to send '%s' to keyserver %s?"),
582     keyid, host);
583     if (id == IDYES) {
584     t = keyid;
585     if (!strncmp (keyid, "0x", 2))
586     t += 2;
587     hkp_send_key (dlg, host, port, t);
588     }
589    
590     return 0;
591     } /* km_send_to_keyserver */
592    
593    
594     int
595     km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
596     {
597     gpgme_key_t key;
598     gpgme_ctx_t ctx=NULL;
599     gpgme_recipients_t rset=NULL;
600     gpgme_error_t rc;
601     const char * s;
602     char keyid[32], tmp[192+256], * p =NULL;
603     int pos;
604    
605     if( listview_count_items( lv, 1 ) > 1 ) {
606     msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
607     return WPTERR_GENERAL;
608     }
609     pos = listview_get_curr_pos( lv );
610     if( pos == -1 ) {
611     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
612     return WPTERR_GENERAL;
613     }
614     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
615     if( get_pubkey( keyid, &key ) )
616     BUG( NULL );
617     s = gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, 0 );
618     GetTempPath (sizeof tmp-1, tmp);
619     strncat (tmp, s, sizeof tmp-200);
620     strncat (tmp, ".asc", sizeof tmp-200);
621     p = fm_quote_file (tmp);
622    
623     rc = gpgme_recipients_new( &rset );
624     if( !rc )
625     rc = gpgme_recipients_add_name( rset, keyid );
626     if( !rc )
627     rc = gpgme_new( &ctx );
628     if( !rc ) {
629     gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
630     rc = gpgme_op_file_export( ctx, rset, p );
631     }
632     if( rc )
633     msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );
634     else
635     mapi_send_pubkey (keyid, tmp);
636     free_if_alloc( p );
637     gpgme_recipients_release( rset );
638     gpgme_release( ctx );
639     return rc;
640     }
641    
642    
643     static void
644     km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
645     {
646     int idx;
647     char keyid[32];
648     const char *t;
649    
650     if (pos != 0)
651     idx = pos;
652     else
653     idx = listview_get_curr_pos (lv);
654     if (idx != -1)
655     {
656     listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
657     t = keyid;
658     if (!strncmp (keyid, "0x", 2))
659     t += 2;
660     hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
661     }
662     }
663    
664    
665     void
666     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
667     {
668     int idx, id, i;
669    
670     if (kserver_check_inet_connection ())
671     {
672     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
673     _("Key Manager"), MB_ERR);
674     return;
675     }
676     idx = listview_count_items (lv, 0);
677     if (listview_count_items (lv, 1) == idx) {
678     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
679     if (id == IDNO)
680     return;
681     for (i = 0; i < idx; i++)
682     km_refresh_one_key (lv, dlg, i);
683     }
684     else if (idx == 1)
685     km_refresh_one_key (lv, dlg, 0);
686     else {
687     for (i=0; i < listview_count_items (lv, 0); i++) {
688     if (listview_get_item_state (lv, i))
689     km_refresh_one_key (lv, dlg, i);
690     }
691     }
692     } /* km_refresh_from_keyserver */
693    
694    
695     void
696     km_set_clip_info( const char *uid )
697     {
698     char buf[256];
699    
700     km_get_clip_info (uid, buf, 255);
701     set_clip_text( NULL, buf, strlen( buf ) );
702     } /* km_set_clip_info */
703    
704    
705    
706     int
707 twoaday 20 km_key_is_v3 (listview_ctrl_t lv, int pos)
708 twoaday 2 {
709     gpgme_key_t pk;
710     char keyid[32];
711    
712 twoaday 20 listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
713     if (get_pubkey (keyid, &pk))
714     BUG (NULL);
715     return gpgme_key_get_ulong_attr (pk, GPGME_ATTR_VERSION, NULL, 0);
716 twoaday 2 } /* km_key_is_v3 */
717    
718    
719     void
720     km_update_default_key_str (HWND dlg, int * ret_len)
721     {
722     char * keyid, defkeyinf[512];
723     const char * fmt;
724    
725     keyid = get_gnupg_default_key ();
726     if (!keyid)
727     BUG (0);
728     if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
729     || (keyid[0] == '0' && keyid[1] == 'x') )
730     fmt = _("Default Key: %s");
731     else
732     fmt = _("Default Key: 0x%s");
733     _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );
734     SetWindowText( dlg, defkeyinf );
735     *ret_len = strlen( defkeyinf );
736     free_if_alloc( keyid );
737     } /* km_return_default_key_str */
738    
739    
740     void
741     km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )
742     {
743     char text[384];
744     int nkeys = 0, nsec = 0, i;
745    
746     GetWindowText( sb, text, sizeof text -1 );
747     nkeys = listview_count_items( lv, 0 );
748     for( i = 0; i < nkeys; i++ ) {
749     if( km_check_for_seckey( lv, i, NULL ) )
750     nsec++;
751     }
752     _snprintf( text+startpos, sizeof text-1, " %d keys (%d secret keys)", nkeys, nsec );
753     SetWindowText( sb, text );
754     } /* km_complete_status_bar */
755    
756    
757     void
758     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
759     {
760     gpgme_error_t err;
761     gpgme_ctx_t ctx;
762     gpgme_editkey_t ek;
763     char keyid[32];
764    
765     listview_get_item_text (lv, pos, 1, keyid, 31);
766     err = gpgme_new (&ctx);
767     if (err)
768     BUG (0);
769     err = gpgme_editkey_new (&ek);
770     if (err)
771     BUG (0);
772     gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);
773     gpgme_editkey_trust_set (ek, 5);
774    
775     err = gpgme_op_editkey (ctx, keyid);
776     if (err)
777     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
778     else {
779     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
780     keycache_set_reload (1);
781     }
782    
783     gpgme_release (ctx);
784     gpgme_editkey_release (ek);
785     }
786    
787    
788     gpg_optfile_t
789     km_groupdb_open( void )
790     {
791     gpg_optfile_t opt;
792     char * optfile;
793     int err = 0;
794    
795     optfile = get_gnupg_cfgfile();
796     if( !optfile )
797     BUG( NULL );
798     if( parse_gpg_options( optfile, &opt ) )
799     err = 1;
800     free_if_alloc( optfile );
801     return err? NULL : opt;
802     } /* km_groupdb_open */
803    
804    
805     int
806     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
807     {
808     gpgme_keycache_t kc;
809     gpgme_key_t pk;
810     gpg_optfile_t opt;
811     gpg_group_t grp;
812     gpg_member_t mbr;
813     int no_trust = 0, n;
814    
815     kc = keycache_get_ctx( 1 );
816     if( !kc )
817     BUG( NULL );
818    
819     opt = km_groupdb_open( );
820     if( !opt )
821     return WPTERR_FILE_OPEN;
822    
823     grp = find_group( opt, name );
824     if( !grp )
825     return WPTERR_GENERAL;
826    
827     /* we are paranoid and check that all group members exist in the
828     key cache. there is no need that it is really the real key, but
829     an entry should be available. the rest is up to GPG. */
830     for( mbr = grp->list; mbr; mbr = mbr->next ) {
831     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
832     BUG( NULL );
833     n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );
834     while( n-- ) {
835     const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );
836     if( s && stristr( s, mbr->name )
837     && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )
838     no_trust++;
839     }
840     }
841    
842     gpgme_recipients_add_name( rset, name );
843     release_gpg_options( opt );
844    
845     return no_trust;
846     } /* km_groupdb_expand_recipients */
847    
848    
849     static HTREEITEM
850     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
851     {
852     TVINSERTSTRUCT tvis;
853     HTREEITEM node;
854    
855     memset( &tvis, 0, sizeof tvis );
856     tvis.hParent = parent;
857     tvis.hInsertAfter = TVI_LAST;
858     tvis.item.mask = TVIF_TEXT;
859     tvis.item.pszText = (char *)text;
860     node = TreeView_InsertItem( tree, &tvis );
861     return node;
862     } /* km_tv_insert_item */
863    
864    
865     int
866     km_groups_new( km_group_t *r_gc, HWND ctrl )
867     {
868     km_group_t gc;
869    
870     gc = new km_group_s;
871     if (!gc)
872     BUG (NULL);
873     gc->tree = ctrl;
874     gc->gh = km_groupdb_open ();
875     *r_gc = gc;
876     return 0;
877     } /* km_groups_new */
878    
879    
880     void
881     km_groups_sync( km_group_t gc )
882     {
883     char * optfile;
884    
885     optfile = get_gnupg_cfgfile ();
886     if( !optfile )
887     BUG( NULL );
888     commit_gpg_options( optfile, gc->gh );
889     free_if_alloc( optfile );
890     gc->need_sync = 0;
891     } /* km_groups_sync */
892    
893    
894     void
895     km_groups_release (km_group_t gc)
896     {
897     if( gc ) {
898     /* xxx: this reset the default key (sync=1) */
899     gc->need_sync=0;
900     if (gc->need_sync)
901     km_groups_sync (gc);
902     if (gc->gh)
903     release_gpg_options( gc->gh );
904     gc->gh = NULL;
905     gc->tree = NULL;
906     delete gc;
907     }
908     } /* km_groups_release */
909    
910    
911     int
912     km_groups_load( km_group_t gc )
913     {
914     HTREEITEM n;
915     gpg_group_t grp, g;
916     gpg_member_t mbr;
917     u32 gid = 0;
918    
919     if( !gc->gh )
920     return 0;
921     grp = gc->gh->grp;
922     if( !grp )
923     return 0; /* no groups */
924    
925     for( g = grp; g; g = g->next ) {
926     n = km_tv_insert_item( gc->tree, NULL, g->name );
927     for( mbr = g->list; mbr; mbr = mbr->next ) {
928     if( mbr->used && mbr->name )
929     km_tv_insert_item( gc->tree, n, mbr->name );
930     }
931     }
932     DragAcceptFiles( gc->tree, TRUE );
933     gc->need_sync = 0;
934     return 0;
935     } /* km_groups_load */
936    
937    
938     int
939     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
940     {
941     TVITEM tvi;
942     char uid[128], valid[64], text[128];
943     int i_valid;
944    
945     memset( &tvi, 0, sizeof tvi );
946     tvi.hItem = TreeView_GetSelection( gc->tree );
947     tvi.pszText = text;
948     tvi.cchTextMax = sizeof text -1;
949     tvi.mask = TVIF_TEXT;
950     TreeView_GetItem( gc->tree, &tvi );
951    
952    
953     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
954     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
955    
956     if( strstr( valid, "Ultimate" ) )
957     i_valid = 5;
958     else if( !strstr( valid, "Full" ) )
959     i_valid = 4;
960     else if( !strstr( valid, "Marginal" ) )
961     i_valid = 3;
962     else
963     i_valid = 0;
964    
965     /* we can't add the full name. one way would be to use the first
966     text until a space appears.
967     group_add_entry(&gc->gh, gid, i_valid, uid);
968     treeview_add_item(gc->tree, tvi.hItem, uid);
969     */
970     gc->need_sync = 1;
971    
972     return 0;
973     } /* km_groups_add */
974    
975    
976     static int
977     km_groups_del_main( km_group_t gc )
978     {
979     TVITEM tvi;
980     char text[128];
981     int id;
982    
983     memset( &tvi, 0, sizeof tvi );
984     tvi.hItem = TreeView_GetSelection( gc->tree );
985     tvi.pszText = text;
986     tvi.cchTextMax = sizeof text -1;
987     tvi.mask = TVIF_TEXT;
988     TreeView_GetItem( gc->tree, &tvi );
989    
990     id = log_box( _("Key Manager"), MB_INFO_ASK,
991     _("Do you really want to delete this group?\n\n%s"), text);
992     if( id == IDNO )
993     return 0;
994     delete_group( gc->gh, text );
995     TreeView_DeleteItem( gc->tree, &tvi );
996     gc->need_sync = 1;
997    
998     return 0;
999     } /* km_groups_del */
1000    
1001    
1002     static int
1003     km_groups_del_entry( km_group_t gc )
1004     {
1005     TVITEM tvi;
1006     HTREEITEM root;
1007     int id;
1008     char text[128], info[256];
1009     gpg_group_t grp = NULL;
1010    
1011     memset( &tvi, 0, sizeof tvi );
1012     tvi.hItem = TreeView_GetSelection( gc->tree );
1013     tvi.pszText = text;
1014     tvi.cchTextMax = sizeof text-1;
1015     tvi.mask = TVIF_TEXT;
1016     TreeView_GetItem( gc->tree, &tvi );
1017    
1018     _snprintf( info, sizeof info -1,
1019     _("Do you really want to delete this entry?\n\n%s"), text );
1020    
1021     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1022     if( id == IDNO )
1023     return 0;
1024    
1025     root = TreeView_GetParent( gc->tree, tvi.hItem );
1026     if( root ) {
1027     }
1028    
1029     delete_member( gc->gh, /*fixme*/NULL, text );
1030     TreeView_DeleteItem( gc->tree, &tvi );
1031     gc->need_sync = 1;
1032     return 0;
1033     } /* km_groups_del_entry */
1034    
1035    
1036     int
1037     km_groups_del( km_group_t gc )
1038     {
1039     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1040     return km_groups_del_entry( gc );
1041     else
1042     return km_groups_del_main( gc );
1043     } /* km_groups_del */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26