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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 87 - (show annotations)
Mon Nov 21 11:44:25 2005 UTC (19 years, 3 months ago) by twoaday
File size: 14799 byte(s)
2005-11-21  Timo Schulz  <ts@g10code.com>
 
        * WinPT.cpp (WinMain): Implement --stop switch.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26