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

Legend:
Removed from v.24  
changed lines
  Added in v.260

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26