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

Contents of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show 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 /* 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