/[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 181 by twoaday, Tue Mar 14 11:01:22 2006 UTC revision 355 by twoaday, Sat Dec 3 18:59:01 2011 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2009 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 12  Line 12 
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   * General Public License for more details.   * General Public License for more details.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
15   */   */
16  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
17  #include <config.h>  #include <config.h>
# Line 30  Line 26 
26  #include <time.h>  #include <time.h>
27    
28  #include "wptGPG.h"  #include "wptGPG.h"
29  #include "wptGpgCmds.h"  #include "wptGPGME.h"
30  #include "wptGPGOptSkel.h"  #include "wptGPGCmds.h"
31  #include "wptTypes.h"  #include "wptTypes.h"
32  #include "wptNLS.h"  #include "wptNLS.h"
33  #include "wptRegistry.h"  #include "wptRegistry.h"
# Line 43  Line 39 
39  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
40  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
41    
42  struct gpg_watcher_s {  /* Context to monitor GPG file changes. */
43      FILETIME    last_access;  struct gpg_monitor_s {
44        FILETIME    last_access;    /* last write access. */
45      FILETIME    access;      FILETIME    access;
46      char        *object;      char        *object;        /* name of the object. */
47      int         modified;      char        *fpath_object;  /* full path to the object. */
48        int         modified;       /* 1 = modified. */
49  };  };
50    typedef struct gpg_monitor_s *gpg_monitor_t;
51    
52    static const char *gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
53  /* 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];  
54  static int gpg_table_count = DIM (gpg_table);  static int gpg_table_count = DIM (gpg_table);
55    
56  int idea_available = 0;  int idea_available = 0; /* if the IDEA extension is available. */
57    
58    
59  static int check_keyring (char ** r_path);  static int check_keyring (char ** r_path);
60    
# Line 65  static int check_keyring (char ** r_path Line 63  static int check_keyring (char ** r_path
63  char*  char*
64  multi_gnupg_path (int strict)  multi_gnupg_path (int strict)
65  {  {
66      static char buf[256+64];      static char buf[MAX_PATH+64];
     BOOL ec;  
67    
68      /* MSDN: buf must be at least MAX_PATH=256 bytes */      /* MSDN: buf must be at least MAX_PATH=256 bytes */
69      memset (buf, 0, sizeof (buf));      memset (buf, 0, sizeof (buf));
70      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */      if (!SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE)) {
71      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);          log_debug ("multi_gnupg_path: SHGetSpecialFolderPath() failed with: %d\r\n",
     if (ec != 1) {  
         log_debug ("multi_gnupg_path: SHGetSpecialFolderPath() failed\r\n",  
72                     (int)GetLastError ());                     (int)GetLastError ());
73          return NULL;          return NULL;
74      }      }
# Line 89  multi_gnupg_path (int strict) Line 84  multi_gnupg_path (int strict)
84  char*  char*
85  get_gnupg_path (void)  get_gnupg_path (void)
86  {  {
87      char *path;      char *path = get_reg_entry_gpg (GPG_REG_HOME);
88        if (path && dir_exist_check (path) == 0)
89      path = get_reg_entry_gpg (GPG_REG_HOME);          return path;
90      if (path) {      free_if_alloc (path);
91          if (dir_exist_check (path) == 0)      return multi_gnupg_path (1);
             return path;  
         free_if_alloc (path);  
     }  
     path = multi_gnupg_path (1);  
     return path;  
92  }  }
93    
94    
# Line 106  get_gnupg_path (void) Line 96  get_gnupg_path (void)
96     A value of NULL indicates an error. */     A value of NULL indicates an error. */
97  char*  char*
98  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
99  {      {
100      char *p = NULL;      char *path = get_gnupg_path ();
     char *optfile = NULL;  
     char *path = NULL;  
     size_t nlen = 0;  
   
     path = get_gnupg_path ();  
101      if (!path)      if (!path)
102          return NULL;          return NULL;
103      p = get_reg_entry_gpg ("OptFile");      char *optfile = make_filename (path, GPG_CONF, NULL);
     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);  
     }  
104      free_if_alloc (path);      free_if_alloc (path);
105      free_if_alloc (p);  
106      return optfile;      return optfile;
107  }  }
108    
109    
110    static char*
111    get_keyring_from_conf (const char *fname, int pub)
112    {
113        config_file_t opt;
114        conf_option_t e;
115        char *kring = NULL;
116    
117        if (parse_config (fname, &opt))
118            return NULL;
119        if (pub)
120            e = conf_find_option (opt, "keyring");
121        else
122            e = conf_find_option (opt, "secret-keyring");
123        if (e != NULL)
124            kring = m_strdup (e->val);
125        release_config (opt);
126    
127        return kring;
128    }
129    
130    
131  /* Return the full path of the keyring. If @pub is 1, the public  /* Return the full path of the keyring. If @pub is 1, the public
132     keyring is return, otherwise the secret keyring. */     keyring is return, otherwise the secret keyring. */
133  char*  char*
134  get_gnupg_keyring (int pub, int strict)  get_gnupg_keyring (int pub, int strict)
135  {      {    
136      char *optfile = NULL;      char *optfile;
137      char *path = NULL;      char *path;
138      char *keyring = NULL;      char *keyring;
139    
140      path = get_gnupg_path ();      path = get_gnupg_path ();
141      if (!path)      if (!path)
# Line 157  get_gnupg_keyring (int pub, int strict) Line 149  get_gnupg_keyring (int pub, int strict)
149          free_if_alloc (path);          free_if_alloc (path);
150          return keyring;          return keyring;
151      }      }
152      if (file_exist_check (keyring) || pub && get_file_size (keyring) == 0) {      if (file_exist_check (keyring) ||
153            (pub && get_file_size (keyring) == 0)) {
154          free_if_alloc (keyring);          free_if_alloc (keyring);
155          optfile = make_filename (path, GPG_CONF, NULL);          optfile = make_filename (path, GPG_CONF, NULL);
156          keyring = get_gnupg_keyring_from_options (optfile, pub);          keyring = get_keyring_from_conf (optfile, pub);
157            free_if_alloc (optfile);
158      }      }
159      free_if_alloc (path);      free_if_alloc (path);
160      free_if_alloc (optfile);      
161      return keyring;      return keyring;
162  }  }
163    
# Line 171  get_gnupg_keyring (int pub, int strict) Line 165  get_gnupg_keyring (int pub, int strict)
165  /* 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
166     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
167     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
168  char*  char*
169  get_gnupg_prog (void)  get_gnupg_prog (void)
170  {      {    
171      char *p;      char *path;
172      char *pgm = NULL;      char *pgm;
173    
174      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
175      if (!p) {      if (pgm)
176          char *path = get_gnupg_path ();          return pgm;
177          if (!path)      path = get_gnupg_path ();
178              return NULL;      if (!path)
179          pgm = make_filename (path, "gpg", "exe");          return NULL;    
180          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
181      }      free_if_alloc (path);
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
182      return pgm;      return pgm;
183  }  }
184    
# Line 198  get_gnupg_prog (void) Line 186  get_gnupg_prog (void)
186  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
187     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
188     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
189  static char *  static char*
190  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
191  {  {    
192        gpgme_key_t key, pk;
193        gpg_keycache_t sec, pub;
194      const char *s;      const char *s;
195      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
196    
197      if (!sec)      sec = keycache_get_ctx (0);
198          BUG (0);      pub = keycache_get_ctx (1);
199      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
200      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
201          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
202              s = key->subkeys->keyid;              s = key->subkeys->keyid;
203              if (s)                  if (s)
204                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
205              break;              break;
206          }          }
207      }      }
# Line 228  default_key_from_cache (int *ret_no_usea Line 216  default_key_from_cache (int *ret_no_usea
216     Return value: 0 on success. */     Return value: 0 on success. */
217  int  int
218  gnupg_load_config (void)  gnupg_load_config (void)
219  {  {    
220      int rc;      config_file_t opt;
221      gpg_optfile_t opt;      char *conf;
222      gpg_option_t o;      int rc = 0;
223      char *conf = get_gnupg_cfgfile ();      
224        conf = get_gnupg_cfgfile ();
225      if (!conf)      if (!conf)
226          return -1;          return -1;
227      rc = parse_gpg_options (conf, &opt);      if (parse_config (conf, &opt)) {
     if (rc) {  
228          free_if_alloc (conf);          free_if_alloc (conf);
229          return -1;          return -1;
230      }      }
231      o = find_option (opt, "ask-cert-level");      free_if_alloc (conf);
232      if (o)      if (conf_find_option (opt, "ask-cert-level"))
233          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
234      o = find_option (opt, "ask-cert-expire");      if (conf_find_option (opt, "ask-cert-expire"))
     if (o)  
235          reg_prefs.gpg.ask_cert_expire = 1;          reg_prefs.gpg.ask_cert_expire = 1;
236      release_gpg_options (opt);      /* The 'textmode' option for GPG is useful for text files
237      free_if_alloc (conf);         but it breaks the output of any binary data. Thus we return
238      return 0;         a warning here to inform the user that binary output is broken. */
239        if (conf_find_option (opt, "textmode"))
240            rc = -2;
241        release_config (opt);
242    
243        return rc;
244    }
245    
246    
247    /* handle the case the user added a '!' to force a subkey. */
248    static char*
249    extract_keyid (const char *val)
250    {    
251        size_t len = strlen (val);
252    
253        if (len > 1 && val[len-1] == '!')
254            return substr (val, 0, len-1);
255        return m_strdup (val);
256  }  }
257    
258    
259    /* Return the default key.
260       This can be either a substring or a key ID. */
261  char*  char*
262  get_gnupg_default_key (void)  get_gnupg_default_key (void)
263  {      {    
264      gpg_optfile_t opt = NULL;      config_file_t opt = NULL;
265      gpg_option_t e;      conf_option_t e;
266      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
267      int no_usable=0, rc = 0;      int no_usable=0;
268    
269      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
270      if (!optfile)      if (!optfile)
271          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
272      rc = parse_gpg_options (optfile, &opt);      if (parse_config (optfile, &opt)) {
     if (rc) {  
273          free_if_alloc (optfile);          free_if_alloc (optfile);
274          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
275      }      }
276      e = find_option( opt, "default-key" );      /* First we search for config entries which specify a default key. */
277      if ( e )      e = conf_find_option (opt, "default-key");
278          keyid = m_strdup( e->val );      if (!e)
279      if( !e ) {          e = conf_find_option (opt, "local-user");
280          e = find_option( opt, "local-user" );      if (e)
281          if( e )          keyid = extract_keyid (e->val);
282              keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
283      free_if_alloc (optfile);      free_if_alloc (optfile);
284      release_gpg_options (opt);      release_config (opt);
285    
286        /* If no entry in the config has been found, we get a key
287           from the key cache. */
288      if (!keyid)      if (!keyid)
289          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
290      return keyid;      return keyid;
291  } /* get_gnupg_default_key */  }
292    
293    
294  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
# Line 322  check_gnupg_prog (void) Line 323  check_gnupg_prog (void)
323    
324  static int  static int
325  parse_version_nr (const char *buf, int *major, int *minor, int *patch)  parse_version_nr (const char *buf, int *major, int *minor, int *patch)
326  {  {  
327      char tmp[8];      char *p;
328      int i;      char *tmp = m_strdup(buf);
329            
330      i=0;      int pos = 0;
331      while (buf && *buf != '.' && i < 8)      while ((p = strsep(&tmp, ".")) != NULL) {
332          tmp[i++] = *buf++;          switch (++pos) {
333      tmp[i] = 0; buf++;          case 1: *major = atoi (p); break;
334      *major = atol( tmp );          case 2: *minor = atoi (p); break;
335      i=0;          case 3: *patch = atoi (p); break;
336      while (buf && *buf != '.' && i < 8)          }
337          tmp[i++] = *buf++;      }
338      tmp[i] = 0; buf++;      delete[] tmp;  
339      *minor = atol (tmp);      if (pos != 3)
340      i=0;          return -1;  
     while (buf && isdigit (*buf) && i < 8)  
         tmp[i++] = *buf++;  
     tmp[i] = 0;  
     *patch = atol (tmp);  
341      return 0;      return 0;
342  }  }
343    
# Line 352  int Line 349  int
349  check_gnupg_engine (const char *need_gpg_ver,  check_gnupg_engine (const char *need_gpg_ver,
350                      int *r_major, int *r_minor, int *r_patch)                      int *r_major, int *r_minor, int *r_patch)
351  {  {
     gpgme_ctx_t ctx;  
352      gpgme_engine_info_t inf;      gpgme_engine_info_t inf;
353      char *eng = NULL;      char *eng = NULL;
354      int major=0, minor=0, patch=0;      int major=0, minor=0, patch=0;
# Line 364  check_gnupg_engine (const char *need_gpg Line 360  check_gnupg_engine (const char *need_gpg
360                            &need_major, &need_minor, &need_patch))                            &need_major, &need_minor, &need_patch))
361          return 1;          return 1;
362            
363      gpgme_new (&ctx);      if (gpgme_get_engine_info (&inf))
364      inf = gpgme_ctx_get_engine_info (ctx);       return -1;
     if (!inf) {  
         gpgme_release (ctx);  
         return -1;  
     }  
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          return -1;       return -1;
369      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
370          idea_available = 1;          idea_available = 1;
371      free (eng);      safe_free (eng);
372      if (parse_version_nr (inf->version, &major, &minor, &patch)) {    
373          gpgme_release (ctx);      if (parse_version_nr (inf->version, &major, &minor, &patch))
374          return 1;          return 1;
     }  
