/[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 74 by twoaday, Tue Nov 8 07:23:16 2005 UTC revision 255 by twoaday, Tue Aug 1 16:37:23 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 43  Line 43 
43  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  /* Context to monitor GPG file changes. */
47      FILETIME    last_access;  struct gpg_monitor_s {
48        FILETIME    last_access;    /* last write access. */
49      FILETIME    access;      FILETIME    access;
50      char        *object;      char        *object;        /* name of the object. */
51      int         modified;      char        *fpath_object;  /* full path to the object. */
52        int         modified;       /* 1 = modified. */
53  };  };
54    typedef struct gpg_monitor_s *gpg_monitor_t;
55    
56    static const char *gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
57  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */  static gpg_monitor_s gpg_table[3];
 static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};  
 static gpg_watcher_s gpg_table[3];  
58  static int gpg_table_count = DIM (gpg_table);  static int gpg_table_count = DIM (gpg_table);
59    
60  int idea_available = 0;  int idea_available = 0; /* if the IDEA extension is available. */
61    
62    
63  static int check_keyring (char ** r_path);  static int check_keyring (char ** r_path);
64    
65    
66  /* Return the application data folder of the current user. */  /* Return the application data folder of the current user. */
67  static char*  char*
68  multi_gnupg_path (int strict)  multi_gnupg_path (int strict)
69  {  {
70      static char buf[256+64];      static char buf[256+64];
# Line 84  multi_gnupg_path (int strict) Line 86  multi_gnupg_path (int strict)
86  }  }
87    
88    
89  /* 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
90     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. */
 */  
