/[winpt]/trunk/Src/wptGPG.cpp
ViewVC logotype

Diff of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 66 by twoaday, Thu Nov 3 17:55:18 2005 UTC revision 200 by twoaday, Mon Apr 17 09:12:50 2006 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 22  Line 22 
22  #endif  #endif
23    
24  #include <windows.h>  #include <windows.h>
 #include <shlobj.h>  
25  #include <string.h>  #include <string.h>
26  #include <stdio.h>  #include <stdio.h>
27  #include <shlobj.h>  #include <shlobj.h>
# Line 40  Line 39 
39  #include "wptW32API.h"  #include "wptW32API.h"
40  #include "wptCrypto.h"  #include "wptCrypto.h"
41    
42  #define GPG_CONF "gpg.conf"  #define GPG_CONF        "gpg.conf"
43    #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44    #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  struct gpg_watcher_s {
47      FILETIME    last_access;      FILETIME    last_access;
# Line 61  static int check_keyring (char ** r_path Line 62  static int check_keyring (char ** r_path
62    
63    
64  /* Return the application data folder of the current user. */  /* Return the application data folder of the current user. */
65  static char*  char*
66  multi_gnupg_path (void)  multi_gnupg_path (int strict)
67  {  {
68      static char buf[256+64];      static char buf[256+64];
69      BOOL ec;      BOOL ec;
# Line 71  multi_gnupg_path (void) Line 72  multi_gnupg_path (void)
72      memset (buf, 0, sizeof (buf));      memset (buf, 0, sizeof (buf));
73      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */
74      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);
75      if (ec != 1)      if (ec != 1) {
76            log_debug ("multi_gnupg_path: SHGetSpecialFolderPath() failed\r\n",
77                       (int)GetLastError ());
78          return NULL;          return NULL;
79        }
80      strcat (buf, "\\gnupg");      strcat (buf, "\\gnupg");
81      if (access (buf, 00))      if (strict && access (buf, 00))
82          return NULL;          return NULL;
83      return m_strdup (buf);      return m_strdup (buf);
84  }  }
85    
86    
87  /* Return the full path of the GnuPG application. First the registry is scanned  /* Return the full path to the GPG home directory. First the 'HomeDir' entry
88     for the entry 'HomeDir'. If it wasn't set, the default dir C:\GNUPG is used.     from the registry is used. Then the default $APPDATA\gnupg path. */
 */  
89  char*  char*
90  get_gnupg_path (void)  get_gnupg_path (void)
91  {  {
92      char *p = NULL, *path = NULL;      char *path;
93        
94      p = get_reg_entry_gpg ("HomeDir");      path = get_reg_entry_gpg (GPG_REG_HOME);
95      if (p) {      if (path) {
96          path = m_strdup (p);          if (dir_exist_check (path) == 0)
97          free_if_alloc (p);              return path;
98          return path;          free_if_alloc (path);
99      }      }
100      else      path = multi_gnupg_path (1);
101          return multi_gnupg_path ();      return path;
     return m_strdup ("c:\\gnupg");  
102  }  }
103    
104    
# Line 105  get_gnupg_path (void) Line 107  get_gnupg_path (void)
107  char*  char*
108  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
109  {      {    
110      char *p = NULL, *optfile = NULL, *path = NULL;      char *p = NULL;
111        char *optfile = NULL;
112        char *path = NULL;
113      size_t nlen = 0;      size_t nlen = 0;
114    
115      path = get_gnupg_path ();      path = get_gnupg_path ();
116      if (!path)      if (!path)
117          return NULL;          return NULL;
118      p = get_reg_entry_gpg ("OptFile");      nlen = strlen (path) + 64;
119      if (p && !strcmp (p, "")) {      optfile = new char[nlen + 1];
120          nlen = strlen (path) + 64;      if (!optfile)
121          optfile = new char[nlen + 1];          BUG (NULL);    
122          if (!optfile)      _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
123              BUG (0);  
         _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);  
     }  
     else if (p) {  
         nlen = strlen( p ) + 4;  
         optfile = new char[nlen + 1];  
         if (!optfile)  
             BUG (NULL);  
         _snprintf (optfile, nlen, "%s", p);  
     }  
     else {  
         nlen = strlen (path) + 64;  
         optfile = new char[nlen + 1];  
         if( !optfile)  
             BUG (NULL);  
         _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);  
     }  
