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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (show annotations)
Fri Oct 28 07:15:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14746 byte(s)
A lot of bug fixes. See ChangeLog.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26