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

Diff of /trunk/Src/wptGPG.cpp

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

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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26