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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26