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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (hide annotations)
Thu Oct 27 15:25:13 2005 UTC (19 years, 4 months ago) by werner
File size: 14753 byte(s)
First set of changes to use autotools for building.
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     #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23    
24     #include <windows.h>
25     #include <windows.h>
26    
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     /* 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     int rc, ec, created = 0, use_cwd = 0, nfiles = 0;
248     int first_start = 0, start_gpgprefs = 0;
249     int winpt_inst_found = 0;
250     const char *s;
251     MSG msg;
252     HWND hwnd = NULL;
253    
254     glob_hinst = hinst;
255    
256     #ifdef _DEBUG
257     gpg_set_debug_mode (1);
258     debug = 1;
259     #endif
260    
261     s = PTD_get_version ();
262     if (strcmp (s, MIN_PTD_VER)) {
263     log_box (_("Privacy Tray Dynamic (PTD)"), MB_ERR,
264     _("Please update your PTD.dll to the newest version, "
265     "the version (%s) you use is too old."), s);
266     return 0;
267     }
268    
269     if (gpg_md_selftest ()) {
270     msg_box (NULL, _("Cryptographic selftest failed."),
271     _("WinPT Error"), MB_ERR);
272     return 0;
273     }
274    
275     s = gpgme_check_version (MIN_GPGME_VER);
276     if (!s || !*s) {
277     msg_box (NULL, _("A newer GPGME version is needed; at least "MIN_GPGME_VER),
278     _("WinPT Error"), MB_ERR);
279     return 0;
280     }
281    
282     CreateMutex (NULL, TRUE, PGM_NAME);
283     if (GetLastError () == ERROR_ALREADY_EXISTS)
284     winpt_inst_found = 1;
285    
286     if (cmdline && stristr (cmdline, "--mobile")) {
287     msg_box (NULL, "WARNING: mobile modus is not fully implemented yet!",
288     "WinPT", MB_INFO);
289     mobile = 1;
290     }
291    
292     set_default_kserver ();
293    
294     if (!mobile) {
295     regist_inst_gnupg (1);
296     regist_inst_winpt (1, &created);
297     }
298     else {
299     enable_mobile_mode ();
300     /* XXX: ask for GPG path */
301     created = 1; /* Disable registry writing */
302     }
303    
304     if (!created) {
305     memset (&reg_prefs, 0, sizeof (reg_prefs));
306     reg_prefs.use_tmpfiles = 1; /* default */
307     reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
308     get_reg_winpt_prefs (&reg_prefs);
309     if (!reg_prefs.no_hotkeys)
310     hotkeys_modify ();
311     }
312    
313     rc = gnupg_check_homedir ();
314     if (rc) {
315     log_box (_("WinPT Error"), MB_ERR,
316     _("GPG home directory is not set correctly.\n"
317     "Please check the GPG registry settings:\n%s."),
318     winpt_strerror (rc));
319     const char * s = get_fileopen_dlg (GetActiveWindow (),
320     _("Select GPG Public Keyring"),
321     _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
322     NULL);
323     if (s != NULL) {
324     size_t n;
325     char * p = strrchr (s, '\\');
326     if (!p)
327     BUG (0);
328     n = p - s;
329     if (n) {
330     char * file = new char[n+1];
331     if (!file)
332     BUG (NULL);
333     memset (file, 0, n);
334     memcpy (file, s, n);
335     file[n] = '\0';
336     set_reg_entry_gpg ("HomeDir", file);
337     free_if_alloc (file);
338     gnupg_check_homedir (); /* change gpgProgram if needed */
339     }
340     }
341     else {
342     msg_box (NULL, _("GPG home directory could not be determited."),
343     _("WinPT Error"), MB_ERR);
344     goto start;
345     }
346     }
347    
348     rc = check_gnupg_prog ();
349     if (rc) {
350     if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
351     "Do you want to start the GPG preferences to "
352     "correct this problem?"), _("WinPT Error"),
353     MB_INFO|MB_YESNO) == IDYES)
354     start_gpgprefs = 1;
355     else
356     {
357     msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
358     return 0;
359     }
360     }
361    
362     rc = gnupg_access_files ();
363     if (!start_gpgprefs && rc) {
364     if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
365     ec = msg_box (NULL,
366     _("Could not access and/or find the public and secret keyring.\n"
367     "If this is an accident, quit the program and fix it.\n\n"
368     "Continue if you want that WinPT offers you more choices.\n"),
369     "WinPT", MB_INFO|MB_YESNO);
370     if (ec == IDYES)
371     first_start = 1;
372     }
373     if (!first_start) {
374     msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
375     return 0;
376     }
377     }
378    
379     if (!first_start) {
380     rc = gpg_check_permissions (1);
381     if (rc && rc == 2)
382     gpg_read_only = 1;
383     else if (rc)
384     return 0;
385     }
386    
387     load_gettext (winpt_inst_found);
388     init_gnupg_table ();
389    
390     nfiles = fm_parse_command_line (cmdline);
391     if (nfiles > 0) {
392     free_gnupg_table ();
393     return 0;
394     }
395    
396     if (cmdline && stristr (cmdline, "--wipe-freespace")) {
397     dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
398     GetDesktopWindow(), space_wipefrees_dlg_proc, NULL,
399     _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
400     free_gnupg_table ();
401     return 0;
402     }
403    
404     load_keyserver_conf (cmdline? 1 : 0);
405    
406     if (cmdline && (stristr (cmdline, "--keymanager")
407     || stristr (cmdline, "--cardmanager"))) {
408     update_keycache (GetDesktopWindow ());
409     if (stristr (cmdline, "keymanager"))
410     dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_KEYMISC,
411     GetDesktopWindow(), keymanager_dlg_proc, NULL,
412     _("Key Manager"), IDS_WINPT_KEYMISC);
413     else {
414     gpg_card_t crd = gpg_card_load ();
415     if (crd)
416     dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_EDIT,
417     GetDesktopWindow(), card_edit_dlg_proc,
418     (LPARAM)crd, _("Card Manager"),
419     IDS_WINPT_CARD_EDIT);
420     gpg_card_release (crd);
421     }
422     keycache_release (0);
423     free_gnupg_table ();
424     return 0;
425     }
426    
427     /* If we found another WinPT instance, just quit to avoid it
428     will be executed twice. */
429     if (winpt_inst_found) {
430     log_debug ("%s", "WinMain: WinPT is already running.");
431     free_gnupg_table ();
432     return 0;
433     }
434    
435     if (cmdline) {
436     if (stristr (cmdline, "--enable-debug") || stristr (cmdline, "--debug")) {
437     gpg_set_debug_mode (1);
438     winpt_debug_msg ();
439     debug = 1;
440     }
441     }
442    
443     wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
444     rc = RegisterClass (&wc);
445     if (rc == FALSE) {
446     msg_box (NULL, _("Could not register window class"),
447     _("WinPT Error"), MB_ERR);
448     free_gnupg_table ();
449     return 0;
450     }
451    
452     hwnd = CreateWindow (PGM_NAME,
453     PGM_NAME,
454     0, 0, 0, 0, 0,
455     NULL,
456     NULL,
457     hinst,
458     NULL);
459     if (hwnd == NULL) {
460     msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
461     free_gnupg_table ();
462     return 0;
463     }
464     glob_hwnd = hwnd;
465     UpdateWindow (hwnd);
466    
467     if (!first_start && !start_gpgprefs) {
468     gnupg_backup_options ();
469     rc = check_crypto_engine ();
470     if (rc) {
471     DestroyWindow (hwnd);
472     free_gnupg_table ();
473     return 0;
474     }
475     }
476    
477     if (start_gpgprefs) {
478     char *ring;
479     size_t size = 0;
480     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
481     gpgprefs_dlg_proc, NULL);
482     ring = get_gnupg_keyring (0, !NO_STRICT);
483     if (gnupg_access_keyring (0) == -1 && get_file_size (ring) == 0)
484     first_start = 1; /* The keyring is empty! */
485     free_if_alloc (ring);
486     }
487    
488     if (first_start) {
489     struct first_start_s fs;
490     struct genkey_s c;
491     HWND h;
492     start:
493     h = GetDesktopWindow ();
494     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
495     gpgprefs_dlg_proc, NULL);
496     DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
497     first_run_dlg_proc, (LPARAM)&fs);
498     switch (fs.choice) {
499     case SETUP_KEYGEN:
500     c.interactive = 1;
501     c.first_start = 1;
502     rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
503     h, keygen_wizard_dlg_proc, (LPARAM)&c);
504     if (!rc)
505     goto start;
506     break;
507    
508     case SETUP_IMPORT:
509     rc = gnupg_copy_keyrings ();
510     if (rc) {
511     msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
512     goto start;
513     }
514     break;
515    
516     case -1:
517     DestroyWindow (hwnd);
518     free_gnupg_table ();
519     return 0;
520     }
521     update_keycache (hwnd);
522     check_crypto_engine ();
523     }
524     else {
525     gpg_keycache_t c;
526     update_keycache (hwnd);
527     c = keycache_get_ctx (1);
528     if (!c || !gpg_keycache_get_size (c)) {
529     gnupg_display_error ();
530     msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
531     "Please check your GPG config (keyrings, pathes...)"),
532     _("WinPT Error"), MB_ERR);
533     ec = msg_box (NULL, _("It seems that GPG is not set properly.\n"
534     "Do you want to start the GPG preferences dialog?"),
535     "WinPT", MB_INFO|MB_YESNO);
536     if (ec == IDYES) {
537     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
538     gpgprefs_dlg_proc, NULL);
539     update_keycache (hwnd);
540     }
541     else {
542     DestroyWindow (hwnd);
543     free_gnupg_table ();
544     return 0;
545     }
546     }
547     if (check_default_key (c)) {
548     char * p = get_gnupg_default_key ();
549     log_box (_("WinPT Error"), MB_ERR,
550     _("Default key from the GPG options file could not be found.\n"
551     "Please check your gpg.conf (options) to correct this:\n\n"
552     "%s: public key not found."), p? p : "[null]");
553     free_if_alloc (p);
554     DestroyWindow (hwnd);
555     free_gnupg_table ();
556     return 0;
557     }
558     if (count_insecure_elgkeys ())
559     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
560     elgamal_warn_dlg_proc, NULL);
561     }
562    
563     accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
564     keyring_check_last_access (); /* init */
565     while (GetMessage (&msg, hwnd, 0, 0)) {
566     if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
567     TranslateMessage (&msg);
568     DispatchMessage (&msg);
569     }
570     }
571    
572     return 0;
573     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26