/[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 167 by twoaday, Thu Jan 26 10:17:17 2006 UTC revision 304 by twoaday, Wed Mar 21 10:59:31 2007 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2007 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 12  Line 12 
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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 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];
67      BOOL ec;      BOOL ec;
68    
69      /* MSDN: buf must be at least MAX_PATH=256 bytes */      /* MSDN: buf must be at least MAX_PATH=256 bytes */
# Line 92  get_gnupg_path (void) Line 90  get_gnupg_path (void)
90      char *path;      char *path;
91    
92      path = get_reg_entry_gpg (GPG_REG_HOME);      path = get_reg_entry_gpg (GPG_REG_HOME);
93      if (path) {      if (path && dir_exist_check (path) == 0)
94          if (dir_exist_check (path) == 0)          return path;
95              return path;      free_if_alloc (path);
96          free_if_alloc (path);      return multi_gnupg_path (1);
     }  
     path = multi_gnupg_path (1);  
     return path;  
97  }  }
98    
99    
# Line 106  get_gnupg_path (void) Line 101  get_gnupg_path (void)
101     A value of NULL indicates an error. */     A value of NULL indicates an error. */
102  char*  char*
103  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
104  {      {
105      char *p = NULL;      char *optfile;
106      char *optfile = NULL;      char *path;
     char *path = NULL;  
     size_t nlen = 0;  
107    
108      path = get_gnupg_path ();      path = get_gnupg_path ();
109      if (!path)      if (!path)
110          return NULL;          return NULL;
111      p = get_reg_entry_gpg ("OptFile");      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);  
     }  
