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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26