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

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (hide annotations)
Fri May 20 08:39:15 2005 UTC (19 years, 9 months ago) by twoaday
File size: 28607 byte(s)
2005-05-09 Timo Schulz  <twoaday@freakmail.de>
                                                                                  
        * wptCommonDlg.cpp (http_file_dlg_proc): Renamed to..
        (http_dlg_proc): ..this.
        (get_keyserver_URL_dlg): New.
        (check_URL): New.
        * wptKeyEditDlgs.cpp (keyedit_set_pref_keyserver): New.
        (keyedit_main_dlg_proc): Avoid massive keycache reloads, just reload
        the single key.
        * wptKeyRevokersDlg.cpp (key_revokers_dlg_proc): Show the key properties
        of the selected desig. revoker.
        * wptVerifyList.cpp (verlist_build): Increase the column size of 'keyid'.
        * wptGPGME.cpp (keycache_update): New.
        * wptKeySigDlg.cpp (keysig_dlg_proc): Update the key if a signature
        was deleted.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Zeroing the key struct
        before we set any values.
                                                                                  

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     int i, rc;
494    
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    
504     for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
505     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     km_key_is_v3( listview_ctrl_t lv, int pos )
708     {
709     gpgme_key_t pk;
710     const char * fpr;
711     unsigned long algo;
712     char keyid[32];
713    
714     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
715     if( get_pubkey( keyid, &pk ) )
716     BUG( NULL );
717     algo = gpgme_key_get_ulong_attr( pk, GPGME_ATTR_ALGO, NULL, 0 );
718     fpr = gpgme_key_get_string_attr( pk, GPGME_ATTR_FPR, NULL, 0 );
719     return strlen( fpr ) == 32 && algo == GPGME_PK_RSA? 1 : 0;
720     } /* km_key_is_v3 */
721    
722    
723     void
724     km_update_default_key_str (HWND dlg, int * ret_len)
725     {
726     char * keyid, defkeyinf[512];
727     const char * fmt;
728    
729     keyid = get_gnupg_default_key ();
730     if (!keyid)
731     BUG (0);
732     if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
733     || (keyid[0] == '0' && keyid[1] == 'x') )
734     fmt = _("Default Key: %s");
735     else
736     fmt = _("Default Key: 0x%s");
737     _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );
738     SetWindowText( dlg, defkeyinf );
739     *ret_len = strlen( defkeyinf );
740     free_if_alloc( keyid );
741     } /* km_return_default_key_str */
742    
743    
744     void
745     km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )
746     {
747     char text[384];
748     int nkeys = 0, nsec = 0, i;
749    
750     GetWindowText( sb, text, sizeof text -1 );
751     nkeys = listview_count_items( lv, 0 );
752     for( i = 0; i < nkeys; i++ ) {
753     if( km_check_for_seckey( lv, i, NULL ) )
754     nsec++;
755     }
756     _snprintf( text+startpos, sizeof text-1, " %d keys (%d secret keys)", nkeys, nsec );
757     SetWindowText( sb, text );
758     } /* km_complete_status_bar */
759    
760    
761     void
762     km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
763     {
764     gpgme_error_t err;
765     gpgme_ctx_t ctx;
766     gpgme_editkey_t ek;
767     char keyid[32];
768    
769     listview_get_item_text (lv, pos, 1, keyid, 31);
770     err = gpgme_new (&ctx);
771     if (err)
772     BUG (0);
773     err = gpgme_editkey_new (&ek);
774     if (err)
775     BUG (0);
776     gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);
777     gpgme_editkey_trust_set (ek, 5);
778    
779     err = gpgme_op_editkey (ctx, keyid);
780     if (err)
781     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
782     else {
783     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
784     keycache_set_reload (1);
785     }
786    
787     gpgme_release (ctx);
788     gpgme_editkey_release (ek);
789     }
790    
791    
792     gpg_optfile_t
793     km_groupdb_open( void )
794     {
795     gpg_optfile_t opt;
796     char * optfile;
797     int err = 0;
798    
799     optfile = get_gnupg_cfgfile();
800     if( !optfile )
801     BUG( NULL );
802     if( parse_gpg_options( optfile, &opt ) )
803     err = 1;
804     free_if_alloc( optfile );
805     return err? NULL : opt;
806     } /* km_groupdb_open */
807    
808    
809     int
810     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
811     {
812     gpgme_keycache_t kc;
813     gpgme_key_t pk;
814     gpg_optfile_t opt;
815     gpg_group_t grp;
816     gpg_member_t mbr;
817     int no_trust = 0, n;
818    
819     kc = keycache_get_ctx( 1 );
820     if( !kc )
821     BUG( NULL );
822    
823     opt = km_groupdb_open( );
824     if( !opt )
825     return WPTERR_FILE_OPEN;
826    
827     grp = find_group( opt, name );
828     if( !grp )
829     return WPTERR_GENERAL;
830    
831     /* we are paranoid and check that all group members exist in the
832     key cache. there is no need that it is really the real key, but
833     an entry should be available. the rest is up to GPG. */
834     for( mbr = grp->list; mbr; mbr = mbr->next ) {
835     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
836     BUG( NULL );
837     n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );
838     while( n-- ) {
839     const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );
840     if( s && stristr( s, mbr->name )
841     && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )
842     no_trust++;
843     }
844     }
845    
846     gpgme_recipients_add_name( rset, name );
847     release_gpg_options( opt );
848    
849     return no_trust;
850     } /* km_groupdb_expand_recipients */
851    
852    
853     static HTREEITEM
854     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
855     {
856     TVINSERTSTRUCT tvis;
857     HTREEITEM node;
858    
859     memset( &tvis, 0, sizeof tvis );
860     tvis.hParent = parent;
861     tvis.hInsertAfter = TVI_LAST;
862     tvis.item.mask = TVIF_TEXT;
863     tvis.item.pszText = (char *)text;
864     node = TreeView_InsertItem( tree, &tvis );
865     return node;
866     } /* km_tv_insert_item */
867    
868    
869     int
870     km_groups_new( km_group_t *r_gc, HWND ctrl )
871     {
872     km_group_t gc;
873    
874     gc = new km_group_s;
875     if (!gc)
876     BUG (NULL);
877     gc->tree = ctrl;
878     gc->gh = km_groupdb_open ();
879     *r_gc = gc;
880     return 0;
881     } /* km_groups_new */
882    
883    
884     void
885     km_groups_sync( km_group_t gc )
886     {
887     char * optfile;
888    
889     optfile = get_gnupg_cfgfile ();
890     if( !optfile )
891     BUG( NULL );
892     commit_gpg_options( optfile, gc->gh );
893     free_if_alloc( optfile );
894     gc->need_sync = 0;
895     } /* km_groups_sync */
896    
897    
898     void
899     km_groups_release (km_group_t gc)
900     {
901     if( gc ) {
902     /* xxx: this reset the default key (sync=1) */
903     gc->need_sync=0;
904     if (gc->need_sync)
905     km_groups_sync (gc);
906     if (gc->gh)
907     release_gpg_options( gc->gh );
908     gc->gh = NULL;
909     gc->tree = NULL;
910     delete gc;
911     }
912     } /* km_groups_release */
913    
914    
915     int
916     km_groups_load( km_group_t gc )
917     {
918     HTREEITEM n;
919     gpg_group_t grp, g;
920     gpg_member_t mbr;
921     u32 gid = 0;
922    
923     if( !gc->gh )
924     return 0;
925     grp = gc->gh->grp;
926     if( !grp )
927     return 0; /* no groups */
928    
929     for( g = grp; g; g = g->next ) {
930     n = km_tv_insert_item( gc->tree, NULL, g->name );
931     for( mbr = g->list; mbr; mbr = mbr->next ) {
932     if( mbr->used && mbr->name )
933     km_tv_insert_item( gc->tree, n, mbr->name );
934     }
935     }
936     DragAcceptFiles( gc->tree, TRUE );
937     gc->need_sync = 0;
938     return 0;
939     } /* km_groups_load */
940    
941    
942     int
943     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
944     {
945     TVITEM tvi;
946     char uid[128], valid[64], text[128];
947     int i_valid;
948    
949     memset( &tvi, 0, sizeof tvi );
950     tvi.hItem = TreeView_GetSelection( gc->tree );
951     tvi.pszText = text;
952     tvi.cchTextMax = sizeof text -1;
953     tvi.mask = TVIF_TEXT;
954     TreeView_GetItem( gc->tree, &tvi );
955    
956    
957     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
958     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
959    
960     if( strstr( valid, "Ultimate" ) )
961     i_valid = 5;
962     else if( !strstr( valid, "Full" ) )
963     i_valid = 4;
964     else if( !strstr( valid, "Marginal" ) )
965     i_valid = 3;
966     else
967     i_valid = 0;
968    
969     /* we can't add the full name. one way would be to use the first
970     text until a space appears.
971     group_add_entry(&gc->gh, gid, i_valid, uid);
972     treeview_add_item(gc->tree, tvi.hItem, uid);
973     */
974     gc->need_sync = 1;
975    
976     return 0;
977     } /* km_groups_add */
978    
979    
980     static int
981     km_groups_del_main( km_group_t gc )
982     {
983     TVITEM tvi;
984     char text[128];
985     int id;
986    
987     memset( &tvi, 0, sizeof tvi );
988     tvi.hItem = TreeView_GetSelection( gc->tree );
989     tvi.pszText = text;
990     tvi.cchTextMax = sizeof text -1;
991     tvi.mask = TVIF_TEXT;
992     TreeView_GetItem( gc->tree, &tvi );
993    
994     id = log_box( _("Key Manager"), MB_INFO_ASK,
995     _("Do you really want to delete this group?\n\n%s"), text);
996     if( id == IDNO )
997     return 0;
998     delete_group( gc->gh, text );
999     TreeView_DeleteItem( gc->tree, &tvi );
1000     gc->need_sync = 1;
1001    
1002     return 0;
1003     } /* km_groups_del */
1004    
1005    
1006     static int
1007     km_groups_del_entry( km_group_t gc )
1008     {
1009     TVITEM tvi;
1010     HTREEITEM root;
1011     int id;
1012     char text[128], info[256];
1013     gpg_group_t grp = NULL;
1014    
1015     memset( &tvi, 0, sizeof tvi );
1016     tvi.hItem = TreeView_GetSelection( gc->tree );
1017     tvi.pszText = text;
1018     tvi.cchTextMax = sizeof text-1;
1019     tvi.mask = TVIF_TEXT;
1020     TreeView_GetItem( gc->tree, &tvi );
1021    
1022     _snprintf( info, sizeof info -1,
1023     _("Do you really want to delete this entry?\n\n%s"), text );
1024    
1025     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1026     if( id == IDNO )
1027     return 0;
1028    
1029     root = TreeView_GetParent( gc->tree, tvi.hItem );
1030     if( root ) {
1031     }
1032    
1033     delete_member( gc->gh, /*fixme*/NULL, text );
1034     TreeView_DeleteItem( gc->tree, &tvi );
1035     gc->need_sync = 1;
1036     return 0;
1037     } /* km_groups_del_entry */
1038    
1039    
1040     int
1041     km_groups_del( km_group_t gc )
1042     {
1043     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1044     return km_groups_del_entry( gc );
1045     else
1046     return km_groups_del_main( gc );
1047     } /* km_groups_del */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26