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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 59 - (hide annotations)
Wed Nov 2 13:50:48 2005 UTC (19 years, 4 months ago) by twoaday
File size: 14614 byte(s)
Removed PTD version check.

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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26