112      free_if_alloc (path);      free_if_alloc (path);
113      free_if_alloc (p);  
114      return optfile;      return optfile;
115  }  }
116    
117    
118    static char*
119    get_keyring_from_conf (const char *fname, int pub)
120    {
121        config_file_t opt;
122        conf_option_t e;
123        char *kring = NULL;
124        int rc;
125    
126        rc = parse_config (fname, &opt);
127        if (rc)
128            return NULL;
129        if (pub)
130            e = conf_find_option (opt, "keyring");
131        else
132            e = conf_find_option (opt, "secret-keyring");
133        if (e != NULL)
134            kring = m_strdup (e->val);
135        release_config (opt);
136    
137        return kring;
138    }
139    
140    
141  /* 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
142     keyring is return, otherwise the secret keyring. */     keyring is return, otherwise the secret keyring. */
143  char*  char*
144  get_gnupg_keyring (int pub, int strict)  get_gnupg_keyring (int pub, int strict)
145  {      {    
146      char *optfile = NULL;      char *optfile;
147      char *path = NULL;      char *path;
148      char *keyring = NULL;      char *keyring;
149    
150      path = get_gnupg_path ();      path = get_gnupg_path ();
151      if (!path)      if (!path)
# Line 157  get_gnupg_keyring (int pub, int strict) Line 159  get_gnupg_keyring (int pub, int strict)
159          free_if_alloc (path);          free_if_alloc (path);
160          return keyring;          return keyring;
161      }      }
162      if (file_exist_check (keyring) || pub && get_file_size (keyring) == 0) {      if (file_exist_check (keyring) ||
163            pub && get_file_size (keyring) == 0) {
164          free_if_alloc (keyring);          free_if_alloc (keyring);
165          optfile = make_filename (path, GPG_CONF, NULL);          optfile = make_filename (path, GPG_CONF, NULL);
166          keyring = get_gnupg_keyring_from_options (optfile, pub);          keyring = get_keyring_from_conf (optfile, pub);
167            free_if_alloc (optfile);
168      }      }
169      free_if_alloc (path);      free_if_alloc (path);
170      free_if_alloc (optfile);      
171      return keyring;      return keyring;
172  }  }
173    
# Line 171  get_gnupg_keyring (int pub, int strict) Line 175  get_gnupg_keyring (int pub, int strict)
175  /* 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
176     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
177     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
178  char*  char*
179  get_gnupg_prog (void)  get_gnupg_prog (void)
180  {      {    
181      char *p;      char *path;
182      char *pgm = NULL;      char *pgm;
183    
184      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
185      if (!p) {      if (pgm)
186          char *path = get_gnupg_path ();          return pgm;
187          if (!path)      path = get_gnupg_path ();
188              return NULL;      if (!path)
189          pgm = make_filename (path, "gpg", "exe");          return NULL;    
190          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
191      }      free_if_alloc (path);
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
192      return pgm;      return pgm;
193  }  }
194    
# Line 198  get_gnupg_prog (void) Line 196  get_gnupg_prog (void)
196  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
197     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
198     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
199  static char *  static char*
200  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
201  {  {    
202        gpgme_key_t key, pk;
203        gpg_keycache_t sec, pub;
204      const char *s;      const char *s;
205      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
206    
207      if (!sec)      sec = keycache_get_ctx (0);
208          BUG (0);      pub = keycache_get_ctx (1);
209      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
210      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
211          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
212              s = key->subkeys->keyid;              s = key->subkeys->keyid;
213              if (s)                  if (s)
214                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
215              break;              break;
216          }          }
217      }      }
# Line 228  default_key_from_cache (int *ret_no_usea Line 226  default_key_from_cache (int *ret_no_usea
226     Return value: 0 on success. */     Return value: 0 on success. */
227  int  int
228  gnupg_load_config (void)  gnupg_load_config (void)
229  {  {    
230      int rc;      config_file_t opt;
231      gpg_optfile_t opt;      char *conf;
232      gpg_option_t o;      int rc = 0;
233      char *conf = get_gnupg_cfgfile ();      
234        conf = get_gnupg_cfgfile ();
235      if (!conf)      if (!conf)
236          return -1;          return -1;
237      rc = parse_gpg_options (conf, &opt);      if (parse_config (conf, &opt)) {
     if (rc) {  
238          free_if_alloc (conf);          free_if_alloc (conf);
239          return -1;          return -1;
240      }      }
     o = find_option (opt, "ask-cert-level");  
     if (o)  
         reg_prefs.gpg.ask_cert_level = 1;  
     release_gpg_options (opt);  
241      free_if_alloc (conf);      free_if_alloc (conf);
242      return 0;      if (conf_find_option (opt, "ask-cert-level"))
243            reg_prefs.gpg.ask_cert_level = 1;
244        if (conf_find_option (opt, "ask-cert-expire"))
245            reg_prefs.gpg.ask_cert_expire = 1;
246        /* The 'textmode' option for GPG is useful for text files
247           but it breaks the output of any binary data. Thus we return
248           a warning here to inform the user that binary output is broken. */
249        if (conf_find_option (opt, "textmode"))
250            rc = -2;
251        release_config (opt);
252    
253        return rc;
254    }
255    
256    
257    /* handle the case the user added a '!' to force a subkey. */
258    static char*
259    extract_keyid (const char *val)
260    {    
261        size_t len = strlen (val);
262    
263        if (len > 1 && val[len-1] == '!')
264            return substr (val, 0, len-1);
265        return m_strdup (val);
266  }  }
267    
268    
269    /* Return the default key.
270       This can be either a substring or a key ID. */
271  char*  char*
272  get_gnupg_default_key (void)  get_gnupg_default_key (void)
273  {      {    
274      gpg_optfile_t opt = NULL;      config_file_t opt = NULL;
275      gpg_option_t e;      conf_option_t e;
276      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
277      int no_usable=0, rc = 0;      int no_usable=0;
278    
279      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
280      if (!optfile)      if (!optfile)
281          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
282      rc = parse_gpg_options (optfile, &opt);      if (parse_config (optfile, &opt)) {
     if (rc) {  
283          free_if_alloc (optfile);          free_if_alloc (optfile);
284          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
285      }      }
286      e = find_option( opt, "default-key" );      /* First we search for config entries which specify a default key. */
287      if ( e )      e = conf_find_option (opt, "default-key");
288          keyid = m_strdup( e->val );      if (!e)
289      if( !e ) {          e = conf_find_option (opt, "local-user");
290          e = find_option( opt, "local-user" );      if (e)
291          if( e )          keyid = extract_keyid (e->val);
292              keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
293      free_if_alloc (optfile);      free_if_alloc (optfile);
294      release_gpg_options (opt);      release_config (opt);
295    
296        /* If no entry in the config has been found, we get a key
297           from the key cache. */
298      if (!keyid)      if (!keyid)
299          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
300      return keyid;      return keyid;
301  } /* get_gnupg_default_key */  }
302    
303    
304  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
# Line 327  parse_version_nr (const char *buf, int * Line 341  parse_version_nr (const char *buf, int *
341      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
342          tmp[i++] = *buf++;          tmp[i++] = *buf++;
343      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
344      *major = atol( tmp );      *major = atoi (tmp);
345      i=0;      i=0;
346      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
347          tmp[i++] = *buf++;          tmp[i++] = *buf++;
348      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
349      *minor = atol (tmp);      *minor = atoi (tmp);
350      i=0;      i=0;
351      while (buf && isdigit (*buf) && i < 8)      while (buf && isdigit (*buf) && i < 8)
352          tmp[i++] = *buf++;          tmp[i++] = *buf++;
353      tmp[i] = 0;      tmp[i] = 0;
354      *patch = atol (tmp);      *patch = atoi (tmp);
355      return 0;      return 0;
356  }  }
357    
# Line 369  check_gnupg_engine (const char *need_gpg Line 383  check_gnupg_engine (const char *need_gpg
383      }      }
384    
385      /* 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. */
386      if (gpg_get_version (&eng))      if (gpg_get_version (&eng)) {
387            gpgme_release (ctx);
388          return -1;          return -1;
389        }
390      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
391          idea_available = 1;          idea_available = 1;
392      free (eng);      safe_free (eng);
393      if (parse_version_nr (inf->version, &major, &minor, &patch)) {      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
394          gpgme_release (ctx);          gpgme_release (ctx);
395          return 1;          return 1;
396      }      }
397        gpgme_release (ctx);
398    
399      if (major > need_major)      if (major > need_major)
400          rc = 0;          rc = 0;
# Line 395  check_gnupg_engine (const char *need_gpg Line 412  check_gnupg_engine (const char *need_gpg
412  }  }
413    
414    
415  int  /* Count the keyring entries in the gpg.conf file.
416  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
417    static int
418    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
419  {  {
420      gpg_optfile_t opt;          config_file_t opt;    
421      gpg_option_t e;      conf_option_t e;
     int rc = 0;  
422    
423      *r_secrings = 0;      *r_secrings = 0;
424      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
425    
426      for( e = opt->list; e; e = e->next ) {      if (parse_config (fname, &opt))
427          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
428              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
429            if (!strcmp (e->name, "secret-keyring")) {
430                if (!file_exist_check (e->val))
431                  r_secrings[0]++;                  r_secrings[0]++;
432          }          }
433          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
434              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
435                  r_pubrings[0]++;                  r_pubrings[0]++;
436          }          }
437      }      }
438      release_gpg_options( opt );      release_config (opt);
439      return 0;      return 0;
440  } /* check_gnupg_cfgfile */  }
441    
442    
443  /* Usually GPG creates the pubring.gpg, secring.gpg on  /* Usually GPG creates the pubring.gpg, secring.gpg on
# Line 430  static void Line 447  static void
447  create_empty_keyring (int _pub)  create_empty_keyring (int _pub)
448  {  {
449      char *name;      char *name;
450      FILE *f;      FILE *fp;
451    
452      name = get_gnupg_keyring (_pub, 0);      name = get_gnupg_keyring (_pub, 0);
453      if (file_exist_check (name) != 0) {      if (name && file_exist_check (name) != 0) {
454          f = fopen (name, "ab");          fp = fopen (name, "ab");
455          if (f != NULL)          if (fp != NULL)
456              fclose (f);              fclose (fp);
457      }      }
458      free_if_alloc (name);      free_if_alloc (name);
459  }  }
# Line 469  gnupg_access_files (void) Line 486  gnupg_access_files (void)
486              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
487          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
488          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
489              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
490              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
491                  free_if_alloc (optfile);                  free_if_alloc (optfile);
492                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
493              }              }
# Line 490  gnupg_access_files (void) Line 507  gnupg_access_files (void)
507    
508    
509  static int  static int
510  create_gpg_options (void)  create_gpg_conf (void)
511  {  {
512      FILE *fp;      FILE *fp;
513      char *s, *optfile;      char *s, *optfile;
514    
515      s = get_gnupg_path ();      s = get_gnupg_path ();
516      if( s == NULL )      if (!s)
517          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
518      optfile = make_filename (s, GPG_CONF, NULL);      optfile = make_filename (s, GPG_CONF, NULL);
519      fp = fopen (optfile, "wb");      fp = fopen (optfile, "wb");
520      if (fp == NULL) {        if (!fp) {
521          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
522          goto fail;          goto fail;
523      }      }
# Line 511  fail: Line 528  fail:
528      free_if_alloc (s);      free_if_alloc (s);
529      free_if_alloc (optfile);      free_if_alloc (optfile);
530      return 0;      return 0;
531  } /* create_gpg_options */  }
532    
533    
534  /*  /* Return the contents of the options file as a char buf. */
535   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
536  get_gnupg_config (void)  get_gnupg_config (void)
537  {  {
538      FILE * fp;      FILE *fp;
539      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
540      int fsize, rc = 0;      int fsize;
541                    
542      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
543      if( optfile == NULL )      if (!optfile)
544          return NULL;          return NULL;
545      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
546      if( !fsize ) {      if (!fsize) {
547          rc = create_gpg_options( );          if (create_gpg_conf ())
         if ( rc )  
548              return NULL;              return NULL;
549          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
550      }      }
551      if( fsize > 100000 )      if (fsize > 100000)
552          goto leave; /* too large */          goto leave; /* too large */
553      p = new char[fsize+1];      p = new char[fsize+1];
554      if( p == NULL )      if (!p)
555          BUG( NULL );          BUG (NULL);
556      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
557      if( fp == NULL ) {      if (!fp) {
558          free_if_alloc( p );          free_if_alloc (p);
559          return NULL;          return NULL;
560      }      }
561      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
562      fclose( fp );      fclose (fp);
563      p[fsize] = '\0';      p[fsize] = '\0';
564      free_if_alloc( optfile );      free_if_alloc (optfile);
565    
566  leave:  leave:
567      return p;      return p;
568  } /* get_gnupg_config */  }
569    
570    
571    /* Set the default key in the gpg.conf.
572       If @key is NULL, the entry will be deleted. */
573  int  int
574  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
575  {  {
576      gpg_optfile_t opt;      config_file_t opt;
577      gpg_option_t e;      conf_option_t e;
578      char *optfile = NULL;      char *optfile = NULL;
579      int rc = 0;      int rc = 0;
580    
581      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
582      if (!optfile)      if (!optfile)
583          return -1;          return WPTERR_FILE_OPEN;
584      rc = parse_gpg_options (optfile, &opt);      rc = parse_config (optfile, &opt);
585      if( rc ) {      if (rc) {
586          free_if_alloc (optfile);          free_if_alloc (optfile);
587          return -1;          return WPTERR_GENERAL;
588      }      }
589      e = find_option (opt, "default-key");      e = conf_find_option (opt, "default-key");
590      if (e) {      if (e && !key)
591            e->used = 0;
592        else if (e) {
593          free_if_alloc (e->val);          free_if_alloc (e->val);
594          e->val = m_strdup (key);          e->val = m_strdup (key);
595          e->used = 1;          e->used = 1;
596      }      }
597      else      else if (key)
598          add_entry (opt, ENTRY_MULTI, "default-key", key);          conf_add_entry (opt, ENTRY_MULTI, "default-key", key);
599      rc = commit_gpg_options (optfile, opt);      rc = commit_config (optfile, opt);
600    
601      free_if_alloc (optfile);      free_if_alloc (optfile);
602      release_gpg_options (opt);      release_config (opt);
   
603      return rc;      return rc;
604  } /* set_gnupg_default_key */  }
605    
606    
607  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
608  int  int
609  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
610  {  {
611      FILE *fp;        FILE *fp;  
612      char *optfile = NULL;      char *optfile;
613    
614      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
615      if( optfile == NULL )      if (!optfile)
616          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
617    
618      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
619      if( fp == NULL ) {      if (!fp) {
620          free_if_alloc( optfile );          free_if_alloc (optfile);
621          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
622      }      }
623      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
624      fclose( fp );      fclose (fp);
625      free_if_alloc( optfile );      free_if_alloc (optfile);
626      return 0;      return 0;
627  } /* set_gnupg_options */  }
628    
629  /*  
630   * Check if the line contains a valid GPG argument.  /* Check if the parameter for the option @buf is an existing file name.
631   */     Return value: 0 on success. */
632    static int
633    check_arg_file_exist (const char *buf)
634    {
635        const char *s = "load-extension ";
636    
637        /* XXX: this is a bit of a kludge because we just
638                detect errors for 'load-extension'. */
639        if (!strncmp (buf, s, strlen (s)))
640            buf += strlen (s);
641        else
642            return 0;
643        return file_exist_check (buf);
644    }
645    
646    
647    /* Check if the line contains a valid GPG argument. */
648  static int  static int
649  check_line( const char *buf )  check_line (const char *buf)
650  {  {
651      int j, len;      int j, len;
652      int rc = 0;      int rc = 0;
653    
654      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
655          return 1;          return 1;
656      rc = 0;      for (j = 0; valid_gpg_args[j]; j++) {
657      for ( j = 0; valid_gpg_args[j]; j++ ) {          len = strlen (valid_gpg_args[j]);
658          len = strlen( valid_gpg_args[j] );          if (!strncmp (valid_gpg_args[j], buf, len))
659          if( !strncmp( valid_gpg_args[j], buf, len ) )              rc = 1;
             rc = 1;      
660      }      }
   
661      return rc;      return rc;
662  } /* check_line */  }
663    
664    
665  int  int
666  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf, int showerr)
667  {  {
668      char line[1024];      char line[1024];
669      int nbytes = 0;      int nbytes = 0, lineno=0;
670      unsigned j;      unsigned j;
671                    
672      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < DIM (line); j++) {
673          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
674          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
675              line[nbytes] = '\0';              line[nbytes] = '\0';
676              if( !check_line( line ) ) {              lineno++;
677                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
678                    if (showerr)
679                        log_box ("GPG Config File", MB_ERR,
680                                 "gpg.conf:%d: invalid keyword '%s'",
681                                 lineno, line);
682                  return 1;                        return 1;      
683              }              }
684                if (check_arg_file_exist (line))
685                    return WPTERR_FILE_EXIST;
686              nbytes = 0;              nbytes = 0;
687          }                }
688      }      }
   