375    
376      if (major > need_major)      if (major > need_major)
377          rc = 0;          rc = 0;
# Line 398  check_gnupg_engine (const char *need_gpg Line 389  check_gnupg_engine (const char *need_gpg
389  }  }
390    
391    
392  int  /* Count the keyring entries in the gpg.conf file.
393  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
394    static int
395    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
396  {  {
397      gpg_optfile_t opt;          config_file_t opt;    
398      gpg_option_t e;      conf_option_t e;
     int rc = 0;  
399    
400      *r_secrings = 0;      *r_secrings = 0;
401      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
402    
403      for( e = opt->list; e; e = e->next ) {      if (parse_config (fname, &opt))
404          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
405              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
406            if (!strcmp (e->name, "secret-keyring")) {
407                if (!file_exist_check (e->val))
408                  r_secrings[0]++;                  r_secrings[0]++;
409          }          }
410          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
411              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
412                  r_pubrings[0]++;                  r_pubrings[0]++;
413          }          }
414      }      }
415      release_gpg_options( opt );      release_config (opt);
416      return 0;      return 0;
417  } /* check_gnupg_cfgfile */  }
418    
419    
420  /* Usually GPG creates the pubring.gpg, secring.gpg on  /* Usually GPG creates the pubring.gpg, secring.gpg on
# Line 432  check_gnupg_cfgfile (const char *fname, Line 423  check_gnupg_cfgfile (const char *fname,
423  static void  static void
424  create_empty_keyring (int _pub)  create_empty_keyring (int _pub)
425  {  {
426      char *name;      char *name = get_gnupg_keyring (_pub, 0);
427      FILE *f;      if (name && file_exist_check (name) != 0) {
428            FILE *fp = fopen (name, "ab");
429      name = get_gnupg_keyring (_pub, 0);          if (fp != NULL)
430      if (file_exist_check (name) != 0) {              fclose (fp);
         f = fopen (name, "ab");  
         if (f != NULL)  
             fclose (f);  
431      }      }
432      free_if_alloc (name);      free_if_alloc (name);
433  }  }
# Line 472  gnupg_access_files (void) Line 460  gnupg_access_files (void)
460              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
461          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
462          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
463              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
464              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
465                  free_if_alloc (optfile);                  free_if_alloc (optfile);
466                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
467              }              }
# Line 492  gnupg_access_files (void) Line 480  gnupg_access_files (void)
480  }  }
481    
482    
 static int  
 create_gpg_options (void)  
 {  
     FILE *fp;  
     char *s, *optfile;  
   
     s = get_gnupg_path ();  
     if( s == NULL )  
         return WPTERR_FILE_CREAT;  
     optfile = make_filename (s, GPG_CONF, NULL);  
     fp = fopen (optfile, "wb");  
     if (fp == NULL) {    
         return WPTERR_FILE_CREAT;  
         goto fail;  
     }  
     fwrite (options_skel, 1, strlen (options_skel), fp);  
     fclose (fp);  
   
 fail:  
     free_if_alloc (s);  
     free_if_alloc (optfile);  
     return 0;  
 } /* create_gpg_options */  
   
