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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show annotations)
Mon Oct 31 14:04:59 2005 UTC (19 years, 4 months ago) by werner
File size: 14813 byte(s)
Minor changes; compiles now but gettext is still missing.

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 #include <windows.h>
26
27 #include "resource.h"
28 #include "wptTypes.h"
29 #include "wptW32API.h"
30 #include "wptVersion.h"
31 #include "wptErrors.h"
32 #include "wptGPG.h"
33 #include "wptRegistry.h"
34 #include "wptCommonCtl.h"
35 #include "wptDlgs.h"
36 #include "wptNLS.h"
37 #include "wptKeyserver.h"
38 #include "wptCard.h"
39 #include "wptFileManager.h"
40 #include "wptContext.h"
41 #include "wptCardEdit.h"
42
43
44 #define MIN_GPG_VER "1.4.3" /* Minimal GPG version. */
45 #define MIN_GPGME_VER "1.2.0" /* Minimal GPGME version. */
46 #define MIN_PTD_VER "0.8.1" /* Minimal PTD version. */
47
48
49 HINSTANCE glob_hinst; /* global instance for the dialogs */
50 HWND glob_hwnd; /* global window handle for the dialogs */
51 HWND activ_hwnd;
52 LOCK mo_file;
53 int scard_support = 0;
54 int debug = 0;
55 int mobile = 0;
56 int gpg_read_only = 0;
57 char gpgver[3];
58
59
60 /* Load the key cache and rebuild the signature cache. */
61 static void
62 update_keycache (HWND hwnd)
63 {
64 refresh_cache_s rcs = {0};
65 rcs.kr_reload = 0;
66 rcs.kr_update = 1;
67 rcs.tr_update = 1;
68 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, hwnd,
69 keycache_dlg_proc, (LPARAM)&rcs);
70 }
71
72
73 /* Set GPGME debug mode. If @val is 0, the debug mode is disabled. */
74 void
75 gpg_set_debug_mode (int val)
76 {
77 if (val)
78 putenv ("GPGME_DEBUG=5:gpgme.dbg");
79 else
80 putenv ("GPGME_DEBUG=");
81 }
82
83
84 /* Return the name of the gettext language file. */
85 static char*
86 get_gettext_lang (void)
87 {
88 char *fname;
89 fname = get_reg_entry_mo ();
90 if (!fname)
91 return NULL;
92 return fname;
93 }
94
95
96 /* Initialize the gettext sub system. */
97 static void
98 load_gettext (int prev_inst)
99 {
100 char *nls = NULL;
101 char *file = NULL;
102
103 nls = get_gettext_lang ();
104 if (nls) {
105 set_gettext_file ("winpt", nls);
106 file = make_filename (nls, "winpt", "mo");
107 if (!file_exist_check (nls) && init_file_lock (&mo_file, file)) {
108 if (!prev_inst)
109 msg_box (NULL, _("Could not initizalize file lock.\n"
110 "Native Language Support"),
111 _("WinPT Error"), MB_ERR);
112 }
113 free_if_alloc (nls);
114 free_if_alloc (file);
115 }
116 }
117
118
119 /* check if the default key from the gpg.conf file is available in the
120 keyring. if not, bail out because encryption won't work properly then. */
121 static int
122 check_default_key (gpg_keycache_t kc)
123 {
124 gpgme_key_t key;
125 gpgme_error_t err = GPG_ERR_NO_ERROR;
126 char * defkey;
127
128 defkey = get_gnupg_default_key ();
129 if (defkey)
130 err = gpg_keycache_find_key (kc, defkey, 0, &key);
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)
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 s = PTD_get_version ();
264 if (strcmp (s, MIN_PTD_VER)) {
265 log_box (_("Privacy Tray Dynamic (PTD)"), MB_ERR,
266 _("Please update your PTD.dll to the newest version, "
267 "the version (%s) you use is too old."), s);
268 return 0;
269 }
270
271 if (gpg_md_selftest ()) {
272 msg_box (NULL, _("Cryptographic selftest failed."),
273 _("WinPT Error"), MB_ERR);
274 return 0;
275 }
276
277 s = gpgme_check_version (MIN_GPGME_VER);
278 if (!s || !*s) {
279 msg_box (NULL, _("A newer GPGME version is needed; at least "MIN_GPGME_VER),
280 _("WinPT Error"), MB_ERR);
281 return 0;
282 }
283
284 CreateMutex (NULL, TRUE, PGM_NAME);
285 if (GetLastError () == ERROR_ALREADY_EXISTS)
286 winpt_inst_found = 1;
287
288 if (cmdline && stristr (cmdline, "--mobile")) {
289 msg_box (NULL, "WARNING: mobile modus is not fully implemented yet!",
290 "WinPT", MB_INFO);
291 mobile = 1;
292 }
293
294 set_default_kserver ();
295
296 if (!mobile) {
297 regist_inst_gnupg (1);
298 regist_inst_winpt (1, &created);
299 }
300 else {
301 enable_mobile_mode ();
302 /* XXX: ask for GPG path */
303 created = 1; /* Disable registry writing */
304 }
305
306 if (!created) {
307 memset (&reg_prefs, 0, sizeof (reg_prefs));
308 reg_prefs.use_tmpfiles = 1; /* default */
309 reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
310 get_reg_winpt_prefs (&reg_prefs);
311 if (!reg_prefs.no_hotkeys)
312 hotkeys_modify ();
313 gnupg_load_config ();
314 }
315
316 rc = gnupg_check_homedir ();
317 if (rc) {
318 log_box (_("WinPT Error"), MB_ERR,
319 _("GPG home directory is not set correctly.\n"
320 "Please check the GPG registry settings:\n%s."),
321 winpt_strerror (rc));
322 const char * s = get_fileopen_dlg (GetActiveWindow (),
323 _("Select GPG Public Keyring"),
324 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
325 NULL);
326 if (s != NULL) {
327 size_t n;
328 char * p = strrchr (s, '\\');
329 if (!p)
330 BUG (0);
331 n = p - s;
332 if (n) {
333 char * file = new char[n+1];
334 if (!file)
335 BUG (NULL);
336 memset (file, 0, n);
337 memcpy (file, s, n);
338 file[n] = '\0';
339 set_reg_entry_gpg ("HomeDir", file);
340 free_if_alloc (file);
341 gnupg_check_homedir (); /* change gpgProgram if needed */
342 }
343 }
344 else {
345 msg_box (NULL, _("GPG home directory could not be determited."),
346 _("WinPT Error"), MB_ERR);
347 goto start;
348 }
349 }
350
351 rc = check_gnupg_prog ();
352 if (rc) {
353 if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
354 "Do you want to start the GPG preferences to "
355 "correct this problem?"), _("WinPT Error"),
356 MB_INFO|MB_YESNO) == IDYES)
357 start_gpgprefs = 1;
358 else
359 {
360 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
361 return 0;
362 }
363 }
364
365 rc = gnupg_access_files ();
366 if (!start_gpgprefs && rc) {
367 if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
368 ec = msg_box (NULL,
369 _("Could not access and/or find the public and secret keyring.\n"
370 "If this is an accident, quit the program and fix it.\n\n"
371 "Continue if you want that WinPT offers you more choices.\n"),
372 "WinPT", MB_INFO|MB_YESNO);
373 if (ec == IDYES)
374 first_start = 1;
375 }
376 if (!first_start) {
377 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
378 return 0;
379 }
380 }
381
382 if (!first_start) {
383 rc = gpg_check_permissions (1);
384 if (rc && rc == 2)
385 gpg_read_only = 1;
386 else if (rc)
387 return 0;
388 }
389
390 load_gettext (winpt_inst_found);
391 init_gnupg_table ();
392
393 nfiles = fm_parse_command_line (cmdline);
394 if (nfiles > 0) {
395 free_gnupg_table ();
396 return 0;
397 }
398
399 if (cmdline && stristr (cmdline, "--wipe-freespace")) {
400 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
401 GetDesktopWindow(), space_wipefrees_dlg_proc, NULL,
402 _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
403 free_gnupg_table ();
404 return 0;
405 }
406
407 load_keyserver_conf (cmdline? 1 : 0);
408
409 if (cmdline && (stristr (cmdline, "--keymanager")
410 || stristr (cmdline, "--cardmanager"))) {
411 update_keycache (GetDesktopWindow ());
412 if (stristr (cmdline, "keymanager"))
413 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYMISC,
414 GetDesktopWindow(), keymanager_dlg_proc, NULL,
415 _("Key Manager"), IDS_WINPT_KEYMISC);
416 else {
417 gpg_card_t crd = gpg_card_load ();
418 if (crd)
419 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_EDIT,
420 GetDesktopWindow(), card_edit_dlg_proc,
421 (LPARAM)crd, _("Card Manager"),
422 IDS_WINPT_CARD_EDIT);
423 gpg_card_release (crd);
424 }
425 keycache_release (0);
426 free_gnupg_table ();
427 return 0;
428 }
429
430 /* If we found another WinPT instance, just quit to avoid it
431 will be executed twice. */
432 if (winpt_inst_found) {
433 log_debug ("%s", "WinMain: WinPT is already running.");
434 free_gnupg_table ();
435 return 0;
436 }
437
438 if (cmdline) {
439 if (stristr (cmdline, "--enable-debug") || stristr (cmdline, "--debug")) {
440 gpg_set_debug_mode (1);
441 winpt_debug_msg ();
442 debug = 1;
443 }
444 }
445
446 wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
447 rc = RegisterClass (&wc);
448 if (rc == FALSE) {
449 msg_box (NULL, _("Could not register window class"),
450 _("WinPT Error"), MB_ERR);
451 free_gnupg_table ();
452 return 0;
453 }
454
455 hwnd = CreateWindow (PGM_NAME,
456 PGM_NAME,
457 0, 0, 0, 0, 0,
458 NULL,
459 NULL,
460 hinst,
461 NULL);
462 if (hwnd == NULL) {
463 msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
464 free_gnupg_table ();
465 return 0;
466 }
467 glob_hwnd = hwnd;
468 UpdateWindow (hwnd);
469
470 if (!first_start && !start_gpgprefs) {
471 gnupg_backup_options ();
472 rc = check_crypto_engine ();
473 if (rc) {
474 DestroyWindow (hwnd);
475 free_gnupg_table ();
476 return 0;
477 }
478 }
479
480 if (start_gpgprefs) {
481 char *ring;
482 size_t size = 0;
483 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
484 gpgprefs_dlg_proc, 0);
485 ring = get_gnupg_keyring (0, !NO_STRICT);
486 if (gnupg_access_keyring (0) == -1 && get_file_size (ring) == 0)
487 first_start = 1; /* The keyring is empty! */
488 free_if_alloc (ring);
489 }
490
491 if (first_start) {
492 struct first_start_s fs;
493 struct genkey_s c;
494 HWND h;
495 start:
496 h = GetDesktopWindow ();
497 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
498 gpgprefs_dlg_proc, 0);
499 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
500 first_run_dlg_proc, (LPARAM)&fs);
501 switch (fs.choice) {
502 case SETUP_KEYGEN:
503 c.interactive = 1;
504 c.first_start = 1;
505 rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
506 h, keygen_wizard_dlg_proc, (LPARAM)&c);
507 if (!rc)
508 goto start;
509 break;
510
511 case SETUP_IMPORT:
512 rc = gnupg_copy_keyrings ();
513 if (rc) {
514 msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
515 goto start;
516 }
517 break;
518
519 case -1:
520 DestroyWindow (hwnd);
521 free_gnupg_table ();
522 return 0;
523 }
524 update_keycache (hwnd);
525 check_crypto_engine ();
526 }
527 else {
528 gpg_keycache_t c;
529 update_keycache (hwnd);
530 c = keycache_get_ctx (1);
531 if (!c || !gpg_keycache_get_size (c)) {
532 gnupg_display_error ();
533 msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
534 "Please check your GPG config (keyrings, pathes...)"),
535 _("WinPT Error"), MB_ERR);
536 ec = msg_box (NULL, _("It seems that GPG is not set properly.\n"
537 "Do you want to start the GPG preferences dialog?"),
538 "WinPT", MB_INFO|MB_YESNO);
539 if (ec == IDYES) {
540 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
541 gpgprefs_dlg_proc, 0);
542 update_keycache (hwnd);
543 }
544 else {
545 DestroyWindow (hwnd);
546 free_gnupg_table ();
547 return 0;
548 }
549 }
550 if (check_default_key (c)) {
551 char * p = get_gnupg_default_key ();
552 log_box (_("WinPT Error"), MB_ERR,
553 _("Default key from the GPG options file could not be found.\n"
554 "Please check your gpg.conf (options) to correct this:\n\n"
555 "%s: public key not found."), p? p : "[null]");
556 free_if_alloc (p);
557 DestroyWindow (hwnd);
558 free_gnupg_table ();
559 return 0;
560 }
561 if (count_insecure_elgkeys ())
562 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
563 elgamal_warn_dlg_proc, 0);
564 }
565
566 accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
567 keyring_check_last_access (); /* init */
568 while (GetMessage (&msg, hwnd, 0, 0)) {
569 if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
570 TranslateMessage (&msg);
571 DispatchMessage (&msg);
572 }
573 }
574
575 return 0;
576 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26