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

Legend:
Removed from v.2  
changed lines
  Added in v.409

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26