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

Contents of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (show annotations)
Fri Oct 28 08:25:30 2005 UTC (19 years, 4 months ago) by werner
File size: 14494 byte(s)
Readded lost changes from revision 40

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26