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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 58 - (show annotations)
Wed Nov 2 13:36:03 2005 UTC (19 years, 3 months ago) by werner
File size: 14913 byte(s)
Add comments and a README.SVN

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 s = PTD_get_version ();
263 // FIXME: Using strcmp here is wrong
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 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
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