91  char*  char*
92  get_gnupg_path (void)  get_gnupg_path (void)
93  {  {
94      char *p = NULL;      char *path;
95      char *path = NULL;  
96            path = get_reg_entry_gpg (GPG_REG_HOME);
97      p = get_reg_entry_gpg (GPG_REG_HOME);      if (path && dir_exist_check (path) == 0)
     if (p) {  
         path = m_strdup (p);  
         free_if_alloc (p);  
98          return path;          return path;
99      }      free_if_alloc (path);
100      else      path = multi_gnupg_path (1);
101          return multi_gnupg_path (1);      return path;
     return m_strdup ("c:\\gnupg");  
102  }  }
103    
104    
# Line 109  get_gnupg_path (void) Line 106  get_gnupg_path (void)
106     A value of NULL indicates an error. */     A value of NULL indicates an error. */
107  char*  char*
108  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
109  {      {
     char *p = NULL;  
110      char *optfile = NULL;      char *optfile = NULL;
111      char *path = NULL;      char *path = NULL;
112      size_t nlen = 0;      size_t nlen = 0;
# Line 118  get_gnupg_cfgfile (void) Line 114  get_gnupg_cfgfile (void)
114      path = get_gnupg_path ();      path = get_gnupg_path ();
115      if (!path)      if (!path)
116          return NULL;          return NULL;
117      p = get_reg_entry_gpg ("OptFile");      nlen = strlen (path) + 64;
118      if (p && !strcmp (p, "")) {      optfile = new char[nlen + 1];
119          nlen = strlen (path) + 64;      if (!optfile)
120          optfile = new char[nlen + 1];          BUG (NULL);    
121          if (!optfile)      _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
122              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);  
     }  
123      free_if_alloc (path);      free_if_alloc (path);
     free_if_alloc (p);  
124      return optfile;      return optfile;
125  }  }
126    
# Line 159  get_gnupg_keyring (int pub, int strict) Line 138  get_gnupg_keyring (int pub, int strict)
138      if (!path)      if (!path)
139          return NULL;          return NULL;
140      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
141      if (!strict && !file_exist_check (keyring)) {      if (strict && !file_exist_check (keyring)) {
142            free_if_alloc (path);
143            return keyring;
144        }
145        else if (!strict) {
146          free_if_alloc (path);          free_if_alloc (path);
147          return keyring;          return keyring;
148      }      }
# Line 177  get_gnupg_keyring (int pub, int strict) Line 160  get_gnupg_keyring (int pub, int strict)
160  /* Return the full path (with the gpg exe name). First the registry is scanned  /* Return the full path (with the gpg exe name). First the registry is scanned
161     for the entry 'gpgProgram'. If it wasn't set, the default path is the     for the entry 'gpgProgram'. If it wasn't set, the default path is the
162     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
163  char*  char*
164  get_gnupg_prog (void)  get_gnupg_prog (void)
165  {      {    
166      char *p;      char *path;
167      char *pgm = NULL;      char *pgm;
168    
169      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
170      if (!p) {      if (pgm)
171          char *path = get_gnupg_path ();          return pgm;
172          if (!path)      path = get_gnupg_path ();
173              return NULL;      if (!path)
174          pgm = make_filename (path, "gpg", "exe");          return NULL;    
175          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
176      }      free_if_alloc (path);    
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
177      return pgm;      return pgm;
178  }  }
179    
# Line 204  get_gnupg_prog (void) Line 181  get_gnupg_prog (void)
181  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
182     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
183     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
184  static char *  static char*
185  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
186  {  {    
187        gpgme_key_t key, pk;
188        gpg_keycache_t sec, pub;
189      const char *s;      const char *s;
190      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
191    
192      if (!sec)      sec = keycache_get_ctx (0);
193          BUG (0);      pub = keycache_get_ctx (1);
194      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
195      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
196          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
197              s = key->subkeys->keyid;              s = key->subkeys->keyid;
198              if (s)                  if (s)
199                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
200              break;              break;
201          }          }
202      }      }
# Line 234  default_key_from_cache (int *ret_no_usea Line 211  default_key_from_cache (int *ret_no_usea
211     Return value: 0 on success. */     Return value: 0 on success. */
212  int  int
213  gnupg_load_config (void)  gnupg_load_config (void)
214  {  {    
     int rc;  
215      gpg_optfile_t opt;      gpg_optfile_t opt;
216      gpg_option_t o;      gpg_option_t o;
217      char *conf = get_gnupg_cfgfile ();      char *conf;
218        
219        conf = get_gnupg_cfgfile ();
220      if (!conf)      if (!conf)
221          return -1;          return -1;
222      rc = parse_gpg_options (conf, &opt);      if (parse_gpg_options (conf, &opt)) {
     if (rc) {  
223          free_if_alloc (conf);          free_if_alloc (conf);
224          return -1;          return -1;
225      }      }
226      o = find_option (opt, "ask-cert-level");      o = find_option (opt, "ask-cert-level");
227      if (o)      if (o)
228          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
229        o = find_option (opt, "ask-cert-expire");
230        if (o)
231            reg_prefs.gpg.ask_cert_expire = 1;
232      release_gpg_options (opt);      release_gpg_options (opt);
233      free_if_alloc (conf);      free_if_alloc (conf);
234      return 0;      return 0;
235  }  }
236    
237    
238    /* handle the case the user added a '!' to force a subkey. */
239    static char*
240    extract_keyid (const char *val)
241    {    
242        size_t len = strlen (val);
243    
244        if (len > 1 && val[len-1] == '!') {
245            char *p = new char[len+1];
246            if (!p)
247                BUG (0);
248            memset (p, 0, len+1);
249            memcpy (p, val, len-1);
250            return p;
251        }
252        return m_strdup (val);
253    }
254    
255    
256  char*  char*
257  get_gnupg_default_key (void)  get_gnupg_default_key (void)
258  {      {    
259      gpg_optfile_t opt = NULL;      gpg_optfile_t opt = NULL;
260      gpg_option_t e;      gpg_option_t e;
261      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
262      int no_usable=0, rc = 0;      int no_usable=0;
263    
264      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
265      if (!optfile)      if (!optfile)
266          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
267      rc = parse_gpg_options (optfile, &opt);      if (parse_gpg_options (optfile, &opt)) {
     if (rc) {  
268          free_if_alloc (optfile);          free_if_alloc (optfile);
269          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
270      }      }
271      e = find_option( opt, "default-key" );      e = find_option (opt, "default-key");
272      if ( e )      if (!e)
273          keyid = m_strdup( e->val );          e = find_option (opt, "local-user");
274      if( !e ) {      if (e)
275          e = find_option( opt, "local-user" );          keyid = extract_keyid (e->val);
276          if( e )  
             keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
277      free_if_alloc (optfile);      free_if_alloc (optfile);
278      release_gpg_options (opt);      release_gpg_options (opt);
   
279      if (!keyid)      if (!keyid)
280          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
281      return keyid;      return keyid;
282  } /* get_gnupg_default_key */  }
   
283    
 char* get_reg_entry_gpg4win (const char *path);  
284    
285  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
286     install path to figure out where the gpg.exe is. */     install path to figure out where the gpg.exe is. */
# Line 326  check_gnupg_prog (void) Line 313  check_gnupg_prog (void)
313    
314    
315  static int  static int
316  parse_version_nr (const char * buf, int *major, int *minor, int *patch)  parse_version_nr (const char *buf, int *major, int *minor, int *patch)
317  {  {
318      char tmp[8];      char tmp[8];
319      int i;      int i;
# Line 335  parse_version_nr (const char * buf, int Line 322  parse_version_nr (const char * buf, int
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      *major = atol( tmp );      *major = atoi (tmp);
326      i=0;      i=0;
327      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
328          tmp[i++] = *buf++;          tmp[i++] = *buf++;
329      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
330      *minor = atol (tmp);      *minor = atoi (tmp);
331      i=0;      i=0;
332      while (buf && isdigit( *buf ) && i < 8)      while (buf && isdigit (*buf) && i < 8)
333          tmp[i++] = *buf++;          tmp[i++] = *buf++;
334      tmp[i] = 0;      tmp[i] = 0;
335      *patch = atol (tmp);      *patch = atoi (tmp);
336      return 0;      return 0;
337  }  }
338    
# Line 354  parse_version_nr (const char * buf, int Line 341  parse_version_nr (const char * buf, int
341     version given in @r_major.@r_minor.@r_patch. On success these     version given in @r_major.@r_minor.@r_patch. On success these
342     variables contain the GPG version which is installed. */     variables contain the GPG version which is installed. */
343  int  int
344  check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)  check_gnupg_engine (const char *need_gpg_ver,
345                        int *r_major, int *r_minor, int *r_patch)
346  {  {
347      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
348      gpgme_engine_info_t inf;      gpgme_engine_info_t inf;
349      char * eng = NULL;      char *eng = NULL;
350      int major=0, minor=0, patch=0;      int major=0, minor=0, patch=0;
351      int rc;      int need_major = 0, need_minor = 0, need_patch = 0;
352                int rc = 1;
353    
354        /* Convert the needed GPG version to the integer format. */
355        if (parse_version_nr (need_gpg_ver,
356                              &need_major, &need_minor, &need_patch))
357            return 1;
358        
359      gpgme_new (&ctx);      gpgme_new (&ctx);
360      inf = gpgme_ctx_get_engine_info (ctx);      inf = gpgme_ctx_get_engine_info (ctx);
361      if (!inf) {      if (!inf) {
362          gpgme_release (ctx);          gpgme_release (ctx);
363          return -1;          return -1;
364      }      }
365    
366      /* 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. */
367      if (gpg_get_version (&eng))      if (gpg_get_version (&eng)) {
368            gpgme_release (ctx);
369          return -1;          return -1;
370        }
371      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
372          idea_available = 1;          idea_available = 1;
373      free (eng);      safe_free (eng);
374      rc = parse_version_nr( inf->version, &major, &minor, &patch );      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
     if( rc ) {  
375          gpgme_release (ctx);          gpgme_release (ctx);
376          return rc;          return 1;
377      }      }
378      /* FIXME: This check is wrong! */      gpgme_release (ctx);
379      if (major < *r_major || minor < *r_minor)  
380          rc = 1;      if (major > need_major)
     else {  
         if (patch < *r_patch)  
             rc = 1;  
381          rc = 0;          rc = 0;
382      }      else if (major == need_major && minor > need_minor)      
383            rc = 0;
384        else if (major == need_major && minor == need_minor &&
385                 patch >= need_patch)
386            rc = 0;
387    
388        /* Return the current GPG version. */
389      *r_major = major;      *r_major = major;
390      *r_minor = minor;      *r_minor = minor;
391      *r_patch = patch;      *r_patch = patch;
# Line 394  check_gnupg_engine (int *r_major, int *r Line 393  check_gnupg_engine (int *r_major, int *r
393  }  }
394    
395    
396  int  /* Count the keyring entries in the gpg.conf file.
397  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
398    static int
399    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
400  {  {
401      gpg_optfile_t opt;          gpg_optfile_t opt;    
402      gpg_option_t e;      gpg_option_t e;
     int rc = 0;  
403    
404      *r_secrings = 0;      *r_secrings = 0;
405      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
406    
407      for( e = opt->list; e; e = e->next ) {      if (parse_gpg_options (fname, &opt))
408          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
409              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
410            if (!strcmp( e->name, "secret-keyring")) {
411                if (!file_exist_check (e->val))
412                  r_secrings[0]++;                  r_secrings[0]++;
413          }          }
414          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
415              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
416                  r_pubrings[0]++;                  r_pubrings[0]++;
417          }          }
418      }      }
419      release_gpg_options( opt );      release_gpg_options (opt);
420      return 0;      return 0;
421  } /* check_gnupg_cfgfile */  }
422    
423    
424  /*  /* Usually GPG creates the pubring.gpg, secring.gpg on
425   * Check if both keyrings are located in the gnupg home directory.     the first start, but to make sure they always exist
426   */     create them empty if needed. */
427    static void
428    create_empty_keyring (int _pub)
429    {
430        char *name;
431        FILE *fp;
432    
433        name = get_gnupg_keyring (_pub, 0);
434        if (name && file_exist_check (name) != 0) {
435            fp = fopen (name, "ab");
436            if (fp != NULL)
437                fclose (fp);
438        }
439        free_if_alloc (name);
440    }
441    
442    
443    /* Check if both keyrings are located in the gnupg home directory. */
444  int  int
445  gnupg_access_files (void)  gnupg_access_files (void)
446  {  {
# Line 433  gnupg_access_files (void) Line 449  gnupg_access_files (void)
449      int secrings = 0, pubrings = 0;      int secrings = 0, pubrings = 0;
450      char *optfile;      char *optfile;
451    
452        create_empty_keyring (1);
453      if (gnupg_access_keyring (1))      if (gnupg_access_keyring (1))
454          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
455      else      else
456          pubring_ok = 1;          pubring_ok = 1;
457    
458        create_empty_keyring (0);
459      if (gnupg_access_keyring (0))      if (gnupg_access_keyring (0))
460          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
461      else      else
# Line 449  gnupg_access_files (void) Line 467  gnupg_access_files (void)
467              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
468          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
469          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
470              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
471              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
472                  free_if_alloc (optfile);                  free_if_alloc (optfile);
473                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
474              }              }
# Line 466  gnupg_access_files (void) Line 484  gnupg_access_files (void)
484          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
485      }      }
486      return rc;      return rc;
487  } /* gnupg_access_files */  }
488    
489    
490  static int  static int
491  create_gpg_options (void)  create_gpg_conf (void)
492  {  {
493      FILE *fp;      FILE *fp;
494      char *s, *optfile;      char *s, *optfile;
495    
496      s = get_gnupg_path ();      s = get_gnupg_path ();
497      if( s == NULL )      if (!s)
498          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
499      optfile = make_filename (s, GPG_CONF, NULL);      optfile = make_filename (s, GPG_CONF, NULL);
500      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
501      if( fp == NULL ) {        if (!fp) {
502          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
503          goto fail;          goto fail;
504      }      }
505      fwrite( options_skel, 1, strlen( options_skel ), fp );      fwrite (options_skel, 1, strlen (options_skel), fp);
506      fclose( fp );      fclose (fp);
507    
508  fail:  fail:
509      free_if_alloc( s );      free_if_alloc (s);
510      free_if_alloc( optfile );      free_if_alloc (optfile);
511      return 0;      return 0;
512  } /* create_gpg_options */  }
513    
514    
515  /*  /* Return the contents of the options file as a char buf. */
516   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
517  get_gnupg_config (void)  get_gnupg_config (void)
518  {  {
519      FILE * fp;      FILE *fp;
520      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
521      int fsize, rc = 0;      int fsize;
522                    
523      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
524      if( optfile == NULL )      if (!optfile)
525          return NULL;          return NULL;
526      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
527      if( !fsize ) {      if (!fsize) {
528          rc = create_gpg_options( );          if (create_gpg_conf ())
         if ( rc )  
529              return NULL;              return NULL;
530          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
531      }      }
532      if( fsize > 100000 )      if (fsize > 100000)
533          goto leave; /* too large */          goto leave; /* too large */
534      p = new char[fsize+1];      p = new char[fsize+1];
535      if( p == NULL )      if (!p)
536          BUG( NULL );          BUG (NULL);
537      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
538      if( fp == NULL ) {      if (!fp) {
539          free_if_alloc( p );          free_if_alloc (p);
540          return NULL;          return NULL;
541      }      }
542      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
543      fclose( fp );      fclose (fp);
544      p[fsize] = '\0';      p[fsize] = '\0';
545      free_if_alloc( optfile );      free_if_alloc (optfile);
546    
547  leave:  leave:
548      return p;      return p;
549  } /* get_gnupg_config */  }
550    
551    
552    /* Set the default key in the gpg.conf.
553       If @key is NULL, the entry will be deleted. */
554  int  int
555  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
556  {  {
557      gpg_optfile_t opt;      gpg_optfile_t opt;
558      gpg_option_t e;      gpg_option_t e;
# Line 544  set_gnupg_default_key (const char * key) Line 561  set_gnupg_default_key (const char * key)
561    
562      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
563      if (!optfile)      if (!optfile)
564          return -1;          return WPTERR_FILE_OPEN;
565      rc = parse_gpg_options (optfile, &opt);      rc = parse_gpg_options (optfile, &opt);
566      if( rc ) {      if (rc) {
567          free_if_alloc (optfile);          free_if_alloc (optfile);
568          return -1;          return WPTERR_GENERAL;
569      }      }
570      e = find_option (opt, "default-key");      e = find_option (opt, "default-key");
571      if (e) {      if (e && !key)
572            e->used = 0;
573        else if (e) {
574          free_if_alloc (e->val);          free_if_alloc (e->val);
575          e->val = m_strdup (key);          e->val = m_strdup (key);
576          e->used = 1;          e->used = 1;
577      }      }
578      else      else if (key)
579          add_entry (opt, ENTRY_MULTI, "default-key", key);          add_entry (opt, ENTRY_MULTI, "default-key", key);
580      rc = commit_gpg_options (optfile, opt);      rc = commit_gpg_options (optfile, opt);
581    
# Line 564  set_gnupg_default_key (const char * key) Line 583  set_gnupg_default_key (const char * key)
583      release_gpg_options (opt);      release_gpg_options (opt);
584    
585      return rc;      return rc;
586  } /* set_gnupg_default_key */  }
587    
588    
589  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
590  int  int
591  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
592  {  {
593      FILE *fp;        FILE *fp;  
594      char *optfile = NULL;      char *optfile;
595    
596      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
597      if( optfile == NULL )      if (!optfile)
598          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
599    
600      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
601      if( fp == NULL ) {      if (!fp) {
602          free_if_alloc( optfile );          free_if_alloc (optfile);
603          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
604      }      }
605      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
606      fclose( fp );      fclose (fp);
607      free_if_alloc( optfile );      free_if_alloc (optfile);
608      return 0;      return 0;
609  } /* set_gnupg_options */  }
610    
611  /*  
612   * Check if the line contains a valid GPG argument.  /* Check if the parameter for the option @buf is an existing file name.
613   */     Return value: 0 on success. */
614  static int  static int
615  check_line( const char *buf )  check_arg_file_exist (const char *buf)
616    {
617        const char *s = "load-extension ";
618    
619        /* XXX: this is a bit of a kludge because we just
620                detect errors for 'load-extension'. */
621        if (!strncmp (buf, s, strlen (s)))
622            buf += strlen (s);
623        else
624            return 0;
625        return file_exist_check (buf);
626    }
627    
628    
629    /* Check if the line contains a valid GPG argument. */
630    static int
631    check_line (const char *buf)
632  {  {
633      int j, len;      int j, len;
634      int rc = 0;      int rc;
635    
636      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
637          return 1;          return 1;
638      rc = 0;      rc = 0;
639      for ( j = 0; valid_gpg_args[j]; j++ ) {      for (j = 0; valid_gpg_args[j]; j++) {
640          len = strlen( valid_gpg_args[j] );          len = strlen (valid_gpg_args[j]);
641          if( !strncmp( valid_gpg_args[j], buf, len ) )          if (!strncmp (valid_gpg_args[j], buf, len))
642              rc = 1;                  rc = 1;
643      }      }
   
644      return rc;      return rc;
645  } /* check_line */  }
646    
647    
648  int  int
649  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf, int showerr)
650  {  {
651      char line[1024];      char line[1024];
652      int nbytes = 0;      int nbytes = 0, lineno=0;
653      unsigned j;      unsigned j;
654                    
655      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < sizeof (line); j++) {
656          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
657          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
658              line[nbytes] = '\0';              line[nbytes] = '\0';
659              if( !check_line( line ) ) {              lineno++;
660                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
661                    if (showerr)
662                        log_box ("GPG Config File", MB_ERR,
663                                 "gpg.conf:%d: invalid keyword '%s'",
664                                 lineno, line);
665                  return 1;                        return 1;      
666              }              }
667                if (check_arg_file_exist (line))
668                    return WPTERR_FILE_EXIST;
669              nbytes = 0;              nbytes = 0;
670          }                }
671      }      }
   
