/[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 138 by twoaday, Mon Jan 9 14:20:00 2006 UTC revision 270 by twoaday, Sat Oct 21 18:08:57 2006 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 43  Line 43 
43  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  /* Context to monitor GPG file changes. */
47      FILETIME    last_access;  struct gpg_monitor_s {
48        FILETIME    last_access;    /* last write access. */
49      FILETIME    access;      FILETIME    access;
50      char        *object;      char        *object;        /* name of the object. */
51      int         modified;      char        *fpath_object;  /* full path to the object. */
52        int         modified;       /* 1 = modified. */
53  };  };
54    typedef struct gpg_monitor_s *gpg_monitor_t;
55    
56    static const char *gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
57  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */  static gpg_monitor_s gpg_table[3];
 static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};  
 static gpg_watcher_s gpg_table[3];  
58  static int gpg_table_count = DIM (gpg_table);  static int gpg_table_count = DIM (gpg_table);
59    
60  int idea_available = 0;  int idea_available = 0; /* if the IDEA extension is available. */
61    
62    
63  static int check_keyring (char ** r_path);  static int check_keyring (char ** r_path);
64    
# Line 92  get_gnupg_path (void) Line 94  get_gnupg_path (void)
94      char *path;      char *path;
95    
96      path = get_reg_entry_gpg (GPG_REG_HOME);      path = get_reg_entry_gpg (GPG_REG_HOME);
97      if (path) {      if (path && dir_exist_check (path) == 0)
98          if (dir_exist_check (path) == 0)          return path;
99              return path;      free_if_alloc (path);
100          free_if_alloc (path);      return multi_gnupg_path (1);
     }  
     path = multi_gnupg_path (1);  
     return path;  