689      return 0;      return 0;
690  } /* check_gnupg_options */  }
691    
692    
693  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
694  static int  static int
695  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
696  {  {
697      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
698    
699      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
700      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
701      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);  
702          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
703      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
704      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
705      return 0;      return 0;
706  }  }
707    
708    
709  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
710  static void  static void
711  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
712  {                {              
713      ctx->modified = 0;      ctx->modified = 0;
714    
715      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
716          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
717          ctx->modified = 1;          ctx->modified = 1;
718        
     /* XXX: find a better way. without it, winpt --keymanager loads  
             the key cache twice. */  
719      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
720          ctx->modified = 0;          ctx->modified = 0;
721    
# Line 700  check_last_gnupg_access (gpg_watcher_s * Line 724  check_last_gnupg_access (gpg_watcher_s *
724  }  }
725    
726    
727  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
728  void  void
729  init_gnupg_table (void)  init_gnupg_table (void)
730  {        {      
731      char *p;      char *path;
732      int j;      int j;
733    
734        path = get_gnupg_path ();
735      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
736          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
737          if (!p)          gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
             BUG (NULL);  
738          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
739          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
740          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
741      }      }
742        free_if_alloc (path);
743  }  }
744    
745    
746    /* Release the GPG monitor table. */
747  void  void
748  free_gnupg_table (void)  free_gnupg_table (void)
749  {  {
750      int j;      int j;
751    
752      for (j=0; j < gpg_table_count; j++)      for (j=0; j < gpg_table_count; j++) {
753          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
754            free_if_alloc (gpg_table[j].fpath_object);
755        }
756  }  }
757    
758    
759  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
760  int  int
761  keyring_check_last_access (void)  keyring_check_last_access (void)
762  {        {
763      int rc, j;      int nfiles;
764        int pos;
765    
766      rc = 0;      nfiles = 0;
767      for (j = 0; j < gpg_table_count; j++) {      for (pos = 0; pos < gpg_table_count; pos++) {
768          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
769          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
770          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
771              rc++;                    nfiles++;
772      }      }
773    
774      return rc;      return nfiles;
775  }  }
776    
777    
# Line 765  gnupg_check_file_ext (const char *fname, Line 794  gnupg_check_file_ext (const char *fname,
794              *r_type = PGP_SIG;              *r_type = PGP_SIG;
795          return "SIGNED";          return "SIGNED";
796      }      }
797      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
798                  !stricmp (file_ext, ".pgp")) {
799          if (r_type)          if (r_type)
800              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
801          return "ENCRYPTED";          return "ENCRYPTED";
# Line 774  gnupg_check_file_ext (const char *fname, Line 804  gnupg_check_file_ext (const char *fname,
804  }  }
805    
806    
807  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 */  
808  static int  static int
809  my_access (const char *fname)  check_file_access (const char *fname, int mode)
810  {  {
811      HANDLE hd;      HANDLE hd;
812      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,  
813        if (!mode)
814            mode = FILE_SHARE_WRITE;
815        hd = CreateFile (fname, GENERIC_WRITE, mode,
816                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
817      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
818          return -1;          return -1;
# Line 811  my_access (const char *fname) Line 820  my_access (const char *fname)
820      return 0;      return 0;
821  }  }
822    
823        
824    /* Check the device where the file @fname is stored on, is either
825       write-protected or if the file is already opened by another process
826       exclusively. And as a result, we cannot use the file for output. */
827    int
828    gpg_check_file_permissions (const char *fname, int mode)
829    {
830        int api_mode;
831        
832        switch (mode) {
833        case 0: api_mode = FILE_SHARE_READ; break;
834        case 1: api_mode = FILE_SHARE_WRITE; break;
835        case 2: api_mode = FILE_SHARE_WRITE|FILE_SHARE_READ; break;
836        default: api_mode = FILE_SHARE_READ; break;
837        }
838    
839        return check_file_access (fname, api_mode);
840    }
841    
842    
843  /* Check the file permissions of the public keyring.  /* Check the file permissions of the public keyring.
844     If @showmsg is 1 output a message in case of errors.     If @showmsg is 1 output a message in case of errors.
# Line 824  gpg_check_permissions (int showmsg) Line 852  gpg_check_permissions (int showmsg)
852      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
853    
854      p = get_gnupg_path ();      p = get_gnupg_path ();
855      if (check_keyring (&p) && p) {      if (p && check_keyring (&p)) {
856          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
857          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
858              ans = msg_box (NULL,              ans = msg_box (NULL,
# Line 845  gpg_check_permissions (int showmsg) Line 873  gpg_check_permissions (int showmsg)
873                  failed = 1;                  failed = 1;
874              }              }
875          }          }
876          if (my_access (name)) {          if (gpg_check_file_permissions (name, 1)) {
877              if (showmsg)              if (showmsg)
878                  msg_box (NULL,                  msg_box (NULL,
879                  _("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 868  gpg_check_permissions (int showmsg) Line 896  gpg_check_permissions (int showmsg)
896  int  int
897  gnupg_check_homedir (void)  gnupg_check_homedir (void)
898  {        {      
899      char *homedir = NULL;      char *homedir;
900      int val = 0;      int val;
901      int rc = 0;      int rc = 0;
902    
903    #ifdef WINPT_MOBILE
904        return 0;
905    #endif
906    
907      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
908      if (!homedir)      if (!homedir)
909          homedir = multi_gnupg_path (0);          homedir = multi_gnupg_path (0);
# Line 896  gnupg_check_homedir (void) Line 928  gnupg_check_homedir (void)
928  int  int
929  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
930  {  {
931      const char * pring, * sring;      const char *pring, *sring;
932      char * file = NULL, * path = NULL;      char *file = NULL, *path = NULL;
933      int id = 0, rc = 0;      int id = 0, rc = 0;
934      HWND hwnd;      HWND hwnd;
935            
# Line 906  gnupg_copy_keyrings (void) Line 938  gnupg_copy_keyrings (void)
938          return WPTERR_GENERAL;          return WPTERR_GENERAL;
939      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
940    
941      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
942                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
943      if (!pring) {      if (!pring) {
944          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
945                     _("WinPT Error"), MB_ERR);
946          free_if_alloc (path);          free_if_alloc (path);
947          return WPTERR_GENERAL;          return WPTERR_GENERAL;
948      }      }
949      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
950      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
951          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
952                          "WinPT", MB_INFO|MB_YESNO);
953          if (id == IDNO)          if (id == IDNO)
954              goto fail;              goto fail;
955      }      }
# Line 926  gnupg_copy_keyrings (void) Line 960  gnupg_copy_keyrings (void)
960      }      }
961      free_if_alloc (file);      free_if_alloc (file);
962    
963      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
964                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
965      if (!sring) {      if (!sring) {
966          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
967                     _("WinPT Error"), MB_ERR);
968          return WPTERR_GENERAL;          return WPTERR_GENERAL;
969      }      }
970      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
971      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
972          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
973          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
974            if (id == IDNO)
975              goto fail;              goto fail;
976      }      }
977      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
978          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
979          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
980      }      }
981    
# Line 947  fail: Line 983  fail:
983      free_if_alloc (file);      free_if_alloc (file);
984      free_if_alloc (path);      free_if_alloc (path);
985      return rc;      return rc;
986  } /* gnupg_import_keyrings */  }
987    
988    
989  /* Backup the gpg.conf file. */  /* Backup the gpg.conf file. */
990  void  void
991  gnupg_backup_options (void)  gnupg_backup_options (void)
992  {  {
993      char *cfgfile = NULL;      char *cfgfile;
994      char bak[512];      char bak[MAX_PATH+32];
995    
996      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
997      if (!cfgfile)      if (!cfgfile)
# Line 970  static int Line 1006  static int
1006  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
1007                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
1008  {  {
1009      char * src, * dst;      char *src, *dst;
1010      BOOL rc;      BOOL rc;
1011    
1012      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
1013      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
1014      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
1015      free_if_alloc (src);      free_if_alloc (src);
1016      free_if_alloc (dst);      free_if_alloc (dst);
1017      if (!rc)      if (!rc) {
     {  
1018          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
1019          return WPTERR_GENERAL;          return WPTERR_GENERAL;
1020      }      }
1021      return 0;      return 0;
1022  } /* backup_one_file */  }
1023    
1024    
1025  /* Figure out first public keyring which is not empty.  /* Figure out first public keyring which is not empty.
# Line 1003  check_keyring (char **r_path) Line 1034  check_keyring (char **r_path)
1034      if (!*r_path)      if (!*r_path)
1035          return 0;          return 0;
1036      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1037      if (!p || get_file_size (p) <= 0)      if (get_file_size (p) <= 0)
1038          return 0;          return 0;
1039    
1040      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
1041      if (!opt)      if (!opt)
1042          BUG (0);          BUG (0);
1043      name = get_gnupg_keyring_from_options (opt, 1);      name = get_keyring_from_conf (opt, 1);
1044      free_if_alloc (opt);      free_if_alloc (opt);
1045      free_if_alloc (p);      free_if_alloc (p);
1046      if (!name)      if (!name)
# Line 1033  static char* Line 1064  static char*
1064  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1065  {  {
1066      struct tm *tm;      struct tm *tm;
1067        const char *fmt;
1068      char *p;      char *p;
1069      time_t t;      time_t t;
1070    
1071      t = time (NULL);      t = time (NULL);
1072      tm = localtime (&t);      tm = localtime (&t);
1073      p = new char [strlen (templ) + 8 + 1];      fmt = "%s-%d";
1074        p = new char [strlen (templ) + strlen (fmt) + 8 + 1];
1075      if (!p)      if (!p)
1076          BUG (0);          BUG (0);
1077      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);      sprintf (p, fmt, templ, tm->tm_wday % 3);
1078      return p;      return p;
1079  }  }
1080    
1081    
1082  /* Make backups of all keyrings. The public key ring is  /* Make backups of all keyrings. The public key ring is rotated like
1083     rotated like this pubring-%d.gpg. */     this pubring-%d.gpg.
1084       If @auto_backup is false, no action is performed.
1085       @include_secr indicated if the backup includes the secret keyring. */
1086  void  void
1087  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1088  {  {
1089      char *srcpath = NULL, *dstpath = NULL;      char *srcpath, *dstpath;
1090      char *name=NULL;      char *name;
1091      int rc, bakmode=0;      int rc;
1092    
1093      if (!reg_prefs.auto_backup)      if (!auto_backup)
1094          return;          return;
     bakmode = reg_prefs.backup.mode;  
1095      srcpath = get_gnupg_path ();      srcpath = get_gnupg_path ();
1096      check_keyring (&srcpath);      check_keyring (&srcpath);
1097      if (bakmode == 1) {      if (backup_mode == 1) {
1098          dstpath = multi_gnupg_path (1);          /* If the backup mode uses the home directory the source
1099               and destination folder will be the same. */
1100            dstpath = get_gnupg_path ();
1101          check_keyring (&dstpath);          check_keyring (&dstpath);
1102      }      }
1103      else if (bakmode == 2) {      else if (backup_mode == 2) {
1104          char *tmpfile;          char *tmpfile;
1105          FILE *fp;          FILE *fp;
1106    
1107          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1108          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1109          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1110          if (!fp)          if (!fp)
1111              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1112                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1113                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1114          else {          else {
1115              rc = 0;              rc = 0;
1116              fclose (fp);              fclose (fp);
1117              remove (tmpfile);              DeleteFile (tmpfile);
1118          }          }
1119          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1120          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL) {
1121                free_if_alloc (dstpath);
1122                free_if_alloc (srcpath);
1123              return;              return;
1124            }
1125      }      }
1126      else {      else {
1127          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1128            free_if_alloc (srcpath);
1129          return;          return;
1130      }      }
1131      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1132      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1133      if (!rc)      if (!rc && include_secr)
1134          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1135      free_if_alloc (name);      free_if_alloc (name);
1136      free_if_alloc (srcpath);      free_if_alloc (srcpath);
# Line 1100  gnupg_backup_keyrings (void) Line 1138  gnupg_backup_keyrings (void)
1138  }  }
1139    
1140    
 /* 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);  
 }  
   
   
   
1141  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1142     Return value: 0 for success. */     Return value: 0 for success. */
1143  int  int

Legend:
Removed from v.167  
changed lines
  Added in v.304

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26