672      return 0;      return 0;
673  } /* check_gnupg_options */  }
674    
675    
676  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
677  static int  static int
678  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
679  {  {
680      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
681    
682      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
683      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_ALWAYS, 0, NULL);
684      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);      if (fd == INVALID_HANDLE_VALUE)
     if (fd == INVALID_HANDLE_VALUE) {  
         free_if_alloc (path);  
         free_if_alloc (file);  
685          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
686      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
687      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
688      return 0;      return 0;
689  }  }
690    
691    
692  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
693  static void  static void
694  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
695  {                {              
696      ctx->modified = 0;      ctx->modified = 0;
697    
# Line 670  check_last_gnupg_access (gpg_watcher_s * Line 699  check_last_gnupg_access (gpg_watcher_s *
699          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
700          ctx->modified = 1;          ctx->modified = 1;
701    
702        if (ctx->last_access.dwLowDateTime == 0)
703            ctx->modified = 0;
704    
705      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
706      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
707  }  }
708    
709    
710  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
711  void  void
712  init_gnupg_table (void)  init_gnupg_table (void)
713  {        {      
714      char *p;      char *path;
715      int j;      int j;
716    
717        path = get_gnupg_path ();
718      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
719          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
720          if (!p)          gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
             BUG (NULL);  
721          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
722          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
723          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
724      }      }
725        free_if_alloc (path);
726  }  }
727    
728    
729    /* Release the GPG monitor table. */
730  void  void
731  free_gnupg_table (void)  free_gnupg_table (void)
732  {  {
733      int j;      int j;
734    
735      for (j=0; j < gpg_table_count; j++)      for (j=0; j < gpg_table_count; j++) {
736          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
737            free_if_alloc (gpg_table[j].fpath_object);
738        }
739  }  }
740    
741    
742  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
743  int  int
744  keyring_check_last_access (void)  keyring_check_last_access (void)
745  {        {
746      int rc, j;      int nfiles;
747        int pos;
748    
749      rc = 0;      nfiles = 0;
750      for (j = 0; j < gpg_table_count; j++) {      for (pos = 0; pos < gpg_table_count; pos++) {
751          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
752          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
753          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
754              rc++;                    nfiles++;
755      }      }
756    
757      return rc;      return nfiles;
758  }  }
759    
760    
# Line 740  gnupg_check_file_ext (const char *fname, Line 777  gnupg_check_file_ext (const char *fname,
777              *r_type = PGP_SIG;              *r_type = PGP_SIG;
778          return "SIGNED";          return "SIGNED";
779      }      }
780      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
781                  !stricmp (file_ext, ".pgp")) {
782          if (r_type)          if (r_type)
783              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
784          return "ENCRYPTED";          return "ENCRYPTED";
# Line 750  gnupg_check_file_ext (const char *fname, Line 788  gnupg_check_file_ext (const char *fname,
788    
789    
790  char*  char*
791  get_gnupg_keyring_from_options (const char * fname, int pub)  get_gnupg_keyring_from_options (const char *fname, int pub)
792  {  {
793      gpg_optfile_t opt;      gpg_optfile_t opt;
794      gpg_option_t e;      gpg_option_t e;
795      char * kring = NULL;      char *kring = NULL;
796      int rc = 0;      int rc;
797    
798      rc = parse_gpg_options (fname, &opt);      rc = parse_gpg_options (fname, &opt);
799      if (rc)      if (rc)
# Line 772  get_gnupg_keyring_from_options (const ch Line 810  get_gnupg_keyring_from_options (const ch
810  }  }
811    
812    
813    /* Check if the device file @fname is stored on, is write-protected. */
 /* XXX: does not work with write-protected floppies */  
814  static int  static int
815  my_access (const char * fname)  my_access (const char *fname)
816  {  {
817      HANDLE hd;      HANDLE hd;
818    
819      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
820                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
821      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
# Line 787  my_access (const char * fname) Line 825  my_access (const char * fname)
825  }  }
826    
827    
828    /* Check the file permissions of the public keyring.
829       If @showmsg is 1 output a message in case of errors.
830       Return value: 1 if read-only attribute
831                     2 if file is opened by another process exclusively. */
832  int  int
833  gpg_check_permissions (int showmsg)  gpg_check_permissions (int showmsg)
834  {  {
835      char * p, * name = NULL;      char *p = NULL;
836        char *name = NULL;
837      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
838    
839      p = get_gnupg_path ();      p = get_gnupg_path ();
840      check_keyring (&p);      if (p && check_keyring (&p)) {
     if (p) {  
841          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
         free_if_alloc (p);  
842          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
843              ans = msg_box (NULL,              ans = msg_box (NULL,
844                             _("The selected keyring has the read-only file\n"                             _("The selected keyring has the read-only file\n"
# Line 813  gpg_check_permissions (int showmsg) Line 854  gpg_check_permissions (int showmsg)
854                  }                  }
855              }              }
856              else if (ans == IDNO) {              else if (ans == IDNO) {
857                  /*                  /* 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);  
                 */  
858                  failed = 1;                  failed = 1;
859              }              }
860          }          }
# Line 832  gpg_check_permissions (int showmsg) Line 870  gpg_check_permissions (int showmsg)
870              failed = 2;              failed = 2;
871          }          }
872      }      }
873        free_if_alloc (p);
874      free_if_alloc (name);      free_if_alloc (name);
875      return failed;      return failed;
876  } /* gpg_check_permissions */  }
877    
878    
879  /* Check the GPG home dir. If all methods failed, try to  /* Check the GPG home dir. First try to read the 'HomeDir' registry entry,
880     create the default folder. */     then check for $APPDATA\gnupg. Create the dir if it does not exists. */
881  static int  int
882  check_homedir (void)  gnupg_check_homedir (void)
883  {        {      
884      char *homedir = NULL;      char *homedir;
885      int yes = 0, set_reg=0;      int val;
886      int rc = 0;      int rc = 0;
887    
888      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
     if (!homedir) {  
         set_reg = 1;  
         homedir = multi_gnupg_path (0);  
     }  
889      if (!homedir)      if (!homedir)
890          homedir = m_strdup ("c:\\gnupg");          homedir = multi_gnupg_path (0);
891      if (homedir) {      if (homedir) {
892          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
893              yes = log_box (_("Preferences"), MB_YESNO,              val = log_box (_("Preferences"), MB_YESNO,
894                             _("%s does not exit.\n"                             _("%s does not exit.\n"
895                               "Do you want to create this directory?"), homedir);                               "Do you want to create this directory?"), homedir);
896              if (yes == IDYES) {              if (val == IDYES) {
897                  if (!CreateDirectory (homedir, NULL))                  if (!CreateDirectory (homedir, NULL))
898                      rc = WPTERR_DIR_CREAT;                      rc = WPTERR_DIR_CREAT;
899              }              }
900              else              else
901                  rc = WPTERR_DIR_OPEN;                  rc = WPTERR_DIR_OPEN;
902          }          }
         if (set_reg)  
             set_reg_entry_gpg (GPG_REG_HOME, homedir);  
903          free_if_alloc (homedir);          free_if_alloc (homedir);
904      }      }
905      return rc;      return rc;
# Line 874  check_homedir (void) Line 907  check_homedir (void)
907    
908    
909  int  int
 gnupg_check_homedir (void)  
 {        
     char *homedir = NULL;  
     char *prog = NULL;  
     int rc = 0;  
       
     rc = check_homedir ();  
     if (rc)  
         return rc;  
     if ((homedir = get_reg_entry_gpg (GPG_REG_HOME)) &&  
         !(prog = get_reg_entry_gpg (GPG_REG_EXE ))) {  
         prog = make_filename (homedir, "gpg", "exe");  
         if (file_exist_check (prog) == 0) {  
             rc = set_reg_entry_gpg (GPG_REG_EXE, prog);  
             if (rc)  
                 goto fail;  
         }  
         free_if_alloc (homedir);  
         free_if_alloc (prog);  
         return rc;  
     }  
     if ((prog = get_reg_entry_gpg (GPG_REG_EXE))  
         && file_exist_check (prog)) {  
         free_if_alloc (prog);  
         homedir = get_reg_entry_gpg (GPG_REG_HOME);  
         if (!homedir) {  
             rc = WPTERR_GENERAL;  
             goto fail;  
         }  
         prog = make_filename (homedir, "gpg", "exe");  
         if (file_exist_check (prog) == 0) {  
             rc = set_reg_entry_gpg (GPG_REG_EXE, prog);  
             if (rc)  
                 goto fail;  
             free_if_alloc (prog);  
             return rc;  
         }  
     }  
       
     /* 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);  
     return rc;  
 } /* gnupg_check_homedir */  
   
   
 int  
910  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
911  {  {
912      const char * pring, * sring;      const char *pring, *sring;
913      char * file = NULL, * path = NULL;      char *file = NULL, *path = NULL;
914      int id = 0, rc = 0;      int id = 0, rc = 0;
915      HWND hwnd;      HWND hwnd;
916            
# Line 938  gnupg_copy_keyrings (void) Line 919  gnupg_copy_keyrings (void)
919          return WPTERR_GENERAL;          return WPTERR_GENERAL;
920      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
921    
922      pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
923                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
924      if (!pring) {      if (!pring) {
925          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
926                     _("WinPT Error"), MB_ERR);
927          free_if_alloc (path);          free_if_alloc (path);
928          return WPTERR_GENERAL;          return WPTERR_GENERAL;
929      }      }
930      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
931      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
932          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
933                          "WinPT", MB_INFO|MB_YESNO);
934          if (id == IDNO)          if (id == IDNO)
935              goto fail;              goto fail;
936      }      }
# Line 958  gnupg_copy_keyrings (void) Line 941  gnupg_copy_keyrings (void)
941      }      }
942      free_if_alloc (file);      free_if_alloc (file);
943    
944      sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
945                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
946      if (!sring) {      if (!sring) {
947          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
948                     _("WinPT Error"), MB_ERR);
949          return WPTERR_GENERAL;          return WPTERR_GENERAL;
950      }      }
951      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
952      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
953          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
954          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
955            if (id == IDNO)
956              goto fail;              goto fail;
957      }      }
958      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
959          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
960          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
961      }      }
962    
# Line 979  fail: Line 964  fail:
964      free_if_alloc (file);      free_if_alloc (file);
965      free_if_alloc (path);      free_if_alloc (path);
966      return rc;      return rc;
967  } /* gnupg_import_keyrings */  }
968    
969    
970    /* Backup the gpg.conf file. */
971  void  void
972  gnupg_backup_options (void)  gnupg_backup_options (void)
973  {  {
974      char *cfgfile = NULL;      char *cfgfile;
975      char bak[512];      char bak[MAX_PATH+32];
976    
977      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
978      if (cfgfile == NULL)      if (!cfgfile)
979          return;          return;
980      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);
981      CopyFile (cfgfile, bak, FALSE);      CopyFile (cfgfile, bak, FALSE);
982      free_if_alloc (cfgfile);      free_if_alloc (cfgfile);
983  } /* gnupg_backup_options */  }
   
