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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations)
Mon Oct 24 08:03:48 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14945 byte(s)
2005-10-23  Timo Schulz  <twoaday@g10code.com>
 
        * wptFileManager.cpp (fm_get_file_type): Detect detached sigs.
        * wptKeyList.cpp (keylist_cmp_cb): Take care of expired/revoked keys.
        (get_ext_validity): New.
        * wptFileVerifyDlg.cpp (file_verify_dlg_proc): Several cleanups.
        * wptClipEditDlg.cpp (load_clipboard): Factored out some code into
        this function.
        (load_clipboard_from_file): Likewise.
        (save_clipboard_to_file): New.
        * wptKeyManagerDlg.cpp (keyprops_dlg_proc): Fix stack overflow.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26