/[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 85 by twoaday, Fri Nov 18 07:20:40 2005 UTC revision 248 by twoaday, Fri Jul 28 11:11:09 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 62  static int check_keyring (char ** r_path Line 62  static int check_keyring (char ** r_path
62    
63    
64  /* Return the application data folder of the current user. */  /* Return the application data folder of the current user. */
65  static char*  char*
66  multi_gnupg_path (int strict)  multi_gnupg_path (int strict)
67  {  {
68      static char buf[256+64];      static char buf[256+64];
# Line 84  multi_gnupg_path (int strict) Line 84  multi_gnupg_path (int strict)
84  }  }
85    
86    
87  /* 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
88     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. */
 */  
89  char*  char*
90  get_gnupg_path (void)  get_gnupg_path (void)
91  {  {
92      char *p = NULL;      char *path;
93      char *path = NULL;  
94            path = get_reg_entry_gpg (GPG_REG_HOME);
95      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);  
96          return path;          return path;
97      }      free_if_alloc (path);
98      else      path = multi_gnupg_path (1);
99          return multi_gnupg_path (1);      return path;
     return m_strdup ("c:\\gnupg");  
100  }  }
101    
102    
# Line 118  get_gnupg_cfgfile (void) Line 113  get_gnupg_cfgfile (void)
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);
123      free_if_alloc (p);      free_if_alloc (p);
124      return optfile;      return optfile;
# Line 159  get_gnupg_keyring (int pub, int strict) Line 138  get_gnupg_keyring (int pub, int strict)
138      if (!path)      if (!path)
139          return NULL;          return NULL;
140      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
141      if (!strict && !file_exist_check (keyring)) {      if (strict && !file_exist_check (keyring)) {
142            free_if_alloc (path);
143            return keyring;
144        }
145        else if (!strict) {
146          free_if_alloc (path);          free_if_alloc (path);
147          return keyring;          return keyring;
148      }      }
# Line 177  get_gnupg_keyring (int pub, int strict) Line 160  get_gnupg_keyring (int pub, int strict)
160  /* Return the full path (with the gpg exe name). First the registry is scanned  /* Return the full path (with the gpg exe name). First the registry is scanned
161     for the entry 'gpgProgram'. If it wasn't set, the default path is the     for the entry 'gpgProgram'. If it wasn't set, the default path is the
162     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
163  char*  char*
164  get_gnupg_prog (void)  get_gnupg_prog (void)
165  {      {    
166      char *p;      char *path;
167      char *pgm = NULL;      char *pgm;
168    
169      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
170      if (!p) {      if (pgm)
171          char *path = get_gnupg_path ();          return pgm;
172          if (!path)      path = get_gnupg_path ();
173              return NULL;      if (!path)
174          pgm = make_filename (path, "gpg", "exe");          return NULL;    
175          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
176      }      free_if_alloc (path);    
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
177      return pgm;      return pgm;
178  }  }
179    
# Line 206  get_gnupg_prog (void) Line 183  get_gnupg_prog (void)
183     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
184  static char *  static char *
185  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
186  {  {    
187        gpgme_key_t key, pk;
188        gpg_keycache_t sec, pub;
189      const char *s;      const char *s;
190      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
191    
192      if (!sec)      sec = keycache_get_ctx (0);
193          BUG (0);      pub = keycache_get_ctx (1);
194      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
195      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
196          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
197              s = key->subkeys->keyid;              s = key->subkeys->keyid;
198              if (s)                  if (s)
199                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
200              break;              break;
201          }          }
202      }      }
# Line 238  gnupg_load_config (void) Line 215  gnupg_load_config (void)
215      int rc;      int rc;
216      gpg_optfile_t opt;      gpg_optfile_t opt;
217      gpg_option_t o;      gpg_option_t o;
218      char *conf = get_gnupg_cfgfile ();      char *conf;
219        
220        conf = get_gnupg_cfgfile ();
221      if (!conf)      if (!conf)
222          return -1;          return -1;
223      rc = parse_gpg_options (conf, &opt);      rc = parse_gpg_options (conf, &opt);
# Line 249  gnupg_load_config (void) Line 228  gnupg_load_config (void)
228      o = find_option (opt, "ask-cert-level");      o = find_option (opt, "ask-cert-level");
229      if (o)      if (o)
230          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
231        o = find_option (opt, "ask-cert-expire");
232        if (o)
233            reg_prefs.gpg.ask_cert_expire = 1;
234      release_gpg_options (opt);      release_gpg_options (opt);
235      free_if_alloc (conf);      free_if_alloc (conf);
236      return 0;      return 0;
237  }  }
238    
239    
240    /* handle the case the user added a '!' to force a subkey. */
241    static char*
242    extract_keyid (const char *val)
243    {    
244        size_t len = strlen (val);
245    
246        if (len > 1 && val[len-1] == '!') {
247            char *p = new char[len+1];
248            if (!p)
249                BUG (0);
250            memset (p, 0, len+1);
251            memcpy (p, val, len-1);
252            return p;
253        }
254        return m_strdup (val);
255    }
256    
257    
258  char*  char*
259  get_gnupg_default_key (void)  get_gnupg_default_key (void)
260  {      {    
261      gpg_optfile_t opt = NULL;      gpg_optfile_t opt = NULL;
262      gpg_option_t e;      gpg_option_t e;
263      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
264      int no_usable=0, rc = 0;      int no_usable=0, rc = 0;
265    
266      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
# Line 271  get_gnupg_default_key (void) Line 271  get_gnupg_default_key (void)
271          free_if_alloc (optfile);          free_if_alloc (optfile);
272          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
273      }      }
274      e = find_option( opt, "default-key" );      e = find_option (opt, "default-key");
275      if ( e )      if (!e)
276          keyid = m_strdup( e->val );          e = find_option (opt, "local-user");
277      if( !e ) {      if (e)
278          e = find_option( opt, "local-user" );          keyid = extract_keyid (e->val);
279          if( e )  
             keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
280      free_if_alloc (optfile);      free_if_alloc (optfile);
281      release_gpg_options (opt);      release_gpg_options (opt);
   
282      if (!keyid)      if (!keyid)
283          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
284      return keyid;      return keyid;
285  } /* get_gnupg_default_key */  }
   
