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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 58 - (hide annotations)
Wed Nov 2 13:36:03 2005 UTC (19 years, 3 months ago) by werner
File size: 14913 byte(s)
Add comments and a README.SVN

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     #define MIN_GPG_VER "1.4.3" /* Minimal GPG version. */
44     #define MIN_GPGME_VER "1.2.0" /* Minimal GPGME version. */
45     #define MIN_PTD_VER "0.8.1" /* Minimal PTD version. */
46    
47    
48     HINSTANCE glob_hinst; /* global instance for the dialogs */
49     HWND glob_hwnd; /* global window handle for the dialogs */
50     HWND activ_hwnd;
51     LOCK mo_file;
52     int scard_support = 0;
53     int debug = 0;
54     int mobile = 0;
55     int gpg_read_only = 0;
56     char gpgver[3];
57    
58    
59     /* Load the key cache and rebuild the signature cache. */
60     static void
61     update_keycache (HWND hwnd)
62     {
63     refresh_cache_s rcs = {0};
64     rcs.kr_reload = 0;
65     rcs.kr_update = 1;
66     rcs.tr_update = 1;
67     DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, hwnd,
68     keycache_dlg_proc, (LPARAM)&rcs);
69     }
70    
71    
72     /* Set GPGME debug mode. If @val is 0, the debug mode is disabled. */
73     void
74     gpg_set_debug_mode (int val)
75     {
76     if (val)
77     putenv ("GPGME_DEBUG=5:gpgme.dbg");
78     else
79     putenv ("GPGME_DEBUG=");
80     }
81    
82    
83     /* Return the name of the gettext language file. */
84     static char*
85     get_gettext_lang (void)
86     {
87     char *fname;
88     fname = get_reg_entry_mo ();
89     if (!fname)
90     return NULL;
91     return fname;
92     }
93    
94    
95     /* Initialize the gettext sub system. */
96     static void
97     load_gettext (int prev_inst)
98     {
99     char *nls = NULL;
100     char *file = NULL;
101    
102     nls = get_gettext_lang ();
103     if (nls) {
104     set_gettext_file ("winpt", nls);
105     file = make_filename (nls, "winpt", "mo");
106     if (!file_exist_check (nls) && init_file_lock (&mo_file, file)) {
107     if (!prev_inst)
108     msg_box (NULL, _("Could not initizalize file lock.\n"
109     "Native Language Support"),
110     _("WinPT Error"), MB_ERR);
111     }
112     free_if_alloc (nls);
113     free_if_alloc (file);
114     }
115     }
116    
117    
118     /* check if the default key from the gpg.conf file is available in the
119     keyring. if not, bail out because encryption won't work properly then. */
120     static int
121     check_default_key (gpg_keycache_t kc)
122     {
123     gpgme_key_t key;
124     gpgme_error_t err = GPG_ERR_NO_ERROR;
125     char * defkey;
126    
127     defkey = get_gnupg_default_key ();
128     if (defkey)
129     err = gpg_keycache_find_key (kc, defkey, 0, &key);
130     free_if_alloc (defkey);
131     return err? -1 : 0;
132     }
133    
134    
135     /* Return the WinPT program file name (with full pathname). */
136     static const char *
137     get_prog_part (const char * fname, int use_cwd)
138     {
139     static char program[512];
140     char currdir[256];
141     char *cmd = NULL;
142     int j;
143    
144     memset (currdir, 0, DIM (currdir));
145     memset (program, 0, DIM (program));
146    
147     if (use_cwd) {
148     GetCurrentDirectory (DIM (currdir)-1, currdir);
149     _snprintf (program, DIM (program)-1, "%s\\%s", currdir, fname);
150     }
151     else {
152     cmd = GetCommandLine ();
153     if (cmd == NULL)
154     return NULL;
155     strncpy (currdir, cmd, sizeof (currdir)-1);
156     j = strlen (currdir);
157     while (j--) {
158     if (currdir[j] == '\\')
159     break;
160     }
161     currdir[j] = 0;
162     _snprintf (program, DIM (program)-1, "%s\\%s", currdir + 1, fname);
163     }
164     return program;
165     }
166    
167    
168     /* Check that the underlying crypto engine fullfills the minimal
169     requirements so all commands work properly. */
170     static int
171     check_crypto_engine (void)
172     {
173     int ma=1, mi=4, pa=3; /* GPG 1.4.3 */
174     int rc;
175    
176     rc = check_gnupg_engine (&ma, &mi, &pa);
177     if (rc == -1) {
178     msg_box (NULL, _("Could not read GnuPG version."),
179     _("WinPT Error"), MB_ERR);
180     return rc;
181     }
182     else if (rc) {
183     log_box (_("WinPT Error"), MB_ERR,
184     _("Sorry, you need a newer GPG version.\n"
185     "GPG version %d.%d.%d required GPG version "MIN_GPG_VER),
186     ma, mi, pa);
187     return rc;
188     }
189     /* We enable smartcard support for GPG: 1.9 or >= 1.4 */
190 werner 58 if ((ma == 1 && mi >= 4) || ma > 1)
191 werner 36 scard_support = 1;
192    
193     gpgver[0] = ma;
194     gpgver[1] = mi;
195     gpgver[2] = pa;
196     return rc;
197     }
198    
199    
200     /* Try to load the keyserver config file. If @quiet is 1
201     do not show any errors. */
202     static int
203     load_keyserver_conf (int quiet)
204     {
205     const char * t;
206     int rc;
207    
208     if (reg_prefs.kserv_conf)
209     t = reg_prefs.kserv_conf;
210     else if (!file_exist_check (get_prog_part ("keyserver.conf", 0)))
211     t = get_prog_part ("keyserver.conf", 0);
212     else
213     t = "keyserver.conf";
214     rc = kserver_load_conf (t);
215     if (rc && !quiet)
216     msg_box (NULL, winpt_strerror (rc), _("Keyserver"), MB_ERR);
217     return rc;
218     }
219    
220    
221     /* Enable the mobility mode. */
222     static void
223     enable_mobile_mode (void)
224     {
225     memset (&reg_prefs, 0, sizeof (reg_prefs));
226     reg_prefs.always_trust = 0;
227     reg_prefs.auto_backup = 0;
228     reg_prefs.cache_time = 0;
229     reg_prefs.expert = 0;
230     reg_prefs.keylist_mode = 1;
231     reg_prefs.kserv_conf = m_strdup ("keyserver.conf");
232     reg_prefs.no_zip_mmedia = 1;
233     reg_prefs.use_tmpfiles = 1;
234     reg_prefs.word_wrap = 80;
235     reg_prefs.use_viewer = 0; /* XXX */
236     }
237    
238     char* multi_gnupg_path (void);
239    
240 twoaday 41 const char * fm_get_file_type (const char *fname, int *r_type);
241    
242 werner 36 /* Main entry point. */
243     int WINAPI
244     WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
245     {
246     WNDCLASS wc = {0, winpt_main_proc, 0, 0, hinst, 0, 0, 0, 0, PGM_NAME};
247     HACCEL accel_tab;
248 twoaday 41 int rc, ec, created = 0, nfiles = 0;
249 werner 36 int first_start = 0, start_gpgprefs = 0;
250     int winpt_inst_found = 0;
251     const char *s;
252     MSG msg;
253     HWND hwnd = NULL;
254    
255     glob_hinst = hinst;
256    
257 werner 58 #ifdef _DEBUG
258 werner 36 gpg_set_debug_mode (1);
259     debug = 1;
260 werner 58 #endif
261 werner 36
262     s = PTD_get_version ();
263 werner 57 // FIXME: Using strcmp here is wrong
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 werner 36
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 werner 48 s = get_fileopen_dlg (GetActiveWindow (),
323     _("Select GPG Public Keyring"),
324     _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),
325     NULL);
326 werner 36 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 werner 48
483 werner 36 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