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

Annotation of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14696 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26