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

Legend:
Removed from v.34  
changed lines
  Added in v.197

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26