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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (show annotations)
Mon Dec 12 11:19:56 2005 UTC (19 years, 2 months ago) by twoaday
File size: 15375 byte(s)
2005-12-11  Timo Schulz  <ts@g10code.com>
 
        * wptW32API.cpp (get_file_version): New.
        * wptGPGUtil.cpp (create_process): Always hide window.
        * wptClipEditDlg.cpp (clipedit_dlg_proc): Use 'Close'
        instead of 'Exit'.
        * wptKeyManager.cpp (km_http_import): New filename
        generation code.
        (km_send_to_mail_recipient): Cleanups.
        * wptKeyEditDlg.cpp (showpref_dlg_proc): Localize dialog.
        * wptKeyManagerDlg.cpp (update_ui_items): Handle the case
        when multiple keys are selected.
        (popup_multiple): New.
        * WinPT.cpp (WinMain): Check that the PTD.dll and WinPT.exe
        file versions are equal. Rewrote --keymanager code.
         
Removed temporary w32gpgme dirctory, all code is now in Src.
Changed configure files.


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."),
131 _("WinPT Error"), MB_ERR);
132 free_if_alloc (defkey);
133 return err? -1 : 0;
134 }
135
136
137 /* Return the WinPT program file name (with full pathname). */
138 static const char*
139 get_prog_part (const char * fname, int use_cwd)
140 {
141 static char program[512];
142 char currdir[256];
143 char *cmd = NULL;
144 int j;
145
146 memset (currdir, 0, DIM (currdir));
147 memset (program, 0, DIM (program));
148
149 if (use_cwd) {
150 GetCurrentDirectory (DIM (currdir)-1, currdir);
151 _snprintf (program, DIM (program)-1, "%s\\%s", currdir, fname);
152 }
153 else {
154 cmd = GetCommandLine ();
155 if (cmd == NULL)
156 return NULL;
157 strncpy (currdir, cmd, sizeof (currdir)-1);
158 j = strlen (currdir);
159 while (j--) {
160 if (currdir[j] == '\\')
161 break;
162 }
163 currdir[j] = 0;
164 _snprintf (program, DIM (program)-1, "%s\\%s", currdir + 1, fname);
165 }
166 return program;
167 }
168
169
170 /* Check that the underlying crypto engine fullfills the minimal
171 requirements so all commands work properly. */
172 static int
173 check_crypto_engine (void)
174 {
175 int ma=1, mi=4, pa=2; /* GPG 1.4.2 */
176 int rc;
177
178 rc = check_gnupg_engine (&ma, &mi, &pa);
179 if (rc == -1) {
180 msg_box (NULL, _("Could not read GnuPG version."),
181 _("WinPT Error"), MB_ERR);
182 return rc;
183 }
184 else if (rc) {
185 log_box (_("WinPT Error"), MB_ERR,
186 _("Sorry, you need a newer GPG version.\n"
187 "GPG version %d.%d.%d required GPG version "MIN_GPG_VER),
188 ma, mi, pa);
189 return rc;
190 }
191 /* We enable smartcard support for GPG: >= 2 or >= 1.4.3 */
192 if (ma > 1 || pa >= 3)
193 scard_support = 1;
194
195 gpgver[0] = ma;
196 gpgver[1] = mi;
197 gpgver[2] = pa;
198 return rc;
199 }
200
201
202 /* Try to load the keyserver config file. If @quiet is 1
203 do not show any errors. */
204 static int
205 load_keyserver_conf (int quiet)
206 {
207 const char *t;
208 int rc;
209
210 if (reg_prefs.kserv_conf)
211 t = reg_prefs.kserv_conf;
212 else if (!file_exist_check (get_prog_part ("keyserver.conf", 0)))
213 t = get_prog_part ("keyserver.conf", 0);
214 else
215 t = "keyserver.conf";
216 rc = kserver_load_conf (t);
217 if (rc && !quiet)
218 msg_box (NULL, winpt_strerror (rc), _("Keyserver"), MB_ERR);
219 return rc;
220 }
221
222
223 /* Enable the mobility mode. */
224 static void
225 enable_mobile_mode (void)
226 {
227 memset (&reg_prefs, 0, sizeof (reg_prefs));
228 reg_prefs.always_trust = 0;
229 reg_prefs.auto_backup = 0;
230 reg_prefs.cache_time = 0;
231 reg_prefs.expert = 0;
232 reg_prefs.keylist_mode = 1;
233 reg_prefs.kserv_conf = m_strdup ("keyserver.conf");
234 reg_prefs.no_zip_mmedia = 1;
235 reg_prefs.use_tmpfiles = 1;
236 reg_prefs.word_wrap = 80;
237 reg_prefs.use_viewer = 0; /* XXX */
238 }
239
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 MSG msg;
248 HWND hwnd = NULL;
249 WORD ver[3], ptdver[4];
250 int rc, ec, created = 0;
251 int first_start = 0, start_gpgprefs = 0;
252 int winpt_inst_found = 0;
253 int start_manager = 0;
254 const char *s;
255
256 glob_hinst = hinst;
257 if (cmdline && stristr (cmdline, "--stop")) {
258 hwnd = FindWindow ("WinPT", "WinPT");
259 if (hwnd != NULL)
260 PostMessage (hwnd, WM_DESTROY, 0, 0);
261 return 0;
262 }
263
264 /*
265 OSVERSIONINFO osinf;
266 memset (&osinf, 0, sizeof (osinf));
267 if (GetVersionEx (&osinf) &&
268 osinf.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
269 osinf.dwMinorVersion == 0) {
270 msg_box (NULL, "WinPT propably does not work on Windows 95 without restrictions",
271 "WinPT Warning", MB_INFO);
272 }
273 */
274
275 #ifdef _DEBUG
276 gpg_set_debug_mode (1);
277 debug = 1;
278 #endif
279
280 get_file_version ("WinPT.exe", &ver[0], &ver[1], &ver[2], &ver[3]);
281 get_file_version ("PTD.dll", &ptdver[0], &ptdver[1],
282 &ptdver[2], &ptdver[3]);
283 /* XXX
284 if (ptdver[0] != ver[0] || ptdver[1] != ver[1]|| ptdver[2] != ver[2]) {
285 log_box (_("WinPT Error"), MB_ERR,
286 _("The PTD.dll file has a different version than WinPT.exe\n"
287 "Please update the PTD.dll to version %d.%d.%d"),
288 ver[0], ver[1], ver[2]);
289 return 0;
290 }
291 */
292 if (gpg_md_selftest ()) {
293 msg_box (NULL, _("Cryptographic selftest failed."),
294 _("WinPT Error"), MB_ERR);
295 return 0;
296 }
297
298 s = gpgme_check_version (MIN_GPGME_VER);
299 if (!s || !*s) {
300 msg_box (NULL, _("A newer GPGME version is needed; at least "MIN_GPGME_VER),
301 _("WinPT Error"), MB_ERR);
302 return 0;
303 }
304
305 CreateMutex (NULL, TRUE, PGM_NAME);
306 if (GetLastError () == ERROR_ALREADY_EXISTS)
307 winpt_inst_found = 1;
308
309 if (cmdline && stristr (cmdline, "--mobile")) {
310 msg_box (NULL, "WARNING: mobile modus is not fully implemented yet!",
311 "WinPT", MB_INFO);
312 mobile = 1;
313 }
314
315 set_default_kserver ();
316 load_gettext (winpt_inst_found);
317
318 if (!mobile) {
319 regist_inst_gnupg (1);
320 regist_inst_winpt (1, &created);
321 }
322 else {
323 enable_mobile_mode ();
324 /* XXX: ask for GPG path */
325 created = 1; /* Disable registry writing */
326 }
327
328 if (!created) {
329 memset (&reg_prefs, 0, sizeof (reg_prefs));
330 reg_prefs.use_tmpfiles = 1; /* default */
331 reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
332 get_reg_winpt_prefs (&reg_prefs);
333 if (!reg_prefs.no_hotkeys)
334 hotkeys_modify ();
335 gnupg_load_config ();
336 }
337
338 rc = gnupg_check_homedir ();
339 if (rc) {
340 log_box (_("WinPT Error"), MB_ERR,
341 _("GPG home directory is not set correctly.\n"
342 "Please check the GPG registry settings:\n%s."),
343 winpt_strerror (rc));
344 s = get_fileopen_dlg (GetActiveWindow (),
345 _("Select GPG Public Keyring"),
346 _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
347 NULL);
348 if (s != NULL) {
349 size_t n;
350 char *p = strrchr (s, '\\');
351 if (!p)
352 BUG (0);
353 n = p - s;
354 if (n) {
355 char *file = new char[n+1];
356 if (!file)
357 BUG (NULL);
358 memset (file, 0, n);
359 memcpy (file, s, n);
360 file[n] = '\0';
361 set_reg_entry_gpg ("HomeDir", file);
362 free_if_alloc (file);
363 gnupg_check_homedir (); /* change gpgProgram if needed */
364 }
365 }
366 else {
367 msg_box (NULL, _("GPG home directory could not be determited."),
368 _("WinPT Error"), MB_ERR);
369 goto start;
370 }
371 }
372
373 rc = check_gnupg_prog ();
374 if (rc) {
375 if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
376 "Do you want to start the GPG preferences to "
377 "correct this problem?"), _("WinPT Error"),
378 MB_INFO|MB_YESNO) == IDYES)
379 start_gpgprefs = 1;
380 else {
381 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
382 return 0;
383 }
384 }
385
386 rc = gnupg_access_files ();
387 if (!start_gpgprefs && rc) {
388 if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
389 ec = msg_box (NULL,
390 _("Could not access and/or find the public and secret keyring.\n"
391 "If this is an accident, quit the program and fix it.\n\n"
392 "Continue if you want that WinPT offers you more choices.\n"),
393 "WinPT", MB_INFO|MB_YESNO);
394 if (ec == IDYES)
395 first_start = 1;
396 }
397 if (!first_start) {
398 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
399 return 0;
400 }
401 }
402
403 if (!first_start) {
404 rc = gpg_check_permissions (1);
405 if (rc && rc == 2)
406 gpg_read_only = 1;
407 else if (rc)
408 return 0;
409 }
410
411 init_gnupg_table ();
412
413 if (fm_parse_command_line (cmdline) > 0) {
414 free_gnupg_table ();
415 return 0;
416 }
417
418 if (cmdline && stristr (cmdline, "--wipe-freespace")) {
419 dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
420 GetDesktopWindow(), space_wipefrees_dlg_proc, 0,
421 _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
422 free_gnupg_table ();
423 return 0;
424 }
425
426 load_keyserver_conf (cmdline? 1 : 0);
427
428 if (cmdline && (stristr (cmdline, "--keymanager")
429 || stristr (cmdline, "--cardmanager"))) {
430 /* If an instance of WinPT is running, just send the command
431 to open the key manager. Otherwise start a new instance.
432 */
433 HWND tray = FindWindow ("WinPT", "WinPT");
434 if (stristr (cmdline, "keymanager"))
435 start_manager = ID_WINPT_KEY;
436 else
437 start_manager = ID_WINPT_CARD;
438 if (tray != NULL) {
439 PostMessage (tray, WM_COMMAND, start_manager, 0);
440 free_gnupg_table ();
441 return 0;
442 }
443 }
444
445 /* If we found another WinPT instance, just quit to avoid it
446 will be executed twice. */
447 if (winpt_inst_found) {
448 log_debug ("%s", "WinMain: WinPT is already running.");
449 free_gnupg_table ();
450 return 0;
451 }
452
453 if (cmdline) {
454 if (stristr (cmdline, "--enable-debug") ||
455 stristr (cmdline, "--debug")) {
456 gpg_set_debug_mode (1);
457 winpt_debug_msg ();
458 debug = 1;
459 }
460 }
461
462 wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
463 rc = RegisterClass (&wc);
464 if (rc == FALSE) {
465 msg_box (NULL, _("Could not register window class"),
466 _("WinPT Error"), MB_ERR);
467 free_gnupg_table ();
468 return 0;
469 }
470
471 hwnd = CreateWindow (PGM_NAME,
472 PGM_NAME,
473 0, 0, 0, 0, 0,
474 NULL,
475 NULL,
476 hinst,
477 NULL);
478 if (hwnd == NULL) {
479 msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
480 free_gnupg_table ();
481 return 0;
482 }
483 glob_hwnd = hwnd;
484 UpdateWindow (hwnd);
485
486 if (!first_start && !start_gpgprefs) {
487 gnupg_backup_options ();
488 rc = check_crypto_engine ();
489 if (rc) {
490 DestroyWindow (hwnd);
491 free_gnupg_table ();
492 return 0;
493 }
494 }
495
496 if (start_gpgprefs) {
497 char *ring;
498 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
499 gpgprefs_dlg_proc, 0);
500 ring = get_gnupg_keyring (0, !NO_STRICT);
501 if (gnupg_access_keyring (0) == -1 && get_file_size (ring) == 0)
502 first_start = 1; /* The keyring is empty! */
503 free_if_alloc (ring);
504 }
505
506 if (first_start) {
507 struct first_start_s fs;
508 struct genkey_s c;
509 HWND h;
510 start:
511 h = GetDesktopWindow ();
512 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
513 gpgprefs_dlg_proc, 0);
514 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
515 first_run_dlg_proc, (LPARAM)&fs);
516 switch (fs.choice) {
517 case SETUP_KEYGEN:
518 c.interactive = 1;
519 c.first_start = 1;
520 rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
521 h, keygen_wizard_dlg_proc, (LPARAM)&c);
522 if (!rc)
523 goto start;
524 break;
525
526 case SETUP_IMPORT:
527 rc = gnupg_copy_keyrings ();
528 if (rc) {
529 msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
530 goto start;
531 }
532 break;
533
534 case -1:
535 DestroyWindow (hwnd);
536 free_gnupg_table ();
537 return 0;
538 }
539 update_keycache (hwnd);
540 check_crypto_engine ();
541 }
542 else {
543 gpg_keycache_t c;
544 update_keycache (hwnd);
545 c = keycache_get_ctx (1);
546 if (!c || !gpg_keycache_get_size (c)) {
547 gnupg_display_error ();
548 msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
549 "Please check your GPG config (keyrings, pathes...)"),
550 _("WinPT Error"), MB_ERR);
551 ec = msg_box (NULL, _("It seems that GPG is not set properly.\n"
552 "Do you want to start the GPG preferences dialog?"),
553 "WinPT", MB_INFO|MB_YESNO);
554 if (ec == IDYES) {
555 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
556 gpgprefs_dlg_proc, 0);
557 update_keycache (hwnd);
558 }
559 else {
560 DestroyWindow (hwnd);
561 free_gnupg_table ();
562 return 0;
563 }
564 }
565 if (check_default_key (c)) {
566 char *p = get_gnupg_default_key ();
567 log_box (_("WinPT Error"), MB_ERR,
568 _("Default key from the GPG options file could not be found.\n"
569 "Please check your gpg.conf (options) to correct this:\n\n"
570 "%s: public key not found."), p? p : "[null]");
571 free_if_alloc (p);
572 DestroyWindow (hwnd);
573 free_gnupg_table ();
574 return 0;
575 }
576 if (count_insecure_elgkeys ())
577 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
578 elgamal_warn_dlg_proc, 0);
579 }
580
581 if (start_manager)
582 PostMessage (hwnd, WM_COMMAND, start_manager, 0);
583
584 accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
585 keyring_check_last_access (); /* init */
586 while (GetMessage (&msg, hwnd, 0, 0)) {
587 if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
588 TranslateMessage (&msg);
589 DispatchMessage (&msg);
590 }
591 }
592
593 return 0;
594 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26