286    
 char* get_reg_entry_gpg4win (const char *path);  
287    
288  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
289     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 316  check_gnupg_prog (void)
316    
317    
318  static int  static int
319  parse_version_nr (const char * buf, int *major, int *minor, int *patch)  parse_version_nr (const char *buf, int *major, int *minor, int *patch)
320  {  {
321      char tmp[8];      char tmp[8];
322      int i;      int i;
# Line 335  parse_version_nr (const char * buf, int Line 325  parse_version_nr (const char * buf, int
325      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
326          tmp[i++] = *buf++;          tmp[i++] = *buf++;
327      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
328      *major = atol( tmp );      *major = atoi (tmp);
329      i=0;      i=0;
330      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
331          tmp[i++] = *buf++;          tmp[i++] = *buf++;
332      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
333      *minor = atol (tmp);      *minor = atoi (tmp);
334      i=0;      i=0;
335      while (buf && isdigit (*buf) && i < 8)      while (buf && isdigit (*buf) && i < 8)
336          tmp[i++] = *buf++;          tmp[i++] = *buf++;
337      tmp[i] = 0;      tmp[i] = 0;
338      *patch = atol (tmp);      *patch = atoi (tmp);
339      return 0;      return 0;
340  }  }
341    
# Line 354  parse_version_nr (const char * buf, int Line 344  parse_version_nr (const char * buf, int
344     version given in @r_major.@r_minor.@r_patch. On success these     version given in @r_major.@r_minor.@r_patch. On success these
345     variables contain the GPG version which is installed. */     variables contain the GPG version which is installed. */
346  int  int
347  check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)  check_gnupg_engine (const char *need_gpg_ver,
348                        int *r_major, int *r_minor, int *r_patch)
349  {  {
350      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
351      gpgme_engine_info_t inf;      gpgme_engine_info_t inf;
352      char *eng = NULL;      char *eng = NULL;
353      int major=0, minor=0, patch=0;      int major=0, minor=0, patch=0;
354        int need_major = 0, need_minor = 0, need_patch = 0;
355      int rc = 1;      int rc = 1;
356            
357        /* Convert the needed GPG version to the integer format. */
358        if (parse_version_nr (need_gpg_ver,
359                              &need_major, &need_minor, &need_patch))
360            return 1;
361        
362      gpgme_new (&ctx);      gpgme_new (&ctx);
363      inf = gpgme_ctx_get_engine_info (ctx);      inf = gpgme_ctx_get_engine_info (ctx);
364      if (!inf) {      if (!inf) {
# Line 370  check_gnupg_engine (int *r_major, int *r Line 367  check_gnupg_engine (int *r_major, int *r
367      }      }
368    
369      /* 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. */
370      if (gpg_get_version (&eng))      if (gpg_get_version (&eng)) {
371            gpgme_release (ctx);
372          return -1;          return -1;
373        }
374      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
375          idea_available = 1;          idea_available = 1;
376      free (eng);      safe_free (eng);
377      rc = parse_version_nr (inf->version, &major, &minor, &patch);      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
     if (rc) {  
378          gpgme_release (ctx);          gpgme_release (ctx);
379          return rc;          return 1;
380      }      }
381        gpgme_release (ctx);
382    
383      if (major > *r_major)      if (major > need_major)
384          rc = 0;          rc = 0;
385      else if (major == *r_major && minor > *r_minor)                else if (major == need_major && minor > need_minor)      
386          rc = 0;          rc = 0;
387      else if (major == *r_major && minor == *r_minor &&      else if (major == need_major && minor == need_minor &&
388               patch >= *r_patch)               patch >= need_patch)
389          rc = 0;          rc = 0;
390    
391        /* Return the current GPG version. */
392      *r_major = major;      *r_major = major;
393      *r_minor = minor;      *r_minor = minor;
394      *r_patch = patch;      *r_patch = patch;
# Line 401  check_gnupg_cfgfile (const char *fname, Line 401  check_gnupg_cfgfile (const char *fname,
401  {  {
402      gpg_optfile_t opt;          gpg_optfile_t opt;    
403      gpg_option_t e;      gpg_option_t e;
     int rc = 0;  
404    
405      *r_secrings = 0;      *r_secrings = 0;
406      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
407    
408      for( e = opt->list; e; e = e->next ) {      if (parse_gpg_options (fname, &opt))
409          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
410              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
411            if (!strcmp( e->name, "secret-keyring")) {
412                if (!file_exist_check (e->val))
413                  r_secrings[0]++;                  r_secrings[0]++;
414          }          }
415          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
416              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
417                  r_pubrings[0]++;                  r_pubrings[0]++;
418          }          }
419      }      }
420      release_gpg_options( opt );      release_gpg_options (opt);
421      return 0;      return 0;
422  } /* check_gnupg_cfgfile */  }
423    
424    
425  /*  /* Usually GPG creates the pubring.gpg, secring.gpg on
426   * Check if both keyrings are located in the gnupg home directory.     the first start, but to make sure they always exist
427   */     create them empty if needed. */
428    static void
429    create_empty_keyring (int _pub)
430    {
431        char *name;
432        FILE *fp;
433    
434        name = get_gnupg_keyring (_pub, 0);
435        if (name && file_exist_check (name) != 0) {
436            fp = fopen (name, "ab");
437            if (fp != NULL)
438                fclose (fp);
439        }
440        free_if_alloc (name);
441    }
442    
443    
444    /* Check if both keyrings are located in the gnupg home directory. */
445  int  int
446  gnupg_access_files (void)  gnupg_access_files (void)
447  {  {
# Line 435  gnupg_access_files (void) Line 450  gnupg_access_files (void)
450      int secrings = 0, pubrings = 0;      int secrings = 0, pubrings = 0;
451      char *optfile;      char *optfile;
452    
453        create_empty_keyring (1);
454      if (gnupg_access_keyring (1))      if (gnupg_access_keyring (1))
455          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
456      else      else
457          pubring_ok = 1;          pubring_ok = 1;
458    
459        create_empty_keyring (0);
460      if (gnupg_access_keyring (0))      if (gnupg_access_keyring (0))
461          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
462      else      else
# Line 452  gnupg_access_files (void) Line 469  gnupg_access_files (void)
469          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
470          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
471              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);
472              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
473                  free_if_alloc (optfile);                  free_if_alloc (optfile);
474                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
475              }              }
# Line 468  gnupg_access_files (void) Line 485  gnupg_access_files (void)
485          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
486      }      }
487      return rc;      return rc;
488  } /* gnupg_access_files */  }
489    
490    
491  static int  static int
# Line 478  create_gpg_options (void) Line 495  create_gpg_options (void)
495      char *s, *optfile;      char *s, *optfile;
496    
497      s = get_gnupg_path ();      s = get_gnupg_path ();
498      if( s == NULL )      if (!s)
499          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
500      optfile = make_filename (s, GPG_CONF, NULL);      optfile = make_filename (s, GPG_CONF, NULL);
501      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
502      if( fp == NULL ) {        if (!fp) {
503          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
504          goto fail;          goto fail;
505      }      }
506      fwrite( options_skel, 1, strlen( options_skel ), fp );      fwrite (options_skel, 1, strlen (options_skel), fp);
507      fclose( fp );      fclose (fp);
508    
509  fail:  fail:
510      free_if_alloc( s );      free_if_alloc (s);
511      free_if_alloc( optfile );      free_if_alloc (optfile);
512      return 0;      return 0;
513  } /* create_gpg_options */  }
514    
515    
516  /*  /* Return the contents of the options file as a char buf. */
517   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
518  get_gnupg_config (void)  get_gnupg_config (void)
519  {  {
520      FILE * fp;      FILE *fp;
521      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
522      int fsize, rc = 0;      int fsize, rc = 0;
523                    
524      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
525      if( optfile == NULL )      if (optfile == NULL)
526          return NULL;          return NULL;
527      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
528      if( !fsize ) {      if (!fsize) {
529          rc = create_gpg_options( );          rc = create_gpg_options ();
530          if ( rc )          if (rc)
531              return NULL;              return NULL;
532          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
533      }      }
534      if( fsize > 100000 )      if (fsize > 100000)
535          goto leave; /* too large */          goto leave; /* too large */
536      p = new char[fsize+1];      p = new char[fsize+1];
537      if( p == NULL )      if (!p)
538          BUG( NULL );          BUG (NULL);
539      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
540      if( fp == NULL ) {      if (!fp) {
541          free_if_alloc( p );          free_if_alloc (p);
542          return NULL;          return NULL;
543      }      }
544      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
545      fclose( fp );      fclose (fp);
546      p[fsize] = '\0';      p[fsize] = '\0';
547      free_if_alloc( optfile );      free_if_alloc (optfile);
548    
549  leave:  leave:
550      return p;      return p;
551  } /* get_gnupg_config */  }
552    
553    
554    /* Set the default key in the gpg.conf.
555       If @key is NULL, the entry will be deleted. */
556  int  int
557  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
558  {  {
559      gpg_optfile_t opt;      gpg_optfile_t opt;
560      gpg_option_t e;      gpg_option_t e;
# Line 546  set_gnupg_default_key (const char * key) Line 563  set_gnupg_default_key (const char * key)
563    
564      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
565      if (!optfile)      if (!optfile)
566          return -1;          return WPTERR_FILE_OPEN;
567      rc = parse_gpg_options (optfile, &opt);      rc = parse_gpg_options (optfile, &opt);
568      if( rc ) {      if (rc) {
569          free_if_alloc (optfile);          free_if_alloc (optfile);
570          return -1;          return WPTERR_GENERAL;
571      }      }
572      e = find_option (opt, "default-key");      e = find_option (opt, "default-key");
573      if (e) {      if (e && !key)
574            e->used = 0;
575        else if (e) {
576          free_if_alloc (e->val);          free_if_alloc (e->val);
577          e->val = m_strdup (key);          e->val = m_strdup (key);
578          e->used = 1;          e->used = 1;
579      }      }
580      else      else if (key)
581          add_entry (opt, ENTRY_MULTI, "default-key", key);          add_entry (opt, ENTRY_MULTI, "default-key", key);
582      rc = commit_gpg_options (optfile, opt);      rc = commit_gpg_options (optfile, opt);
583    
# Line 566  set_gnupg_default_key (const char * key) Line 585  set_gnupg_default_key (const char * key)
585      release_gpg_options (opt);      release_gpg_options (opt);
586    
587      return rc;      return rc;
588  } /* set_gnupg_default_key */  }
589    
590    
591  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
592  int  int
593  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
594  {  {
595      FILE *fp;        FILE *fp;  
596      char *optfile = NULL;      char *optfile = NULL;
597    
598      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
599      if( optfile == NULL )      if (!optfile)
600          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
601    
602      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
603      if( fp == NULL ) {      if (!fp) {
604          free_if_alloc( optfile );          free_if_alloc (optfile);
605          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
606      }      }
607      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
608      fclose( fp );      fclose (fp);
609      free_if_alloc( optfile );      free_if_alloc (optfile);
610      return 0;      return 0;
611  } /* set_gnupg_options */  }
612    
613    
614  /*  /*
615   * Check if the line contains a valid GPG argument.   * Check if the line contains a valid GPG argument.
616   */   */
617  static int  static int
618  check_line( const char *buf )  check_line (const char *buf)
619  {  {
620      int j, len;      int j, len;
621      int rc = 0;      int rc = 0;
622    
623      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
624          return 1;          return 1;
625      rc = 0;      rc = 0;
626      for ( j = 0; valid_gpg_args[j]; j++ ) {      for (j = 0; valid_gpg_args[j]; j++) {
627          len = strlen( valid_gpg_args[j] );          len = strlen (valid_gpg_args[j]);
628          if( !strncmp( valid_gpg_args[j], buf, len ) )          if (!strncmp (valid_gpg_args[j], buf, len))
629              rc = 1;                  rc = 1;
630      }      }
631    
632      return rc;      return rc;
633  } /* check_line */  }
634    
635    
636  int  int
637  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf)
638  {  {
639      char line[1024];      char line[1024];
640      int nbytes = 0;      int nbytes = 0;
# Line 635  check_gnupg_options( const char *buf ) Line 653  check_gnupg_options( const char *buf )
653      }      }
654    
655      return 0;      return 0;
656  } /* check_gnupg_options */  }
657    
658    
659  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
# Line 648  get_last_gnupg_access (gpg_watcher_s *ct Line 666  get_last_gnupg_access (gpg_watcher_s *ct
666    
667      path = get_gnupg_path ();      path = get_gnupg_path ();
668      file =  make_filename (path, ctx->object, NULL);      file =  make_filename (path, ctx->object, NULL);
669      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,
670                         OPEN_ALWAYS, 0, NULL);
671      if (fd == INVALID_HANDLE_VALUE) {      if (fd == INVALID_HANDLE_VALUE) {
672          free_if_alloc (path);          free_if_alloc (path);
673          free_if_alloc (file);          free_if_alloc (file);
# Line 673  check_last_gnupg_access (gpg_watcher_s * Line 692  check_last_gnupg_access (gpg_watcher_s *
692          ctx->modified = 1;          ctx->modified = 1;
693            
694      /* XXX: find a better way. without it, winpt --keymanager loads      /* XXX: find a better way. without it, winpt --keymanager loads
695              the key cache twice otherwise. */              the key cache twice. */
696      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
697          ctx->modified = 0;          ctx->modified = 0;
698        
699      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
700      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
701  }  }
# Line 691  init_gnupg_table (void) Line 710  init_gnupg_table (void)
710    
711      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
712          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          p = gpg_table[j].object = m_strdup (gpg_objs[j]);
         if (!p)  
             BUG (NULL);  