483    
484  /*  /* Return the contents of the options file as a char buf. */
485   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
486  get_gnupg_config (void)  get_gnupg_config (void)
487  {  {
488      FILE * fp;      FILE *fp;
489      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile;
490      int fsize, rc = 0;      int fsize;
491                    
492      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
493      if( optfile == NULL )      if (!optfile)
494          return NULL;          return NULL;
495      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
496      if( !fsize ) {      if (fsize < 1 || fsize > 100000)
497          rc = create_gpg_options( );          goto leave; /* too large or does not exist */
498          if ( rc )      
499              return NULL;      fp = fopen (optfile, "rb");
500          fsize = get_file_size( optfile );      if (!fp)
501      }          goto leave;
     if( fsize > 100000 )  
         goto leave; /* too large */  
502      p = new char[fsize+1];      p = new char[fsize+1];
503      if( p == NULL )      if (!p)
504          BUG( NULL );          BUG (NULL);
505      fp = fopen( optfile, "rb" );      fread (p, 1, fsize, fp);
506      if( fp == NULL ) {      fclose (fp);
         free_if_alloc( p );  
         return NULL;  
     }  
     fread( p, 1, fsize, fp );  
     fclose( fp );  
507      p[fsize] = '\0';      p[fsize] = '\0';
508      free_if_alloc( optfile );      
   
509  leave:  leave:
510        free_if_alloc (optfile);
511      return p;      return p;
512  } /* get_gnupg_config */  }
513    
514    
515  /* Set the default key in the gpg.conf.  /* Set the default key in the gpg.conf.
# Line 562  leave: Line 517  leave:
517  int  int
518  set_gnupg_default_key (const char *key)  set_gnupg_default_key (const char *key)
519  {  {
520      gpg_optfile_t opt;      config_file_t opt;
521      gpg_option_t e;      conf_option_t e;
522      char *optfile = NULL;      char *optfile = NULL;
523      int rc = 0;      int rc = 0;
524    
525      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
526      if (!optfile)      if (!optfile)
527          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
528      rc = parse_gpg_options (optfile, &opt);      rc = parse_config (optfile, &opt);
529      if (rc) {      if (rc) {
530          free_if_alloc (optfile);          free_if_alloc (optfile);
531          return WPTERR_GENERAL;          return WPTERR_GENERAL;
532      }      }
533      e = find_option (opt, "default-key");      e = conf_find_option (opt, "default-key");
534      if (e && !key)      if (e && !key)
535          e->used = 0;          e->used = 0;
536      else if (e) {      else if (e) {
# Line 583  set_gnupg_default_key (const char *key) Line 538  set_gnupg_default_key (const char *key)
538          e->val = m_strdup (key);          e->val = m_strdup (key);
539          e->used = 1;          e->used = 1;
540      }      }
541      else      else if (key)
542          add_entry (opt, ENTRY_MULTI, "default-key", key);          conf_add_entry (opt, ENTRY_MULTI, "default-key", key);
543      rc = commit_gpg_options (optfile, opt);      rc = commit_config (optfile, opt);
544    
545      free_if_alloc (optfile);      free_if_alloc (optfile);
546      release_gpg_options (opt);      release_config (opt);
   
547      return rc;      return rc;
548  }  }
549    
550    
551  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
552  int  int
553  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
554  {  {
555      FILE *fp;        FILE *fp;  
556      char *optfile = NULL;      char *optfile;
557    
558      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
559      if( optfile == NULL )      if (!optfile)
560          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
561    
562      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
563      if( fp == NULL ) {      if (!fp) {
564          free_if_alloc( optfile );          free_if_alloc (optfile);
565          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
566      }      }
567      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
568      fclose( fp );      fclose (fp);
569      free_if_alloc( optfile );      free_if_alloc (optfile);
570      return 0;      return 0;
571  } /* set_gnupg_options */  }
572    
573  /*  
574   * Check if the line contains a valid GPG argument.  /* Check if the parameter for the option @buf is an existing file name.
575   */     Return value: 0 on success. */
576    static int
577    check_arg_file_exist (const char *buf)
578    {
579        const char *s = "load-extension ";
580    
581        /* XXX: this is a bit of a kludge because we just
582                detect errors for 'load-extension'. */
583        if (!strncmp (buf, s, strlen (s)))
584            buf += strlen (s);
585        else
586            return 0;
587        return file_exist_check (buf);
588    }
589    
590    
591    /* Check if the line contains a valid GPG argument. */
592  static int  static int
593  check_line( const char *buf )  check_line (const char *buf)
594  {  {
595      int j, len;      int j, len;
596      int rc = 0;      int rc = 0;
597    
598      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
599          return 1;          return 1;
600      rc = 0;      for (j = 0; valid_gpg_args[j]; j++) {
601      for ( j = 0; valid_gpg_args[j]; j++ ) {          len = strlen (valid_gpg_args[j]);
602          len = strlen( valid_gpg_args[j] );          if (!strncmp (valid_gpg_args[j], buf, len))
603          if( !strncmp( valid_gpg_args[j], buf, len ) )              rc = 1;
             rc = 1;      
604      }      }
   
605      return rc;      return rc;
606  } /* check_line */  }
607    
608    
609  int  int
610  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf, int showerr)
611  {  {
612      char line[1024];      char line[1024];
613      int nbytes = 0;      int nbytes = 0, lineno=0;
614      unsigned j;      unsigned j;
615                    
616      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < DIM (line); j++) {
617          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
618          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
619              line[nbytes] = '\0';              line[nbytes] = '\0';
620              if( !check_line( line ) ) {              lineno++;
621                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
622                    if (showerr)
623                        log_box ("GPG Config File", MB_ERR,
624                                 "gpg.conf:%d: invalid keyword '%s'",
625                                 lineno, line);
626                  return 1;                        return 1;      
627              }              }
628                if (check_arg_file_exist (line))
629                    return WPTERR_FILE_EXIST;
630              nbytes = 0;              nbytes = 0;
631          }                }
632      }      }
   
