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

Contents of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 14620 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26