101  }  }
102    
103    
# Line 106  get_gnupg_path (void) Line 105  get_gnupg_path (void)
105     A value of NULL indicates an error. */     A value of NULL indicates an error. */
106  char*  char*
107  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
108  {      {
     char *p = NULL;  
109      char *optfile = NULL;      char *optfile = NULL;
110      char *path = NULL;      char *path;
111      size_t nlen = 0;      size_t nlen;
112    
113      path = get_gnupg_path ();      path = get_gnupg_path ();
114      if (!path)      if (!path)
115          return NULL;          return NULL;
116      p = get_reg_entry_gpg ("OptFile");      nlen = strlen (path) + 64;
117      if (p && !strcmp (p, "")) {      optfile = new char[nlen + 1];
118          nlen = strlen (path) + 64;      if (!optfile)
119          optfile = new char[nlen + 1];          BUG (NULL);
120          if (!optfile)      _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
121              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);  
     }  
122      free_if_alloc (path);      free_if_alloc (path);
     free_if_alloc (p);  
123      return optfile;      return optfile;
124  }  }
125    
# Line 178  get_gnupg_keyring (int pub, int strict) Line 159  get_gnupg_keyring (int pub, int strict)
159  /* 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
160     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
161     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
162  char*  char*
163  get_gnupg_prog (void)  get_gnupg_prog (void)
164  {      {    
165      char *p;      char *path;
166      char *pgm = NULL;      char *pgm;
167    
168      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
169      if (!p) {      if (pgm)
170          char *path = get_gnupg_path ();          return pgm;
171          if (!path)      path = get_gnupg_path ();
172              return NULL;      if (!path)
173          pgm = make_filename (path, "gpg", "exe");          return NULL;    
174          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
175      }      free_if_alloc (path);
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
176      return pgm;      return pgm;
177  }  }
178    
# Line 205  get_gnupg_prog (void) Line 180  get_gnupg_prog (void)
180  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
181     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
182     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
183  static char *  static char*
184  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
185  {  {    
186        gpgme_key_t key, pk;
187        gpg_keycache_t sec, pub;
188      const char *s;      const char *s;
189      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
190    
191      if (!sec)      sec = keycache_get_ctx (0);
192          BUG (0);      pub = keycache_get_ctx (1);
193      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
194      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
195          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
196              s = key->subkeys->keyid;              s = key->subkeys->keyid;
197              if (s)                  if (s)
198                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
199              break;              break;
200          }          }
201      }      }
# Line 235  default_key_from_cache (int *ret_no_usea Line 210  default_key_from_cache (int *ret_no_usea
210     Return value: 0 on success. */     Return value: 0 on success. */
211  int  int
212  gnupg_load_config (void)  gnupg_load_config (void)
213  {  {    
     int rc;  
214      gpg_optfile_t opt;      gpg_optfile_t opt;
215      gpg_option_t o;      char *conf;
216      char *conf = get_gnupg_cfgfile ();      
217        conf = get_gnupg_cfgfile ();
218      if (!conf)      if (!conf)
219          return -1;          return -1;
220      rc = parse_gpg_options (conf, &opt);      if (parse_config (conf, &opt)) {
     if (rc) {  
221          free_if_alloc (conf);          free_if_alloc (conf);
222          return -1;          return -1;
223      }      }
224      o = find_option (opt, "ask-cert-level");      if (find_option (opt, "ask-cert-level"))
     if (o)  
225          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
226      release_gpg_options (opt);      if (find_option (opt, "ask-cert-expire"))
227            reg_prefs.gpg.ask_cert_expire = 1;
228        release_config (opt);
229      free_if_alloc (conf);      free_if_alloc (conf);
230      return 0;      return 0;
231  }  }
232    
233    
234    /* handle the case the user added a '!' to force a subkey. */
235    static char*
236    extract_keyid (const char *val)
237    {    
238        size_t len = strlen (val);
239    
240        if (len > 1 && val[len-1] == '!') {
241            char *p = new char[len+1];
242            if (!p)
243                BUG (0);
244            memset (p, 0, len+1);
245            memcpy (p, val, len-1);
246            return p;
247        }
248        return m_strdup (val);
249    }
250    
251    
252  char*  char*
253  get_gnupg_default_key (void)  get_gnupg_default_key (void)
254  {      {    
255      gpg_optfile_t opt = NULL;      gpg_optfile_t opt = NULL;
256      gpg_option_t e;      gpg_option_t e;
257      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
258      int no_usable=0, rc = 0;      int no_usable=0;
259    
260      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
261      if (!optfile)      if (!optfile)
262          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
263      rc = parse_gpg_options (optfile, &opt);      if (parse_config (optfile, &opt)) {
     if (rc) {  
264          free_if_alloc (optfile);          free_if_alloc (optfile);
265          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
266      }      }
267      e = find_option( opt, "default-key" );      e = find_option (opt, "default-key");
268      if ( e )      if (!e)
269          keyid = m_strdup( e->val );          e = find_option (opt, "local-user");
270      if( !e ) {      if (e)
271          e = find_option( opt, "local-user" );          keyid = extract_keyid (e->val);
         if( e )  
             keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
     free_if_alloc (optfile);  
     release_gpg_options (opt);  
272    
273        free_if_alloc (optfile);
274        release_config (opt);
275      if (!keyid)      if (!keyid)
276          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
277      return keyid;      return keyid;
278  } /* get_gnupg_default_key */  }
279    
280    
281  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
# Line 334  parse_version_nr (const char *buf, int * Line 318  parse_version_nr (const char *buf, int *
318      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
319          tmp[i++] = *buf++;          tmp[i++] = *buf++;
320      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
321      *major = atol( tmp );      *major = atoi (tmp);
322      i=0;      i=0;
323      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
324          tmp[i++] = *buf++;          tmp[i++] = *buf++;
325      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
326      *minor = atol (tmp);      *minor = atoi (tmp);
327      i=0;      i=0;
328      while (buf && isdigit (*buf) && i < 8)      while (buf && isdigit (*buf) && i < 8)
329          tmp[i++] = *buf++;          tmp[i++] = *buf++;
330      tmp[i] = 0;      tmp[i] = 0;
331      *patch = atol (tmp);      *patch = atoi (tmp);
332      return 0;      return 0;
333  }  }
334    
# Line 376  check_gnupg_engine (const char *need_gpg Line 360  check_gnupg_engine (const char *need_gpg
360      }      }
361    
362      /* 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. */
363      if (gpg_get_version (&eng))      if (gpg_get_version (&eng)) {
364            gpgme_release (ctx);
365          return -1;          return -1;
366        }
367      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
368          idea_available = 1;          idea_available = 1;
369      free (eng);      safe_free (eng);
370      if (parse_version_nr (inf->version, &major, &minor, &patch)) {      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
371          gpgme_release (ctx);          gpgme_release (ctx);
372          return 1;          return 1;
373      }      }
374        gpgme_release (ctx);
375    
376      if (major > need_major)      if (major > need_major)
377          rc = 0;          rc = 0;
# Line 402  check_gnupg_engine (const char *need_gpg Line 389  check_gnupg_engine (const char *need_gpg
389  }  }
390    
391    
392  int  /* Count the keyring entries in the gpg.conf file.
393  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
394    static int
395    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
396  {  {
397      gpg_optfile_t opt;          gpg_optfile_t opt;    
398      gpg_option_t e;      gpg_option_t e;
     int rc = 0;  
399    
400      *r_secrings = 0;      *r_secrings = 0;
401      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
402    
403      for( e = opt->list; e; e = e->next ) {      if (parse_config (fname, &opt))
404          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
405              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
406            if (!strcmp (e->name, "secret-keyring")) {
407                if (!file_exist_check (e->val))
408                  r_secrings[0]++;                  r_secrings[0]++;
409          }          }
410          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
411              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
412                  r_pubrings[0]++;                  r_pubrings[0]++;
413          }          }
414      }      }
415      release_gpg_options( opt );      release_config (opt);
416      return 0;      return 0;
417  } /* check_gnupg_cfgfile */  }
418    
419    
420  /* Usually GPG creates the pubring.gpg, secring.gpg on  /* Usually GPG creates the pubring.gpg, secring.gpg on
# Line 437  static void Line 424  static void
424  create_empty_keyring (int _pub)  create_empty_keyring (int _pub)
425  {  {
426      char *name;      char *name;
427      FILE *f;      FILE *fp;
428    
429      name = get_gnupg_keyring (_pub, 0);      name = get_gnupg_keyring (_pub, 0);
430      if (file_exist_check (name) != 0) {      if (name && file_exist_check (name) != 0) {
431          f = fopen (name, "ab");          fp = fopen (name, "ab");
432          if (f != NULL)          if (fp != NULL)
433              fclose (f);              fclose (fp);
434      }      }
435      free_if_alloc (name);      free_if_alloc (name);
436  }  }
# Line 476  gnupg_access_files (void) Line 463  gnupg_access_files (void)
463              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
464          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
465          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
466              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
467              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
468                  free_if_alloc (optfile);                  free_if_alloc (optfile);
469                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
470              }              }
# Line 497  gnupg_access_files (void) Line 484  gnupg_access_files (void)
484    
485    
486  static int  static int
487  create_gpg_options (void)  create_gpg_conf (void)
488  {  {
489      FILE *fp;      FILE *fp;
490      char *s, *optfile;      char *s, *optfile;
491    
492      s = get_gnupg_path ();      s = get_gnupg_path ();
493      if( s == NULL )      if (!s)
494          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
495      optfile = make_filename (s, GPG_CONF, NULL);      optfile = make_filename (s, GPG_CONF, NULL);
496      fp = fopen (optfile, "wb");      fp = fopen (optfile, "wb");
497      if (fp == NULL) {        if (!fp) {
498          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
499          goto fail;          goto fail;
500      }      }
# Line 518  fail: Line 505  fail:
505      free_if_alloc (s);      free_if_alloc (s);
506      free_if_alloc (optfile);      free_if_alloc (optfile);
507      return 0;      return 0;
508  } /* create_gpg_options */  }
509    
510    
511  /*  /* Return the contents of the options file as a char buf. */
512   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
513  get_gnupg_config (void)  get_gnupg_config (void)
514  {  {
515      FILE * fp;      FILE *fp;
516      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
517      int fsize, rc = 0;      int fsize;
518                    
519      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
520      if( optfile == NULL )      if (!optfile)
521          return NULL;          return NULL;
522      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
523      if( !fsize ) {      if (!fsize) {
524          rc = create_gpg_options( );          if (create_gpg_conf ())
         if ( rc )  
525              return NULL;              return NULL;
526          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
527      }      }
528      if( fsize > 100000 )      if (fsize > 100000)
529          goto leave; /* too large */          goto leave; /* too large */
530      p = new char[fsize+1];      p = new char[fsize+1];
531      if( p == NULL )      if (!p)
532          BUG( NULL );          BUG (NULL);
533      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
534      if( fp == NULL ) {      if (!fp) {
535          free_if_alloc( p );          free_if_alloc (p);
536          return NULL;          return NULL;
537      }      }
538      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
539      fclose( fp );      fclose (fp);
540      p[fsize] = '\0';      p[fsize] = '\0';
541      free_if_alloc( optfile );      free_if_alloc (optfile);
542    
543  leave:  leave:
544      return p;      return p;
545  } /* get_gnupg_config */  }
546    
547    
548    /* Set the default key in the gpg.conf.
549       If @key is NULL, the entry will be deleted. */
550  int  int
551  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
552  {  {
553      gpg_optfile_t opt;      gpg_optfile_t opt;
554      gpg_option_t e;      gpg_option_t e;
# Line 571  set_gnupg_default_key (const char * key) Line 557  set_gnupg_default_key (const char * key)
557    
558      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
559      if (!optfile)      if (!optfile)
560          return -1;          return WPTERR_FILE_OPEN;
561      rc = parse_gpg_options (optfile, &opt);      rc = parse_config (optfile, &opt);
562      if( rc ) {      if (rc) {
563          free_if_alloc (optfile);          free_if_alloc (optfile);
564          return -1;          return WPTERR_GENERAL;
565      }      }
566      e = find_option (opt, "default-key");      e = find_option (opt, "default-key");
567      if (e) {      if (e && !key)
568            e->used = 0;
569        else if (e) {
570          free_if_alloc (e->val);          free_if_alloc (e->val);
571          e->val = m_strdup (key);          e->val = m_strdup (key);
572          e->used = 1;          e->used = 1;
573      }      }
574      else      else if (key)
575          add_entry (opt, ENTRY_MULTI, "default-key", key);          add_entry (opt, ENTRY_MULTI, "default-key", key);
576      rc = commit_gpg_options (optfile, opt);      rc = commit_config (optfile, opt);
577    
578      free_if_alloc (optfile);      free_if_alloc (optfile);
579      release_gpg_options (opt);      release_config (opt);
   
580      return rc;      return rc;
581  } /* set_gnupg_default_key */  }
582    
583    
584  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
585  int  int
586  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
587  {  {
588      FILE *fp;        FILE *fp;  
589      char *optfile = NULL;      char *optfile;
590    
591      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
592      if( optfile == NULL )      if (!optfile)
593          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
594    
595      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
596      if( fp == NULL ) {      if (!fp) {
597          free_if_alloc( optfile );          free_if_alloc (optfile);
598          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
599      }      }
600      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
601      fclose( fp );      fclose (fp);
602      free_if_alloc( optfile );      free_if_alloc (optfile);
603      return 0;      return 0;
604  } /* set_gnupg_options */  }
605    
606  /*  
607   * Check if the line contains a valid GPG argument.  /* Check if the parameter for the option @buf is an existing file name.
608   */     Return value: 0 on success. */
609    static int
610    check_arg_file_exist (const char *buf)
611    {
612        const char *s = "load-extension ";
613    
614        /* XXX: this is a bit of a kludge because we just
615                detect errors for 'load-extension'. */
616        if (!strncmp (buf, s, strlen (s)))
617            buf += strlen (s);
618        else
619            return 0;
620        return file_exist_check (buf);
621    }
622    
623    
624    /* Check if the line contains a valid GPG argument. */
625  static int  static int
626  check_line( const char *buf )  check_line (const char *buf)
627  {  {
628      int j, len;      int j, len;
629      int rc = 0;      int rc;
630    
631      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
632          return 1;          return 1;
633      rc = 0;      rc = 0;
634      for ( j = 0; valid_gpg_args[j]; j++ ) {      for (j = 0; valid_gpg_args[j]; j++) {
635          len = strlen( valid_gpg_args[j] );          len = strlen (valid_gpg_args[j]);
636          if( !strncmp( valid_gpg_args[j], buf, len ) )          if (!strncmp (valid_gpg_args[j], buf, len))
637              rc = 1;                  rc = 1;
638      }      }
   
639      return rc;      return rc;
640  } /* check_line */  }
641    
642    
643  int  int
644  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf, int showerr)
645  {  {
646      char line[1024];      char line[1024];
647      int nbytes = 0;      int nbytes = 0, lineno=0;
648      unsigned j;      unsigned j;
649                    
650      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < sizeof (line); j++) {
651          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
652          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
653              line[nbytes] = '\0';              line[nbytes] = '\0';
654              if( !check_line( line ) ) {              lineno++;
655                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
656                    if (showerr)
657                        log_box ("GPG Config File", MB_ERR,
658                                 "gpg.conf:%d: invalid keyword '%s'",
659                                 lineno, line);
660                  return 1;                        return 1;      
661              }              }
662                if (check_arg_file_exist (line))
663                    return WPTERR_FILE_EXIST;
664              nbytes = 0;              nbytes = 0;
665          }                }
666      }      }
   