124      free_if_alloc (path);      free_if_alloc (path);
125      free_if_alloc (p);      free_if_alloc (p);
126      return optfile;      return optfile;
# Line 152  get_gnupg_keyring (int pub, int strict) Line 140  get_gnupg_keyring (int pub, int strict)
140      if (!path)      if (!path)
141          return NULL;          return NULL;
142      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
143      if (!strict && !file_exist_check (keyring)) {      if (strict && !file_exist_check (keyring)) {
144            free_if_alloc (path);
145            return keyring;
146        }
147        else if (!strict) {
148          free_if_alloc (path);          free_if_alloc (path);
149          return keyring;          return keyring;
150      }      }
# Line 177  get_gnupg_prog (void) Line 169  get_gnupg_prog (void)
169  {      {    
170      char *p;      char *p;
171      char *pgm = NULL;      char *pgm = NULL;
     size_t nlen = 0;  
172    
173      p = get_reg_entry_gpg ("gpgProgram");      p = get_reg_entry_gpg (GPG_REG_EXE);
174      if (!p) {      if (!p) {
175          char *path = get_gnupg_path ();          char *path = get_gnupg_path ();
176          if (!path)          if (!path)
# Line 200  get_gnupg_prog (void) Line 191  get_gnupg_prog (void)
191     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
192  static char *  static char *
193  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
194  {  {    
195      const char * s;      gpgme_key_t key, pk;
196      char * keyid = NULL;      gpg_keycache_t sec, pub;
197      gpgme_key_t key;      const char *s;
198      gpg_keycache_t sec = keycache_get_ctx (0);      char *keyid = NULL;
199    
200        sec = keycache_get_ctx (0);
201      if (!sec)      if (!sec)
202          BUG (0);          BUG (0);
203        pub = keycache_get_ctx (1);
204      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
205      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
206          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
207              s = key->subkeys->keyid;              s = key->subkeys->keyid;
208              if (s)                  if (s)
209                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
210              break;              break;
211          }          }
212      }      }
213      if (!keyid)      if (!keyid)
214          *ret_no_useable = 1;          *ret_no_useable = 1;    
215      return keyid;      return keyid;
216  }  }
217    
# Line 232  gnupg_load_config (void) Line 225  gnupg_load_config (void)
225      int rc;      int rc;
226      gpg_optfile_t opt;      gpg_optfile_t opt;
227      gpg_option_t o;      gpg_option_t o;
228      char *conf = get_gnupg_cfgfile ();      char *conf;
229        
230        conf = get_gnupg_cfgfile ();
231      if (!conf)      if (!conf)
232          return -1;          return -1;
233      rc = parse_gpg_options (conf, &opt);      rc = parse_gpg_options (conf, &opt);
# Line 243  gnupg_load_config (void) Line 238  gnupg_load_config (void)
238      o = find_option (opt, "ask-cert-level");      o = find_option (opt, "ask-cert-level");
239      if (o)      if (o)
240          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
241        o = find_option (opt, "ask-cert-expire");
242        if (o)
243            reg_prefs.gpg.ask_cert_expire = 1;
244      release_gpg_options (opt);      release_gpg_options (opt);
245      free_if_alloc (conf);      free_if_alloc (conf);
246      return 0;      return 0;
# Line 254  get_gnupg_default_key (void) Line 252  get_gnupg_default_key (void)
252  {      {    
253      gpg_optfile_t opt = NULL;      gpg_optfile_t opt = NULL;
254      gpg_option_t e;      gpg_option_t e;
255      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
256      int no_usable=0, rc = 0;      int no_usable=0, rc = 0;
257    
258      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
# Line 262  get_gnupg_default_key (void) Line 260  get_gnupg_default_key (void)
260          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
261      rc = parse_gpg_options (optfile, &opt);      rc = parse_gpg_options (optfile, &opt);
262      if (rc) {      if (rc) {
263          free_if_alloc( optfile );          free_if_alloc (optfile);
264          return default_key_from_cache( &no_usable );          return default_key_from_cache (&no_usable);
     }  
     e = find_option( opt, "default-key" );  
     if ( e )  
         keyid = m_strdup( e->val );  
     if( !e ) {  
         e = find_option( opt, "local-user" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
265      }      }
266        e = find_option (opt, "default-key");
267        if (!e)
268            e = find_option (opt, "local-user");
269        if (e)
270            keyid = m_strdup (e->val);
271    
272      free_if_alloc (optfile);      free_if_alloc (optfile);
273      release_gpg_options (opt);      release_gpg_options (opt);
   
274      if (!keyid)      if (!keyid)
275          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
276      return keyid;      return keyid;
277  } /* get_gnupg_default_key */  }
278    
279    
280    /* Check if GPG4WIN is available and if so, use the
281       install path to figure out where the gpg.exe is. */
282    char*
283    check_for_gpg4win (void)
284    {
285        return get_reg_entry_gpg4win ("gpg.exe");
286    }
287    
288    
289  /* Check if the gpg application (exe file) is available. */  /* Check if the gpg application (exe file) is available. */
290  int  int
291  check_gnupg_prog (void)  check_gnupg_prog (void)
292  {  {
293      char *pgm = NULL;      char *gpgexe = NULL;
294      int rc = 0;      int rc = 0;
295    
296      pgm = get_gnupg_prog ();      gpgexe = get_gnupg_prog ();
297      if (!pgm)      if (!gpgexe || file_exist_check (gpgexe)) {
298          rc = WPTERR_GPG_EXEFILE;          free_if_alloc (gpgexe);
299      if (file_exist_check (pgm))          gpgexe = check_for_gpg4win ();
300          rc = WPTERR_GPG_EXEFILE;          if (!gpgexe || file_exist_check (gpgexe))
301      free_if_alloc (pgm);              rc = WPTERR_GPG_EXEFILE;
302            else
303                set_reg_entry_gpg (GPG_REG_EXE, gpgexe);
304        }
305        free_if_alloc (gpgexe);
306      return rc;      return rc;
307  }  }
308    
309    
310  static int  static int
311  parse_version_nr (const char * buf, int *major, int *minor, int *patch)  parse_version_nr (const char *buf, int *major, int *minor, int *patch)
312  {  {
313      char tmp[8];      char tmp[8];
314      int i;      int i;
# Line 314  parse_version_nr (const char * buf, int Line 317  parse_version_nr (const char * buf, int
317      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
318          tmp[i++] = *buf++;          tmp[i++] = *buf++;
319      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
320      *major = atol( tmp );      *major = atoi (tmp);
321      i=0;      i=0;
322      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
323          tmp[i++] = *buf++;          tmp[i++] = *buf++;
324      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
325      *minor = atol (tmp);      *minor = atoi (tmp);
326      i=0;      i=0;
327      while (buf && isdigit( *buf ) && i < 8)      while (buf && isdigit (*buf) && i < 8)
328          tmp[i++] = *buf++;          tmp[i++] = *buf++;
329      tmp[i] = 0;      tmp[i] = 0;
330      *patch = atol (tmp);      *patch = atoi (tmp);
331      return 0;      return 0;
332  }  }
333    
# Line 333  parse_version_nr (const char * buf, int Line 336  parse_version_nr (const char * buf, int
336     version given in @r_major.@r_minor.@r_patch. On success these     version given in @r_major.@r_minor.@r_patch. On success these
337     variables contain the GPG version which is installed. */     variables contain the GPG version which is installed. */
338  int  int
339  check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)  check_gnupg_engine (const char *need_gpg_ver,
340                        int *r_major, int *r_minor, int *r_patch)
341  {  {
342      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
343      gpgme_engine_info_t inf;      gpgme_engine_info_t inf;
344      char * eng = NULL;      char *eng = NULL;
345      int major=0, minor=0, patch=0;      int major=0, minor=0, patch=0;
346      int rc;      int need_major = 0, need_minor = 0, need_patch = 0;
347                int rc = 1;
348    
349        /* Convert the needed GPG version to the integer format. */
350        if (parse_version_nr (need_gpg_ver,
351                              &need_major, &need_minor, &need_patch))
352            return 1;
353        
354      gpgme_new (&ctx);      gpgme_new (&ctx);
355      inf = gpgme_ctx_get_engine_info (ctx);      inf = gpgme_ctx_get_engine_info (ctx);
356      if (!inf) {      if (!inf) {
357          gpgme_release (ctx);          gpgme_release (ctx);
358          return -1;          return -1;
359      }      }
360    
361      /* We need to exec GPG again to find out if IDEA is available. */      /* We need to exec GPG again to find out if IDEA is available. */
362      if (gpg_get_version (&eng))      if (gpg_get_version (&eng))
363          return -1;          return -1;
364      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
365          idea_available = 1;          idea_available = 1;
366      free (eng);      safe_free (eng);
367      rc = parse_version_nr( inf->version, &major, &minor, &patch );      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
     if( rc ) {  
368          gpgme_release (ctx);          gpgme_release (ctx);
369          return rc;          return 1;
370      }      }
371        gpgme_release (ctx);
372    
373      /* FIXME: This check is wrong! */      if (major > need_major)
     if (major < *r_major || minor < *r_minor)  
         rc = 1;  
     else {  
         if (patch < *r_patch)  
             rc = 1;  
374          rc = 0;          rc = 0;
375      }      else if (major == need_major && minor > need_minor)      
376            rc = 0;
377        else if (major == need_major && minor == need_minor &&
378                 patch >= need_patch)
379            rc = 0;
380    
381        /* Return the current GPG version. */
382      *r_major = major;      *r_major = major;
383      *r_minor = minor;      *r_minor = minor;
384      *r_patch = patch;      *r_patch = patch;
# Line 379  check_gnupg_cfgfile (const char *fname, Line 391  check_gnupg_cfgfile (const char *fname,
391  {  {
392      gpg_optfile_t opt;          gpg_optfile_t opt;    
393      gpg_option_t e;      gpg_option_t e;
     int rc = 0;  
394    
395      *r_secrings = 0;      *r_secrings = 0;
396      *r_pubrings = 0;      *r_pubrings = 0;
397      rc = parse_gpg_options( fname, &opt );      if (parse_gpg_options (fname, &opt))
     if( rc )  
398          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
399    
400      for( e = opt->list; e; e = e->next ) {      for (e = opt->list; e; e = e->next) {
401          if( !strcmp( e->name, "secret-keyring" ) ) {          if (!strcmp( e->name, "secret-keyring")) {
402              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
403                  r_secrings[0]++;                  r_secrings[0]++;
404          }          }
405          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
406              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
407                  r_pubrings[0]++;                  r_pubrings[0]++;
408          }          }
409      }      }
410      release_gpg_options( opt );      release_gpg_options (opt);
411      return 0;      return 0;
412  } /* check_gnupg_cfgfile */  }
413    
414    
415  /*  /* Usually GPG creates the pubring.gpg, secring.gpg on
416   * Check if both keyrings are located in the gnupg home directory.     the first start, but to make sure they always exist
417   */     create them empty if needed. */
418    static void
419    create_empty_keyring (int _pub)
420    {
421        char *name;
422        FILE *fp;
423    
424        name = get_gnupg_keyring (_pub, 0);
425        if (name && file_exist_check (name) != 0) {
426            fp = fopen (name, "ab");
427            if (fp != NULL)
428                fclose (fp);
429        }
430        free_if_alloc (name);
431    }
432    
433    
434    /* Check if both keyrings are located in the gnupg home directory. */
435  int  int
436  gnupg_access_files (void)  gnupg_access_files (void)
437  {  {
# Line 413  gnupg_access_files (void) Line 440  gnupg_access_files (void)
440      int secrings = 0, pubrings = 0;      int secrings = 0, pubrings = 0;
441      char *optfile;      char *optfile;
442    
443        create_empty_keyring (1);
444      if (gnupg_access_keyring (1))      if (gnupg_access_keyring (1))
445          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
446      else      else
447          pubring_ok = 1;          pubring_ok = 1;
448    
449        create_empty_keyring (0);
450      if (gnupg_access_keyring (0))      if (gnupg_access_keyring (0))
451          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
452      else      else
453          secring_ok = 1;          secring_ok = 1;
454    
455      if (!pubring_ok || !secring_ok) {      if (!pubring_ok || !secring_ok) {
456          optfile = get_gnupg_cfgfile ();          optfile = get_gnupg_cfgfile ();
457          if (!optfile)          if (!optfile)
458              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
459          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
460          if (!rc && get_file_size(optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
461              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);
462              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
463                  free_if_alloc (optfile);                  free_if_alloc (optfile);
464                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
465              }              }
# Line 445  gnupg_access_files (void) Line 475  gnupg_access_files (void)
475          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
476      }      }
477      return rc;      return rc;
478  } /* gnupg_access_files */  }
479    
480    
481  static int  static int
# Line 454  create_gpg_options (void) Line 484  create_gpg_options (void)
484      FILE *fp;      FILE *fp;
485      char *s, *optfile;      char *s, *optfile;
486    
487      s = get_gnupg_path( );      s = get_gnupg_path ();
488      if( s == NULL )      if (!s)
489          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
490      optfile = make_filename( s, GPG_CONF, NULL );      optfile = make_filename (s, GPG_CONF, NULL);
491      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
492      if( fp == NULL ) {        if (!fp) {
493          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
494          goto fail;          goto fail;
495      }      }
496      fwrite( options_skel, 1, strlen( options_skel ), fp );      fwrite (options_skel, 1, strlen (options_skel), fp);
497      fclose( fp );      fclose (fp);
498    
499  fail:  fail:
500      free_if_alloc( s );      free_if_alloc (s);
501      free_if_alloc( optfile );      free_if_alloc (optfile);
502      return 0;      return 0;
503  } /* create_gpg_options */  }
504    
505    
506  /*  /* Return the contents of the options file as a char buf. */
507   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
508  get_gnupg_config (void)  get_gnupg_config (void)
509  {  {
510      FILE * fp;      FILE *fp;
511      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
512      int fsize, rc = 0;      int fsize, rc = 0;
513                    
514      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
515      if( optfile == NULL )      if (optfile == NULL)
516          return NULL;          return NULL;
517      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
518      if( !fsize ) {      if (!fsize) {
519          rc = create_gpg_options( );          rc = create_gpg_options ();
520          if ( rc )          if (rc)
521              return NULL;              return NULL;
522          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
523      }      }
524      if( fsize > 100000 )      if (fsize > 100000)
525          goto leave; /* too large */          goto leave; /* too large */
526      p = new char[fsize+1];      p = new char[fsize+1];
527      if( p == NULL )      if (!p)
528          BUG( NULL );          BUG (NULL);
529      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
530      if( fp == NULL ) {      if (!fp) {
531          free_if_alloc( p );          free_if_alloc (p);
532          return NULL;          return NULL;
533      }      }
534      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
535      fclose( fp );      fclose (fp);
536      p[fsize] = '\0';      p[fsize] = '\0';
537      free_if_alloc( optfile );      free_if_alloc (optfile);
538    
539  leave:  leave:
540      return p;      return p;
541  } /* get_gnupg_config */  }
542    
543    
544    /* Set the default key in the gpg.conf.
545       If @key is NULL, the entry will be deleted. */
546  int  int
547  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
548  {  {
549      gpg_optfile_t opt;      gpg_optfile_t opt;
550      gpg_option_t e;      gpg_option_t e;
# Line 523  set_gnupg_default_key (const char * key) Line 553  set_gnupg_default_key (const char * key)
553    
554      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
555      if (!optfile)      if (!optfile)
556          return -1;          return WPTERR_FILE_OPEN;
557      rc = parse_gpg_options (optfile, &opt);      rc = parse_gpg_options (optfile, &opt);
558      if( rc ) {      if (rc) {
559          free_if_alloc (optfile);          free_if_alloc (optfile);
560          return -1;          return WPTERR_GENERAL;
561      }      }
562      e = find_option (opt, "default-key");      e = find_option (opt, "default-key");
563      if (e) {      if (e && !key)
564            e->used = 0;
565        else if (e) {
566          free_if_alloc (e->val);          free_if_alloc (e->val);
567          e->val = m_strdup (key);          e->val = m_strdup (key);
568          e->used = 1;          e->used = 1;
569      }      }
570      else      else if (key)
571          add_entry (opt, ENTRY_MULTI, "default-key", key);          add_entry (opt, ENTRY_MULTI, "default-key", key);
572      rc = commit_gpg_options (optfile, opt);      rc = commit_gpg_options (optfile, opt);
573    
# Line 543  set_gnupg_default_key (const char * key) Line 575  set_gnupg_default_key (const char * key)
575      release_gpg_options (opt);      release_gpg_options (opt);
576    
577      return rc;      return rc;
578  } /* set_gnupg_default_key */  }
579    
580    
581  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
582  int  int
583  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options( const char *buf, size_t buflen )
584  {  {
# Line 625  get_last_gnupg_access (gpg_watcher_s *ct Line 655  get_last_gnupg_access (gpg_watcher_s *ct
655    
656      path = get_gnupg_path ();      path = get_gnupg_path ();
657      file =  make_filename (path, ctx->object, NULL);      file =  make_filename (path, ctx->object, NULL);
658      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,
659                         OPEN_ALWAYS, 0, NULL);
660      if (fd == INVALID_HANDLE_VALUE) {      if (fd == INVALID_HANDLE_VALUE) {
661          free_if_alloc (path);          free_if_alloc (path);
662          free_if_alloc (file);          free_if_alloc (file);
# Line 648  check_last_gnupg_access (gpg_watcher_s * Line 679  check_last_gnupg_access (gpg_watcher_s *
679      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
680          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
681          ctx->modified = 1;          ctx->modified = 1;
682        
683        /* XXX: find a better way. without it, winpt --keymanager loads
684                the key cache twice. */
685        if (ctx->last_access.dwLowDateTime == 0)
686            ctx->modified = 0;
687    
688      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
689      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
# Line 754  get_gnupg_keyring_from_options (const ch Line 790  get_gnupg_keyring_from_options (const ch
790    
791  /* XXX: does not work with write-protected floppies */  /* XXX: does not work with write-protected floppies */
792  static int  static int
793  my_access (const char * fname)  my_access (const char *fname)
794  {  {
795      HANDLE hd;      HANDLE hd;
796      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
# Line 766  my_access (const char * fname) Line 802  my_access (const char * fname)
802  }  }
803    
804    
805    /* Check the file permissions of the public keyring.
806       If @showmsg is 1 output a message in case of errors.
807       Return value: 1 if read-only attribute
808                     2 if file is opened by another process exclusively. */
809  int  int
810  gpg_check_permissions (int showmsg)  gpg_check_permissions (int showmsg)
811  {  {
812      char * p, * name = NULL;      char *p = NULL;
813        char *name = NULL;
814      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
815    
816      p = get_gnupg_path ();      p = get_gnupg_path ();
817      check_keyring (&p);      if (p && check_keyring (&p)) {
     if (p) {  
818          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
         free_if_alloc (p);  
819          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
820              ans = msg_box (NULL,              ans = msg_box (NULL,
821                             _("The selected keyring has the read-only file\n"                             _("The selected keyring has the read-only file\n"
# Line 792  gpg_check_permissions (int showmsg) Line 831  gpg_check_permissions (int showmsg)
831                  }                  }
832              }              }
833              else if (ans == IDNO) {              else if (ans == IDNO) {
834                  /*                  /* All commands with write access will be disabled. */
                 msg_box (NULL, _("All commands with write access to the keyring\n"  
                                  "will be disabled."), _("GPG Information"), MB_INFO);  
                 */  
835                  failed = 1;                  failed = 1;
836              }              }
837          }          }
# Line 811  gpg_check_permissions (int showmsg) Line 847  gpg_check_permissions (int showmsg)
847              failed = 2;              failed = 2;
848          }          }
849      }      }
850        free_if_alloc (p);
851      free_if_alloc (name);      free_if_alloc (name);
852      return failed;      return failed;
853  } /* gpg_check_permissions */  }
854    
855    
856  /* Check the GPG home dir. If all methods failed, try to  /* Check the GPG home dir. First try to read the 'HomeDir' registry entry,
857     create the default folder. */     then check for $APPDATA\gnupg. Create the dir if it does not exists. */
858  static int  int
859  check_homedir (void)  gnupg_check_homedir (void)
860  {        {      
861      char *homedir = NULL;      char *homedir = NULL;
862      int yes = 0;      int val = 0;
863        int rc = 0;
864    
865      homedir = get_reg_entry_gpg ("HomeDir");      homedir = get_reg_entry_gpg (GPG_REG_HOME);
     if (!homedir)  
         homedir = multi_gnupg_path ();  
866      if (!homedir)      if (!homedir)
867          homedir = m_strdup ("c:\\gnupg");          homedir = multi_gnupg_path (0);
868      if (homedir) {      if (homedir) {
869          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
870              yes = log_box (_("Preferences"), MB_YESNO,              val = log_box (_("Preferences"), MB_YESNO,
871                             _("%s does not exit.\n"                             _("%s does not exit.\n"
872                               "Do you want to create this directory?"), homedir);                               "Do you want to create this directory?"), homedir);
873              if (yes == IDYES) {              if (val == IDYES) {
874                  BOOL ec = CreateDirectory (homedir, NULL);                  if (!CreateDirectory (homedir, NULL))
875                  free_if_alloc (homedir);                      rc = WPTERR_DIR_CREAT;
                 if (ec == FALSE)  
                     return WPTERR_DIR_CREAT;  
                 return 0;  
876              }              }
877              return WPTERR_DIR_OPEN;              else
878          }                  rc = WPTERR_DIR_OPEN;
         free_if_alloc (homedir);  
     }  
     return 0;  
 }  
   
   
 int  
 gnupg_check_homedir (void)  
 {        
     char *homedir = NULL;  
     char *prog = NULL;  
     int rc = 0, ec = 0;  
       
     rc = check_homedir ();  
     if (rc)  
         return rc;  
     if ((homedir = get_reg_entry_gpg ("HomeDir")) &&  
         !(prog = get_reg_entry_gpg ("gpgProgram" ))) {  
         prog = make_filename (homedir, "gpg", "exe");  
         if (file_exist_check (prog) == 0) {  
             rc = set_reg_entry_gpg ("gpgProgram", prog);  
             if (rc)  
                 goto fail;  
879          }          }
880          free_if_alloc (homedir);          free_if_alloc (homedir);
         free_if_alloc (prog);  
         return rc;  
     }  
     if ((prog = get_reg_entry_gpg ("gpgProgram"))  
         && file_exist_check (prog)) {  
         free_if_alloc (prog);  
         homedir = get_reg_entry_gpg ("HomeDir");  
         if (!homedir) {  
             rc = WPTERR_GENERAL;  
             goto fail;  
         }  
         prog = make_filename (homedir, "gpg", "exe");  
         if (file_exist_check (prog) == 0) {  
             rc = set_reg_entry_gpg ("gpgProgram", prog);  
             if (rc)  
                 goto fail;  
             free_if_alloc (prog);  
             return rc;  
         }  
881      }      }
       
     /* Change the return code if homedir doesn't exist or if the program  
        doesn't exist. Note that exist_checks return 0 to suggest existance. */  
     if ((!homedir || dir_exist_check (homedir)))  
         rc = WPTERR_GENERAL;  
       
 fail:  
     free_if_alloc (homedir);  
     free_if_alloc (prog);  
