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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (show annotations)
Sat Oct 8 10:43:08 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14895 byte(s)
Bug fixes to correct some problems introduced by
the MyGPGME to GPGME port.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26