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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (show annotations)
Mon Oct 31 21:14:11 2005 UTC (19 years, 4 months ago) by werner
File size: 14850 byte(s)
More changes.  Compiles again but there are at least gettext issues with
w32-gettext.c.  I can't get a gpg-error build with ENABLE_NLS.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26