/[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 35 by twoaday, Wed Oct 26 11:20:09 2005 UTC revision 36 by werner, Thu Oct 27 15:25:13 2005 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2004 Timo Schulz   *      Copyright (C) 2001-2004 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or   * WinPT is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public License   * modify it under the terms of the GNU General Public License
8   * as published by the Free Software Foundation; either version 2   * as published by the Free Software Foundation; either version 2
9   * of the License, or (at your option) any later version.   * of the License, or (at your option) any later version.
10   *     *  
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
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.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19   */   */
20    
21  #include <string.h>  #ifdef HAVE_CONFIG_H
22  #include <stdio.h>  #include <config.h>
23  #include <windows.h>  #endif
24  #include <shlobj.h>  
25  #include <ctype.h>  #include <string.h>
26  #include <io.h>  #include <string.h>
27    #include <stdio.h>
28  #include "wptGPG.h"  #include <windows.h>
29  #include "wptGPGCmds.h"  #include <shlobj.h>
30  #include "wptGPGOptSkel.h"  #include <ctype.h>
31  #include "wptTypes.h"  #include <io.h>
32  #include "wptNLS.h"  
33  #include "wptRegistry.h"  #include "wptGPG.h"
34  #include "wptErrors.h"  #include "wptGPGCmds.h"
35  #include "wptW32API.h"  #include "wptGPGOptSkel.h"
36  #include "wptCrypto.h"  #include "wptTypes.h"
37    #include "wptNLS.h"
38  #define GPG_CONF "gpg.conf"  #include "wptRegistry.h"
39    #include "wptErrors.h"
40  struct gpg_watcher_s {  #include "wptW32API.h"
41      FILETIME    last_access;  #include "wptCrypto.h"
42      FILETIME    access;  
43      char        *object;  #define GPG_CONF "gpg.conf"
44      int         modified;  
45  };  struct gpg_watcher_s {
46        FILETIME    last_access;
47        FILETIME    access;
48  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */      char        *object;
49  static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};      int         modified;
50  static gpg_watcher_s gpg_table[3];  };
51  static int gpg_table_count = DIM (gpg_table);  
52    
53  int idea_available = 0;  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */
54    static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
55  static int check_keyring (char ** r_path);  static gpg_watcher_s gpg_table[3];
56    static int gpg_table_count = DIM (gpg_table);
57    
58  /* Return the application data folder of the current user. */  int idea_available = 0;
59  static char*  
60  multi_gnupg_path (void)  static int check_keyring (char ** r_path);
61  {  
62      static char buf[256+64];  
63      BOOL ec;  /* Return the application data folder of the current user. */
64    static char*
65      /* MSDN: buf must be at least MAX_PATH=256 bytes */  multi_gnupg_path (void)
66      memset (buf, 0, sizeof (buf));  {
67      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */      static char buf[256+64];
68      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);      BOOL ec;
69      if (ec != 1)  
70          return NULL;      /* MSDN: buf must be at least MAX_PATH=256 bytes */
71      strcat (buf, "\\gnupg");      memset (buf, 0, sizeof (buf));
72      if (access (buf, 00))      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */
73          return NULL;      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);
74      return m_strdup (buf);      if (ec != 1)
75  }          return NULL;
76        strcat (buf, "\\gnupg");
77        if (access (buf, 00))
78  /* Return the full path of the GnuPG application. First the registry is scanned          return NULL;
79     for the entry 'HomeDir'. If it wasn't set, the default dir C:\GNUPG is used.      return m_strdup (buf);
80  */  }
81  char*  
82  get_gnupg_path (void)  
83  {  /* Return the full path of the GnuPG application. First the registry is scanned
84      char *p = NULL, *path = NULL;     for the entry 'HomeDir'. If it wasn't set, the default dir C:\GNUPG is used.
85        */
86      p = get_reg_entry_gpg ("HomeDir");  char*
87      if (p) {  get_gnupg_path (void)
88          path = m_strdup (p);  {
89          free_if_alloc (p);      char *p = NULL, *path = NULL;
90          return path;      
91      }      p = get_reg_entry_gpg ("HomeDir");
92      else      if (p) {
93          return multi_gnupg_path ();          path = m_strdup (p);
94      return m_strdup ("c:\\gnupg");          free_if_alloc (p);
95  }          return path;
96        }
97        else
98  /* Return the full path of the gpg config file.          return multi_gnupg_path ();
99     A value of NULL indicates an error. */      return m_strdup ("c:\\gnupg");
100  char*  }
101  get_gnupg_cfgfile (void)  
102  {      
103      char *p = NULL, *optfile = NULL, *path = NULL;  /* Return the full path of the gpg config file.
104      size_t nlen = 0;     A value of NULL indicates an error. */
105    char*
106      path = get_gnupg_path ();  get_gnupg_cfgfile (void)
107      if (!path)  {    
108          return NULL;      char *p = NULL, *optfile = NULL, *path = NULL;
109      p = get_reg_entry_gpg ("OptFile");      size_t nlen = 0;
110      if (p && !strcmp (p, "")) {  
111          nlen = strlen (path) + 64;      path = get_gnupg_path ();
112          optfile = new char[nlen + 1];      if (!path)
113          if (!optfile)          return NULL;
114              BUG (0);      p = get_reg_entry_gpg ("OptFile");
115          _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);      if (p && !strcmp (p, "")) {
116      }          nlen = strlen (path) + 64;
117      else if (p) {          optfile = new char[nlen + 1];
118          nlen = strlen( p ) + 4;          if (!optfile)
119          optfile = new char[nlen + 1];              BUG (0);
120          if (!optfile)          _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
121              BUG (NULL);      }
122          _snprintf (optfile, nlen, "%s", p);      else if (p) {
123      }          nlen = strlen( p ) + 4;
124      else {          optfile = new char[nlen + 1];
125          nlen = strlen (path) + 64;          if (!optfile)
126          optfile = new char[nlen + 1];              BUG (NULL);
127          if( !optfile)          _snprintf (optfile, nlen, "%s", p);
128              BUG (NULL);      }
129          _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);      else {
130      }          nlen = strlen (path) + 64;
131      free_if_alloc (path);          optfile = new char[nlen + 1];
132      free_if_alloc (p);          if( !optfile)
133      return optfile;              BUG (NULL);
134  }          _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
135        }
136        free_if_alloc (path);
137  /* Return the full path of the keyring. If @pub is 1, the public      free_if_alloc (p);
138     keyring is return, otherwise the secret keyring. */      return optfile;
139  char*  }
140  get_gnupg_keyring (int pub, int strict)  
141  {      
142      char *optfile = NULL;  /* Return the full path of the keyring. If @pub is 1, the public
143      char *path = NULL;     keyring is return, otherwise the secret keyring. */
144      char *keyring = NULL;  char*
145    get_gnupg_keyring (int pub, int strict)
146      path = get_gnupg_path ();  {    
147      if (!path)      char *optfile = NULL;
148          return NULL;      char *path = NULL;
149      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");      char *keyring = NULL;
150      if (!strict && !file_exist_check (keyring)) {  
151          free_if_alloc (path);      path = get_gnupg_path ();
152          return keyring;      if (!path)
153      }          return NULL;
154      if (file_exist_check (keyring) || get_file_size (keyring) == 0) {      keyring = make_filename (path, pub? "pubring" : "secring", "gpg");
155          free_if_alloc (keyring);      if (!strict && !file_exist_check (keyring)) {
156          optfile = make_filename (path, GPG_CONF, NULL);          free_if_alloc (path);
157          keyring = get_gnupg_keyring_from_options (optfile, pub);          return keyring;
158      }      }
159      free_if_alloc (path);      if (file_exist_check (keyring) || get_file_size (keyring) == 0) {
160      free_if_alloc (optfile);          free_if_alloc (keyring);
161      return keyring;          optfile = make_filename (path, GPG_CONF, NULL);
162  }          keyring = get_gnupg_keyring_from_options (optfile, pub);
163        }
164        free_if_alloc (path);
165  /* Return the full path (with the gpg exe name). First the registry is scanned      free_if_alloc (optfile);
166     for the entry 'gpgProgram'. If it wasn't set, the default path is the      return keyring;
167     appended string 'gpg.exe' is used. */  }
168  char*  
169  get_gnupg_prog (void)  
170  {      /* Return the full path (with the gpg exe name). First the registry is scanned
171      char *p;     for the entry 'gpgProgram'. If it wasn't set, the default path is the
172      char *pgm = NULL;     appended string 'gpg.exe' is used. */
173      size_t nlen = 0;  char*
174    get_gnupg_prog (void)
175      p = get_reg_entry_gpg ("gpgProgram");  {    
176      if (!p) {      char *p;
177          char *path = get_gnupg_path ();      char *pgm = NULL;
178          if (!path)      size_t nlen = 0;
179              return NULL;  
180          pgm = make_filename (path, "gpg", "exe");      p = get_reg_entry_gpg ("gpgProgram");
181          free_if_alloc (path);      if (!p) {
182      }          char *path = get_gnupg_path ();
183      else {          if (!path)
184          pgm = m_strdup (p);              return NULL;
185          free_if_alloc (p);          pgm = make_filename (path, "gpg", "exe");
186      }          free_if_alloc (path);
187      return pgm;      }
188  }      else {
189            pgm = m_strdup (p);
190            free_if_alloc (p);
191  /* Retrieve the first usable secret key from cache.      }
192     If no usable was found, @ret_no_useable is 1.      return pgm;
193     Return value: the keyid of the secret key. */  }
194  static char *  
195  default_key_from_cache (int *ret_no_useable)  
196  {  /* Retrieve the first usable secret key from cache.
197      const char * s;     If no usable was found, @ret_no_useable is 1.
198      char * keyid = NULL;     Return value: the keyid of the secret key. */
199      gpgme_key_t key;  static char *
200      gpg_keycache_t sec = keycache_get_ctx (0);  default_key_from_cache (int *ret_no_useable)
201    {
202      if (!sec)      const char * s;
203          BUG (0);      char * keyid = NULL;
204      gpg_keycache_rewind (sec);      gpgme_key_t key;
205      while (!gpg_keycache_next_key (sec, 1, &key)) {      gpg_keycache_t sec = keycache_get_ctx (0);
206          if (key_is_useable (key)) {  
207              s = key->subkeys->keyid;      if (!sec)
208              if (s)              BUG (0);
209                  keyid = m_strdup (s+8);      gpg_keycache_rewind (sec);
210              break;      while (!gpg_keycache_next_key (sec, 1, &key)) {
211          }          if (key_is_useable (key)) {
212      }              s = key->subkeys->keyid;
213      if (!keyid) {              if (s)    
214          *ret_no_useable = 1;                  keyid = m_strdup (s+8);
215          msg_box (NULL, _("No useable secret key found."), _("GPG Error"), MB_ERR);              break;
216      }          }
217      return keyid;      }
218  }      if (!keyid) {
219            *ret_no_useable = 1;
220            msg_box (NULL, _("No useable secret key found."), _("GPG Error"), MB_ERR);
221  char*      }
222  get_gnupg_default_key (void)      return keyid;
223  {      }
224      gpg_optfile_t opt = NULL;  
225      gpg_option_t e;  
226      char * keyid = NULL, * optfile = NULL;  char*
227      int no_usable=0, rc = 0;  get_gnupg_default_key (void)
228    {    
229      optfile = get_gnupg_cfgfile ();      gpg_optfile_t opt = NULL;
230      if (!optfile)      gpg_option_t e;
231          return default_key_from_cache (&no_usable);      char * keyid = NULL, * optfile = NULL;
232      rc = parse_gpg_options (optfile, &opt);      int no_usable=0, rc = 0;
233      if (rc) {  
234          free_if_alloc( optfile );      optfile = get_gnupg_cfgfile ();
235          return default_key_from_cache( &no_usable );      if (!optfile)
236      }          return default_key_from_cache (&no_usable);
237      e = find_option( opt, "default-key" );      rc = parse_gpg_options (optfile, &opt);
238      if ( e )      if (rc) {
239          keyid = m_strdup( e->val );          free_if_alloc( optfile );
240      if( !e ) {          return default_key_from_cache( &no_usable );
241          e = find_option( opt, "local-user" );      }
242          if( e )      e = find_option( opt, "default-key" );
243              keyid = m_strdup( e->val );      if ( e )
244      }          keyid = m_strdup( e->val );
245      if( !e ) {      if( !e ) {
246          e = find_option( opt, "encrypt-to" );          e = find_option( opt, "local-user" );
247          if( e )          if( e )
248              keyid = m_strdup( e->val );              keyid = m_strdup( e->val );
249      }      }
250      free_if_alloc( optfile );      if( !e ) {
251      release_gpg_options( opt );              e = find_option( opt, "encrypt-to" );
252            if( e )
253      if( !keyid )              keyid = m_strdup( e->val );
254          keyid = default_key_from_cache( &no_usable );      }
255      return keyid;      free_if_alloc( optfile );
256  } /* get_gnupg_default_key */      release_gpg_options( opt );    
257    
258        if( !keyid )
259  /* Check if the gpg application (exe file) is available. */          keyid = default_key_from_cache( &no_usable );
260  int      return keyid;
261  check_gnupg_prog (void)  } /* get_gnupg_default_key */
262  {  
263      char *pgm = NULL;  
264      int rc = 0;  /* Check if the gpg application (exe file) is available. */
265    int
266      pgm = get_gnupg_prog ();  check_gnupg_prog (void)
267      if (!pgm)  {
268          rc = WPTERR_GPG_EXEFILE;      char *pgm = NULL;
269      if (file_exist_check (pgm))      int rc = 0;
270          rc = WPTERR_GPG_EXEFILE;  
271      free_if_alloc (pgm);      pgm = get_gnupg_prog ();
272      return rc;      if (!pgm)
273  }          rc = WPTERR_GPG_EXEFILE;
274        if (file_exist_check (pgm))
275            rc = WPTERR_GPG_EXEFILE;
276  static int      free_if_alloc (pgm);
277  parse_version_nr (const char * buf, int *major, int *minor, int *patch)      return rc;
278  {  }
279      char tmp[8];  
280      int i;  
281        static int
282      i=0;  parse_version_nr (const char * buf, int *major, int *minor, int *patch)
283      while (buf && *buf != '.' && i < 8)  {
284          tmp[i++] = *buf++;      char tmp[8];
285      tmp[i] = 0; buf++;      int i;
286      *major = atol( tmp );      
287      i=0;      i=0;
288      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
289          tmp[i++] = *buf++;          tmp[i++] = *buf++;
290      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
291      *minor = atol (tmp);      *major = atol( tmp );
292      i=0;      i=0;
293      while (buf && isdigit( *buf ) && i < 8)      while (buf && *buf != '.' && i < 8)
294          tmp[i++] = *buf++;          tmp[i++] = *buf++;
295      tmp[i] = 0;      tmp[i] = 0; buf++;
296      *patch = atol (tmp);      *minor = atol (tmp);
297      return 0;      i=0;
298  }      while (buf && isdigit( *buf ) && i < 8)
299            tmp[i++] = *buf++;
300        tmp[i] = 0;
301  /* Check if the gnupg engine fullfills the minimum requirement      *patch = atol (tmp);
302     version given in @r_major.@r_minor.@r_patch. On success these      return 0;
303     variables contain the GPG version which is installed. */  }
304  int  
305  check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)  
306  {  /* Check if the gnupg engine fullfills the minimum requirement
307      gpgme_ctx_t ctx;     version given in @r_major.@r_minor.@r_patch. On success these
308      gpgme_engine_info_t inf;     variables contain the GPG version which is installed. */
309      char * eng = NULL;  int
310      int major=0, minor=0, patch=0;  check_gnupg_engine (int *r_major, int *r_minor, int *r_patch)
311      int rc;  {
312                gpgme_ctx_t ctx;
313      gpgme_new (&ctx);      gpgme_engine_info_t inf;
314      inf = gpgme_ctx_get_engine_info (ctx);      char * eng = NULL;
315      if (!inf) {      int major=0, minor=0, patch=0;
316          gpgme_release (ctx);      int rc;
317          return -1;          
318      }      gpgme_new (&ctx);
319      /* We need to exec GPG again to find out if IDEA is available. */      inf = gpgme_ctx_get_engine_info (ctx);
320      if (gpg_get_version (&eng))      if (!inf) {
321          return -1;          gpgme_release (ctx);
322      if (strstr (eng, "IDEA"))          return -1;
323          idea_available = 1;      }
324      free (eng);      /* We need to exec GPG again to find out if IDEA is available. */
325      rc = parse_version_nr( inf->version, &major, &minor, &patch );      if (gpg_get_version (&eng))
326      if( rc ) {          return -1;
327          gpgme_release (ctx);      if (strstr (eng, "IDEA"))
328          return rc;          idea_available = 1;
329      }      free (eng);
330      if (major < *r_major || minor < *r_minor)      rc = parse_version_nr( inf->version, &major, &minor, &patch );
331          rc = 1;      if( rc ) {
332      else {          gpgme_release (ctx);
333          if (patch < *r_patch)          return rc;
334              rc = 1;      }
335          rc = 0;      if (major < *r_major || minor < *r_minor)
336      }          rc = 1;
337      *r_major = major;      else {
338      *r_minor = minor;          if (patch < *r_patch)
339      *r_patch = patch;              rc = 1;
340      return rc;          rc = 0;
341  }      }
342        *r_major = major;
343        *r_minor = minor;
344  int      *r_patch = patch;
345  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)      return rc;
346  {  }
347      gpg_optfile_t opt;      
348      gpg_option_t e;  
349      int rc = 0;  int
350    check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)
351      *r_secrings = 0;  {
352      *r_pubrings = 0;      gpg_optfile_t opt;    
353      rc = parse_gpg_options( fname, &opt );      gpg_option_t e;
354      if( rc )      int rc = 0;
355          return WPTERR_FILE_OPEN;  
356        *r_secrings = 0;
357      for( e = opt->list; e; e = e->next ) {      *r_pubrings = 0;
358          if( !strcmp( e->name, "secret-keyring" ) ) {      rc = parse_gpg_options( fname, &opt );
359              if( !file_exist_check( e->val ) )      if( rc )
360                  r_secrings[0]++;          return WPTERR_FILE_OPEN;
361          }  
362          else if( !strcmp( e->name, "keyring" ) ) {      for( e = opt->list; e; e = e->next ) {
363              if( !file_exist_check( e->val ) )          if( !strcmp( e->name, "secret-keyring" ) ) {
364                  r_pubrings[0]++;              if( !file_exist_check( e->val ) )
365          }                  r_secrings[0]++;
366      }          }
367      release_gpg_options( opt );          else if( !strcmp( e->name, "keyring" ) ) {
368      return 0;              if( !file_exist_check( e->val ) )
369  } /* check_gnupg_cfgfile */                  r_pubrings[0]++;
370            }
371        }
372  /*      release_gpg_options( opt );
373   * Check if both keyrings are located in the gnupg home directory.      return 0;
374   */  } /* check_gnupg_cfgfile */
375  int  
376  gnupg_access_files (void)  
377  {  /*
378      int rc = 0;   * Check if both keyrings are located in the gnupg home directory.
379      int pubring_ok = 0, secring_ok = 0;   */
380      int secrings = 0, pubrings = 0;  int
381      char *optfile;  gnupg_access_files (void)
382    {
383      if (gnupg_access_keyring (1))      int rc = 0;
384          rc = WPTERR_GPG_KEYRINGS;      int pubring_ok = 0, secring_ok = 0;
385      else      int secrings = 0, pubrings = 0;
386          pubring_ok = 1;      char *optfile;
387    
388      if (gnupg_access_keyring (0))      if (gnupg_access_keyring (1))
389          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
390      else      else
391          secring_ok = 1;          pubring_ok = 1;
392      if (!pubring_ok || !secring_ok) {  
393          optfile = get_gnupg_cfgfile ();      if (gnupg_access_keyring (0))
394          if (!optfile)          rc = WPTERR_GPG_KEYRINGS;
395              return WPTERR_GPG_KEYRINGS;      else
396          rc = file_exist_check (optfile);          secring_ok = 1;
397          if (!rc && get_file_size(optfile) > 0) {      if (!pubring_ok || !secring_ok) {
398              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);          optfile = get_gnupg_cfgfile ();
399              if (!rc && secrings && pubrings) {          if (!optfile)
400                  free_if_alloc (optfile);              return WPTERR_GPG_KEYRINGS;
401                  return 0; /* found two keyrings in the option file */          rc = file_exist_check (optfile);
402              }          if (!rc && get_file_size(optfile) > 0) {
403              else if ((!rc && pubrings && secring_ok)              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);
404                    || (!rc && secrings && pubring_ok)) {              if (!rc && secrings && pubrings) {
405                  free_if_alloc (optfile);                  free_if_alloc (optfile);
406                  return 0; /* found one keyring and one entry in the options file */                  return 0; /* found two keyrings in the option file */
407              }              }
408              else              else if ((!rc && pubrings && secring_ok)
409                  return WPTERR_GPG_OPT_KEYRINGS;                    || (!rc && secrings && pubring_ok)) {
410          }                  free_if_alloc (optfile);
411          free_if_alloc (optfile);                  return 0; /* found one keyring and one entry in the options file */
412          rc = WPTERR_GPG_KEYRINGS;              }
413      }              else
414      return rc;                  return WPTERR_GPG_OPT_KEYRINGS;
415  } /* gnupg_access_files */          }
416            free_if_alloc (optfile);
417            rc = WPTERR_GPG_KEYRINGS;
418  static int      }
419  create_gpg_options (void)      return rc;
420  {  } /* gnupg_access_files */
421      FILE *fp;  
422      char *s, *optfile;  
423    static int
424      s = get_gnupg_path( );  create_gpg_options (void)
425      if( s == NULL )  {
426          return WPTERR_FILE_CREAT;      FILE *fp;
427      optfile = make_filename( s, GPG_CONF, NULL );      char *s, *optfile;
428      fp = fopen( optfile, "wb" );  
429      if( fp == NULL ) {        s = get_gnupg_path( );
430          return WPTERR_FILE_CREAT;      if( s == NULL )
431          goto fail;          return WPTERR_FILE_CREAT;
432      }      optfile = make_filename( s, GPG_CONF, NULL );
433      fwrite( options_skel, 1, strlen( options_skel ), fp );      fp = fopen( optfile, "wb" );
434      fclose( fp );      if( fp == NULL ) {  
435            return WPTERR_FILE_CREAT;
436  fail:          goto fail;
437      free_if_alloc( s );      }
438      free_if_alloc( optfile );      fwrite( options_skel, 1, strlen( options_skel ), fp );
439      return 0;      fclose( fp );
440  } /* create_gpg_options */  
441    fail:
442        free_if_alloc( s );
443  /*      free_if_alloc( optfile );
444   * Return the contents of the options file as a char buf.      return 0;
445   */  } /* create_gpg_options */
446  char *  
447  get_gnupg_config (void)  
448  {  /*
449      FILE * fp;   * Return the contents of the options file as a char buf.
450      char * p = NULL, * optfile = NULL;   */
451      int fsize, rc = 0;  char *
452            get_gnupg_config (void)
453      optfile = get_gnupg_cfgfile ();  {
454      if( optfile == NULL )      FILE * fp;
455          return NULL;      char * p = NULL, * optfile = NULL;
456      fsize = get_file_size( optfile );      int fsize, rc = 0;
457      if( !fsize ) {          
458          rc = create_gpg_options( );      optfile = get_gnupg_cfgfile ();
459          if ( rc )      if( optfile == NULL )
460              return NULL;          return NULL;
461          fsize = get_file_size( optfile );      fsize = get_file_size( optfile );
462      }      if( !fsize ) {
463      if( fsize > 100000 )          rc = create_gpg_options( );
464          goto leave; /* too large */          if ( rc )
465      p = new char[fsize+1];              return NULL;
466      if( p == NULL )          fsize = get_file_size( optfile );
467          BUG( NULL );      }
468      fp = fopen( optfile, "rb" );      if( fsize > 100000 )
469      if( fp == NULL ) {          goto leave; /* too large */
470          free_if_alloc( p );      p = new char[fsize+1];
471          return NULL;      if( p == NULL )
472      }          BUG( NULL );
473      fread( p, 1, fsize, fp );      fp = fopen( optfile, "rb" );
474      fclose( fp );      if( fp == NULL ) {
475      p[fsize] = '\0';          free_if_alloc( p );
476      free_if_alloc( optfile );          return NULL;
477        }
478  leave:      fread( p, 1, fsize, fp );
479      return p;      fclose( fp );
480  } /* get_gnupg_config */      p[fsize] = '\0';
481        free_if_alloc( optfile );
482    
483  int  leave:
484  set_gnupg_default_key (const char * key)      return p;
485  {  } /* get_gnupg_config */
486      gpg_optfile_t opt;  
487      gpg_option_t e;  
488      char *optfile = NULL;  int
489      int rc = 0;  set_gnupg_default_key (const char * key)
490    {
491      optfile = get_gnupg_cfgfile ();      gpg_optfile_t opt;
492      if (!optfile)      gpg_option_t e;
493          return -1;      char *optfile = NULL;
494      rc = parse_gpg_options (optfile, &opt);      int rc = 0;
495      if( rc ) {  
496          free_if_alloc (optfile);      optfile = get_gnupg_cfgfile ();
497          return -1;      if (!optfile)
498      }          return -1;
499      e = find_option (opt, "default-key");      rc = parse_gpg_options (optfile, &opt);
500      if (e) {      if( rc ) {
501          free_if_alloc (e->val);          free_if_alloc (optfile);
502          e->val = m_strdup (key);          return -1;
503          e->used = 1;      }
504      }      e = find_option (opt, "default-key");
505      else      if (e) {
506          add_entry (opt, ENTRY_MULTI, "default-key", key);          free_if_alloc (e->val);
507      rc = commit_gpg_options (optfile, opt);          e->val = m_strdup (key);
508            e->used = 1;
509      free_if_alloc (optfile);      }
510      release_gpg_options (opt);      else
511            add_entry (opt, ENTRY_MULTI, "default-key", key);
512      return rc;      rc = commit_gpg_options (optfile, opt);
513  } /* set_gnupg_default_key */  
514        free_if_alloc (optfile);
515        release_gpg_options (opt);
516  /*  
517   * Set the contents of the options file.      return rc;
518   */  } /* set_gnupg_default_key */
519  int  
520  set_gnupg_options( const char *buf, size_t buflen )  
521  {  /*
522      FILE *fp;     * Set the contents of the options file.
523      char *optfile = NULL;   */
524    int
525      optfile = get_gnupg_cfgfile( );  set_gnupg_options( const char *buf, size_t buflen )
526      if( optfile == NULL )  {
527          return WPTERR_FILE_CREAT;      FILE *fp;  
528        char *optfile = NULL;
529      fp = fopen( optfile, "wb" );  
530      if( fp == NULL ) {      optfile = get_gnupg_cfgfile( );
531          free_if_alloc( optfile );      if( optfile == NULL )
532          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
533      }  
534      fwrite( buf, 1, buflen, fp );      fp = fopen( optfile, "wb" );
535      fclose( fp );      if( fp == NULL ) {
536      free_if_alloc( optfile );          free_if_alloc( optfile );
537      return 0;          return WPTERR_FILE_CREAT;
538  } /* set_gnupg_options */      }
539        fwrite( buf, 1, buflen, fp );
540  /*      fclose( fp );
541   * Check if the line contains a valid GPG argument.      free_if_alloc( optfile );
542   */      return 0;
543  static int  } /* set_gnupg_options */
544  check_line( const char *buf )  
545  {  /*
546      int j, len;   * Check if the line contains a valid GPG argument.
547      int rc = 0;   */
548    static int
549      if( *buf == '#' || *buf == '\r' || *buf == '\n' )  check_line( const char *buf )
550          return 1;  {
551      rc = 0;      int j, len;
552      for ( j = 0; valid_gpg_args[j]; j++ ) {      int rc = 0;
553          len = strlen( valid_gpg_args[j] );  
554          if( !strncmp( valid_gpg_args[j], buf, len ) )      if( *buf == '#' || *buf == '\r' || *buf == '\n' )
555              rc = 1;              return 1;
556      }      rc = 0;
557        for ( j = 0; valid_gpg_args[j]; j++ ) {
558      return rc;          len = strlen( valid_gpg_args[j] );
559  } /* check_line */          if( !strncmp( valid_gpg_args[j], buf, len ) )
560                rc = 1;    
561        }
562  int  
563  check_gnupg_options( const char *buf )      return rc;
564  {  } /* check_line */
565      char line[1024];  
566      int nbytes = 0;  
567      unsigned j;  int
568            check_gnupg_options( const char *buf )
569      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {  {
570          line[nbytes++] = buf[j];      char line[1024];
571          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {      int nbytes = 0;
572              line[nbytes] = '\0';      unsigned j;
573              if( !check_line( line ) ) {          
574                  msg_box( NULL, line, "options", MB_OK );      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {
575                  return 1;                line[nbytes++] = buf[j];
576              }          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {
577              nbytes = 0;              line[nbytes] = '\0';
578          }                    if( !check_line( line ) ) {
579      }                  msg_box( NULL, line, "options", MB_OK );
580                    return 1;      
581      return 0;              }
582  } /* check_gnupg_options */              nbytes = 0;
583            }      
584        }
585  /* Store the last access of the file inside the watcher @ctx. */  
586  static int      return 0;
587  get_last_gnupg_access (gpg_watcher_s *ctx)  } /* check_gnupg_options */
588  {  
589      HANDLE fd;  
590      char *path;  /* Store the last access of the file inside the watcher @ctx. */
591      char *file;  static int
592    get_last_gnupg_access (gpg_watcher_s *ctx)
593      path = get_gnupg_path ();  {
594      file =  make_filename (path, ctx->object, NULL);      HANDLE fd;
595      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);      char *path;
596      if (fd == INVALID_HANDLE_VALUE) {      char *file;
597          free_if_alloc (path);  
598          free_if_alloc (file);      path = get_gnupg_path ();
599          return WPTERR_FILE_OPEN;      file =  make_filename (path, ctx->object, NULL);
600      }      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
601      GetFileTime (fd, NULL, NULL, &ctx->access);      if (fd == INVALID_HANDLE_VALUE) {
602      CloseHandle (fd);          free_if_alloc (path);
603      free_if_alloc (path);          free_if_alloc (file);
604      free_if_alloc (file);          return WPTERR_FILE_OPEN;
605      return 0;      }
606  }      GetFileTime (fd, NULL, NULL, &ctx->access);
607        CloseHandle (fd);
608        free_if_alloc (path);
609  /* Check if the file inside watcher @ctx was modified. */      free_if_alloc (file);
610  static void      return 0;
611  check_last_gnupg_access (gpg_watcher_s *ctx)  }
612  {                
613      ctx->modified = 0;  
614    /* Check if the file inside watcher @ctx was modified. */
615      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&  static void
616          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)  check_last_gnupg_access (gpg_watcher_s *ctx)
617          ctx->modified = 1;  {              
618        ctx->modified = 0;
619      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;  
620      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
621  }          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
622            ctx->modified = 1;
623    
624  /* Init GPG watcher table for all monitored files. */      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
625  void      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
626  init_gnupg_table (void)  }
627  {        
628      char *p;  
629      int j;  /* Init GPG watcher table for all monitored files. */
630    void
631      for (j = 0; j < gpg_table_count; j++) {  init_gnupg_table (void)
632          p = gpg_table[j].object = m_strdup (gpg_objs[j]);  {      
633          if (!p)      char *p;
634              BUG (NULL);      int j;
635          memset (&gpg_table[j].access, 0, sizeof (FILETIME));  
636          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));      for (j = 0; j < gpg_table_count; j++) {
637          gpg_table[j].modified = 0;          p = gpg_table[j].object = m_strdup (gpg_objs[j]);
638      }          if (!p)
639  }              BUG (NULL);
640            memset (&gpg_table[j].access, 0, sizeof (FILETIME));
641            memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
642  void          gpg_table[j].modified = 0;
643  free_gnupg_table (void)      }
644  {  }
645      int j;  
646    
647      for (j=0; j < gpg_table_count; j++)  void
648          free_if_alloc (gpg_table[j].object);  free_gnupg_table (void)
649  }  {
650        int j;
651    
652  /* Return the amount of files modified since the last call. */      for (j=0; j < gpg_table_count; j++)
653  int          free_if_alloc (gpg_table[j].object);
654  keyring_check_last_access (void)  }
655  {        
656      int rc, j;  
657    /* Return the amount of files modified since the last call. */
658      rc = 0;  int
659      for (j = 0; j < gpg_table_count; j++) {  keyring_check_last_access (void)
660          get_last_gnupg_access (&gpg_table[j]);  {      
661          check_last_gnupg_access (&gpg_table[j]);      int rc, j;
662          if (gpg_table[j].modified)  
663              rc++;            rc = 0;
664      }      for (j = 0; j < gpg_table_count; j++) {
665            get_last_gnupg_access (&gpg_table[j]);
666      return rc;          check_last_gnupg_access (&gpg_table[j]);
667  }          if (gpg_table[j].modified)
668                rc++;      
669        }
670  const char*  
671  gnupg_check_file_ext (const char *fname, int *r_type)      return rc;
672  {                }
673      char file_ext[5];  
674    
675      if (r_type)  const char*
676          *r_type = PGP_NONE;  gnupg_check_file_ext (const char *fname, int *r_type)
677      if (!strchr (fname, '.' ))  {              
678          return "UNKNOWN";      char file_ext[5];
679    
680      strncpy (file_ext, fname + strlen (fname) - 4, 4);      if (r_type)
681      file_ext[4] = '\0';          *r_type = PGP_NONE;
682      if (!stricmp (file_ext, ".asc"))      if (!strchr (fname, '.' ))
683          return "ARMORED";          return "UNKNOWN";
684      else if (!stricmp (file_ext, ".sig")) {  
685          if (r_type)      strncpy (file_ext, fname + strlen (fname) - 4, 4);
686              *r_type = PGP_SIG;      file_ext[4] = '\0';
687          return "SIGNED";      if (!stricmp (file_ext, ".asc"))
688      }          return "ARMORED";
689      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if (!stricmp (file_ext, ".sig")) {
690          if (r_type)          if (r_type)
691              *r_type = PGP_MESSAGE;              *r_type = PGP_SIG;
692          return "ENCRYPTED";          return "SIGNED";
693      }      }
694      return "UNKNOWN";      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {
695  }          if (r_type)
696                *r_type = PGP_MESSAGE;
697            return "ENCRYPTED";
698  char*      }
699  get_gnupg_keyring_from_options (const char * fname, int pub)      return "UNKNOWN";
700  {  }
701      gpg_optfile_t opt;  
702      gpg_option_t e;  
703      char * kring = NULL;  char*
704      int rc = 0;  get_gnupg_keyring_from_options (const char * fname, int pub)
705    {
706      rc = parse_gpg_options (fname, &opt);      gpg_optfile_t opt;
707      if (rc)      gpg_option_t e;
708          return NULL;      char * kring = NULL;
709      if (pub)      int rc = 0;
710          e = find_option (opt, "keyring");  
711      else      rc = parse_gpg_options (fname, &opt);
712          e = find_option (opt, "secret-keyring");      if (rc)
713      if (e)          return NULL;
714          kring = m_strdup (e->val);      if (pub)
715      release_gpg_options (opt);          e = find_option (opt, "keyring");
716        else
717      return kring;          e = find_option (opt, "secret-keyring");
718  }      if (e)
719            kring = m_strdup (e->val);
720        release_gpg_options (opt);
721    
722  /* XXX: does not work with write-protected floppies */      return kring;
723  static int  }
724  my_access (const char * fname)  
725  {  
726      HANDLE hd;  
727      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,  /* XXX: does not work with write-protected floppies */
728                       NULL, OPEN_EXISTING, 0, NULL);  static int
729      if (hd == INVALID_HANDLE_VALUE)  my_access (const char * fname)
730          return -1;  {
731      CloseHandle (hd);      HANDLE hd;
732      return 0;      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
733  }                       NULL, OPEN_EXISTING, 0, NULL);
734        if (hd == INVALID_HANDLE_VALUE)
735            return -1;
736  int      CloseHandle (hd);
737  gpg_check_permissions (int showmsg)      return 0;
738  {  }
739      char * p, * name = NULL;  
740      int failed = 0, ans=0, attrs=0;  
741    int
742      p = get_gnupg_path ();  gpg_check_permissions (int showmsg)
743      check_keyring (&p);  {
744      if (p) {      char * p, * name = NULL;
745          name = make_filename (p, "pubring", "gpg");      int failed = 0, ans=0, attrs=0;
746          free_if_alloc (p);  
747          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {      p = get_gnupg_path ();
748              ans = msg_box (NULL,      check_keyring (&p);
749                             _("The selected keyring has the read-only file\n"      if (p) {
750                               "attribute. In this state you do not have write\n"          name = make_filename (p, "pubring", "gpg");
751                               "access. Do you want to remove the attribute?"),          free_if_alloc (p);
752                       _("GPG Information"), MB_YESNO);          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
753              if (ans == IDYES) {              ans = msg_box (NULL,
754                  attrs &= ~FILE_ATTRIBUTE_READONLY;                             _("The selected keyring has the read-only file\n"
755                  if (!SetFileAttributes (name, attrs)) {                               "attribute. In this state you do not have write\n"
756                      msg_box (NULL, _("Could not reset read-only state."),                               "access. Do you want to remove the attribute?"),
757                               _("GPG Error"), MB_ERR);                       _("GPG Information"), MB_YESNO);
758                      failed = 1;              if (ans == IDYES) {
759                  }                  attrs &= ~FILE_ATTRIBUTE_READONLY;
760              }                  if (!SetFileAttributes (name, attrs)) {
761              else if (ans == IDNO) {                      msg_box (NULL, _("Could not reset read-only state."),
762                  /*                               _("GPG Error"), MB_ERR);
763                  msg_box (NULL, _("All commands with write access to the keyring\n"                      failed = 1;
764                                   "will be disabled."), _("GPG Information"), MB_INFO);                  }
765                  */              }
766                  failed = 1;              else if (ans == IDNO) {
767              }                  /*
768          }                  msg_box (NULL, _("All commands with write access to the keyring\n"
769          if (my_access (name)) {                                   "will be disabled."), _("GPG Information"), MB_INFO);
770              if (showmsg)                  */
771                  msg_box (NULL,                  failed = 1;
772                  _("You do not have file access to modify the contents of\n"              }
773                    "one or both of the selected keyrings.\n"          }
774                    "\n"          if (my_access (name)) {
775                    "The keyrings are in a read-only state which is propably\n"              if (showmsg)
776                    "caused by another program which already opened the files.\n"),                  msg_box (NULL,
777                     _("GPG Warning"), MB_WARN);                  _("You do not have file access to modify the contents of\n"
778              failed = 2;                    "one or both of the selected keyrings.\n"
779          }                    "\n"
780      }                    "The keyrings are in a read-only state which is propably\n"
781      free_if_alloc (name);                    "caused by another program which already opened the files.\n"),
782      return failed;                     _("GPG Warning"), MB_WARN);
783  } /* gpg_check_permissions */              failed = 2;
784            }
785        }
786  /* Check the GPG home dir. If all methods failed, try to      free_if_alloc (name);
787     create the default folder. */      return failed;
788  static int  } /* gpg_check_permissions */
789  check_homedir (void)  
790  {        
791      char *homedir = NULL;  /* Check the GPG home dir. If all methods failed, try to
792      int yes = 0;     create the default folder. */
793    static int
794      homedir = get_reg_entry_gpg ("HomeDir");  check_homedir (void)
795      if (!homedir)  {      
796          homedir = multi_gnupg_path ();      char *homedir = NULL;
797      if (!homedir)      int yes = 0;
798          homedir = m_strdup ("c:\\gnupg");  
799      if (homedir) {      homedir = get_reg_entry_gpg ("HomeDir");
800          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {      if (!homedir)
801              yes = log_box (_("Preferences"), MB_YESNO,          homedir = multi_gnupg_path ();
802                             _("%s does not exit.\n"      if (!homedir)
803                               "Do you want to create this directory?"), homedir);          homedir = m_strdup ("c:\\gnupg");
804              if (yes == IDYES) {      if (homedir) {
805                  BOOL ec = CreateDirectory (homedir, NULL);          if (GetFileAttributes (homedir) == 0xFFFFFFFF) {
806                  free_if_alloc (homedir);              yes = log_box (_("Preferences"), MB_YESNO,
807                  if (ec == FALSE)                             _("%s does not exit.\n"
808                      return WPTERR_DIR_CREAT;                               "Do you want to create this directory?"), homedir);
809                  return 0;              if (yes == IDYES) {
810              }                  BOOL ec = CreateDirectory (homedir, NULL);
811              return WPTERR_DIR_OPEN;                  free_if_alloc (homedir);
812          }                  if (ec == FALSE)
813          free_if_alloc (homedir);                      return WPTERR_DIR_CREAT;
814      }                  return 0;
815      return 0;              }
816  }              return WPTERR_DIR_OPEN;
817            }
818            free_if_alloc (homedir);
819  int      }
820  gnupg_check_homedir (void)      return 0;
821  {        }
822      char *homedir = NULL;  
823      char *prog = NULL;  
824      int rc = 0, ec = 0;  int
825        gnupg_check_homedir (void)
826      rc = check_homedir ();  {      
827      if (rc)      char *homedir = NULL;
828          return rc;      char *prog = NULL;
829      if ((homedir = get_reg_entry_gpg ("HomeDir")) &&      int rc = 0, ec = 0;
830          !(prog = get_reg_entry_gpg ("gpgProgram" ))) {      
831          prog = make_filename (homedir, "gpg", "exe");      rc = check_homedir ();
832          if (file_exist_check (prog) == 0) {      if (rc)
833              rc = set_reg_entry_gpg ("gpgProgram", prog);          return rc;
834              if (rc)      if ((homedir = get_reg_entry_gpg ("HomeDir")) &&
835                  goto fail;          !(prog = get_reg_entry_gpg ("gpgProgram" ))) {
836          }          prog = make_filename (homedir, "gpg", "exe");
837          free_if_alloc (homedir);          if (file_exist_check (prog) == 0) {
838          free_if_alloc (prog);              rc = set_reg_entry_gpg ("gpgProgram", prog);
839          return rc;              if (rc)
840      }                  goto fail;
841      if ((prog = get_reg_entry_gpg ("gpgProgram"))          }
842          && file_exist_check (prog)) {          free_if_alloc (homedir);
843          free_if_alloc (prog);          free_if_alloc (prog);
844          homedir = get_reg_entry_gpg ("HomeDir");          return rc;
845          if (!homedir) {      }
846              rc = WPTERR_GENERAL;      if ((prog = get_reg_entry_gpg ("gpgProgram"))
847              goto fail;          && file_exist_check (prog)) {
848          }          free_if_alloc (prog);
849          prog = make_filename (homedir, "gpg", "exe");          homedir = get_reg_entry_gpg ("HomeDir");
850          if (file_exist_check (prog) == 0) {          if (!homedir) {
851              rc = set_reg_entry_gpg ("gpgProgram", prog);              rc = WPTERR_GENERAL;
852              if (rc)              goto fail;
853                  goto fail;          }
854              free_if_alloc (prog);          prog = make_filename (homedir, "gpg", "exe");
855              return rc;          if (file_exist_check (prog) == 0) {
856          }              rc = set_reg_entry_gpg ("gpgProgram", prog);
857      }              if (rc)
858                        goto fail;
859      /* Change the return code if homedir doesn't exist or if the program              free_if_alloc (prog);
860         doesn't exist. Note that exist_checks return 0 to suggest existance. */              return rc;
861      if ((!homedir || dir_exist_check (homedir)))          }
862          rc = WPTERR_GENERAL;      }
863            
864  fail:      /* Change the return code if homedir doesn't exist or if the program
865      free_if_alloc (homedir);         doesn't exist. Note that exist_checks return 0 to suggest existance. */
866      free_if_alloc (prog);      if ((!homedir || dir_exist_check (homedir)))
867      return rc;          rc = WPTERR_GENERAL;
868  } /* gnupg_check_homedir */      
869    fail:
870        free_if_alloc (homedir);
871  int      free_if_alloc (prog);
872  gnupg_copy_keyrings (void)      return rc;
873  {  } /* gnupg_check_homedir */
874      const char * pring, * sring;  
875      char * file = NULL, * path = NULL;  
876      int id = 0, rc = 0;  int
877      HWND hwnd;  gnupg_copy_keyrings (void)
878        {
879      path = get_gnupg_path ();      const char * pring, * sring;
880      if (!path)      char * file = NULL, * path = NULL;
881          return WPTERR_GENERAL;      int id = 0, rc = 0;
882      hwnd = GetDesktopWindow ();      HWND hwnd;
883        
884      pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),      path = get_gnupg_path ();
885                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);      if (!path)
886      if (!pring) {          return WPTERR_GENERAL;
887          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);      hwnd = GetDesktopWindow ();
888          free_if_alloc (path);  
889          return WPTERR_GENERAL;      pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),
890      }                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);
891      file = make_filename (path, "pubring", "gpg");      if (!pring) {
892      if (file_exist_check (file) == 0) {          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);
893          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          free_if_alloc (path);
894          if (id == IDNO)          return WPTERR_GENERAL;
895              goto fail;      }
896      }      file = make_filename (path, "pubring", "gpg");
897      if (!CopyFile (pring, file, FALSE)) {      if (file_exist_check (file) == 0) {
898          msg_box (hwnd, _("Could not copy file."), _("WinPT Error"), MB_ERR);          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);
899          rc = WPTERR_FILE_READ;          if (id == IDNO)
900          goto fail;              goto fail;
901      }      }
902      free_if_alloc (file);      if (!CopyFile (pring, file, FALSE)) {
903            msg_box (hwnd, _("Could not copy file."), _("WinPT Error"), MB_ERR);
904      sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),          rc = WPTERR_FILE_READ;
905                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);          goto fail;
906      if (!sring) {      }
907          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );      free_if_alloc (file);
908          return WPTERR_GENERAL;  
909      }      sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),
910      file = make_filename (path, "secring", "gpg");                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);
911      if (file_exist_check (file) == 0) {      if (!sring) {
912          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );
913          if( id == IDNO )          return WPTERR_GENERAL;
914              goto fail;      }
915      }      file = make_filename (path, "secring", "gpg");
916      if (!CopyFile (sring, file, FALSE)) {      if (file_exist_check (file) == 0) {
917          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);
918          rc = WPTERR_FILE_READ;          if( id == IDNO )
919      }              goto fail;
920        }
921  fail:      if (!CopyFile (sring, file, FALSE)) {
922      free_if_alloc (file);          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
923      free_if_alloc (path);          rc = WPTERR_FILE_READ;
924      return rc;      }
925  } /* gnupg_import_keyrings */  
926    fail:
927        free_if_alloc (file);
928  void      free_if_alloc (path);
929  gnupg_backup_options (void)      return rc;
930  {  } /* gnupg_import_keyrings */
931      char *cfgfile = NULL;  
932      char bak[512];  
933    void
934      cfgfile = get_gnupg_cfgfile ();  gnupg_backup_options (void)
935      if (cfgfile == NULL)  {
936          return;      char *cfgfile = NULL;
937      _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);      char bak[512];
938      CopyFile (cfgfile, bak, FALSE);  
939      free_if_alloc (cfgfile);      cfgfile = get_gnupg_cfgfile ();
940  } /* gnupg_backup_options */      if (cfgfile == NULL)
941            return;
942        _snprintf (bak, DIM (bak)-1, "%s.bak", cfgfile);
943        CopyFile (cfgfile, bak, FALSE);
944  static int      free_if_alloc (cfgfile);
945  backup_one_file (const char *srcpath, const char *srcn,  } /* gnupg_backup_options */
946                   const char *dstpath, const char *dstn)  
947  {  
948      char * src, * dst;  
949      BOOL rc;  static int
950    backup_one_file (const char *srcpath, const char *srcn,
951      src = make_filename (srcpath, srcn, "gpg");                   const char *dstpath, const char *dstn)
952      if (!src)  {
953          BUG (NULL);      char * src, * dst;
954      dst = make_filename (dstpath, dstn, "gpg");      BOOL rc;
955      if (!dst)  
956          BUG (NULL);      src = make_filename (srcpath, srcn, "gpg");
957      rc = CopyFile (src, dst, FALSE);      if (!src)
958      free_if_alloc (src);          BUG (NULL);
959      free_if_alloc (dst);      dst = make_filename (dstpath, dstn, "gpg");
960      if (!rc)      if (!dst)
961      {          BUG (NULL);
962          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);      rc = CopyFile (src, dst, FALSE);
963          return WPTERR_GENERAL;      free_if_alloc (src);
964      }      free_if_alloc (dst);
965      return 0;      if (!rc)
966  } /* backup_one_file */      {
967            log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
968            return WPTERR_GENERAL;
969  static int      }
970  check_keyring (char ** r_path)      return 0;
971  {  } /* backup_one_file */
972      char * p;  
973      char * opt, * name;  
974    static int
975      if (!*r_path)  check_keyring (char ** r_path)
976          return 0;  {
977      p = make_filename (*r_path, "pubring", "gpg");      char * p;
978      if (!p || get_file_size (p) > 0)      char * opt, * name;
979          return 0;  
980        if (!*r_path)
981      opt = get_gnupg_cfgfile ();          return 0;
982      if (!opt)      p = make_filename (*r_path, "pubring", "gpg");
983          BUG (0);      if (!p || get_file_size (p) > 0)
984      name = get_gnupg_keyring_from_options (opt, 1);          return 0;
985      free_if_alloc (opt);  
986      free_if_alloc (p);      opt = get_gnupg_cfgfile ();
987      if (!name)      if (!opt)
988          return 0;          BUG (0);
989      p = strrchr (name, '\\');      name = get_gnupg_keyring_from_options (opt, 1);
990      if (!p)      free_if_alloc (opt);
991      {      free_if_alloc (p);
992          free_if_alloc (name);      if (!name)
993          return 0;                return 0;
994      }      p = strrchr (name, '\\');
995      free_if_alloc (*r_path);      if (!p)
996      *r_path = new char [strlen (name)+1];      {
997      memset (*r_path, 0, strlen (name));          free_if_alloc (name);
998      strncpy (*r_path, name, (p-name));          return 0;      
999      free_if_alloc (name);      }
1000      return 1;      free_if_alloc (*r_path);
1001  }      *r_path = new char [strlen (name)+1];
1002        memset (*r_path, 0, strlen (name));
1003        strncpy (*r_path, name, (p-name));
1004  static char*      free_if_alloc (name);
1005  get_backup_name (const char *templ)      return 1;
1006  {  }
1007      struct tm *tm;  
1008      char *p;  
1009    static char*
1010      time_t t = time (NULL);  get_backup_name (const char *templ)
1011      tm = localtime (&t);  {
1012      p = new char [strlen (templ) + 8 + 1];      struct tm *tm;
1013      if (!p)      char *p;
1014          BUG (0);  
1015      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);      time_t t = time (NULL);
1016      return p;      tm = localtime (&t);
1017  }      p = new char [strlen (templ) + 8 + 1];
1018        if (!p)
1019            BUG (0);
1020  void      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);
1021  gnupg_backup_keyrings (void)      return p;
1022  {  }
1023      char *srcpath = NULL, *dstpath = NULL;  
1024      char *name=NULL;  
1025      int rc, bakmode=0;  void
1026    gnupg_backup_keyrings (void)
1027      if (!reg_prefs.auto_backup)  {
1028          return;      char *srcpath = NULL, *dstpath = NULL;
1029      bakmode = reg_prefs.backup.mode;      char *name=NULL;
1030      srcpath =  get_gnupg_path ();      int rc, bakmode=0;
1031      check_keyring (&srcpath);  
1032      if (bakmode == 1) {      if (!reg_prefs.auto_backup)
1033          dstpath = get_gnupg_path ();          return;
1034          check_keyring (&dstpath);      bakmode = reg_prefs.backup.mode;
1035      }      srcpath =  get_gnupg_path ();
1036      else if (bakmode == 2) {      check_keyring (&srcpath);
1037          char * tmpfile;      if (bakmode == 1) {
1038          FILE * fp;          dstpath = get_gnupg_path ();
1039            check_keyring (&dstpath);
1040          dstpath = m_strdup (reg_prefs.backup.path);      }
1041          if (!dstpath)      else if (bakmode == 2) {
1042              BUG (0);          char * tmpfile;
1043          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          FILE * fp;
1044          fp = fopen (tmpfile, "wb");  
1045          if (!fp)          dstpath = m_strdup (reg_prefs.backup.path);
1046              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,          if (!dstpath)
1047                            _("The backup drive '%s' does not seems to accessable.\n"              BUG (0);
1048                              "Please insert/check the drive to continue."), dstpath);          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1049          else {          fp = fopen (tmpfile, "wb");
1050              rc = 0;          if (!fp)
1051              fclose (fp);              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1052              unlink (tmpfile);                            _("The backup drive '%s' does not seems to accessable.\n"
1053          }                              "Please insert/check the drive to continue."), dstpath);
1054          free_if_alloc (tmpfile);          else {
1055          if (!fp || rc == IDCANCEL)              rc = 0;
1056              return;              fclose (fp);
1057      }              unlink (tmpfile);
1058      else {          }
1059          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          free_if_alloc (tmpfile);
1060          return;          if (!fp || rc == IDCANCEL)
1061      }              return;
1062      name = get_backup_name ("pubring-bak");      }
1063      rc = backup_one_file (srcpath, "pubring", dstpath, name);      else {
1064      if (!rc)          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);
1065          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          return;
1066      free_if_alloc (name);      }
1067      free_if_alloc (srcpath);      name = get_backup_name ("pubring-bak");
1068      free_if_alloc (dstpath);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1069  } /* gnupg_backup_keyrings */      if (!rc)
1070            rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1071        free_if_alloc (name);
1072  /* Display GPG error from file if possible. */      free_if_alloc (srcpath);
1073  void      free_if_alloc (dstpath);
1074  gnupg_display_error (void)  } /* gnupg_backup_keyrings */
1075  {        
1076      char tmpath[512], * errstr;  
1077      size_t size = 0;  /* Display GPG error from file if possible. */
1078      FILE * fp;  void
1079    gnupg_display_error (void)
1080      GetTempPath (sizeof tmpath - 32, (tmpath));  {      
1081      strcat (tmpath, "gpg_stderr");      char tmpath[512], * errstr;
1082      size = get_file_size (tmpath);      size_t size = 0;
1083      if (file_exist_check (tmpath) || size <= 0)      FILE * fp;
1084          return;  
1085      fp = fopen( tmpath, "rb" );      GetTempPath (sizeof tmpath - 32, (tmpath));
1086      if (!fp) {      strcat (tmpath, "gpg_stderr");
1087          msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );      size = get_file_size (tmpath);
1088          return;      if (file_exist_check (tmpath) || size <= 0)
1089      }          return;
1090      errstr = new char[size+1];      fp = fopen( tmpath, "rb" );
1091      if (!errstr)      if (!fp) {
1092          BUG (0);          msg_box( NULL, _("No GPG error description available."), _("GPG Error"), MB_INFO );
1093      fread (errstr, 1, size, fp);          return;
1094      errstr[size] = '\0';      }
1095      fclose (fp);      errstr = new char[size+1];
1096      msg_box (NULL, errstr, _("GPG Error"), MB_INFO);      if (!errstr)
1097      free_if_alloc (errstr);          BUG (0);
1098  }      fread (errstr, 1, size, fp);
1099        errstr[size] = '\0';
1100        fclose (fp);
1101        msg_box (NULL, errstr, _("GPG Error"), MB_INFO);
1102  /* check that the requested GPG keyring exist and.      free_if_alloc (errstr);
1103     Return value: 0 for success. */  }
1104  int  
1105  gnupg_access_keyring (int _pub)  
1106  {  
1107      int rc = 0;  /* check that the requested GPG keyring exist and.
1108      char *name = get_gnupg_keyring (_pub, 1);     Return value: 0 for success. */
1109      if (!name || file_exist_check (name))  int
1110          rc = -1;  gnupg_access_keyring (int _pub)
1111      free_if_alloc (name);  {
1112      return rc;      int rc = 0;
1113  }      char *name = get_gnupg_keyring (_pub, 1);
1114        if (!name || file_exist_check (name))
1115            rc = -1;
1116        free_if_alloc (name);
1117        return rc;
1118    }

Legend:
Removed from v.35  
changed lines
  Added in v.36

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26