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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 34 - (hide annotations)
Wed Oct 26 11:20:09 2005 UTC (19 years, 4 months ago) by twoaday
File size: 15251 byte(s)
2005-10-25  Timo Schulz  <twoaday@g10code.com>
                                                                                
        * wptGPGUtil.cpp (create_process): Hide window.
        * wptKeyPropsDlg.cpp (get_photo_tmpname): New.
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Remove
        static var 'enable'.
        * wptKeygenDlg.cpp (keygen_dlg_proc): Likewise.
        (gpg_genkey_params): Make sure all primary keys are capable
        for signing and certification.
        * wptKeySigDlg.cpp (is_sig): If no item is selected, return 0.
        * wptGPG.cpp (gnupg_access_keyring): Check return value for
        NULL. Noted by Ralf.
        (get_gnupg_prog): Simplified.
        (check_homedir): Fixed. Return 0 when the dir is successfully created.
        * wptKeyManagerDlg.cpp (km_file_import): Use the hourglass to
        indicate a pending GPG process.
        * wptFileManager.cpp (op_begin, op_end): New. Indicate an start
        and and of an operation. For now just the cursor changes.
        (fm_parse_command_line): Remove debug output. Thanks to Ralf again.
        * WinPT.cpp (WinMain): Check if there is already an instance and
        set a variable early as possible.
        (load_gettext): If a previous instance was found, do not output
        any errors. Kudos to Ralf.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26