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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 59 - (show annotations)
Wed Nov 2 13:50:48 2005 UTC (19 years, 3 months ago) by twoaday
File size: 14614 byte(s)
Removed PTD version check.

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) || ma > 1)
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 if (gpg_md_selftest ()) {
263 msg_box (NULL, _("Cryptographic selftest failed."),
264 _("WinPT Error"), MB_ERR);
265 return 0;
266 }
267
268 s = gpgme_check_version (MIN_GPGME_VER);
269 if (!s || !*s) {
270 msg_box (NULL, _("A newer GPGME version is needed; at least "MIN_GPGME_VER),
271 _("WinPT Error"), MB_ERR);
272 return 0;
273 }
274
275 CreateMutex (NULL, TRUE, PGM_NAME);
276 if (GetLastError () == ERROR_ALREADY_EXISTS)
277 winpt_inst_found = 1;
278
279 if (cmdline && stristr (cmdline, "--mobile")) {
280 msg_box (NULL, "WARNING: mobile modus is not fully implemented yet!",
281 "WinPT", MB_INFO);
282 mobile = 1;
283 }
284
285 set_default_kserver ();
286
287 if (!mobile) {
288 regist_inst_gnupg (1);
289 regist_inst_winpt (1, &created);
290 }
291 else {
292 enable_mobile_mode ();
293 /* XXX: ask for GPG path */
294 created = 1; /* Disable registry writing */
295 }
296
297 if (!created) {
298 memset (&reg_prefs, 0, sizeof (reg_prefs));
299 reg_prefs.use_tmpfiles = 1; /* default */
300 reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
301 get_reg_winpt_prefs (&reg_prefs);
302 if (!reg_prefs.no_hotkeys)
303 hotkeys_modify ();
304 gnupg_load_config ();
305 }
306
307 rc = gnupg_check_homedir ();
308 if (rc) {
309 log_box (_("WinPT Error"), MB_ERR,
310 _("GPG home directory is not set correctly.\n"
311 "Please check the GPG registry settings:\n%s."),
312 winpt_strerror (rc));
313 s = get_fileopen_dlg (GetActiveWindow (),
314 _("Select GPG Public Keyring"),
315 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
316 NULL);
317 if (s != NULL) {
318 size_t n;
319 char * p = strrchr (s, '\\');
320 if (!p)
321 BUG (0);
322 n = p - s;
323 if (n) {
324 char * file = new char[n+1];
325 if (!file)
326 BUG (NULL);
327 memset (file, 0, n);
328 memcpy (file, s, n);
329 file[n] = '\0';
330 set_reg_entry_gpg ("HomeDir", file);
331 free_if_alloc (file);
332 gnupg_check_homedir (); /* change gpgProgram if needed */
333 }
334 }
335 else {
336 msg_box (NULL, _("GPG home directory could not be determited."),
337 _("WinPT Error"), MB_ERR);
338 goto start;
339 }
340 }
341
342 rc = check_gnupg_prog ();
343 if (rc) {
344 if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
345 "Do you want to start the GPG preferences to "
346 "correct this problem?"), _("WinPT Error"),
347 MB_INFO|MB_YESNO) == IDYES)
348 start_gpgprefs = 1;
349 else
350 {
351 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
352 return 0;
353 }
354 }
355
356 rc = gnupg_access_files ();
357 if (!start_gpgprefs && rc) {
358 if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
359 ec = msg_box (NULL,
360 _("Could not access and/or find the public and secret keyring.\n"
361 "If this is an accident, quit the program and fix it.\n\n"
362 "Continue if you want that WinPT offers you more choices.\n"),
363 "WinPT", MB_INFO|MB_YESNO);
364 if (ec == IDYES)
365 first_start = 1;
366 }
367 if (!first_start) {
368 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
369 return 0;
370 }
371 }
372
373 if (!first_start) {
374 rc = gpg_check_permissions (1);
375 if (rc && rc == 2)
376 gpg_read_only = 1;
377 else if (rc)
378 return 0;
379 }
380
381 load_gettext (winpt_inst_found);
382 init_gnupg_table ();
383
384 nfiles = fm_parse_command_line (cmdline);
385 if (nfiles > 0) {
386 free_gnupg_table ();
387 return 0;
388 }
389
390 if (cmdline && stristr (cmdline, "--wipe-freespace")) {
391 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
392 GetDesktopWindow(), space_wipefrees_dlg_proc, NULL,
393 _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
394 free_gnupg_table ();
395 return 0;
396 }
397
398 load_keyserver_conf (cmdline? 1 : 0);
399
400 if (cmdline && (stristr (cmdline, "--keymanager")
401 || stristr (cmdline, "--cardmanager"))) {
402 update_keycache (GetDesktopWindow ());
403 if (stristr (cmdline, "keymanager"))
404 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYMISC,
405 GetDesktopWindow(), keymanager_dlg_proc, NULL,
406 _("Key Manager"), IDS_WINPT_KEYMISC);
407 else {
408 gpg_card_t crd = gpg_card_load ();
409 if (crd)
410 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_EDIT,
411 GetDesktopWindow(), card_edit_dlg_proc,
412 (LPARAM)crd, _("Card Manager"),
413 IDS_WINPT_CARD_EDIT);
414 gpg_card_release (crd);
415 }
416 keycache_release (0);
417 free_gnupg_table ();
418 return 0;
419 }
420
421 /* If we found another WinPT instance, just quit to avoid it
422 will be executed twice. */
423 if (winpt_inst_found) {
424 log_debug ("%s", "WinMain: WinPT is already running.");
425 free_gnupg_table ();
426 return 0;
427 }
428
429 if (cmdline) {
430 if (stristr (cmdline, "--enable-debug") || stristr (cmdline, "--debug")) {
431 gpg_set_debug_mode (1);
432 winpt_debug_msg ();
433 debug = 1;
434 }
435 }
436
437 wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
438 rc = RegisterClass (&wc);
439 if (rc == FALSE) {
440 msg_box (NULL, _("Could not register window class"),
441 _("WinPT Error"), MB_ERR);
442 free_gnupg_table ();
443 return 0;
444 }
445
446 hwnd = CreateWindow (PGM_NAME,
447 PGM_NAME,
448 0, 0, 0, 0, 0,
449 NULL,
450 NULL,
451 hinst,
452 NULL);
453 if (hwnd == NULL) {
454 msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
455 free_gnupg_table ();
456 return 0;
457 }
458 glob_hwnd = hwnd;
459 UpdateWindow (hwnd);
460
461 if (!first_start && !start_gpgprefs) {
462 gnupg_backup_options ();
463 rc = check_crypto_engine ();
464 if (rc) {
465 DestroyWindow (hwnd);
466 free_gnupg_table ();
467 return 0;
468 }
469 }
470
471 if (start_gpgprefs) {
472 char *ring;
473
474 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
475 gpgprefs_dlg_proc, 0);
476 ring = get_gnupg_keyring (0, !NO_STRICT);
477 if (gnupg_access_keyring (0) == -1 && get_file_size (ring) == 0)
478 first_start = 1; /* The keyring is empty! */
479 free_if_alloc (ring);
480 }
481
482 if (first_start) {
483 struct first_start_s fs;
484 struct genkey_s c;
485 HWND h;
486 start:
487 h = GetDesktopWindow ();
488 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
489 gpgprefs_dlg_proc, 0);
490 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
491 first_run_dlg_proc, (LPARAM)&fs);
492 switch (fs.choice) {
493 case SETUP_KEYGEN:
494 c.interactive = 1;
495 c.first_start = 1;
496 rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
497 h, keygen_wizard_dlg_proc, (LPARAM)&c);
498 if (!rc)
499 goto start;
500 break;
501
502 case SETUP_IMPORT:
503 rc = gnupg_copy_keyrings ();
504 if (rc) {
505 msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
506 goto start;
507 }
508 break;
509
510 case -1:
511 DestroyWindow (hwnd);
512 free_gnupg_table ();
513 return 0;
514 }
515 update_keycache (hwnd);
516 check_crypto_engine ();
517 }
518 else {
519 gpg_keycache_t c;
520 update_keycache (hwnd);
521 c = keycache_get_ctx (1);
522 if (!c || !gpg_keycache_get_size (c)) {
523 gnupg_display_error ();
524 msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
525 "Please check your GPG config (keyrings, pathes...)"),
526 _("WinPT Error"), MB_ERR);
527 ec = msg_box (NULL, _("It seems that GPG is not set properly.\n"
528 "Do you want to start the GPG preferences dialog?"),
529 "WinPT", MB_INFO|MB_YESNO);
530 if (ec == IDYES) {
531 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
532 gpgprefs_dlg_proc, 0);
533 update_keycache (hwnd);
534 }
535 else {
536 DestroyWindow (hwnd);
537 free_gnupg_table ();
538 return 0;
539 }
540 }
541 if (check_default_key (c)) {
542 char * p = get_gnupg_default_key ();
543 log_box (_("WinPT Error"), MB_ERR,
544 _("Default key from the GPG options file could not be found.\n"
545 "Please check your gpg.conf (options) to correct this:\n\n"
546 "%s: public key not found."), p? p : "[null]");
547 free_if_alloc (p);
548 DestroyWindow (hwnd);
549 free_gnupg_table ();
550 return 0;
551 }
552 if (count_insecure_elgkeys ())
553 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
554 elgamal_warn_dlg_proc, 0);
555 }
556
557 accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
558 keyring_check_last_access (); /* init */
559 while (GetMessage (&msg, hwnd, 0, 0)) {
560 if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
561 TranslateMessage (&msg);
562 DispatchMessage (&msg);
563 }
564 }
565
566 return 0;
567 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26