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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Sat Oct 22 10:17:59 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14812 byte(s)
Sync with old SVN repository.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26