713          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
714          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
715          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
# Line 782  get_gnupg_keyring_from_options (const ch Line 799  get_gnupg_keyring_from_options (const ch
799    
800  /* XXX: does not work with write-protected floppies */  /* XXX: does not work with write-protected floppies */
801  static int  static int
802  my_access (const char * fname)  my_access (const char *fname)
803  {  {
804      HANDLE hd;      HANDLE hd;
805      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
# Line 801  my_access (const char * fname) Line 818  my_access (const char * fname)
818  int  int
819  gpg_check_permissions (int showmsg)  gpg_check_permissions (int showmsg)
820  {  {
821      char * p, * name = NULL;      char *p = NULL;
822        char *name = NULL;
823      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
824    
825      p = get_gnupg_path ();      p = get_gnupg_path ();
826      check_keyring (&p);      if (p && check_keyring (&p)) {
     if (p) {  
827          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
         free_if_alloc (p);  
828          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
829              ans = msg_box (NULL,              ans = msg_box (NULL,
830                             _("The selected keyring has the read-only file\n"                             _("The selected keyring has the read-only file\n"
# Line 840  gpg_check_permissions (int showmsg) Line 856  gpg_check_permissions (int showmsg)
856              failed = 2;              failed = 2;
857          }          }
858      }      }
859        free_if_alloc (p);
860      free_if_alloc (name);      free_if_alloc (name);
861      return failed;      return failed;
862  }  }
863    
864    
865  /* Check the GPG home dir. If all methods failed, try to  /* Check the GPG home dir. First try to read the 'HomeDir' registry entry,
866     create the default folder. */     then check for $APPDATA\gnupg. Create the dir if it does not exists. */
867  static int  int
868  check_homedir (void)  gnupg_check_homedir (void)
869  {        {      
870      char *homedir = NULL;      char *homedir = NULL;
871      int yes = 0, set_reg=0;      int val = 0;
872      int rc = 0;      int rc = 0;
873    
874      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);  
     }  
875      if (!homedir)      if (!homedir)
876          homedir = m_strdup ("c:\\gnupg");          homedir = multi_gnupg_path (0);
877      if (homedir) {      if (homedir) {
878          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
879              yes = log_box (_("Preferences"), MB_YESNO,              val = log_box (_("Preferences"), MB_YESNO,
880                             _("%s does not exit.\n"                             _("%s does not exit.\n"
881                               "Do you want to create this directory?"), homedir);                               "Do you want to create this directory?"), homedir);
882              if (yes == IDYES) {              if (val == IDYES) {
883                  if (!CreateDirectory (homedir, NULL))                  if (!CreateDirectory (homedir, NULL))
884                      rc = WPTERR_DIR_CREAT;                      rc = WPTERR_DIR_CREAT;
885              }              }
886              else              else
887                  rc = WPTERR_DIR_OPEN;                  rc = WPTERR_DIR_OPEN;
888          }          }
         if (set_reg)  
             set_reg_entry_gpg (GPG_REG_HOME, homedir);  
889          free_if_alloc (homedir);          free_if_alloc (homedir);
890      }      }
891      return rc;      return rc;
# Line 882  check_homedir (void) Line 893  check_homedir (void)
893    
894    
895  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  
896  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
897  {  {
898      const char * pring, * sring;      const char * pring, * sring;
# Line 946  gnupg_copy_keyrings (void) Line 905  gnupg_copy_keyrings (void)
905          return WPTERR_GENERAL;          return WPTERR_GENERAL;
906      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
907    
908      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
909                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
910      if (!pring) {      if (!pring) {
911          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
912                     _("WinPT Error"), MB_ERR);
913          free_if_alloc (path);          free_if_alloc (path);
914          return WPTERR_GENERAL;          return WPTERR_GENERAL;
915      }      }
916      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
917      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
918          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
919                          "WinPT", MB_INFO|MB_YESNO);
920          if (id == IDNO)          if (id == IDNO)
921              goto fail;              goto fail;
922      }      }
# Line 966  gnupg_copy_keyrings (void) Line 927  gnupg_copy_keyrings (void)
927      }      }
928      free_if_alloc (file);      free_if_alloc (file);
929    
930      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
931                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
932      if (!sring) {      if (!sring) {
933          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
934                     _("WinPT Error"), MB_ERR);
935          return WPTERR_GENERAL;          return WPTERR_GENERAL;
936      }      }
937      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
938      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
939          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
940          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
941            if (id == IDNO)
942              goto fail;              goto fail;
943      }      }
944      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
945          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
946          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
947      }      }
948    
# Line 987  fail: Line 950  fail:
950      free_if_alloc (file);      free_if_alloc (file);
951      free_if_alloc (path);      free_if_alloc (path);
952      return rc;      return rc;
953  } /* gnupg_import_keyrings */  }
954    
955    
956    /* Backup the gpg.conf file. */
957  void  void
958  gnupg_backup_options (void)  gnupg_backup_options (void)
959  {  {
# Line 997  gnupg_backup_options (void) Line 961  gnupg_backup_options (void)
961      char bak[512];      char bak[512];
962    
963      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
964      if (cfgfile == NULL)      if (!cfgfile)
965          return;          return;
966      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);
967      CopyFile (cfgfile, bak, FALSE);      CopyFile (cfgfile, bak, FALSE);
968      free_if_alloc (cfgfile);      free_if_alloc (cfgfile);
969  } /* gnupg_backup_options */  }
   