633      return 0;      return 0;
634  } /* check_gnupg_options */  }
635    
636    
637  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
638  static int  static int
639  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
640  {  {
641      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
642    
643      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
644      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
645      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);  
646          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
647      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
648      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
649      return 0;      return 0;
650  }  }
651    
652    
653  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
654  static void  static void
655  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
656  {                {              
657      ctx->modified = 0;      ctx->modified = 0;
658    
659      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
660          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
661          ctx->modified = 1;          ctx->modified = 1;
662        
     /* XXX: find a better way. without it, winpt --keymanager loads  
             the key cache twice. */  
663      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
664          ctx->modified = 0;          ctx->modified = 0;
665    
# Line 707  check_last_gnupg_access (gpg_watcher_s * Line 668  check_last_gnupg_access (gpg_watcher_s *
668  }  }
669    
670    
671  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
672  void  void
673  init_gnupg_table (void)  init_gnupg_table (void)
674  {        {      
675      char *p;      char *path;
676      int j;      int j;
677    
678        path = get_gnupg_path ();
679      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
680          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
681          if (!p)          gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
             BUG (NULL);  
682          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
683          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
684          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
685      }      }
686        free_if_alloc (path);
687  }  }
688    
689    
690    /* Release the GPG monitor table. */
691  void  void
692  free_gnupg_table (void)  free_gnupg_table (void)
693  {  {
694      int j;      for (int j=0; j < gpg_table_count; j++) {
   
     for (j=0; j < gpg_table_count; j++)  
695          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
696            free_if_alloc (gpg_table[j].fpath_object);
697        }
698  }  }
699    
700    
701  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
702  int  int
703  keyring_check_last_access (void)  keyring_check_last_access (void)
704  {        {
705      int rc, j;      int nfiles;
706    
707      rc = 0;      nfiles = 0;
708      for (j = 0; j < gpg_table_count; j++) {      for (int pos = 0; pos < gpg_table_count; pos++) {
709          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
710          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
711          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
712              rc++;                    nfiles++;
713      }      }
714    
715      return rc;      return nfiles;
716  }  }
717    
718    
# Line 772  gnupg_check_file_ext (const char *fname, Line 735  gnupg_check_file_ext (const char *fname,
735              *r_type = PGP_SIG;              *r_type = PGP_SIG;
736          return "SIGNED";          return "SIGNED";
737      }      }
738      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
739                  !stricmp (file_ext, ".pgp")) {
740          if (r_type)          if (r_type)
741              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
742          return "ENCRYPTED";          return "ENCRYPTED";
# Line 781  gnupg_check_file_ext (const char *fname, Line 745  gnupg_check_file_ext (const char *fname,
745  }  }
746    
747    
748  char*  /* Check if the device where file @fname is stored on, is write-protected. */
 get_gnupg_keyring_from_options (const char * fname, int pub)  
 {  
     gpg_optfile_t opt;  
     gpg_option_t e;  
     char * kring = NULL;  
     int rc = 0;  
   
     rc = parse_gpg_options (fname, &opt);  
     if (rc)  
         return NULL;  
     if (pub)  
         e = find_option (opt, "keyring");  
     else  
         e = find_option (opt, "secret-keyring");  
     if (e)  
         kring = m_strdup (e->val);  
     release_gpg_options (opt);  
   
     return kring;  
 }  
   
   
   
 /* XXX: does not work with write-protected floppies */  
