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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide annotations)
Fri Oct 28 07:15:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14746 byte(s)
A lot of bug fixes. See ChangeLog.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26