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

Contents of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 109 - (show annotations)
Fri Dec 2 07:32:13 2005 UTC (19 years, 3 months ago) by twoaday
File size: 14804 byte(s)
2005-12-01  Timo Schulz  <ts@g10code.com>
 
        * wptClipVerifyDlg.cpp (clipverify_dlg_proc): Use new semantic
        for get_gpg_sigstat().
        * wptGPGME.cpp (get_gpg_sigstat): New. It is now a function.
        As a macro strings will not be translated at runtime.
        * wptKeyserverDlg.cpp (hkp_recv_key): Properly detect if we
        need to update the cache. Thanks to Jan-Oliver.
        * wptKeyImportStatusDlg.cpp (import_status_dlg_proc): Localized.
         

Prepare a new release.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26