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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 14519 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26