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

Legend:
Removed from v.36  
changed lines
  Added in v.295

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26