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

Annotation of /trunk/Src/wptKeyserverDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 109 - (hide 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 werner 36 /* 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 werner 42 #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23    
24 werner 36 #include <windows.h>
25     #include <commctrl.h>
26     #include <malloc.h>
27    
28 werner 47 #include "resource.h"
29 werner 36 #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 twoaday 109 char* get_reg_entry_keyserver (const char *);
45 werner 36 int set_reg_entry_keyserver (const char *, const char *);
46    
47    
48 twoaday 109 /* Print out keyserver error and a possible Winsock error. */
49 werner 36 static void
50 twoaday 109 hkp_err_box (HWND dlg, const char *host, WORD port, int rc)
51 werner 36 {
52 twoaday 109 const char *err = kserver_strerror ();
53 werner 36
54 twoaday 109 log_box (_("Keyserver"), MB_ERR, "%s:%d: %s",
55     host, port, winpt_strerror (rc));
56 werner 36 if (err)
57     msg_box (dlg, err, wsock_strerror (), MB_ERR);
58 twoaday 109 }
59 werner 36
60    
61 twoaday 109 /* Send the extracted key with keyid @pattern to the
62     keyserver @kserver (port @port).
63     Return value: 0 on success. */
64 werner 36 int
65 twoaday 109 hkp_send_key (HWND dlg, const char *kserver, WORD port, const char *pattern)
66 werner 36 {
67 twoaday 109 gpgme_ctx_t ctx;
68 werner 36 gpgme_data_t keydata;
69     gpgme_error_t ec;
70 twoaday 109 char *rawkey = NULL;
71     char msg[384];
72 werner 36 size_t n;
73    
74 twoaday 109 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 werner 36 goto leave;
85     }
86     rawkey = gpgme_data_release_and_get_mem (keydata, &n);
87 twoaday 109 ec = kserver_sendkey (kserver, port, rawkey, n);
88     if (ec) {
89     hkp_err_box (dlg, kserver, port, ec);
90 werner 36 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 twoaday 109 gpgme_release (ctx);
98 werner 36 if (rawkey)
99     gpgme_free (rawkey);
100 twoaday 109 return ec? -1 : 0;
101     }
102 werner 36
103    
104 twoaday 109 /* Receive a key from the keyserver @kserver (port @port)
105     with the pattern @pattern.
106     Return value: 0 on success. */
107 werner 36 int
108 twoaday 109 hkp_recv_key (HWND dlg, const char *kserver, WORD port,
109 werner 36 const char *pattern, int proto, int flags)
110     {
111     gpgme_ctx_t ctx;
112     gpgme_data_t keydata;
113     gpgme_error_t ec;
114 twoaday 73 gpgme_import_result_t import_res = NULL;
115 werner 36 int rc;
116 twoaday 109 char *rawkey = NULL;
117     char msg[384];
118 werner 36
119     rawkey = new char[MAX_KEYSIZE];
120     if (!rawkey)
121     BUG (0);
122     memset (rawkey, 0, MAX_KEYSIZE);
123 twoaday 109 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 werner 36 "Please make sure you have an online connection"
128     " and gpgkeys_ldap.exe is installed"),
129 twoaday 109 _("Keyserver"), MB_ERR);
130     free_if_alloc (rawkey);
131 werner 36 return rc;
132     }
133     }
134     else if (proto == KSPROTO_FINGER) {
135     rc = finger_recvkey (kserver, pattern, rawkey, MAX_KEYSIZE-1);
136     if (rc) {
137 twoaday 109 log_box (_("Keyserver"), MB_ERR,
138     _("Finger key import failed: %s\n"), winpt_strerror (rc));
139 werner 36 free_if_alloc (rawkey);
140     return rc;
141     }
142     }
143 twoaday 109 else if ((rc = kserver_recvkey (kserver, port,
144     kserver_check_keyid (pattern),
145     rawkey, MAX_KEYSIZE-1))) {
146 werner 36 hkp_err_box (dlg, kserver, port, rc);
147     free_if_alloc (rawkey);
148     return rc;
149     }
150     else {
151 twoaday 109 if (!strstr (rawkey, "BEGIN PGP PUBLIC KEY BLOCK")) {
152     msg_box (dlg, _("This is not a valid OpenPGP key."),
153     _("Keyserver"), MB_ERR);
154 werner 36 goto leave;
155     }
156 twoaday 109 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 werner 36 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 twoaday 109 if (import_res && import_res->unchanged == 1) {
172 werner 36 _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 twoaday 109 }
189 werner 36
190    
191 twoaday 109 #define my_iskeychar(a) (((a) >='0' && (a) <= '9' ) || ((a) >= 'A' && (a) <= 'F'))
192 werner 36
193     static int
194 twoaday 109 check_pattern (const char *pattern)
195 werner 36 {
196     int rc = 1;
197    
198     /* Whitespace are not allowed! */
199 twoaday 109 if (strchr( pattern, ' ')) {
200 werner 36 rc = WPTERR_GENERAL;
201     goto leave;
202     }
203    
204 twoaday 109 if (((strstr (pattern, "0x")) && (strlen (pattern) == 10)) ||
205     (strstr(pattern, "0x")) && (strlen (pattern) == 18)) {
206     rc = 0; /* Either long or short keyid */
207 werner 36 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 twoaday 109 char proxy[256];
230 werner 36 int port = 0;
231    
232     strcpy (proxy, "HTTP proxy: ");
233     if (kserver_get_proxy (&port)) {
234 twoaday 109 char t[128];
235 werner 36 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 twoaday 109 strcat (proxy, "none");
241     SetDlgItemText (dlg, IDC_KEYSERVER_PROXY, proxy);
242 werner 36 } /* 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 twoaday 109 /* Dialog box procedure to access keyservers. */
359 werner 36 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 twoaday 101 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
381    
382 werner 36 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 twoaday 109 keyserver_proxy_dlg_proc, NULL,
414 werner 36 _("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 twoaday 109 msg_box (dlg, _("Please select one of the keyservers."),
423     _("Keyserver"), MB_INFO);
424 werner 36 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 twoaday 109 msg_box (dlg, _("Please select one of the keyservers."),
450     _("Keyserver"), MB_INFO);
451 werner 36 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 twoaday 109 save_default_ks (lv);
486 werner 36 break;
487    
488     case IDCANCEL:
489 twoaday 109 EndDialog (dlg, FALSE);
490 werner 36 return FALSE;
491     }
492     break;
493     }
494    
495     return FALSE;
496 twoaday 109 }
497    

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26