882      return rc;      return rc;
883  } /* gnupg_check_homedir */  }
884    
885    
886  int  int
# Line 914  gnupg_copy_keyrings (void) Line 896  gnupg_copy_keyrings (void)
896          return WPTERR_GENERAL;          return WPTERR_GENERAL;
897      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
898    
899      pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
900                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
901      if (!pring) {      if (!pring) {
902          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
903                     _("WinPT Error"), MB_ERR);
904          free_if_alloc (path);          free_if_alloc (path);
905          return WPTERR_GENERAL;          return WPTERR_GENERAL;
906      }      }
907      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
908      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
909          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
910                          "WinPT", MB_INFO|MB_YESNO);
911          if (id == IDNO)          if (id == IDNO)
912              goto fail;              goto fail;
913      }      }
# Line 934  gnupg_copy_keyrings (void) Line 918  gnupg_copy_keyrings (void)
918      }      }
919      free_if_alloc (file);      free_if_alloc (file);
920    
921      sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
922                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
923      if (!sring) {      if (!sring) {
924          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
925                     _("WinPT Error"), MB_ERR);
926          return WPTERR_GENERAL;          return WPTERR_GENERAL;
927      }      }
928      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
929      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
930          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
931          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
932            if (id == IDNO)
933              goto fail;              goto fail;
934      }      }
935      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
936          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
937          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
938      }      }
939    
# Line 955  fail: Line 941  fail:
941      free_if_alloc (file);      free_if_alloc (file);
942      free_if_alloc (path);      free_if_alloc (path);
943      return rc;      return rc;
944  } /* gnupg_import_keyrings */  }
945    
946    
947    /* Backup the gpg.conf file. */
948  void  void
949  gnupg_backup_options (void)  gnupg_backup_options (void)
950  {  {
# Line 965  gnupg_backup_options (void) Line 952  gnupg_backup_options (void)
952      char bak[512];      char bak[512];
953    
954      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
955      if (cfgfile == NULL)      if (!cfgfile)
956          return;          return;
957      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);
958      CopyFile (cfgfile, bak, FALSE);      CopyFile (cfgfile, bak, FALSE);
959      free_if_alloc (cfgfile);      free_if_alloc (cfgfile);
960  } /* gnupg_backup_options */  }
   
