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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations)
Mon Oct 17 08:49:30 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14470 byte(s)
More bug fixes all over the place.
See ChangeLog for details.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26