970    
971    
972  static int  static int
973  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
974                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
975  {  {
976      char * src, * dst;      char *src, *dst;
977      BOOL rc;      BOOL rc;
978    
979      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
# Line 1022  backup_one_file (const char *srcpath, co Line 985  backup_one_file (const char *srcpath, co
985      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
986      free_if_alloc (src);      free_if_alloc (src);
987      free_if_alloc (dst);      free_if_alloc (dst);
988      if (!rc)      if (!rc) {
     {  
989          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
990          return WPTERR_GENERAL;          return WPTERR_GENERAL;
991      }      }
992      return 0;      return 0;
993  } /* backup_one_file */  }
994    
995    
996    /* Figure out first public keyring which is not empty.
997       Return value: 1 on success. */
998  static int  static int
999  check_keyring (char ** r_path)  check_keyring (char **r_path)
1000  {  {
1001      char * p;      char *p;
1002      char * opt, * name;      char *opt;
1003        char *name;
1004    
1005      if (!*r_path)      if (!*r_path)
1006          return 0;          return 0;
1007      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1008      if (!p || get_file_size (p) > 0)      if (!p || get_file_size (p) <= 0)
1009          return 0;          return 0;
1010    
1011      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
# Line 1052  check_keyring (char ** r_path) Line 1017  check_keyring (char ** r_path)
1017      if (!name)      if (!name)
1018          return 0;          return 0;
1019      p = strrchr (name, '\\');      p = strrchr (name, '\\');
1020      if (!p)      if (!p) {
     {  
1021          free_if_alloc (name);          free_if_alloc (name);
1022          return 0;                return 0;      
1023      }      }
# Line 1066  check_keyring (char ** r_path) Line 1030  check_keyring (char ** r_path)
1030  }  }
1031    
1032    
1033    /* Return a temp name based on the day of the week. */
1034  static char*  static char*
1035  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1036  {  {
1037      struct tm *tm;      struct tm *tm;
1038      char *p;      char *p;
1039        time_t t;
1040    
1041      time_t t = time (NULL);      t = time (NULL);
1042      tm = localtime (&t);      tm = localtime (&t);
1043      p = new char [strlen (templ) + 8 + 1];      p = new char [strlen (templ) + 8 + 1];
1044      if (!p)      if (!p)
# Line 1082  get_backup_name (const char *templ) Line 1048  get_backup_name (const char *templ)
1048  }  }
1049    
1050    
1051    /* Make backups of all keyrings. The public key ring is rotated like
1052       this pubring-%d.gpg.
1053       If @auto_backup is false, no action is performed.
1054       @include_secr indicated if the backup includes the secret keyring. */
1055  void  void
1056  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1057  {  {
1058      char *srcpath = NULL, *dstpath = NULL;      char *srcpath = NULL, *dstpath = NULL;
1059      char *name=NULL;      char *name=NULL;
1060      int rc, bakmode=0;      int rc;
1061    
1062      if (!reg_prefs.auto_backup)      if (!auto_backup)
1063          return;          return;
1064      bakmode = reg_prefs.backup.mode;      srcpath = get_gnupg_path ();
     srcpath =  get_gnupg_path ();  
1065      check_keyring (&srcpath);      check_keyring (&srcpath);
1066      if (bakmode == 1) {      if (backup_mode == 1) {
1067          dstpath = get_gnupg_path ();          dstpath = multi_gnupg_path (1);
1068          check_keyring (&dstpath);          check_keyring (&dstpath);
1069      }      }
1070      else if (bakmode == 2) {      else if (backup_mode == 2) {
1071          char * tmpfile;          char *tmpfile;
1072          FILE * fp;          FILE *fp;
1073    
1074          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1075          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1076          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1077          if (!fp)          if (!fp)
1078              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1079                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1080                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1081          else {          else {
1082              rc = 0;              rc = 0;
# Line 1121  gnupg_backup_keyrings (void) Line 1088  gnupg_backup_keyrings (void)
1088              return;              return;
1089      }      }
1090      else {      else {
1091          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1092          return;          return;
1093      }      }
1094      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1095      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1096      if (!rc)      if (!rc && include_secr)
1097          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1098      free_if_alloc (name);      free_if_alloc (name);
1099      free_if_alloc (srcpath);      free_if_alloc (srcpath);
1100      free_if_alloc (dstpath);      free_if_alloc (dstpath);
1101  } /* gnupg_backup_keyrings */  }
1102    
1103    
1104  /* Display GPG error from file if possible. */  /* Display GPG error from file if possible. */
1105  void  void
1106  gnupg_display_error (void)  gnupg_display_error (void)
1107  {        {      
1108      char tmpath[512], * errstr;      char tmpath[512], *errstr;
1109      size_t size = 0;      size_t size = 0;
1110      FILE * fp;      FILE *fp;
1111    
1112      GetTempPath (sizeof tmpath - 32, (tmpath));      get_temp_name (tmpath, sizeof (tmpath), "gpg_stderr");
     strcat (tmpath, "gpg_stderr");  
1113      size = get_file_size (tmpath);      size = get_file_size (tmpath);
1114      if (file_exist_check (tmpath) || size <= 0)      if (file_exist_check (tmpath) || size <= 0)
1115          return;          return;
1116      fp = fopen( tmpath, "rb" );      fp = fopen( tmpath, "rb" );
1117      if (!fp) {      if (!fp) {
1118          msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );          msg_box (NULL, _("No GPG error description available."),
1119                     _("GPG Error"), MB_INFO);
1120          return;          return;
1121      }      }
1122      errstr = new char[size+1];      errstr = new char[size+1];

Legend:
Removed from v.85  
changed lines
  Added in v.248

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26