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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (hide annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 22223 byte(s)


1 werner 36 /* WinPT.cpp - Windows Privacy Tray (WinPT)
2 twoaday 133 * Copyright (C) 2000-2006 Timo Schulz
3 werner 36 *
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 twoaday 154 #include <shlobj.h>
26 werner 36
27 werner 47 #include "resource.h"
28 werner 36 #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 werner 48 #include "wptCrypto.h"
43 twoaday 190 #include "wptUTF8.h"
44 werner 36
45 twoaday 172 void remove_crit_file_attrs (const char *fname, int force);
46 twoaday 208 BOOL user_is_admin (void);
47 twoaday 273 int pcsc_available (void);
48 twoaday 154
49 twoaday 208 /* Global variables. */
50 werner 36 HINSTANCE glob_hinst; /* global instance for the dialogs */
51     HWND glob_hwnd; /* global window handle for the dialogs */
52     int scard_support = 0;
53     int debug = 0;
54     int gpg_read_only = 0;
55 twoaday 208 int admin_user = 0;
56 werner 36 char gpgver[3];
57 twoaday 208 /* End */
58 werner 36
59    
60     /* Load the key cache and rebuild the signature cache. */
61 twoaday 255 int
62 werner 36 update_keycache (HWND hwnd)
63     {
64 twoaday 255 int err;
65 twoaday 273 refresh_cache_s rcs;
66 twoaday 255
67 twoaday 273 /* no need to rebuild the sig cache each time. */
68     memset (&rcs, 0, sizeof (rcs));
69     rcs.kring_update = 1;
70 twoaday 255 err = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYCACHE, hwnd,
71 werner 36 keycache_dlg_proc, (LPARAM)&rcs);
72 twoaday 255 if (err) {
73 twoaday 270 char *cfgf = get_gnupg_config ();
74     if (cfgf && check_gnupg_options (cfgf, 0) == WPTERR_FILE_EXIST)
75 twoaday 255 msg_box (NULL, _("The gpg.conf contains at least one argument which points to a non-existing file."), "WinPT", MB_ERR);
76 twoaday 270 free_if_alloc (cfgf);
77 twoaday 255 return -1;
78     }
79     return 0;
80 werner 36 }
81    
82    
83     /* Set GPGME debug mode. If @val is 0, the debug mode is disabled. */
84     void
85     gpg_set_debug_mode (int val)
86 twoaday 181 {
87 twoaday 190 static char buf[256];
88     char tmp[128];
89    
90     /* XXX: no gpgme.dbg is created. */
91     if (val > 0) {
92 twoaday 271 GetTempPath (DIM (tmp)-1, tmp);
93     _snprintf (buf, DIM (buf)-1, "GPGME_DEBUG=5:%sgpgme.dbg", tmp);
94 twoaday 190 putenv (buf);
95     }
96 werner 36 else
97     putenv ("GPGME_DEBUG=");
98     }
99    
100    
101     /* Initialize the gettext sub system. */
102     static void
103 twoaday 193 load_gettext (void)
104 werner 36 {
105 twoaday 270 char *nls;
106 werner 36
107 twoaday 193 /* Return the name of the gettext language file. */
108     nls = get_reg_entry_mo ();
109 twoaday 137 if (nls != NULL) {
110 werner 36 set_gettext_file ("winpt", nls);
111     free_if_alloc (nls);
112     }
113     }
114    
115    
116 twoaday 167 /* Return true if the GPG environment is useable. */
117     static bool
118     gpg_prefs_ok (void)
119     {
120     char *p;
121    
122     p = get_reg_entry_gpg4win ("gpg.exe");
123     if (!p || file_exist_check (p) != 0) {
124     free_if_alloc (p);
125     p = get_reg_entry_gpg ("gpgProgram");
126     if (!p || file_exist_check (p) != 0) {
127     free_if_alloc (p);
128 twoaday 190 log_debug ("gpg_prefs_ok: could not locate gpg.exe");
129 twoaday 167 return false;
130     }
131     }
132     free_if_alloc (p);
133 twoaday 270 p = get_reg_entry_gpg4win (NULL);
134 twoaday 167 if (!p || dir_exist_check (p) != 0) {
135     free_if_alloc (p);
136     p = get_reg_entry_gpg ("HomeDir");
137     if (!p || dir_exist_check (p) != 0) {
138     free_if_alloc (p);
139 twoaday 190 log_debug ("gpg_prefs_ok: could not determine home directory");
140 twoaday 167 return false;
141     }
142     }
143     free_if_alloc (p);
144     return true;
145     }
146    
147    
148 twoaday 172 /* Check gpg files if they are read-only and ask the user
149     if this should be corrected. */
150     static void
151     check_readonly_attr (const char *homedir)
152     {
153     const char *files[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg", NULL};
154     char *file;
155     int i;
156 twoaday 167
157 twoaday 172 for (i=0; files[i] != NULL; i++) {
158     file = make_filename (homedir, files[i], NULL);
159     remove_crit_file_attrs (file, 0);
160     free_if_alloc (file);
161     }
162     }
163    
164    
165 twoaday 128 /* Load the GPG environment. On the first start, some
166     checks are performed to find out in what state GPG is.
167     Return value: 0 everything OK.
168     >0 fatal error.
169     -1 public keyring is empty or does not exist. */
170     static int
171     load_gpg_env (void)
172     {
173     SECURITY_ATTRIBUTES sec_attr;
174     char *p;
175     char *pkr;
176 twoaday 270 int err = 0;
177 twoaday 128
178     p = get_reg_entry_gpg4win ("gpg.exe");
179     if (!p)
180     return (1);
181     if (file_exist_check (p)) {
182     free_if_alloc (p);
183     return (1);
184     }
185     free_if_alloc (p);
186 twoaday 167
187     p = get_reg_entry_gpg ("HomeDir");
188     if (!p || dir_exist_check (p) != 0) {
189     free_if_alloc (p);
190     p = multi_gnupg_path (0);
191     }
192 twoaday 128 if (p && dir_exist_check (p)) {
193     memset (&sec_attr, 0, sizeof (sec_attr));
194     sec_attr.nLength = sizeof (sec_attr);
195     if (!CreateDirectory (p, &sec_attr)) {
196     msg_box (NULL, _("Could not create GPG home directory"),
197     _("WinPT Error"), MB_ERR);
198     free_if_alloc (p);
199     return (2);
200     }
201     }
202 twoaday 172 check_readonly_attr (p);
203 twoaday 128 pkr = make_filename (p, "pubring", "gpg");
204     free_if_alloc (p);
205 twoaday 270 if (get_file_size (pkr) == 0)
206     err = -1;
207     free_if_alloc (pkr);
208     return err;
209 twoaday 128 }
210    
211 twoaday 133
212 werner 36 /* check if the default key from the gpg.conf file is available in the
213     keyring. if not, bail out because encryption won't work properly then. */
214     static int
215 twoaday 273 check_default_key (void)
216 werner 36 {
217     gpgme_key_t key;
218 twoaday 193 gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
219 twoaday 273 gpg_keycache_t kc;
220 twoaday 128 char *defkey;
221 werner 36
222 twoaday 273 kc = keycache_get_ctx (0);
223 werner 36 defkey = get_gnupg_default_key ();
224 twoaday 273 if (defkey) {
225 werner 36 err = gpg_keycache_find_key (kc, defkey, 0, &key);
226 twoaday 273 if (err) {
227     free_if_alloc (defkey);
228     return -1;
229     }
230     }
231     else {
232     /* Actually this is just a warning but we still continue. */
233 twoaday 121 msg_box (NULL, _("No useable secret key found."),
234 twoaday 217 _("WinPT Warning"), MB_WARN);
235 twoaday 273 free_if_alloc (defkey);
236     return 0;
237     }
238    
239     /* Because the secret key listing has no information
240     about the validity/status, we need to check the public key. */
241     kc = keycache_get_ctx (1);
242     if (!gpg_keycache_find_key (kc, defkey, 0, &key) &&
243     (key->revoked || key->expired)) {
244     msg_box (NULL, _("Default secret key is unuseable"),
245     _("WinPT Warning"), MB_ERR);
246     free_if_alloc (defkey);
247     return -1;
248     }
249 werner 36 free_if_alloc (defkey);
250 twoaday 273 return 0;
251 werner 36 }
252    
253    
254     /* Return the WinPT program file name (with full pathname). */
255 twoaday 121 static const char*
256 twoaday 273 get_prog_part (const char *fname, int use_cwd)
257 werner 36 {
258 twoaday 270 static char program[2*MAX_PATH+1];
259     char currdir[MAX_PATH+1];
260 werner 36 char *cmd = NULL;
261     int j;
262    
263     memset (currdir, 0, DIM (currdir));
264     memset (program, 0, DIM (program));
265    
266     if (use_cwd) {
267     GetCurrentDirectory (DIM (currdir)-1, currdir);
268     _snprintf (program, DIM (program)-1, "%s\\%s", currdir, fname);
269     }
270     else {
271     cmd = GetCommandLine ();
272 twoaday 270 if (!cmd)
273 werner 36 return NULL;
274 twoaday 271 strncpy (currdir, cmd, DIM (currdir)-1);
275 werner 36 j = strlen (currdir);
276     while (j--) {
277     if (currdir[j] == '\\')
278     break;
279     }
280     currdir[j] = 0;
281     _snprintf (program, DIM (program)-1, "%s\\%s", currdir + 1, fname);
282     }
283     return program;
284     }
285    
286    
287     /* Check that the underlying crypto engine fullfills the minimal
288     requirements so all commands work properly. */
289 twoaday 128 static bool
290 werner 36 check_crypto_engine (void)
291     {
292 twoaday 193 int ma = 0, mi = 0, pa = 0;
293 werner 36 int rc;
294    
295 twoaday 137 rc = check_gnupg_engine (NEED_GPG_VERSION, &ma, &mi, &pa);
296 werner 36 if (rc == -1) {
297     msg_box (NULL, _("Could not read GnuPG version."),
298     _("WinPT Error"), MB_ERR);
299 twoaday 128 return false;
300 werner 36 }
301     else if (rc) {
302     log_box (_("WinPT Error"), MB_ERR,
303     _("Sorry, you need a newer GPG version.\n"
304 twoaday 137 "GPG version %d.%d.%d required GPG version "NEED_GPG_VERSION),
305 werner 36 ma, mi, pa);
306 twoaday 128 return false;
307 werner 36 }
308 twoaday 270 /* Enable smart card support for GPG 2 or >= 1.4 */
309 twoaday 262 if ((ma > 1 || pa >= 4) && pcsc_available ())
310 werner 36 scard_support = 1;
311    
312     gpgver[0] = ma;
313     gpgver[1] = mi;
314     gpgver[2] = pa;
315 twoaday 128 return true;
316 werner 36 }
317    
318    
319     /* Try to load the keyserver config file. If @quiet is 1
320     do not show any errors. */
321     static int
322     load_keyserver_conf (int quiet)
323 twoaday 248 {
324     const char *t, *conf;
325 twoaday 154 char *buf;
326 werner 36 int rc;
327    
328 twoaday 271 #ifdef WINPT_MOBILE
329     /* In mobile mode we automatically assume the config file
330     in the current directory. */
331     return kserver_load_conf ("keyserver.conf");
332     #endif
333    
334 twoaday 154 /* Create $APPDATA\winpt if needed. */
335     buf = make_special_filename (CSIDL_APPDATA, "winpt", NULL);
336     if (buf && dir_exist_check (buf) && !CreateDirectory (buf, NULL)) {
337     MessageBox (NULL, _("Failed to create WinPT directory"),
338     _("Keyserver"), MB_ERR);
339     free_if_alloc (buf);
340     return -1;
341     }
342     free_if_alloc (buf);
343    
344     /* Check for $APPDATA\winpt\keyserver.conf */
345     buf = make_special_filename (CSIDL_APPDATA, "winpt\\keyserver.conf", NULL);
346    
347 twoaday 193 conf = get_prog_part ("keyserver.conf", 0);
348     if (!file_exist_check (conf))
349     t = conf;
350 twoaday 154 else
351 werner 36 t = "keyserver.conf";
352 twoaday 154 if (file_exist_check (t) == 0 && file_exist_check (buf) != 0) {
353     if (!CopyFile (t, buf, FALSE)) {
354     MessageBox (NULL, _("Failed to copy the keyserver.conf"),
355     _("Keyserver"), MB_ERR);
356     free_if_alloc (buf);
357     return -1;
358     }
359     t = buf;
360     }
361     else
362     t = buf;
363    
364 werner 36 rc = kserver_load_conf (t);
365     if (rc && !quiet)
366     msg_box (NULL, winpt_strerror (rc), _("Keyserver"), MB_ERR);
367 twoaday 154 else {
368     free_if_alloc (reg_prefs.kserv_conf);
369     reg_prefs.kserv_conf = m_strdup (t);
370     }
371     free_if_alloc (buf);
372 werner 36 return rc;
373     }
374    
375    
376 twoaday 133 /* Check if both keyrings are empty. This indicates that
377     WinPT should offer to generate a key pair. */
378     static bool
379     check_for_empty_keyrings (bool pub_only)
380     {
381     char *p;
382     int n = 0;
383    
384     p = get_gnupg_keyring (1, 0);
385     if (file_exist_check (p) == 0 && get_file_size (p) == 0)
386     n++;
387     free_if_alloc (p);
388     if (pub_only)
389     return n == 1? true : false;
390     p = get_gnupg_keyring (0, 0);
391     if (file_exist_check (p) == 0 && get_file_size (p) == 0)
392     n++;
393     free_if_alloc (p);
394     return n==2? true : false;
395     }
396    
397    
398 twoaday 271 #ifdef WINPT_MOBILE
399     /* Enable the mobile mode if possible.
400     There are some constraints which must be fullfilled.
401     Return value: 0 on success. */
402 twoaday 190 static int
403 werner 36 enable_mobile_mode (void)
404     {
405 twoaday 271 static const char *test_fname = "winpt_mobile_test.txt";
406     FILE *fp;
407     char *pubring;
408     ULARGE_INTEGER caller, total;
409     DWORD temp_size;
410    
411     fp = fopen (test_fname, "wb");
412     if (fp == NULL) {
413     MessageBox (NULL, "Mobile mode cannot be used without write permission\n"
414     "for the current directory", "WinPT Error", MB_ERR);
415    
416     return -1;
417 twoaday 190 }
418 twoaday 271 fclose (fp);
419     DeleteFile (test_fname);
420     if (file_exist_check ("gpg.exe")) {
421     MessageBox (NULL, "The GnuPG program needs to be in the same directory\n"
422     "as the WinPT program", "WinPT Error", MB_ERR);
423     return -1;
424     }
425    
426     /* Because write operations to the keyring result in a temporary
427     file, we need at least 2 MB plus the size of the keyring for
428     free space. */
429     pubring = get_gnupg_keyring (1);
430     temp_size = get_file_size (pubring) + 2097152;
431     free_if_alloc (pubring);
432 twoaday 190
433 twoaday 271 if (!GetDiskFreeSpaceEx (NULL, &caller, &total, NULL) ||
434     caller.LowPart < temp_size) {
435     log_box ("WinPT Error", MB_ERR,
436     "The mobile mode needs at least %lu KB for temporary files",
437     temp_size/1024);
438     return -1;
439     }
440    
441     /* XXX: shall we check for 'temp-directory' in the gpg.conf? */
442    
443 twoaday 190 return 0;
444 werner 36 }
445 twoaday 271 #endif
446 werner 36
447    
448 twoaday 271 /* Set the default keyserver for this instance. */
449 twoaday 181 void
450     set_default_keyserver (void)
451     {
452     char *host = get_reg_entry_keyserver ("Default");
453     char *str_port = get_reg_entry_keyserver ("Default_Port");
454     WORD port = HKP_PORT;
455    
456     if (!host)
457     keyserver_set_default (NULL, 0);
458     else {
459     if (str_port && *str_port)
460     port = atoi (str_port);
461     keyserver_set_default (host, port);
462     }
463     free_if_alloc (host);
464     free_if_alloc (str_port);
465     }
466    
467    
468 twoaday 190 /* Display info message that WinPT is now in debug mode. */
469     void
470     winpt_debug_msg (void)
471     {
472     char output[512];
473     char temp[128];
474    
475 twoaday 271 GetTempPath (DIM (temp) -1, temp);
476     _snprintf (output, DIM (output)-1,
477 twoaday 190 "The GPGME output file is %sgpgme.dbg\n"
478     "The WinPT output file is %swinpt.log\n", temp, temp);
479     MessageBox (NULL, output, "WinPT now runs in DEBUG MODE", MB_INFO);
480     }
481    
482    
483 twoaday 217 /* Search for insecure ElGamal keys and return the
484     number of founded keys. */
485     static int
486     count_insecure_elgkeys (void)
487     {
488     gpg_keycache_t pc;
489     gpgme_key_t key;
490     int n = 0;
491 twoaday 208
492 twoaday 217 pc = keycache_get_ctx (1);
493     while (!gpg_keycache_next_key (pc, 0, &key)) {
494     if (key->subkeys->pubkey_algo == GPGME_PK_ELG)
495     n++;
496     }
497     gpg_keycache_rewind (pc);
498     return n;
499     }
500    
501    
502 werner 36 /* Main entry point. */
503     int WINAPI
504     WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
505     {
506     WNDCLASS wc = {0, winpt_main_proc, 0, 0, hinst, 0, 0, 0, 0, PGM_NAME};
507     HACCEL accel_tab;
508 twoaday 121 MSG msg;
509     HWND hwnd = NULL;
510 twoaday 248 WORD ver[3], ptdver[4];
511     const char *s;
512 twoaday 121 int rc, ec, created = 0;
513 werner 36 int first_start = 0, start_gpgprefs = 0;
514     int winpt_inst_found = 0;
515 twoaday 248 int start_manager = 0;
516 werner 36
517 twoaday 271 #ifdef WINPT_MOBILE
518     /* Do not continue in case of problems. */
519     if (enable_mobile_mode ())
520     return 0;
521     #endif
522    
523 werner 36 glob_hinst = hinst;
524 twoaday 87 if (cmdline && stristr (cmdline, "--stop")) {
525     hwnd = FindWindow ("WinPT", "WinPT");
526     if (hwnd != NULL)
527     PostMessage (hwnd, WM_DESTROY, 0, 0);
528     return 0;
529     }
530 twoaday 121
531     #ifdef _DEBUG
532 werner 36 gpg_set_debug_mode (1);
533     debug = 1;
534 twoaday 121 #endif
535 werner 36
536 twoaday 121 get_file_version ("WinPT.exe", &ver[0], &ver[1], &ver[2], &ver[3]);
537 twoaday 271 ec = get_file_version ("PTD.dll", &ptdver[0], &ptdver[1],
538 twoaday 121 &ptdver[2], &ptdver[3]);
539 twoaday 193
540 twoaday 270 if (!ec && (ptdver[0] != ver[0] ||
541     ptdver[1] != ver[1] ||
542     ptdver[2] != ver[2])) {
543 twoaday 121 log_box (_("WinPT Error"), MB_ERR,
544     _("The PTD.dll file has a different version than WinPT.exe\n"
545     "Please update the PTD.dll to version %d.%d.%d"),
546     ver[0], ver[1], ver[2]);
547     return 0;
548     }
549 twoaday 128
550 werner 36 if (gpg_md_selftest ()) {
551     msg_box (NULL, _("Cryptographic selftest failed."),
552     _("WinPT Error"), MB_ERR);
553     return 0;
554     }
555    
556 twoaday 137 s = gpgme_check_version (NEED_GPGME_VERSION);
557 werner 36 if (!s || !*s) {
558 twoaday 137 msg_box (NULL, _("A newer GPGME version is needed; at least "NEED_GPGME_VERSION),
559 werner 36 _("WinPT Error"), MB_ERR);
560     return 0;
561     }
562    
563     CreateMutex (NULL, TRUE, PGM_NAME);
564     if (GetLastError () == ERROR_ALREADY_EXISTS)
565     winpt_inst_found = 1;
566 twoaday 190
567 twoaday 181 set_default_keyserver ();
568 twoaday 193 load_gettext ();
569 twoaday 208 admin_user = user_is_admin ();
570 werner 36
571 twoaday 271 regist_inst_gnupg (1);
572     regist_inst_winpt (1, &created);
573 werner 36
574     if (!created) {
575     memset (&reg_prefs, 0, sizeof (reg_prefs));
576 twoaday 271 get_reg_winpt_prefs (&reg_prefs);
577 werner 36 reg_prefs.fm.progress = 0; /* XXX: fix the bug and enable it again */
578 twoaday 273 if (gnupg_load_config () == -2)
579     msg_box (NULL, _("The gpg.conf file contains the 'textmode' option\n"
580     "which leads to broken binary output during decryption.\n"
581     "If this is on purpose, just continue otherwise the option should be disabled."),
582     _("WinPT Error"), MB_ERR);
583 werner 36 }
584    
585 twoaday 128 if (is_gpg4win_installed ())
586     load_gpg_env (); /* XXX: check return code. */
587    
588 werner 36 rc = gnupg_check_homedir ();
589     if (rc) {
590 twoaday 271 char *p;
591    
592 werner 36 log_box (_("WinPT Error"), MB_ERR,
593     _("GPG home directory is not set correctly.\n"
594     "Please check the GPG registry settings:\n%s."),
595     winpt_strerror (rc));
596 werner 48 s = get_fileopen_dlg (GetActiveWindow (),
597 twoaday 121 _("Select GPG Public Keyring"),
598 twoaday 167 "GPG Keyrings (*.gpg)\0*.gpg\0\0",
599 twoaday 121 NULL);
600 twoaday 271 if (s != NULL && (p=strrchr (s, '\\'))) {
601     char *path = substr (s, 0, (p-s));
602    
603     set_reg_entry_gpg ("HomeDir", path);
604     free_if_alloc (path);
605 werner 36 }
606     else {
607 twoaday 231 msg_box (NULL, _("GPG home directory could not be determined."),
608 werner 36 _("WinPT Error"), MB_ERR);
609     goto start;
610     }
611     }
612    
613     rc = check_gnupg_prog ();
614     if (rc) {
615     if (msg_box (NULL, _("Could not find the GPG binary (gpg.exe).\n"
616     "Do you want to start the GPG preferences to "
617     "correct this problem?"), _("WinPT Error"),
618     MB_INFO|MB_YESNO) == IDYES)
619     start_gpgprefs = 1;
620 twoaday 121 else {
621 werner 36 msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
622     return 0;
623     }
624     }
625    
626     rc = gnupg_access_files ();
627     if (!start_gpgprefs && rc) {
628     if (rc == WPTERR_GPG_KEYRINGS || rc == WPTERR_GPG_OPT_KEYRINGS) {
629     ec = msg_box (NULL,
630     _("Could not access and/or find the public and secret keyring.\n"
631     "If this is an accident, quit the program and fix it.\n\n"
632 twoaday 248 "Continue if you want WinPT to offer you more choices.\n"),
633 werner 36 "WinPT", MB_INFO|MB_YESNO);
634     if (ec == IDYES)
635     first_start = 1;
636     }
637     if (!first_start) {
638     msg_box (NULL, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
639     return 0;
640     }
641     }
642 twoaday 133 if (check_for_empty_keyrings (false))
643     first_start = 1;
644 werner 36
645     if (!first_start) {
646     rc = gpg_check_permissions (1);
647 twoaday 271 if (rc && rc == 2) /* 2 means read-only mode. */
648 werner 36 gpg_read_only = 1;
649     else if (rc)
650     return 0;
651     }
652 twoaday 121
653 werner 36 init_gnupg_table ();
654    
655 twoaday 121 if (fm_parse_command_line (cmdline) > 0) {
656 werner 36 free_gnupg_table ();
657     return 0;
658     }
659    
660     if (cmdline && stristr (cmdline, "--wipe-freespace")) {
661     dialog_box_param (glob_hinst, (LPCTSTR)IDD_WINPT_SPACE_SECDEL,
662 twoaday 73 GetDesktopWindow(), space_wipefrees_dlg_proc, 0,
663 werner 36 _("Wipe Free Space"), IDS_WINPT_SPACE_SECDEL);
664     free_gnupg_table ();
665     return 0;
666     }
667    
668     load_keyserver_conf (cmdline? 1 : 0);
669    
670     if (cmdline && (stristr (cmdline, "--keymanager")
671     || stristr (cmdline, "--cardmanager"))) {
672 twoaday 102 /* If an instance of WinPT is running, just send the command
673 twoaday 270 to open the key manager. Otherwise start a new instance. */
674 twoaday 102 HWND tray = FindWindow ("WinPT", "WinPT");
675 twoaday 121 if (stristr (cmdline, "keymanager"))
676     start_manager = ID_WINPT_KEY;
677     else
678     start_manager = ID_WINPT_CARD;
679 twoaday 102 if (tray != NULL) {
680 twoaday 121 PostMessage (tray, WM_COMMAND, start_manager, 0);
681 twoaday 102 free_gnupg_table ();
682     return 0;
683     }
684 werner 36 }
685    
686     /* If we found another WinPT instance, just quit to avoid it
687     will be executed twice. */
688     if (winpt_inst_found) {
689     log_debug ("%s", "WinMain: WinPT is already running.");
690     free_gnupg_table ();
691     return 0;
692     }
693    
694 twoaday 271 #ifndef WINPT_MOBILE
695 twoaday 190 if (cmdline && (stristr (cmdline, "--enable-debug") ||
696     stristr (cmdline, "--debug"))) {
697     gpg_set_debug_mode (1);
698     winpt_debug_msg ();
699     debug = 1;
700 werner 36 }
701 twoaday 271 #endif
702 werner 36
703     wc.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_WINPT));
704     rc = RegisterClass (&wc);
705     if (rc == FALSE) {
706     msg_box (NULL, _("Could not register window class"),
707     _("WinPT Error"), MB_ERR);
708     free_gnupg_table ();
709     return 0;
710     }
711    
712     hwnd = CreateWindow (PGM_NAME,
713     PGM_NAME,
714     0, 0, 0, 0, 0,
715     NULL,
716     NULL,
717     hinst,
718     NULL);
719     if (hwnd == NULL) {
720     msg_box (NULL, _("Could not create window"), _("WinPT Error"), MB_ERR);
721     free_gnupg_table ();
722     return 0;
723     }
724     glob_hwnd = hwnd;
725     UpdateWindow (hwnd);
726    
727     if (!first_start && !start_gpgprefs) {
728     gnupg_backup_options ();
729 twoaday 128 if (!check_crypto_engine ()) {
730 werner 36 DestroyWindow (hwnd);
731     free_gnupg_table ();
732     return 0;
733     }
734     }
735    
736     if (start_gpgprefs) {
737     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
738 twoaday 41 gpgprefs_dlg_proc, 0);
739 twoaday 133 if (check_for_empty_keyrings (true))
740 twoaday 271 first_start = 1; /* The public keyring is empty. */
741 werner 36 }
742    
743     if (first_start) {
744     struct genkey_s c;
745 twoaday 167 int choice;
746 werner 36 HWND h;
747     start:
748     h = GetDesktopWindow ();
749 twoaday 167 if (!gpg_prefs_ok ())
750     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, h,
751 twoaday 41 gpgprefs_dlg_proc, 0);
752 twoaday 167 choice = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FIRST, h,
753     first_run_dlg_proc, 0);
754     switch (choice) {
755 werner 36 case SETUP_KEYGEN:
756     c.interactive = 1;
757     c.first_start = 1;
758     rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_KEYWIZARD,
759     h, keygen_wizard_dlg_proc, (LPARAM)&c);
760     if (!rc)
761     goto start;
762     break;
763    
764     case SETUP_IMPORT:
765     rc = gnupg_copy_keyrings ();
766     if (rc) {
767     msg_box (hwnd, winpt_strerror (rc), _("WinPT Error"), MB_ERR);
768     goto start;
769     }
770     break;
771    
772 twoaday 260 case SETUP_CARDGEN:
773     rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_CARD_KEYGEN,
774     h, card_keygen_dlg_proc, 0);
775     if (!rc)
776     goto start;
777     break;
778    
779 twoaday 167 case 0: /* Cancel/Abort. */
780     default:
781 werner 36 DestroyWindow (hwnd);
782     free_gnupg_table ();
783     return 0;
784     }
785     update_keycache (hwnd);
786 twoaday 167 if (!check_crypto_engine ()) {
787     DestroyWindow (hwnd);
788     free_gnupg_table ();
789 twoaday 255 keycache_release (1);
790 twoaday 167 return 0;
791     }
792 twoaday 193 if (!is_gpg4win_installed ()) {
793     select_language ();
794     load_gettext ();
795     }
796 werner 36 }
797     else {
798 twoaday 273 gpg_keycache_t c;
799 twoaday 255 if (update_keycache (hwnd)) {
800     DestroyWindow (hwnd);
801     free_gnupg_table ();
802     keycache_release (1);
803     return 0;
804     }
805 twoaday 271 /* XXX: rewrite this part. */
806 werner 36 c = keycache_get_ctx (1);
807 twoaday 255 if (!gpg_keycache_get_size (c)) {
808 werner 36 msg_box (hwnd, _("The keycache was not initialized or is empty.\n"
809     "Please check your GPG config (keyrings, pathes...)"),
810     _("WinPT Error"), MB_ERR);
811 twoaday 248 ec = msg_box (NULL, _("It seems that GPG is not configured properly.\n"
812 werner 36 "Do you want to start the GPG preferences dialog?"),
813     "WinPT", MB_INFO|MB_YESNO);
814     if (ec == IDYES) {
815     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_GPGPREFS, hwnd,
816 twoaday 41 gpgprefs_dlg_proc, 0);
817 werner 36 update_keycache (hwnd);
818     }
819     else {
820     DestroyWindow (hwnd);
821     free_gnupg_table ();
822 twoaday 255 keycache_release (1);
823 werner 36 return 0;
824     }
825 twoaday 273 }
826     if (check_default_key ()) {
827 twoaday 121 char *p = get_gnupg_default_key ();
828 twoaday 273 log_box (_("WinPT Error"), MB_ERR,
829     _("Default key (from the GPG config file) could not be found or is unuseable.\n"
830     "The default key will be resetted and can be set later in the Key Manager again.\n\n"
831     "%s: secret key not found."), p? p : "?");
832 twoaday 197 set_gnupg_default_key (NULL);
833 twoaday 273 free_if_alloc (p);
834 werner 36 }
835     if (count_insecure_elgkeys ())
836     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_ELGWARN, glob_hwnd,
837 twoaday 41 elgamal_warn_dlg_proc, 0);
838 werner 36 }
839    
840 twoaday 121 if (start_manager)
841     PostMessage (hwnd, WM_COMMAND, start_manager, 0);
842    
843 werner 36 accel_tab = LoadAccelerators (glob_hinst, (LPCTSTR)IDR_WINPT_ACCELERATOR);
844     keyring_check_last_access (); /* init */
845     while (GetMessage (&msg, hwnd, 0, 0)) {
846     if (!TranslateAccelerator (msg.hwnd, accel_tab, &msg)) {
847     TranslateMessage (&msg);
848     DispatchMessage (&msg);
849     }
850     }
851    
852     return 0;
853     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26