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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 34 - (show annotations)
Wed Oct 26 11:20:09 2005 UTC (19 years, 4 months ago) by twoaday
File size: 15251 byte(s)
2005-10-25  Timo Schulz  <twoaday@g10code.com>
                                                                                
        * wptGPGUtil.cpp (create_process): Hide window.
        * wptKeyPropsDlg.cpp (get_photo_tmpname): New.
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Remove
        static var 'enable'.
        * wptKeygenDlg.cpp (keygen_dlg_proc): Likewise.
        (gpg_genkey_params): Make sure all primary keys are capable
        for signing and certification.
        * wptKeySigDlg.cpp (is_sig): If no item is selected, return 0.
        * wptGPG.cpp (gnupg_access_keyring): Check return value for
        NULL. Noted by Ralf.
        (get_gnupg_prog): Simplified.
        (check_homedir): Fixed. Return 0 when the dir is successfully created.
        * wptKeyManagerDlg.cpp (km_file_import): Use the hourglass to
        indicate a pending GPG process.
        * wptFileManager.cpp (op_begin, op_end): New. Indicate an start
        and and of an operation. For now just the cursor changes.
        (fm_parse_command_line): Remove debug output. Thanks to Ralf again.
        * WinPT.cpp (WinMain): Check if there is already an instance and
        set a variable early as possible.
        (load_gettext): If a previous instance was found, do not output
        any errors. Kudos to Ralf.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26