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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 73 - (show annotations)
Tue Nov 8 07:15:13 2005 UTC (19 years, 3 months ago) by twoaday
File size: 14636 byte(s)
2005-11-08  Timo Schulz  <ts@g10code.com>
 
        More minor changes to avoid GCC warnings.
         
        * wptGPG.cpp (check_homedir): Free memory in case of errors.
        (multi_gnupg_path): Add strict mode. If non-strict mode return
        the folder even if it does not exist.
        (check_for_gpgwin): New.
        * wptKeyserverDlg.cpp (hkp_recv_key): Make sure import_res is
        initialized.
        * wptRegistry.cpp (get_reg_entry_gpg4win): New.
        (get_reg_entry_mo): Support for gpg4win.
         
For complete changes see ChangeLogs.

1 /* WinPT.cpp - Windows Privacy Tray (WinPT)
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
26 #include "resource.h"
27 #include "wptTypes.h"
28 #include "wptW32API.h"
29 #include "wptVersion.h"
30 #include "wptErrors.h"
31 #include "wptGPG.h"
32 #include "wptRegistry.h"
33 #include "wptCommonCtl.h"
34 #include "wptDlgs.h"
35 #include "wptNLS.h"
36 #include "wptKeyserver.h"
37 #include "wptCard.h"
38 #include "wptFileManager.h"
39 #include "wptContext.h"
40 #include "wptCardEdit.h"
41 #include "wptCrypto.h"
42
43 #define MIN_GPG_VER "1.4.3" /* Minimal GPG version. */
44 #define MIN_GPGME_VER "1.2.0" /* Minimal GPGME version. */
45
46
47 HINSTANCE glob_hinst; /* global instance for the dialogs */
48 HWND glob_hwnd; /* global window handle for the dialogs */
49 HWND activ_hwnd;
50 LOCK mo_file;
51 int scard_support = 0;
52 int debug = 0;
53 int mobile = 0;
54 int gpg_read_only = 0;
55 char gpgver[3];
56
57
58 /* Load the key cache and rebuild the signature cache. */
59 static void
60 update_keycache (HWND hwnd)
61 {
62 refresh_cache_s rcs = {0};
63 rcs.kr_reload = 0;
64 rcs.kr_update = 1;
65 rcs.tr_update = 1;
66 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, hwnd,
67 keycache_dlg_proc, (LPARAM)&rcs);
68 }
69
70
71 /* Set GPGME debug mode. If @val is 0, the debug mode is disabled. */
72 void
73 gpg_set_debug_mode (int val)
74 {
75 if (val)
76 putenv ("GPGME_DEBUG=5:gpgme.dbg");
77 else
78 putenv ("GPGME_DEBUG=");
79 }
80
81
82 /* Return the name of the gettext language file. */
83 static char*
84 get_gettext_lang (void)
85 {
86 char *fname;
87 fname = get_reg_entry_mo ();
88 if (!fname)
89 return NULL;
90 return fname;
91 }
92
93
94 /* Initialize the gettext sub system. */
95 static void
96 load_gettext (int prev_inst)
97 {
98 char *nls = NULL;
99 char *file = NULL;
100
101 nls = get_gettext_lang ();
102 if (nls) {
103 set_gettext_file ("winpt", nls);
104 file = make_filename (nls, "winpt", "mo");
105 if (!file_exist_check (nls) && init_file_lock (&mo_file, file)) {
106 if (!prev_inst)
107 msg_box (NULL, _("Could not initizalize file lock.\n"
108 "Native Language Support"),
109 _("WinPT Error"), MB_ERR);
110 }
111 free_if_alloc (nls);
112 free_if_alloc (file);
113 }
114 }
115
116
117 /* check if the default key from the gpg.conf file is available in the
118 keyring. if not, bail out because encryption won't work properly then. */
119 static int
120 check_default_key (gpg_keycache_t kc)
121 {
122 gpgme_key_t key;
123 gpgme_error_t err = GPG_ERR_NO_ERROR;
124 char * defkey;
125
126 defkey = get_gnupg_default_key ();
127 if (defkey)
128 err = gpg_keycache_find_key (kc, defkey, 0, &key);
129 else
130 msg_box (NULL, _("No useable secret key found."), _("WinPT Error"), MB_ERR);
131 free_if_alloc (defkey);
132 return err? -1 : 0;
133 }
134
135
136 /* Return the WinPT program file name (with full pathname). */
137 static const char *
138 get_prog_part (const char * fname, int use_cwd)
139 {
140 static char program[512];
141 char currdir[256];
142 char *cmd = NULL;
143 int j;
144
145 memset (currdir, 0, DIM (currdir));
146 memset (program, 0, DIM (program));
147
148 if (use_cwd) {
149 GetCurrentDirectory (DIM (currdir)-1, currdir);
150 _snprintf (program, DIM (program)-1, "%s\\%s", currdir, fname);
151 }
152 else {
153 cmd = GetCommandLine ();
154 if (cmd == NULL)
155 return NULL;
156 strncpy (currdir, cmd, sizeof (currdir)-1);
157 j = strlen (currdir);
158 while (j--) {
159 if (currdir[j] == '\\')
160 break;
161 }
162 currdir[j] = 0;
163 _snprintf (program, DIM (program)-1, "%s\\%s", currdir + 1, fname);
164 }
165 return program;
166 }
167
168
169 /* Check that the underlying crypto engine fullfills the minimal
170 requirements so all commands work properly. */
171 static int
172 check_crypto_engine (void)
173 {
174 int ma=1, mi=4, pa=3; /* GPG 1.4.3 */
175 int rc;
176
177 rc = check_gnupg_engine (&ma, &mi, &pa);
178 if (rc == -1) {
179 msg_box (NULL, _("Could not read GnuPG version."),
180 _("WinPT Error"), MB_ERR);
181 return rc;
182 }
183 else if (rc) {
184 log_box (_("WinPT Error"), MB_ERR,
185 _("Sorry, you need a newer GPG version.\n"
186 "GPG version %d.%d.%d required GPG version "MIN_GPG_VER),
187 ma, mi, pa);
188 return rc;
189 }
190 /* We enable smartcard support for GPG: 1.9 or >= 1.4 */
191 if ((ma == 1 && mi >= 4) || ma > 1)
192 scard_support = 1;
193
194 gpgver[0] = ma;
195 gpgver[1] = mi;
196 gpgver[2] = pa;
197 return rc;
198 }
199
200
201 /* Try to load the keyserver config file. If @quiet is 1
202 do not show any errors. */
203 static int
204 load_keyserver_conf (int quiet)
205 {
206 const char * t;
207 int rc;
208
209 if (reg_prefs.kserv_conf)
210 t = reg_prefs.kserv_conf;
211 else if (!file_exist_check (get_prog_part ("keyserver.conf", 0)))
212 t = get_prog_part ("keyserver.conf", 0);
213 else
214 t = "keyserver.conf";
215 rc = kserver_load_conf (t);
216 if (rc && !quiet)
217 msg_box (NULL, winpt_strerror (rc), _("Keyserver"), MB_ERR);
218 return rc;
219 }
220
221
222 /* Enable the mobility mode. */
223 static void
224 enable_mobile_mode (void)
225 {
226 memset (&reg_prefs, 0, sizeof (reg_prefs));
227 reg_prefs.always_trust = 0;
228 reg_prefs.auto_backup = 0;
229 reg_prefs.cache_time = 0;
230 reg_prefs.expert = 0;
231 reg_prefs.keylist_mode = 1;
232 reg_prefs.kserv_conf = m_strdup ("keyserver.conf");
233 reg_prefs.no_zip_mmedia = 1;
234 reg_prefs.use_tmpfiles = 1;
235 reg_prefs.word_wrap = 80;
236 reg_prefs.use_viewer = 0; /* XXX */
237 }
238
239 char* multi_gnupg_path (void);
240
241 const char * fm_get_file_type (const char *fname, int *r_type);
242
243 /* Main entry point. */
244 int WINAPI
245 WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
246 {
247 WNDCLASS wc = {0, winpt_main_proc, 0, 0, hinst, 0, 0, 0, 0, PGM_NAME};
248 HACCEL accel_tab;
249 int rc, ec, created = 0, nfiles = 0;
250 int first_start = 0, start_gpgprefs = 0;
251 int winpt_inst_found = 0;
252 const char *s;
253 MSG msg;
254 HWND hwnd = NULL;
255
256 glob_hinst = hinst;
257
258 #ifdef _DEBUG
259 gpg_set_debug_mode (1);
260 debug = 1;
261 #endif
262
263 if (gpg_md_selftest ()) {
264 msg_box (NULL, _("Cryptographic selftest failed."),
265 _("WinPT Error"), MB_ERR);
266 return 0;
267 }
268
269 s = gpgme_check_version (MIN_GPGME_VER);
270 if (!s || !*s) {
271 msg_box (NULL, _("A newer GPGME version is needed; at least "MIN_GPGME_VER),
272 _("WinPT Error"), MB_ERR);
273 return 0;
274 }
275
276 CreateMutex (NULL, TRUE, PGM_NAME);
277 if (GetLastError () == ERROR_ALREADY_EXISTS)
278 winpt_inst_found = 1;
279
280 if (cmdline && stristr (cmdline, "--mobile")) {
281 msg_box (NULL, "WARNING: mobile modus is not fully implemented yet!",
282 "WinPT", MB_INFO);
283 mobile = 1;
284 }
285
286 set_default_kserver ();
287
288 if (!mobile) {
289 regist_inst_gnupg (1);
290 regist_inst_winpt (1, &created);
291 }
292 else {
293 enable_mobile_mode ();
294 /* XXX: ask for GPG path */
295 created = 1; /* Disable registry writing */
296 }
297
298 if (!created) {
299 memset (&reg_prefs, 0, sizeof (reg_prefs));
300 reg_prefs.use_tmpfiles = 1; /* default */
301 reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
302 get_reg_winpt_prefs (&reg_prefs);
303 if (!reg_prefs.no_hotkeys)
304 hotkeys_modify ();
305 gnupg_load_config ();
306 }
307
308 rc = gnupg_check_homedir ();
309 if (rc) {
310 log_box (_("WinPT Error"), MB_ERR,
311 _("GPG home directory is not set correctly.\n"
312 "Please check the GPG registry settings:\n%s."),
313 winpt_strerror (rc));
314 s = get_fileopen_dlg (GetActiveWindow (),
315 _("Select GPG Public Keyring"),
316 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
317 NULL);
318 if (s != NULL) {
319 size_t n;
320 char * p = strrchr (s, '\\');
321 if (!p)
322 BUG (0);
323 n = p - s;
324 if (n) {
325 char * file = new char[n+1];
326 if (!file)
327 BUG (NULL);
328 memset (file, 0, n);
329 memcpy (file, s, n);
330 file[n] = '\0';
331 set_reg_entry_gpg ("HomeDir", file);
332 free_if_alloc (file);
333 gnupg_check_homedir (); /* change gpgProgram if needed */
334 }
335 }
336 else {
337 msg_box (NULL, _("GPG home directory could not be determited."),
338 _("WinPT Error"), MB_ERR);
339 goto start;
340 }
341 }
342
343 rc = check_gnupg_prog ();
344 if (rc) {
345 if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
346 "Do you want to start the GPG preferences to "
347 "correct this problem?"), _("WinPT Error"),
348 MB_INFO|MB_YESNO) == IDYES)
349 start_gpgprefs = 1;
350 else
351 {
352 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
353 return 0;
354 }
355 }
356
357 rc = gnupg_access_files ();
358 if (!start_gpgprefs && rc) {
359 if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
360 ec = msg_box (NULL,
361 _("Could not access and/or find the public and secret keyring.\n"
362 "If this is an accident, quit the program and fix it.\n\n"
363 "Continue if you want that WinPT offers you more choices.\n"),
364 "WinPT", MB_INFO|MB_YESNO);
365 if (ec == IDYES)
366 first_start = 1;
367 }
368 if (!first_start) {
369 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
370 return 0;
371 }
372 }
373
374 if (!first_start) {
375 rc = gpg_check_permissions (1);
376 if (rc && rc == 2)
377 gpg_read_only = 1;
378 else if (rc)
379 return 0;
380 }
381
382 load_gettext (winpt_inst_found);
383 init_gnupg_table ();
384
385 nfiles = fm_parse_command_line (cmdline);
386 if (nfiles > 0) {
387 free_gnupg_table ();
388 return 0;
389 }
390
391 if (cmdline && stristr (cmdline, "--wipe-freespace")) {
392 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
393 GetDesktopWindow(), space_wipefrees_dlg_proc, 0,
394 _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
395 free_gnupg_table ();
396 return 0;
397 }
398
399 load_keyserver_conf (cmdline? 1 : 0);
400
401 if (cmdline && (stristr (cmdline, "--keymanager")
402 || stristr (cmdline, "--cardmanager"))) {
403 update_keycache (GetDesktopWindow ());
404 if (stristr (cmdline, "keymanager"))
405 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYMISC,
406 GetDesktopWindow(), keymanager_dlg_proc, 0,
407 _("Key Manager"), IDS_WINPT_KEYMISC);
408 else {
409 gpg_card_t crd = gpg_card_load ();
410 if (crd)
411 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_EDIT,
412 GetDesktopWindow(), card_edit_dlg_proc,
413 (LPARAM)crd, _("Card Manager"),
414 IDS_WINPT_CARD_EDIT);
415 gpg_card_release (crd);
416 }
417 keycache_release (0);
418 free_gnupg_table ();
419 return 0;
420 }
421
422 /* If we found another WinPT instance, just quit to avoid it
423 will be executed twice. */
424 if (winpt_inst_found) {
425 log_debug ("%s", "WinMain: WinPT is already running.");
426 free_gnupg_table ();
427 return 0;
428 }
429
430 if (cmdline) {
431 if (stristr (cmdline, "--enable-debug") || stristr (cmdline, "--debug")) {
432 gpg_set_debug_mode (1);
433 winpt_debug_msg ();
434 debug = 1;
435 }
436 }
437
438 wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
439 rc = RegisterClass (&wc);
440 if (rc == FALSE) {
441 msg_box (NULL, _("Could not register window class"),
442 _("WinPT Error"), MB_ERR);
443 free_gnupg_table ();
444 return 0;
445 }
446
447 hwnd = CreateWindow (PGM_NAME,
448 PGM_NAME,
449 0, 0, 0, 0, 0,
450 NULL,
451 NULL,
452 hinst,
453 NULL);
454 if (hwnd == NULL) {
455 msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
456 free_gnupg_table ();
457 return 0;
458 }
459 glob_hwnd = hwnd;
460 UpdateWindow (hwnd);
461
462 if (!first_start && !start_gpgprefs) {
463 gnupg_backup_options ();
464 rc = check_crypto_engine ();
465 if (rc) {
466 DestroyWindow (hwnd);
467 free_gnupg_table ();
468 return 0;
469 }
470 }
471
472 if (start_gpgprefs) {
473 char *ring;
474
475 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
476 gpgprefs_dlg_proc, 0);
477 ring = get_gnupg_keyring (0, !NO_STRICT);
478 if (gnupg_access_keyring (0) == -1 && get_file_size (ring) == 0)
479 first_start = 1; /* The keyring is empty! */
480 free_if_alloc (ring);
481 }
482
483 if (first_start) {
484 struct first_start_s fs;
485 struct genkey_s c;
486 HWND h;
487 start:
488 h = GetDesktopWindow ();
489 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
490 gpgprefs_dlg_proc, 0);
491 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
492 first_run_dlg_proc, (LPARAM)&fs);
493 switch (fs.choice) {
494 case SETUP_KEYGEN:
495 c.interactive = 1;
496 c.first_start = 1;
497 rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
498 h, keygen_wizard_dlg_proc, (LPARAM)&c);
499 if (!rc)
500 goto start;
501 break;
502
503 case SETUP_IMPORT:
504 rc = gnupg_copy_keyrings ();
505 if (rc) {
506 msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
507 goto start;
508 }
509 break;
510
511 case -1:
512 DestroyWindow (hwnd);
513 free_gnupg_table ();
514 return 0;
515 }
516 update_keycache (hwnd);
517 check_crypto_engine ();
518 }
519 else {
520 gpg_keycache_t c;
521 update_keycache (hwnd);
522 c = keycache_get_ctx (1);
523 if (!c || !gpg_keycache_get_size (c)) {
524 gnupg_display_error ();
525 msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
526 "Please check your GPG config (keyrings, pathes...)"),
527 _("WinPT Error"), MB_ERR);
528 ec = msg_box (NULL, _("It seems that GPG is not set properly.\n"
529 "Do you want to start the GPG preferences dialog?"),
530 "WinPT", MB_INFO|MB_YESNO);
531 if (ec == IDYES) {
532 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
533 gpgprefs_dlg_proc, 0);
534 update_keycache (hwnd);
535 }
536 else {
537 DestroyWindow (hwnd);
538 free_gnupg_table ();
539 return 0;
540 }
541 }
542 if (check_default_key (c)) {
543 char * p = get_gnupg_default_key ();
544 log_box (_("WinPT Error"), MB_ERR,
545 _("Default key from the GPG options file could not be found.\n"
546 "Please check your gpg.conf (options) to correct this:\n\n"
547 "%s: public key not found."), p? p : "[null]");
548 free_if_alloc (p);
549 DestroyWindow (hwnd);
550 free_gnupg_table ();
551 return 0;
552 }
553 if (count_insecure_elgkeys ())
554 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
555 elgamal_warn_dlg_proc, 0);
556 }
557
558 accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
559 keyring_check_last_access (); /* init */
560 while (GetMessage (&msg, hwnd, 0, 0)) {
561 if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
562 TranslateMessage (&msg);
563 DispatchMessage (&msg);
564 }
565 }
566
567 return 0;
568 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26