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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations)
Fri Oct 28 08:25:30 2005 UTC (19 years, 4 months ago) by werner
File size: 14816 byte(s)
Readded lost changes from revision 40

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26