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

Annotation of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 14887 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


1 twoaday 2 /* wptKeyserverDlg.cpp - Keyserver dialog
2     * Copyright (C) 2000-2005 Timo Schulz
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (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
14     * GNU 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    
21     #include <windows.h>
22     #include <commctrl.h>
23     #include <malloc.h>
24    
25     #include "../resource.h"
26     #include "wptKeyserver.h"
27     #include "wptErrors.h"
28     #include "wptTypes.h"
29     #include "wptCommonCtl.h"
30     #include "wptNLS.h"
31     #include "wptW32API.h"
32     #include "wptVersion.h"
33     #include "wptGPG.h"
34     #include "wptKeyManager.h"
35     #include "wptContext.h" /* for passphrase_s */
36     #include "wptDlgs.h"
37    
38    
39     #define MAX_KEYSIZE 70000
40    
41     char * get_reg_entry_keyserver (const char *);
42     int set_reg_entry_keyserver (const char *, const char *);
43    
44    
45     static void
46     hkp_err_box (HWND dlg, const char * host, u16 port, int rc)
47     {
48     const char *err = kserver_strerror();
49    
50     log_box( _("Keyserver"), MB_ERR, "%s:%d: %s", host, port, winpt_strerror (rc));
51     if (err)
52     msg_box (dlg, err, wsock_strerror (), MB_ERR);
53     } /* hkp_err_box */
54    
55    
56     int
57     hkp_send_key (HWND dlg, const char *kserver, u16 port, const char *pattern)
58     {
59     gpgme_ctx_t c;
60     gpgme_recipients_t rset;
61     gpgme_data_t keydata;
62     gpgme_error_t ec;
63     char *rawkey = NULL, msg[1024];
64     int rc;
65    
66     ec = gpgme_recipients_new( &rset );
67     if( ec )
68     BUG( NULL );
69     gpgme_recipients_add_name( rset, pattern );
70     ec = gpgme_new( &c );
71     if( ec )
72     BUG( NULL );
73     gpgme_control( c, GPGME_CTRL_ARMOR, 1 );
74     ec = gpgme_data_new( &keydata );
75     if( ec )
76     BUG( NULL );
77     rc = (int) gpgme_op_export( c, rset, keydata );
78     if( rc ) {
79     msg_box( dlg, gpgme_strerror( (gpgme_error_t)rc ), _("Export"), MB_ERR );
80     goto leave;
81     }
82     rawkey = gpgme_data_release_and_return_string (keydata);
83     rc = kserver_sendkey (kserver, port, rawkey, strlen (rawkey));
84     if (rc) {
85     hkp_err_box (dlg, kserver, port, rc);
86     goto leave;
87     }
88    
89     _snprintf (msg, sizeof (msg) -1, _("Key '%s' successfully sent"), pattern);
90     status_box (dlg, msg, _("GnuPG status"));
91    
92     leave:
93     gpgme_release (c);
94     gpgme_recipients_release (rset);
95     safe_free (rawkey);
96     return rc;
97     } /* hkp_send_key */
98    
99    
100     int
101 twoaday 22 hkp_recv_key (HWND dlg, const char *kserver, u16 port,
102     const char *pattern, int proto, int flags)
103 twoaday 2 {
104     gpgme_ctx_t ctx;
105     gpgme_data_t keydata;
106     gpgme_error_t ec;
107     int rc, import_res[14];
108 twoaday 22 char *rawkey = NULL, msg[384];
109 twoaday 2
110     rawkey = new char[MAX_KEYSIZE];
111     if (!rawkey)
112     BUG (0);
113     memset (rawkey, 0, MAX_KEYSIZE);
114     if( proto == KSPROTO_LDAP ) {
115     rc = ldap_recvkey( kserver, pattern, rawkey, MAX_KEYSIZE-1 );
116     if( rc ) {
117     msg_box( dlg, _("LDAP key import failed.\n"
118     "Please make sure you have an online connection"
119     " and gpgkeys_ldap.exe is installed"),
120     _("Keyserver"), MB_ERR );
121     free_if_alloc( rawkey );
122     return rc;
123     }
124     }
125     else if (proto == KSPROTO_FINGER) {
126     rc = finger_recvkey (kserver, pattern, rawkey, MAX_KEYSIZE-1);
127     if (rc) {
128     log_box (_("Keyserver"), MB_ERR, _("Finger key import failed: %s\n"),
129     winpt_strerror (rc));
130 twoaday 22 free_if_alloc (rawkey);
131 twoaday 2 return rc;
132     }
133     }
134     else if( ( rc = kserver_recvkey( kserver, port, kserver_check_keyid( pattern ),
135     rawkey, MAX_KEYSIZE-1 ) ) ) {
136     hkp_err_box (dlg, kserver, port, rc);
137     free_if_alloc (rawkey);
138     return rc;
139     }
140     else {
141     if( !strstr( rawkey, "BEGIN PGP PUBLIC KEY BLOCK" ) ) {
142     msg_box( dlg, _("This is not a valid OpenPGP key."), _("Keyserver"), MB_ERR );
143     goto leave;
144     }
145     ec = gpgme_new( &ctx );
146     if( ec )
147     BUG( NULL );
148     gpgme_data_new_from_mem( &keydata, rawkey, strlen( rawkey ), 1 );
149     rc = gpgme_op_import( ctx, NULL, keydata );
150     if( rc ) {
151     msg_box( dlg, gpgme_strerror( (gpgme_error_t)rc ), _("Import"), MB_ERR );
152     goto leave;
153     }
154 twoaday 22 gpgme_get_import_status (ctx, import_res, NULL);
155 twoaday 2 }
156    
157     /* if we use the refresh mode, a lot of keys will be fetched and thus only
158     a summarize at the end is presented and not for each key. */
159 twoaday 22 if (!(flags & KM_KS_REFRESH)) {
160     if (import_res[GPGME_IMPSTAT_NPKEYS] == 0) {
161     _snprintf (msg, DIM (msg)-1,
162 twoaday 2 _("Key '%s' successfully received but nothing was changed."), pattern );
163 twoaday 22 status_box (dlg, msg, _("GnuPG Status"));
164 twoaday 2 rc = WPTERR_GENERAL;
165     goto leave;
166     }
167 twoaday 22 _snprintf (msg, DIM (msg)-1, _("Key '%s' sucessfully received and imported."), pattern);
168     status_box (dlg, msg, _("GnuPG Status"));
169 twoaday 2 }
170    
171     leave:
172     free_if_alloc (rawkey);
173     gpgme_release (ctx);
174     gpgme_data_release (keydata);
175    
176     return rc;
177     } /* hkp_recv_key */
178    
179    
180     #define my_iskeychar(a) ( ( (a) >='0' && (a) <= '9' ) || ( (a) >= 'A' && (a) <= 'F' ) )
181    
182     static int
183     check_pattern( const char *pattern )
184     {
185     int rc = 1;
186    
187     /* Whitespace are not allowed! */
188     if( strchr( pattern, ' ') ) {
189     rc = WPTERR_GENERAL;
190     goto leave;
191     }
192    
193     if( (( strstr( pattern, "0x" ) ) && ( strlen( pattern ) == 10 ) )
194     || (strstr(pattern, "0x")) && ( strlen( pattern ) == 18 ) ) {
195     rc = 0;
196     goto leave;
197     }
198    
199     if( (( my_iskeychar( pattern[0] )) && ( strlen( pattern ) == 8 ) )
200     || (my_iskeychar(pattern[0])) && ( strlen( pattern ) == 16) ) {
201     rc = 0;
202     goto leave;
203     }
204    
205     if( ( strchr( pattern, '@' ) ) && ( strlen( pattern ) >= 3 ) ) {
206     rc = 0;
207     goto leave;
208     }
209    
210     leave:
211     return rc;
212     } /* check_pattern */
213    
214    
215     static void
216     set_proxy (HWND dlg)
217     {
218     char proxy[384];
219     int port = 0;
220    
221     strcpy (proxy, "HTTP proxy: ");
222     if (kserver_get_proxy (&port)) {
223     char t[256];
224     const char *http = kserver_get_proxy (&port);
225     _snprintf (t, sizeof (t) - 1, "\"%s:%d\"", http, port);
226     strcat (proxy, t);
227     }
228     else
229     strcat( proxy, "none" );
230     SetDlgItemText( dlg, IDC_KEYSERVER_PROXY, proxy );
231     } /* set_proxy */
232    
233    
234     static int inline
235     kserver_get_pos (listview_ctrl_t lv)
236     {
237     if (listview_count_items (lv, 0) == 1)
238     return 0;
239     return listview_get_curr_pos (lv);
240     }
241    
242    
243     static u16 inline
244     kserver_get_port (listview_ctrl_t lv)
245     {
246     char buf[16];
247    
248     listview_get_item_text (lv, kserver_get_pos (lv), 3, buf, 15);
249     return (u16)strtoul (buf, NULL, 10);
250     }
251    
252     static void
253     load_default_ks (listview_ctrl_t lv)
254     {
255     char * p, buf[192];
256     int i;
257    
258     p = get_reg_entry_keyserver ("Default");
259     if (!p)
260     return;
261     for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {
262     listview_get_item_text( lv, i, 0, buf, sizeof (buf)-1 );
263     if( !strncmp( p, buf, strlen( p ) ) ) {
264     listview_add_sub_item( lv, i, 2, "x" );
265     break;
266     }
267     }
268     free_if_alloc (p);
269     } /* load_default_ks */
270    
271    
272     static int
273     save_default_ks (listview_ctrl_t lv)
274     {
275     char buf[192], port[32];
276     int idx, i;
277    
278     idx = listview_get_curr_pos( lv );
279     if( idx == -1 ) {
280     msg_box( NULL, _("Please select one of the servers."), _("Keyserver"), MB_ERR );
281     return -1;
282     }
283     listview_get_item_text( lv, idx, 1, buf, sizeof (buf)-1 );
284     if( *buf != 'H' ) {
285     msg_box( NULL, _("Only HTTP keyserver can be used."), _("Keyserver"), MB_ERR );
286     return -1;
287     }
288     for (i = 0; i < listview_count_items( lv, 0 ); i++)
289     listview_add_sub_item (lv, i, 2, "");
290     listview_add_sub_item (lv, idx, 2, "x");
291     listview_get_item_text (lv, idx, 0, buf, sizeof (buf)-1);
292     set_reg_entry_keyserver ("Default", buf);
293     i = kserver_get_port (lv);
294     sprintf (port, "%d", i);
295     set_reg_entry_keyserver ("Default_Port", port);
296     keyserver_set_default (buf, (u16)i);
297     return 0;
298     } /* save_default_ks */
299    
300    
301     int
302     keyserver_list_build (listview_ctrl_t *r_lv, HWND hwnd)
303     {
304     struct listview_column_s keyserver[] = {
305     {0, 160, (char *)_("DNS Name")},
306     {1, 52, (char *)_("Protocol")},
307     {2, 46, (char *)_("Default")},
308     {3, 46, (char *)_("Port")},
309     {0, 0, NULL}
310     };
311     listview_ctrl_t lv;
312     char buf[32];
313     int j;
314    
315     listview_new (&lv);
316     lv->ctrl = hwnd;
317     for (j=0; keyserver[j].fieldname; j++)
318     listview_add_column (lv, &keyserver[j]);
319     for (j = 0; j<MAX_KEYSERVERS; j++) {
320     if (!server[j].used)
321     continue;
322     listview_add_item (lv, " ");
323     listview_add_sub_item (lv, 0, 0, server[j].name);
324     switch (server[j].proto) {
325     case KSPROTO_HTTP:
326     listview_add_sub_item( lv, 0, 1, "H" ); break;
327     case KSPROTO_LDAP:
328     listview_add_sub_item( lv, 0, 1, "L" ); break;
329     case KSPROTO_FINGER:
330     listview_add_sub_item( lv, 0, 1, "F" ); break;
331     }
332     sprintf (buf, "%d", server[j].port);
333     listview_add_sub_item (lv, 0, 3, buf);
334     }
335     load_default_ks (lv);
336     if (listview_count_items (lv, 0) == 0) {
337     listview_add_item (lv, "");
338     listview_add_sub_item (lv, 0, 0, DEF_HKP_KEYSERVER);
339     listview_add_sub_item (lv, 0, 1, "H");
340     }
341     listview_set_ext_style (lv);
342     *r_lv = lv;
343     return 0;
344     }
345    
346    
347     BOOL CALLBACK
348     keyserver_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
349     {
350     static listview_ctrl_t lv = NULL;
351     static int lv_idx = 0;
352     int rc, proto_nr = 0;
353     char kserver[128], pattern[128];
354     char proto[16];
355     keyserver_ctx ksc;
356    
357     switch ( msg ) {
358     case WM_INITDIALOG:
359     #ifndef LANG_DE
360     SetWindowText( dlg, _("Keyserver Access") );
361     SetDlgItemText( dlg, IDC_KEYSERVER_SEND,
362     _("Send key (default is receiving)") );
363     SetDlgItemText( dlg, IDC_KEYSERVER_INFO,
364 twoaday 22 _("Please enter the key ID or email address you search for"));
365 twoaday 2 SetDlgItemText( dlg, IDC_KEYSERVER_INDEX, _("&Search") );
366     #endif
367     set_proxy (dlg);
368     keyserver_list_build (&lv, GetDlgItem (dlg, IDC_KEYSERVER_LIST));
369     center_window (dlg);
370     SetForegroundWindow (dlg);
371     return TRUE;
372    
373     case WM_NOTIFY:
374     NMHDR *notify;
375     notify = (NMHDR *)lparam;
376     if( notify && notify->code == NM_CLICK
377     && notify->idFrom == IDC_KEYSERVER_LIST )
378     lv_idx = listview_get_curr_pos( lv );
379     return TRUE;
380    
381     case WM_DESTROY:
382     if( lv ) {
383     listview_release( lv );
384     lv = NULL;
385     }
386     lv_idx = 0;
387     return FALSE;
388    
389     case WM_SYSCOMMAND:
390     if( LOWORD( wparam ) == SC_CLOSE )
391     EndDialog( dlg, TRUE );
392     return FALSE;
393    
394     case WM_COMMAND:
395     switch( LOWORD( wparam ) ) {
396     case IDC_KEYSERVER_PROXSETT:
397     dialog_box_param( glob_hinst, (LPCTSTR)IDD_WINPT_KEYSERVER_PROXY, glob_hwnd,
398     keyserver_proxy_dlg_proc, NULL,
399     _("Proxy Settings"), IDS_WINPT_KEYSERVER_PROXY );
400     set_proxy( dlg );
401     return TRUE;
402    
403     case IDC_KEYSERVER_INDEX:
404     if (!lv_idx) {
405     lv_idx = kserver_get_pos (lv);
406     if (lv_idx == -1) {
407     msg_box (dlg, _("Please select one of the keyservers."), _("Keyserver"), MB_INFO);
408     return FALSE;
409     }
410     }
411     listview_get_item_text (lv, lv_idx, 1, proto, sizeof (proto)-1);
412     if (*proto == 'L') {
413     msg_box( dlg, _("This is not implemented yet!"), _("Keyserver"), MB_ERR );
414     return FALSE;
415     }
416     listview_get_item_text (lv, lv_idx, 0, kserver, sizeof (kserver)-1);
417     if (!GetDlgItemText (dlg, IDC_KEYSERVER_SEARCH, pattern, sizeof (pattern)-1)) {
418     msg_box (dlg, _("Please enter the search pattern."), _("Keyserver"), MB_INFO);
419     return FALSE;
420     }
421     ksc.name = kserver;
422     ksc.pattern = pattern;
423     ksc.port = kserver_get_port (lv);
424     DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_HKPSEARCH, dlg,
425     hkpsearch_dlg_proc, (LPARAM) &ksc );
426     return TRUE;
427    
428     case IDC_KEYSERVER_RECV:
429     memset (&kserver, 0, sizeof (kserver));
430     if (!lv_idx) {
431     lv_idx = kserver_get_pos (lv);
432     if (lv_idx == -1) {
433     msg_box( dlg, _("Please select one of the keyservers."), _("Keyserver"), MB_INFO );
434     return FALSE;
435     }
436     }
437     listview_get_item_text( lv, lv_idx, 1, proto, sizeof (proto)-1 );
438     proto_nr = KSPROTO_HTTP;
439     if( *proto == 'L' )
440     proto_nr = KSPROTO_LDAP;
441     else if( *proto == 'F' )
442     proto_nr = KSPROTO_FINGER;
443     listview_get_item_text( lv, lv_idx, 0, kserver, sizeof (kserver)-1 );
444     if( !GetDlgItemText( dlg, IDC_KEYSERVER_SEARCH, pattern, sizeof (pattern)-1 ) ) {
445     msg_box( dlg, _("Please enter the search pattern."), _("Keyserver"), MB_INFO );
446     return FALSE;
447     }
448     if( proto_nr == KSPROTO_LDAP && strchr( pattern, '@' ) ) {
449     msg_box( dlg, _("Only keyids are allowed."), _("LDAP Keyserver"), MB_INFO );
450     return FALSE;
451     }
452 twoaday 22 else if (proto_nr == KSPROTO_FINGER) {
453     if (strchr (pattern, '@') || strchr (pattern, ' ')) {
454     msg_box (dlg, _("Only enter the name of the user."), _("FINGER Keyserver"), MB_INFO);
455     return FALSE;
456     }
457 twoaday 2 }
458     else if( check_pattern( pattern ) ) {
459 twoaday 22 msg_box( dlg, _("Only email addresses or keyids are allowed."), _("HKP Keyserver"), MB_INFO );
460 twoaday 2 return FALSE;
461     }
462     rc = hkp_recv_key (dlg, kserver, kserver_get_port (lv), pattern, proto_nr, 0);
463     if (!rc)
464     keycache_set_reload (1);
465     return TRUE;
466    
467     case IDC_KEYSERVER_DEFAULT:
468     save_default_ks( lv );
469     break;
470    
471     case IDCANCEL:
472     EndDialog( dlg, FALSE );
473     return FALSE;
474     }
475     break;
476     }
477    
478     return FALSE;
479     } /* keyserver_dlg_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26