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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (hide annotations)
Mon Dec 12 11:19:56 2005 UTC (19 years, 2 months ago) by twoaday
File size: 15375 byte(s)
2005-12-11  Timo Schulz  <ts@g10code.com>
 
        * wptW32API.cpp (get_file_version): New.
        * wptGPGUtil.cpp (create_process): Always hide window.
        * wptClipEditDlg.cpp (clipedit_dlg_proc): Use 'Close'
        instead of 'Exit'.
        * wptKeyManager.cpp (km_http_import): New filename
        generation code.
        (km_send_to_mail_recipient): Cleanups.
        * wptKeyEditDlg.cpp (showpref_dlg_proc): Localize dialog.
        * wptKeyManagerDlg.cpp (update_ui_items): Handle the case
        when multiple keys are selected.
        (popup_multiple): New.
        * WinPT.cpp (WinMain): Check that the PTD.dll and WinPT.exe
        file versions are equal. Rewrote --keymanager code.
         
Removed temporary w32gpgme dirctory, all code is now in Src.
Changed configure files.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26