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

Annotation of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 14927 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26