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

Legend:
Removed from v.26  
changed lines
  Added in v.181

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26