749  static int  static int
750  my_access (const char *fname)  check_file_access (const char *fname, int mode)
751  {  {
752      HANDLE hd;      HANDLE hd;
753      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,  
754        if (!mode)
755            mode = FILE_SHARE_WRITE;
756        hd = CreateFile (fname, GENERIC_WRITE, mode,
757                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
758      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
759          return -1;          return -1;
# Line 818  my_access (const char *fname) Line 761  my_access (const char *fname)
761      return 0;      return 0;
762  }  }
763    
764        
765    /* Check the device where the file @fname is stored on, is either
766       write-protected or if the file is already opened by another process
767       exclusively. And as a result, we cannot use the file for output. */
768    int
769    gpg_check_file_permissions (const char *fname, int mode)
770    {
771        int api_mode;
772        
773        switch (mode) {
774        case 0: api_mode = FILE_SHARE_READ; break;
775        case 1: api_mode = FILE_SHARE_WRITE; break;
776        case 2: api_mode = FILE_SHARE_WRITE|FILE_SHARE_READ; break;
777        default: api_mode = FILE_SHARE_READ; break;
778        }
779    
780        return check_file_access (fname, api_mode);
781    }
782    
783    
784  /* Check the file permissions of the public keyring.  /* Check the file permissions of the public keyring.
785     If @showmsg is 1 output a message in case of errors.     If @showmsg is 1 output a message in case of errors.
# Line 831  gpg_check_permissions (int showmsg) Line 793  gpg_check_permissions (int showmsg)
793      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
794    
795      p = get_gnupg_path ();      p = get_gnupg_path ();
796      if (check_keyring (&p) && p) {      if (p && check_keyring (&p)) {
797          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
798          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
799              ans = msg_box (NULL,              ans = msg_box (NULL,
# Line 852  gpg_check_permissions (int showmsg) Line 814  gpg_check_permissions (int showmsg)
814                  failed = 1;                  failed = 1;
815              }              }
816          }          }
817          if (my_access (name)) {          if (gpg_check_file_permissions (name, 1)) {
818              if (showmsg)              if (showmsg)
819                  msg_box (NULL,                  msg_box (NULL,
820                  _("You do not have file access to modify the contents of\n"                  _("You do not have file access to modify the contents of\n"
# Line 875  gpg_check_permissions (int showmsg) Line 837  gpg_check_permissions (int showmsg)
837  int  int
838  gnupg_check_homedir (void)  gnupg_check_homedir (void)
839  {        {      
840      char *homedir = NULL;      char *homedir;
841      int val = 0;      int val;
842      int rc = 0;      int rc = 0;
843    
844      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
# Line 901  gnupg_check_homedir (void) Line 863  gnupg_check_homedir (void)
863    
864    
865  int  int
866    gnupg_import_keypair (void)
867    {
868        const char *file;
869        gpgme_error_t err;
870        GPGME gpgme;
871        HWND hwnd = GetDesktopWindow ();
872    
873        file = get_fileopen_dlg (hwnd, _("Please choose your Key Pair"),
874                                 "GPG Key File (*.gpg)\0*.gpg\0"
875                                 "GPG Armored Key File (*.asc)\0*.asc\0\0",
876                                 NULL);
877        if (file == NULL)
878            return WPTERR_FILE_OPEN;
879        err = gpgme.importFromFile (file);
880        if (err)
881            msg_box (hwnd, gpgme_strerror (err), _("WinPT Error"), MB_ERR);
882        else
883            msg_box (hwnd, _("Key pair successfully imported."), "WinPT", MB_OK);
884        return 0;
885    }
886    
887    int
888  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
889  {  {
890      const char * pring, * sring;      const char *pring, *sring;
891      char * file = NULL, * path = NULL;      char *file = NULL, *path;
892      int id = 0, rc = 0;      int id, rc = 0;
893      HWND hwnd;      HWND hwnd;
894            
895      path = get_gnupg_path ();      path = get_gnupg_path ();
# Line 913  gnupg_copy_keyrings (void) Line 897  gnupg_copy_keyrings (void)
897          return WPTERR_GENERAL;          return WPTERR_GENERAL;
898      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
899    
900      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
901                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
902      if (!pring) {      if (!pring) {
903          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
904                     _("WinPT Error"), MB_ERR);
905          free_if_alloc (path);          free_if_alloc (path);
906          return WPTERR_GENERAL;          return WPTERR_GENERAL;
907      }      }
908      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
909      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
910          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
911                          "WinPT", MB_INFO|MB_YESNO);
912          if (id == IDNO)          if (id == IDNO)
913              goto fail;              goto fail;
914      }      }
915      if (!CopyFile (pring, file, FALSE)) {      if (!CopyFile (pring, file, FALSE)) {
916          msg_box (hwnd, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("Could not copy public keyring."),
917                     _("WinPT Error"), MB_ERR);
918          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
919          goto fail;          goto fail;
920      }      }
921      free_if_alloc (file);      free_if_alloc (file);
922    
923      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
924                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
925      if (!sring) {      if (!sring) {
926          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
927                     _("WinPT Error"), MB_ERR);
928          return WPTERR_GENERAL;          return WPTERR_GENERAL;
929      }      }
930      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
931      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
932          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
933          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
934            if (id == IDNO)
935              goto fail;              goto fail;
936      }      }
937      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
938          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy secret keyring."), _("WinPT Error"), MB_ERR);
939          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
940      }      }
941    
# Line 954  fail: Line 943  fail:
943      free_if_alloc (file);      free_if_alloc (file);
944      free_if_alloc (path);      free_if_alloc (path);
945      return rc;      return rc;
946  } /* gnupg_import_keyrings */  }
947    
948    
949  /* Backup the gpg.conf file. */  /* Backup the gpg.conf file. */
950  void  void
951  gnupg_backup_options (void)  gnupg_backup_options (void)
952  {  {
953      char *cfgfile = NULL;      char *cfgfile;
954      char bak[512];      char bak[MAX_PATH+32];
955    
956      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
957      if (!cfgfile)      if (!cfgfile)
# Line 977  static int Line 966  static int
966  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
967                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
968  {  {
969      char * src, * dst;      char *src, *dst;
970      BOOL rc;      BOOL rc;
971    
972      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
973      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
974      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
975      free_if_alloc (src);      free_if_alloc (src);
976      free_if_alloc (dst);      free_if_alloc (dst);
977      if (!rc)      if (!rc) {
     {  
978          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
979          return WPTERR_GENERAL;          return WPTERR_GENERAL;
980      }      }
981      return 0;      return 0;
982  } /* backup_one_file */  }
983    
984    
985  /* Figure out first public keyring which is not empty.  /* Figure out first public keyring which is not empty.
# Line 1010  check_keyring (char **r_path) Line 994  check_keyring (char **r_path)
994      if (!*r_path)      if (!*r_path)
995          return 0;          return 0;
996      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
997      if (!p || get_file_size (p) <= 0)      if (get_file_size (p) <= 0)
998          return 0;          return 0;
999    
1000      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
1001      if (!opt)      if (!opt)
1002          BUG (0);          BUG (0);
1003      name = get_gnupg_keyring_from_options (opt, 1);      name = get_keyring_from_conf (opt, 1);
1004      free_if_alloc (opt);      free_if_alloc (opt);
1005      free_if_alloc (p);      free_if_alloc (p);
1006      if (!name)      if (!name)
# Line 1040  static char* Line 1024  static char*
1024  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1025  {  {
1026      struct tm *tm;      struct tm *tm;
1027        const char *fmt;
1028      char *p;      char *p;
1029      time_t t;      time_t t;
1030    
1031      t = time (NULL);      t = time (NULL);
1032      tm = localtime (&t);      tm = localtime (&t);
1033      p = new char [strlen (templ) + 8 + 1];      fmt = "%s-%d";
1034        p = new char [strlen (templ) + strlen (fmt) + 8 + 1];
1035      if (!p)      if (!p)
1036          BUG (0);          BUG (0);
1037      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);      sprintf (p, fmt, templ, tm->tm_wday % 3);
1038      return p;      return p;
1039  }  }
1040    
1041    
1042  /* Make backups of all keyrings. The public key ring is  /* Make backups of all keyrings. The public key ring is rotated like
1043     rotated like this pubring-%d.gpg. */     this pubring-%d.gpg.
1044       If @auto_backup is false, no action is performed.
1045       @include_secr indicated if the backup includes the secret keyring. */
1046  void  void
1047  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1048  {  {
1049      char *srcpath = NULL, *dstpath = NULL;      char *srcpath, *dstpath;
1050      char *name=NULL;      char *name;
1051      int rc, bakmode=0;      int rc;
1052    
1053      if (!reg_prefs.auto_backup)      if (!auto_backup)
1054          return;          return;
     bakmode = reg_prefs.backup.mode;  
1055      srcpath = get_gnupg_path ();      srcpath = get_gnupg_path ();
1056      check_keyring (&srcpath);      check_keyring (&srcpath);
1057      if (bakmode == 1) {      if (backup_mode == 1) {
1058          dstpath = multi_gnupg_path (1);          /* If the backup mode uses the home directory the source
1059               and destination folder will be the same. */
1060            dstpath = get_gnupg_path ();
1061          check_keyring (&dstpath);          check_keyring (&dstpath);
1062      }      }
1063      else if (bakmode == 2) {      else if (backup_mode == 2) {
1064          char *tmpfile;          char *tmpfile;
1065          FILE *fp;          FILE *fp;
1066    
1067          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1068          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1069          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1070          if (!fp)          if (!fp)
1071              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1072                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1073                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1074          else {          else {
1075              rc = 0;              rc = 0;
1076              fclose (fp);              fclose (fp);
1077              remove (tmpfile);              DeleteFile (tmpfile);
1078          }          }
1079          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1080          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL) {
1081                free_if_alloc (dstpath);
1082                free_if_alloc (srcpath);
1083              return;              return;
1084            }
1085      }      }
1086      else {      else {
1087          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1088            free_if_alloc (srcpath);
1089          return;          return;
1090      }      }
1091      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1092      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1093      if (!rc)      if (!rc && include_secr)
1094          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1095      free_if_alloc (name);      free_if_alloc (name);
1096      free_if_alloc (srcpath);      free_if_alloc (srcpath);
# Line 1107  gnupg_backup_keyrings (void) Line 1098  gnupg_backup_keyrings (void)
1098  }  }
1099    
1100    
 /* Display GPG error from file if possible. */  
 void  
 gnupg_display_error (void)  
 {        
     char tmpath[512], *errstr;  
     size_t size = 0;  
     FILE *fp;  
   
     get_temp_name (tmpath, sizeof (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);  
 }  
   
   
   
1101  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1102     Return value: 0 for success. */     Return value: 0 for success. */
1103  int  int

Legend:
Removed from v.181  
changed lines
  Added in v.355

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26