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

Contents of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 101 - (show annotations)
Fri Nov 25 10:56:05 2005 UTC (19 years, 3 months ago) by twoaday
File size: 14505 byte(s)
Localized 'Cancel' buttons.
Fix 'addrevoker' hanging problem.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26