984    
985    
986  static int  static int
987  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
988                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
989  {  {
990      char * src, * dst;      char *src, *dst;
991      BOOL rc;      BOOL rc;
992    
993      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
994      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
995      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
996      free_if_alloc (src);      free_if_alloc (src);
997      free_if_alloc (dst);      free_if_alloc (dst);
998      if (!rc)      if (!rc) {
     {  
999          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
1000          return WPTERR_GENERAL;          return WPTERR_GENERAL;
1001      }      }
1002      return 0;      return 0;
1003  } /* backup_one_file */  }
1004    
1005    
1006    /* Figure out first public keyring which is not empty.
1007       Return value: 1 on success. */
1008  static int  static int
1009  check_keyring (char ** r_path)  check_keyring (char **r_path)
1010  {  {
1011      char * p;      char *p;
1012      char * opt, * name;      char *opt;
1013        char *name;
1014    
1015      if (!*r_path)      if (!*r_path)
1016          return 0;          return 0;
1017      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1018      if (!p || get_file_size (p) > 0)      if (get_file_size (p) <= 0)
1019          return 0;          return 0;
1020    
1021      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
# Line 1044  check_keyring (char ** r_path) Line 1027  check_keyring (char ** r_path)
1027      if (!name)      if (!name)
1028          return 0;          return 0;
1029      p = strrchr (name, '\\');      p = strrchr (name, '\\');
1030      if (!p)      if (!p) {
     {  
1031          free_if_alloc (name);          free_if_alloc (name);
1032          return 0;                return 0;      
1033      }      }
# Line 1058  check_keyring (char ** r_path) Line 1040  check_keyring (char ** r_path)
1040  }  }
1041    
1042    
1043    /* Return a temp name based on the day of the week. */
1044  static char*  static char*
1045  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1046  {  {
1047      struct tm *tm;      struct tm *tm;
1048      char *p;      char *p;
1049        time_t t;
1050    
1051      time_t t = time (NULL);      t = time (NULL);
1052      tm = localtime (&t);      tm = localtime (&t);
1053      p = new char [strlen (templ) + 8 + 1];      p = new char [strlen (templ) + 8 + 1];
1054      if (!p)      if (!p)
# Line 1074  get_backup_name (const char *templ) Line 1058  get_backup_name (const char *templ)
1058  }  }
1059    
1060    
1061    /* Make backups of all keyrings. The public key ring is rotated like
1062       this pubring-%d.gpg.
1063       If @auto_backup is false, no action is performed.
1064       @include_secr indicated if the backup includes the secret keyring. */
1065  void  void
1066  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1067  {  {
1068      char *srcpath = NULL, *dstpath = NULL;      char *srcpath = NULL, *dstpath = NULL;
1069      char *name=NULL;      char *name=NULL;
1070      int rc, bakmode=0;      int rc;
1071    
1072      if (!reg_prefs.auto_backup)      if (!auto_backup)
1073          return;          return;
1074      bakmode = reg_prefs.backup.mode;      srcpath = get_gnupg_path ();
     srcpath =  get_gnupg_path ();  
1075      check_keyring (&srcpath);      check_keyring (&srcpath);
1076      if (bakmode == 1) {      if (backup_mode == 1) {
1077          dstpath = get_gnupg_path ();          dstpath = multi_gnupg_path (1);
1078          check_keyring (&dstpath);          check_keyring (&dstpath);
1079      }      }
1080      else if (bakmode == 2) {      else if (backup_mode == 2) {
1081          char * tmpfile;          char *tmpfile;
1082          FILE * fp;          FILE *fp;
1083    
1084          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1085          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1086          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1087          if (!fp)          if (!fp)
1088              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1089                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1090                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1091          else {          else {
1092              rc = 0;              rc = 0;
1093              fclose (fp);              fclose (fp);
1094              remove (tmpfile);              DeleteFile (tmpfile);
1095          }          }
1096          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1097          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL)
1098              return;              return;
1099      }      }
1100      else {      else {
1101          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1102          return;          return;
1103      }      }
1104      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1105      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1106      if (!rc)      if (!rc && include_secr)
1107          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1108      free_if_alloc (name);      free_if_alloc (name);
1109      free_if_alloc (srcpath);      free_if_alloc (srcpath);
1110      free_if_alloc (dstpath);      free_if_alloc (dstpath);
 } /* gnupg_backup_keyrings */  
   
   
 /* Display GPG error from file if possible. */  
 void  
 gnupg_display_error (void)  
 {        
     char tmpath[512], * errstr;  
     size_t size = 0;  
     FILE * fp;  
   
     GetTempPath (sizeof tmpath - 32, (tmpath));  
     strcat (tmpath, "gpg_stderr");  
     size = get_file_size (tmpath);  
     if (file_exist_check (tmpath) || size <= 0)  
         return;  
     fp = fopen( tmpath, "rb" );  
     if (!fp) {  
         msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );  
         return;  
     }  
     errstr = new char[size+1];  
     if (!errstr)  
         BUG (0);  
     fread (errstr, 1, size, fp);  
     errstr[size] = '\0';  
     fclose (fp);  
     msg_box (NULL, errstr, _("GPG Error"), MB_INFO);  
     free_if_alloc (errstr);  
1111  }  }
1112    
1113    
   
1114  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1115     Return value: 0 for success. */     Return value: 0 for success. */
1116  int  int

Legend:
Removed from v.74  
changed lines
  Added in v.255

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26