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

Annotation of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 295 - (hide annotations)
Tue Mar 13 18:53:40 2007 UTC (17 years, 11 months ago) by twoaday
File size: 21985 byte(s)


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26