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

Contents of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 14887 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26