961    
962    
963  static int  static int
964  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
965                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
966  {  {
967      char * src, * dst;      char *src, *dst;
968      BOOL rc;      BOOL rc;
969    
970      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
# Line 990  backup_one_file (const char *srcpath, co Line 976  backup_one_file (const char *srcpath, co
976      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
977      free_if_alloc (src);      free_if_alloc (src);
978      free_if_alloc (dst);      free_if_alloc (dst);
979      if (!rc)      if (!rc) {
     {  
980          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
981          return WPTERR_GENERAL;          return WPTERR_GENERAL;
982      }      }
983      return 0;      return 0;
984  } /* backup_one_file */  }
985    
986    
987    /* Figure out first public keyring which is not empty.
988       Return value: 1 on success. */
989  static int  static int
990  check_keyring (char ** r_path)  check_keyring (char **r_path)
991  {  {
992      char * p;      char *p;
993      char * opt, * name;      char *opt;
994        char *name;
995    
996      if (!*r_path)      if (!*r_path)
997          return 0;          return 0;
998      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
999      if (!p || get_file_size (p) > 0)      if (!p || get_file_size (p) <= 0)
1000          return 0;          return 0;
1001    
1002      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
# Line 1020  check_keyring (char ** r_path) Line 1008  check_keyring (char ** r_path)
1008      if (!name)      if (!name)
1009          return 0;          return 0;
1010      p = strrchr (name, '\\');      p = strrchr (name, '\\');
1011      if (!p)      if (!p) {
     {  
1012          free_if_alloc (name);          free_if_alloc (name);
1013          return 0;                return 0;      
1014      }      }
# Line 1034  check_keyring (char ** r_path) Line 1021  check_keyring (char ** r_path)
1021  }  }
1022    
1023    
1024    /* Return a temp name based on the day of the week. */
1025  static char*  static char*
1026  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1027  {  {
1028      struct tm *tm;      struct tm *tm;
1029      char *p;      char *p;
1030        time_t t;
1031    
1032      time_t t = time (NULL);      t = time (NULL);
1033      tm = localtime (&t);      tm = localtime (&t);
1034      p = new char [strlen (templ) + 8 + 1];      p = new char [strlen (templ) + 8 + 1];
1035      if (!p)      if (!p)
# Line 1050  get_backup_name (const char *templ) Line 1039  get_backup_name (const char *templ)
1039  }  }
1040    
1041    
1042    /* Make backups of all keyrings. The public key ring is
1043       rotated like this pubring-%d.gpg. */
1044  void  void
1045  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode)
1046  {  {
1047      char *srcpath = NULL, *dstpath = NULL;      char *srcpath = NULL, *dstpath = NULL;
1048      char *name=NULL;      char *name=NULL;
1049      int rc, bakmode=0;      int rc;
1050    
1051      if (!reg_prefs.auto_backup)      if (!auto_backup)
1052          return;          return;
1053      bakmode = reg_prefs.backup.mode;      srcpath = get_gnupg_path ();
     srcpath =  get_gnupg_path ();  
1054      check_keyring (&srcpath);      check_keyring (&srcpath);
1055      if (bakmode == 1) {      if (backup_mode == 1) {
1056          dstpath = get_gnupg_path ();          dstpath = multi_gnupg_path (1);
1057          check_keyring (&dstpath);          check_keyring (&dstpath);
1058      }      }
1059      else if (bakmode == 2) {      else if (backup_mode == 2) {
1060          char * tmpfile;          char *tmpfile;
1061          FILE * fp;          FILE *fp;
1062    
1063          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
1064          if (!dstpath)          if (!dstpath)
# Line 1082  gnupg_backup_keyrings (void) Line 1072  gnupg_backup_keyrings (void)
1072          else {          else {
1073              rc = 0;              rc = 0;
1074              fclose (fp);              fclose (fp);
1075              unlink (tmpfile);              remove (tmpfile);
1076          }          }
1077          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1078          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL)
1079              return;              return;
1080      }      }
1081      else {      else {
1082          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1083          return;          return;
1084      }      }
1085      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
# Line 1099  gnupg_backup_keyrings (void) Line 1089  gnupg_backup_keyrings (void)
1089      free_if_alloc (name);      free_if_alloc (name);
1090      free_if_alloc (srcpath);      free_if_alloc (srcpath);
1091      free_if_alloc (dstpath);      free_if_alloc (dstpath);
1092  } /* gnupg_backup_keyrings */  }
1093    
1094    
1095  /* Display GPG error from file if possible. */  /* Display GPG error from file if possible. */
1096  void  void
1097  gnupg_display_error (void)  gnupg_display_error (void)
1098  {        {      
1099      char tmpath[512], * errstr;      char tmpath[512], *errstr;
1100      size_t size = 0;      size_t size = 0;
1101      FILE * fp;      FILE *fp;
1102    
1103      GetTempPath (sizeof tmpath - 32, (tmpath));      get_temp_name (tmpath, sizeof (tmpath), "gpg_stderr");
     strcat (tmpath, "gpg_stderr");  
1104      size = get_file_size (tmpath);      size = get_file_size (tmpath);
1105      if (file_exist_check (tmpath) || size <= 0)      if (file_exist_check (tmpath) || size <= 0)
1106          return;          return;
1107      fp = fopen( tmpath, "rb" );      fp = fopen( tmpath, "rb" );
1108      if (!fp) {      if (!fp) {
1109          msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );          msg_box (NULL, _("No GPG error description available."),
1110                     _("GPG Error"), MB_INFO);
1111          return;          return;
1112      }      }
1113      errstr = new char[size+1];      errstr = new char[size+1];

Legend:
Removed from v.66  
changed lines
  Added in v.200

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26