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

Diff of /trunk/Src/WinPT.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.28  
changed lines
  Added in v.262

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26