667      return 0;      return 0;
668  } /* check_gnupg_options */  }
669    
670    
671  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
672  static int  static int
673  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
674  {  {
675      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
676    
677      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
678      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_ALWAYS, 0, NULL);
679      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);  
680          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
681      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
682      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
683      return 0;      return 0;
684  }  }
685    
686    
687  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
688  static void  static void
689  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
690  {                {              
691      ctx->modified = 0;      ctx->modified = 0;
692    
693      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
694          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
695          ctx->modified = 1;          ctx->modified = 1;
696        
     /* XXX: find a better way. without it, winpt --keymanager loads  
             the key cache twice. */  
697      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
698          ctx->modified = 0;          ctx->modified = 0;
699    
# Line 707  check_last_gnupg_access (gpg_watcher_s * Line 702  check_last_gnupg_access (gpg_watcher_s *
702  }  }
703    
704    
705  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
706  void  void
707  init_gnupg_table (void)  init_gnupg_table (void)
708  {        {      
709      char *p;      char *path;
710      int j;      int j;
711    
712        path = get_gnupg_path ();
713      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
714          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
715          if (!p)          gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
             BUG (NULL);  
716          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
717          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
718          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
719      }      }
720        free_if_alloc (path);
721  }  }
722    
723    
724    /* Release the GPG monitor table. */
725  void  void
726  free_gnupg_table (void)  free_gnupg_table (void)
727  {  {
728      int j;      int j;
729    
730      for (j=0; j < gpg_table_count; j++)      for (j=0; j < gpg_table_count; j++) {
731          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
732            free_if_alloc (gpg_table[j].fpath_object);
733        }
734  }  }
735    
736    
737  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
738  int  int
739  keyring_check_last_access (void)  keyring_check_last_access (void)
740  {        {
741      int rc, j;      int nfiles;
742        int pos;
743    
744      rc = 0;      nfiles = 0;
745      for (j = 0; j < gpg_table_count; j++) {      for (pos = 0; pos < gpg_table_count; pos++) {
746          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
747          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
748          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
749              rc++;                    nfiles++;
750      }      }
751    
752      return rc;      return nfiles;
753  }  }
754    
755    
# Line 772  gnupg_check_file_ext (const char *fname, Line 772  gnupg_check_file_ext (const char *fname,
772              *r_type = PGP_SIG;              *r_type = PGP_SIG;
773          return "SIGNED";          return "SIGNED";
774      }      }
775      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
776                  !stricmp (file_ext, ".pgp")) {
777          if (r_type)          if (r_type)
778              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
779          return "ENCRYPTED";          return "ENCRYPTED";
# Line 782  gnupg_check_file_ext (const char *fname, Line 783  gnupg_check_file_ext (const char *fname,
783    
784    
785  char*  char*
786  get_gnupg_keyring_from_options (const char * fname, int pub)  get_gnupg_keyring_from_options (const char *fname, int pub)
787  {  {
788      gpg_optfile_t opt;      gpg_optfile_t opt;
789      gpg_option_t e;      gpg_option_t e;
790      char * kring = NULL;      char *kring = NULL;
791      int rc = 0;      int rc;
792    
793      rc = parse_gpg_options (fname, &opt);      rc = parse_config (fname, &opt);
794      if (rc)      if (rc)
795          return NULL;          return NULL;
796      if (pub)      if (pub)
# Line 798  get_gnupg_keyring_from_options (const ch Line 799  get_gnupg_keyring_from_options (const ch
799          e = find_option (opt, "secret-keyring");          e = find_option (opt, "secret-keyring");
800      if (e)      if (e)
801          kring = m_strdup (e->val);          kring = m_strdup (e->val);
802      release_gpg_options (opt);      release_config (opt);
803    
804      return kring;      return kring;
805  }  }
806    
807    
808    /* Check if the device file @fname is stored on, is write-protected. */
 /* XXX: does not work with write-protected floppies */  
809  static int  static int
810  my_access (const char *fname)  my_access (const char *fname)
811  {  {
812      HANDLE hd;      HANDLE hd;
813    
814      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
815                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
816      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
# Line 831  gpg_check_permissions (int showmsg) Line 832  gpg_check_permissions (int showmsg)
832      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
833    
834      p = get_gnupg_path ();      p = get_gnupg_path ();
835      if (check_keyring (&p) && p) {      if (p && check_keyring (&p)) {
836          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
837          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
838              ans = msg_box (NULL,              ans = msg_box (NULL,
# Line 875  gpg_check_permissions (int showmsg) Line 876  gpg_check_permissions (int showmsg)
876  int  int
877  gnupg_check_homedir (void)  gnupg_check_homedir (void)
878  {        {      
879      char *homedir = NULL;      char *homedir;
880      int val = 0;      int val;
881      int rc = 0;      int rc = 0;
882    
883      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
# Line 903  gnupg_check_homedir (void) Line 904  gnupg_check_homedir (void)
904  int  int
905  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
906  {  {
907      const char * pring, * sring;      const char *pring, *sring;
908      char * file = NULL, * path = NULL;      char *file = NULL, *path = NULL;
909      int id = 0, rc = 0;      int id = 0, rc = 0;
910      HWND hwnd;      HWND hwnd;
911            
# Line 913  gnupg_copy_keyrings (void) Line 914  gnupg_copy_keyrings (void)
914          return WPTERR_GENERAL;          return WPTERR_GENERAL;
915      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
916    
917      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
918                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
919      if (!pring) {      if (!pring) {
920          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
921                     _("WinPT Error"), MB_ERR);
922          free_if_alloc (path);          free_if_alloc (path);
923          return WPTERR_GENERAL;          return WPTERR_GENERAL;
924      }      }
925      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
926      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
927          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
928                          "WinPT", MB_INFO|MB_YESNO);
929          if (id == IDNO)          if (id == IDNO)
930              goto fail;              goto fail;
931      }      }
# Line 933  gnupg_copy_keyrings (void) Line 936  gnupg_copy_keyrings (void)
936      }      }
937      free_if_alloc (file);      free_if_alloc (file);
938    
939      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
940                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
941      if (!sring) {      if (!sring) {
942          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
943                     _("WinPT Error"), MB_ERR);
944          return WPTERR_GENERAL;          return WPTERR_GENERAL;
945      }      }
946      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
947      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
948          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
949          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
950            if (id == IDNO)
951              goto fail;              goto fail;
952      }      }
953      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
954          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
955          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
956      }      }
957    
# Line 954  fail: Line 959  fail:
959      free_if_alloc (file);      free_if_alloc (file);
960      free_if_alloc (path);      free_if_alloc (path);
961      return rc;      return rc;
962  } /* gnupg_import_keyrings */  }
963    
964    
965  /* Backup the gpg.conf file. */  /* Backup the gpg.conf file. */
966  void  void
967  gnupg_backup_options (void)  gnupg_backup_options (void)
968  {  {
969      char *cfgfile = NULL;      char *cfgfile;
970      char bak[512];      char bak[MAX_PATH+32];
971    
972      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
973      if (!cfgfile)      if (!cfgfile)
# Line 977  static int Line 982  static int
982  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
983                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
984  {  {
985      char * src, * dst;      char *src, *dst;
986      BOOL rc;      BOOL rc;
987    
988      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
989      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
990      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
991      free_if_alloc (src);      free_if_alloc (src);
992      free_if_alloc (dst);      free_if_alloc (dst);
993      if (!rc)      if (!rc) {
     {  
994          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
995          return WPTERR_GENERAL;          return WPTERR_GENERAL;
996      }      }
997      return 0;      return 0;
998  } /* backup_one_file */  }
999    
1000    
1001  /* Figure out first public keyring which is not empty.  /* Figure out first public keyring which is not empty.
# Line 1010  check_keyring (char **r_path) Line 1010  check_keyring (char **r_path)
1010      if (!*r_path)      if (!*r_path)
1011          return 0;          return 0;
1012      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1013      if (!p || get_file_size (p) <= 0)      if (get_file_size (p) <= 0)
1014          return 0;          return 0;
1015    
1016      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
# Line 1053  get_backup_name (const char *templ) Line 1053  get_backup_name (const char *templ)
1053  }  }
1054    
1055    
1056  /* Make backups of all keyrings. The public key ring is  /* Make backups of all keyrings. The public key ring is rotated like
1057     rotated like this pubring-%d.gpg. */     this pubring-%d.gpg.
1058       If @auto_backup is false, no action is performed.
1059       @include_secr indicated if the backup includes the secret keyring. */
1060  void  void
1061  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1062  {  {
1063      char *srcpath = NULL, *dstpath = NULL;      char *srcpath = NULL, *dstpath = NULL;
1064      char *name=NULL;      char *name=NULL;
1065      int rc, bakmode=0;      int rc;
1066    
1067      if (!reg_prefs.auto_backup)      if (!auto_backup)
1068          return;          return;
     bakmode = reg_prefs.backup.mode;  
1069      srcpath = get_gnupg_path ();      srcpath = get_gnupg_path ();
1070      check_keyring (&srcpath);      check_keyring (&srcpath);
1071      if (bakmode == 1) {      if (backup_mode == 1) {
1072          dstpath = multi_gnupg_path (1);          dstpath = multi_gnupg_path (1);
1073          check_keyring (&dstpath);          check_keyring (&dstpath);
1074      }      }
1075      else if (bakmode == 2) {      else if (backup_mode == 2) {
1076          char *tmpfile;          char *tmpfile;
1077          FILE *fp;          FILE *fp;
1078    
1079          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1080          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1081          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1082          if (!fp)          if (!fp)
1083              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1084                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1085                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1086          else {          else {
1087              rc = 0;              rc = 0;
1088              fclose (fp);              fclose (fp);
1089              remove (tmpfile);              DeleteFile (tmpfile);
1090          }          }
1091          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1092          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL)
1093              return;              return;
1094      }      }
1095      else {      else {
1096          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1097          return;          return;
1098      }      }
1099      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1100      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1101      if (!rc)      if (!rc && include_secr)
1102          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1103      free_if_alloc (name);      free_if_alloc (name);
1104      free_if_alloc (srcpath);      free_if_alloc (srcpath);
# Line 1107  gnupg_backup_keyrings (void) Line 1106  gnupg_backup_keyrings (void)
1106  }  }
1107    
1108    
 /* 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);  
 }  
   
   
   
1109  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1110     Return value: 0 for success. */     Return value: 0 for success. */
1111  int  int

Legend:
Removed from v.138  
changed lines
  Added in v.270

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26