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

Annotation of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 115 - (hide annotations)
Wed Dec 7 08:11:34 2005 UTC (19 years, 2 months ago) by twoaday
File size: 15493 byte(s)
2005-12-06  Timo Schulz  <ts@g10code.com>
 
        * WinPT.cpp (WinMain): Load the gettext environment soon
        as possible so all 'first start' messages are localized.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): If a single key is
        received via the keyserver, return the gpgme key context on
        success and add it directly to the list.
        * wptKeyserverDlg.cpp (keyserver_dlg_proc): Support a param
        to store the key.
        (hkp_recv_key2): Add extra param for the fingerprint.
        (hkp_recv_key): Call hkp_recv_key2 without fingerprint.
         

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26