/[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 42 by werner, Fri Oct 28 08:25:30 2005 UTC revision 117 by twoaday, Thu Dec 8 09:26:32 2005 UTC
# Line 22  Line 22 
22  #endif  #endif
23    
24  #include <windows.h>  #include <windows.h>
 #include <windows.h>  
25  #include <string.h>  #include <string.h>
26  #include <stdio.h>  #include <stdio.h>
27  #include <shlobj.h>  #include <shlobj.h>
# Line 31  Line 30 
30  #include <time.h>  #include <time.h>
31    
32  #include "wptGPG.h"  #include "wptGPG.h"
33  #include "wptGPGCmds.h"  #include "wptGpgCmds.h"
34  #include "wptGPGOptSkel.h"  #include "wptGPGOptSkel.h"
35  #include "wptTypes.h"  #include "wptTypes.h"
36  #include "wptNLS.h"  #include "wptNLS.h"
# Line 40  Line 39 
39  #include "wptW32API.h"  #include "wptW32API.h"
40  #include "wptCrypto.h"  #include "wptCrypto.h"
41    
42  #define GPG_CONF "gpg.conf"  #define GPG_CONF        "gpg.conf"
43    #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44    #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  struct gpg_watcher_s {
47      FILETIME    last_access;      FILETIME    last_access;
# Line 62  static int check_keyring (char ** r_path Line 63  static int check_keyring (char ** r_path
63    
64  /* Return the application data folder of the current user. */  /* Return the application data folder of the current user. */
65  static char*  static char*
66  multi_gnupg_path (void)  multi_gnupg_path (int strict)
67  {  {
68      static char buf[256+64];      static char buf[256+64];
69      BOOL ec;      BOOL ec;
# Line 71  multi_gnupg_path (void) Line 72  multi_gnupg_path (void)
72      memset (buf, 0, sizeof (buf));      memset (buf, 0, sizeof (buf));
73      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */      /* XXX: ec should be NOERROR (MSDN) but NOERROR is defined as '0' !? */
74      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);      ec = SHGetSpecialFolderPath (HWND_DESKTOP, buf, CSIDL_APPDATA, TRUE);
75      if (ec != 1)      if (ec != 1) {
76            log_debug ("multi_gnupg_path: SHGetSpecialFolderPath() failed\r\n",
77                       (int)GetLastError ());
78          return NULL;          return NULL;
79        }
80      strcat (buf, "\\gnupg");      strcat (buf, "\\gnupg");
81      if (access (buf, 00))      if (strict && access (buf, 00))
82          return NULL;          return NULL;
83      return m_strdup (buf);      return m_strdup (buf);
84  }  }
# Line 86  multi_gnupg_path (void) Line 90  multi_gnupg_path (void)
90  char*  char*
91  get_gnupg_path (void)  get_gnupg_path (void)
92  {  {
93      char *p = NULL, *path = NULL;      char *p = NULL;
94        char *path = NULL;
95            
96      p = get_reg_entry_gpg ("HomeDir");      p = get_reg_entry_gpg (GPG_REG_HOME);
97      if (p) {      if (p) {
98          path = m_strdup (p);          path = m_strdup (p);
99          free_if_alloc (p);          free_if_alloc (p);
100          return path;          return path;
101      }      }
102      else      else
103          return multi_gnupg_path ();          return multi_gnupg_path (1);
104      return m_strdup ("c:\\gnupg");      return m_strdup ("c:\\gnupg");
105  }  }
106    
# Line 105  get_gnupg_path (void) Line 110  get_gnupg_path (void)
110  char*  char*
111  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
112  {      {    
113      char *p = NULL, *optfile = NULL, *path = NULL;      char *p = NULL;
114        char *optfile = NULL;
115        char *path = NULL;
116      size_t nlen = 0;      size_t nlen = 0;
117    
118      path = get_gnupg_path ();      path = get_gnupg_path ();
# Line 156  get_gnupg_keyring (int pub, int strict) Line 163  get_gnupg_keyring (int pub, int strict)
163          free_if_alloc (path);          free_if_alloc (path);
164          return keyring;          return keyring;
165      }      }
166      if (file_exist_check (keyring) || get_file_size (keyring) == 0) {      if (file_exist_check (keyring) || pub && get_file_size (keyring) == 0) {
167          free_if_alloc (keyring);          free_if_alloc (keyring);
168          optfile = make_filename (path, GPG_CONF, NULL);          optfile = make_filename (path, GPG_CONF, NULL);
169          keyring = get_gnupg_keyring_from_options (optfile, pub);          keyring = get_gnupg_keyring_from_options (optfile, pub);
# Line 170  get_gnupg_keyring (int pub, int strict) Line 177  get_gnupg_keyring (int pub, int strict)
177  /* 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
178     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
179     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
180    
181    /* FIXME:  Use gpgme's engine info here. */
182  char*  char*
183  get_gnupg_prog (void)  get_gnupg_prog (void)
184  {      {    
185      char *p;      char *p;
186      char *pgm = NULL;      char *pgm = NULL;
     size_t nlen = 0;  
187    
188      p = get_reg_entry_gpg ("gpgProgram");      p = get_reg_entry_gpg (GPG_REG_EXE);
189      if (!p) {      if (!p) {
190          char *path = get_gnupg_path ();          char *path = get_gnupg_path ();
191          if (!path)          if (!path)
# Line 199  get_gnupg_prog (void) Line 207  get_gnupg_prog (void)
207  static char *  static char *
208  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
209  {  {
210      const char * s;      const char *s;
211      char * keyid = NULL;      char *keyid = NULL;
212      gpgme_key_t key;      gpgme_key_t key;
213      gpg_keycache_t sec = keycache_get_ctx (0);      gpg_keycache_t sec = keycache_get_ctx (0);
214    
# Line 215  default_key_from_cache (int *ret_no_usea Line 223  default_key_from_cache (int *ret_no_usea
223              break;              break;
224          }          }
225      }      }
226      if (!keyid) {      if (!keyid)
227          *ret_no_useable = 1;          *ret_no_useable = 1;
         msg_box (NULL, _("No useable secret key found."), _("GPG Error"), MB_ERR);  
     }  
228      return keyid;      return keyid;
229  }  }
230    
# Line 262  get_gnupg_default_key (void) Line 268  get_gnupg_default_key (void)
268          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
269      rc = parse_gpg_options (optfile, &opt);      rc = parse_gpg_options (optfile, &opt);
270      if (rc) {      if (rc) {
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 )
# Line 287  get_gnupg_default_key (void) Line 293  get_gnupg_default_key (void)
293  } /* get_gnupg_default_key */  } /* get_gnupg_default_key */
294    
295    
296    char* get_reg_entry_gpg4win (const char *path);
297    
298    /* Check if GPG4WIN is available and if so, use the
299       install path to figure out where the gpg.exe is. */
300    char*
301    check_for_gpg4win (void)
302    {
303        return get_reg_entry_gpg4win ("gpg.exe");
304    }
305    
306    
307  /* Check if the gpg application (exe file) is available. */  /* Check if the gpg application (exe file) is available. */
308  int  int
309  check_gnupg_prog (void)  check_gnupg_prog (void)
310  {  {
311      char *pgm = NULL;      char *gpgexe = NULL;
312      int rc = 0;      int rc = 0;
313    
314      pgm = get_gnupg_prog ();      gpgexe = get_gnupg_prog ();
315      if (!pgm)      if (!gpgexe || file_exist_check (gpgexe)) {
316          rc = WPTERR_GPG_EXEFILE;          free_if_alloc (gpgexe);
317      if (file_exist_check (pgm))          gpgexe = check_for_gpg4win ();
318          rc = WPTERR_GPG_EXEFILE;          if (!gpgexe || file_exist_check (gpgexe))
319      free_if_alloc (pgm);              rc = WPTERR_GPG_EXEFILE;
320            else
321                set_reg_entry_gpg (GPG_REG_EXE, gpgexe);
322        }
323        free_if_alloc (gpgexe);
324      return rc;      return rc;
325  }  }
326    
# Line 321  parse_version_nr (const char * buf, int Line 342  parse_version_nr (const char * buf, int
342      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
343      *minor = atol (tmp);      *minor = atol (tmp);
344      i=0;      i=0;
345      while (buf && isdigit( *buf ) && i < 8)      while (buf && isdigit (*buf) && i < 8)
346          tmp[i++] = *buf++;          tmp[i++] = *buf++;
347      tmp[i] = 0;      tmp[i] = 0;
348      *patch = atol (tmp);      *patch = atol (tmp);
# Line 337  check_gnupg_engine (int *r_major, int *r Line 358  check_gnupg_engine (int *r_major, int *r
358  {  {
359      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
360      gpgme_engine_info_t inf;      gpgme_engine_info_t inf;
361      char * eng = NULL;      char *eng = NULL;
362      int major=0, minor=0, patch=0;      int major=0, minor=0, patch=0;
363      int rc;      int rc = 1;
364                    
365      gpgme_new (&ctx);      gpgme_new (&ctx);
366      inf = gpgme_ctx_get_engine_info (ctx);      inf = gpgme_ctx_get_engine_info (ctx);
# Line 347  check_gnupg_engine (int *r_major, int *r Line 368  check_gnupg_engine (int *r_major, int *r
368          gpgme_release (ctx);          gpgme_release (ctx);
369          return -1;          return -1;
370      }      }
371    
372      /* 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. */
373      if (gpg_get_version (&eng))      if (gpg_get_version (&eng))
374          return -1;          return -1;
375      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
376          idea_available = 1;          idea_available = 1;
377      free (eng);      free (eng);
378      rc = parse_version_nr( inf->version, &major, &minor, &patch );      rc = parse_version_nr (inf->version, &major, &minor, &patch);
379      if( rc ) {      if (rc) {
380          gpgme_release (ctx);          gpgme_release (ctx);
381          return rc;          return rc;
382      }      }
383      if (major < *r_major || minor < *r_minor)  
384          rc = 1;      if (major > *r_major)
     else {  
         if (patch < *r_patch)  
             rc = 1;  
385          rc = 0;          rc = 0;
386      }      else if (major == *r_major && minor > *r_minor)          
387            rc = 0;
388        else if (major == *r_major && minor == *r_minor &&
389                 patch >= *r_patch)
390            rc = 0;
391    
392      *r_major = major;      *r_major = major;
393      *r_minor = minor;      *r_minor = minor;
394      *r_patch = patch;      *r_patch = patch;
# Line 420  gnupg_access_files (void) Line 444  gnupg_access_files (void)
444          rc = WPTERR_GPG_KEYRINGS;          rc = WPTERR_GPG_KEYRINGS;
445      else      else
446          secring_ok = 1;          secring_ok = 1;
447    
448      if (!pubring_ok || !secring_ok) {      if (!pubring_ok || !secring_ok) {
449          optfile = get_gnupg_cfgfile ();          optfile = get_gnupg_cfgfile ();
450          if (!optfile)          if (!optfile)
451              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
452          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
453          if (!rc && get_file_size(optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
454              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);
455              if (!rc && secrings && pubrings) {              if (!rc && secrings && pubrings) {
456                  free_if_alloc (optfile);                  free_if_alloc (optfile);
# Line 452  create_gpg_options (void) Line 477  create_gpg_options (void)
477      FILE *fp;      FILE *fp;
478      char *s, *optfile;      char *s, *optfile;
479    
480      s = get_gnupg_path( );      s = get_gnupg_path ();
481      if( s == NULL )      if( s == NULL )
482          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
483      optfile = make_filename( s, GPG_CONF, NULL );      optfile = make_filename (s, GPG_CONF, NULL);
484      fp = fopen( optfile, "wb" );      fp = fopen( optfile, "wb" );
485      if( fp == NULL ) {        if( fp == NULL ) {  
486          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
# Line 646  check_last_gnupg_access (gpg_watcher_s * Line 671  check_last_gnupg_access (gpg_watcher_s *
671      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
672          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
673          ctx->modified = 1;          ctx->modified = 1;
674        
675        /* XXX: find a better way. without it, winpt --keymanager loads
676                the key cache twice. */
677        if (ctx->last_access.dwLowDateTime == 0)
678            ctx->modified = 0;
679    
680      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;      ctx->last_access.dwLowDateTime = ctx->access.dwLowDateTime;
681      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;      ctx->last_access.dwHighDateTime = ctx->access.dwHighDateTime;
# Line 764  my_access (const char * fname) Line 794  my_access (const char * fname)
794  }  }
795    
796    
797    /* Check the file permissions of the public keyring.
798       If @showmsg is 1 output a message in case of errors.
799       Return value: 1 if read-only attribute
800                     2 if file is opened by another process exclusively. */
801  int  int
802  gpg_check_permissions (int showmsg)  gpg_check_permissions (int showmsg)
803  {  {
# Line 790  gpg_check_permissions (int showmsg) Line 824  gpg_check_permissions (int showmsg)
824                  }                  }
825              }              }
826              else if (ans == IDNO) {              else if (ans == IDNO) {
827                  /*                  /* All commands with write access will be disabled. */
                 msg_box (NULL, _("All commands with write access to the keyring\n"  
                                  "will be disabled."), _("GPG Information"), MB_INFO);  
                 */  
828                  failed = 1;                  failed = 1;
829              }              }
830          }          }
# Line 811  gpg_check_permissions (int showmsg) Line 842  gpg_check_permissions (int showmsg)
842      }      }
843      free_if_alloc (name);      free_if_alloc (name);
844      return failed;      return failed;
845  } /* gpg_check_permissions */  }
846    
847    
848  /* Check the GPG home dir. If all methods failed, try to  /* Check the GPG home dir. If all methods failed, try to
# Line 820  static int Line 851  static int
851  check_homedir (void)  check_homedir (void)
852  {        {      
853      char *homedir = NULL;      char *homedir = NULL;
854      int yes = 0;      int yes = 0, set_reg=0;
855        int rc = 0;
856    
857      homedir = get_reg_entry_gpg ("HomeDir");      homedir = get_reg_entry_gpg (GPG_REG_HOME);
858      if (!homedir)      if (!homedir) {
859          homedir = multi_gnupg_path ();          set_reg = 1;
860            homedir = multi_gnupg_path (0);
861        }
862      if (!homedir)      if (!homedir)
863          homedir = m_strdup ("c:\\gnupg");          homedir = m_strdup ("c:\\gnupg");
864      if (homedir) {      if (homedir) {
# Line 833  check_homedir (void) Line 867  check_homedir (void)
867                             _("%s does not exit.\n"                             _("%s does not exit.\n"
868                               "Do you want to create this directory?"), homedir);                               "Do you want to create this directory?"), homedir);
869              if (yes == IDYES) {              if (yes == IDYES) {
870                  BOOL ec = CreateDirectory (homedir, NULL);                  if (!CreateDirectory (homedir, NULL))
871                  free_if_alloc (homedir);                      rc = WPTERR_DIR_CREAT;
                 if (ec == FALSE)  
                     return WPTERR_DIR_CREAT;  
                 return 0;  
872              }              }
873              return WPTERR_DIR_OPEN;              else
874                    rc = WPTERR_DIR_OPEN;
875          }          }
876            if (set_reg)
877                set_reg_entry_gpg (GPG_REG_HOME, homedir);
878          free_if_alloc (homedir);          free_if_alloc (homedir);
879      }      }
880      return 0;      return rc;
881  }  }
882    
883    
# Line 852  gnupg_check_homedir (void) Line 886  gnupg_check_homedir (void)
886  {        {      
887      char *homedir = NULL;      char *homedir = NULL;
888      char *prog = NULL;      char *prog = NULL;
889      int rc = 0, ec = 0;      int rc = 0;
890            
891      rc = check_homedir ();      rc = check_homedir ();
892      if (rc)      if (rc)
893          return rc;          return rc;
894      if ((homedir = get_reg_entry_gpg ("HomeDir")) &&      if ((homedir = get_reg_entry_gpg (GPG_REG_HOME)) &&
895          !(prog = get_reg_entry_gpg ("gpgProgram" ))) {          !(prog = get_reg_entry_gpg (GPG_REG_EXE ))) {
896          prog = make_filename (homedir, "gpg", "exe");          prog = make_filename (homedir, "gpg", "exe");
897          if (file_exist_check (prog) == 0) {          if (file_exist_check (prog) == 0) {
898              rc = set_reg_entry_gpg ("gpgProgram", prog);              rc = set_reg_entry_gpg (GPG_REG_EXE, prog);
899              if (rc)              if (rc)
900                  goto fail;                  goto fail;
901          }          }
# Line 869  gnupg_check_homedir (void) Line 903  gnupg_check_homedir (void)
903          free_if_alloc (prog);          free_if_alloc (prog);
904          return rc;          return rc;
905      }      }
906      if ((prog = get_reg_entry_gpg ("gpgProgram"))      if ((prog = get_reg_entry_gpg (GPG_REG_EXE))
907          && file_exist_check (prog)) {          && file_exist_check (prog)) {
908          free_if_alloc (prog);          free_if_alloc (prog);
909          homedir = get_reg_entry_gpg ("HomeDir");          homedir = get_reg_entry_gpg (GPG_REG_HOME);
910          if (!homedir) {          if (!homedir) {
911              rc = WPTERR_GENERAL;              rc = WPTERR_GENERAL;
912              goto fail;              goto fail;
913          }          }
914          prog = make_filename (homedir, "gpg", "exe");          prog = make_filename (homedir, "gpg", "exe");
915          if (file_exist_check (prog) == 0) {          if (file_exist_check (prog) == 0) {
916              rc = set_reg_entry_gpg ("gpgProgram", prog);              rc = set_reg_entry_gpg (GPG_REG_EXE, prog);
917              if (rc)              if (rc)
918                  goto fail;                  goto fail;
919              free_if_alloc (prog);              free_if_alloc (prog);
# Line 912  gnupg_copy_keyrings (void) Line 946  gnupg_copy_keyrings (void)
946          return WPTERR_GENERAL;          return WPTERR_GENERAL;
947      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
948    
949      pring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),
950                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"),NULL);
951      if (!pring) {      if (!pring) {
952          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);
# Line 932  gnupg_copy_keyrings (void) Line 966  gnupg_copy_keyrings (void)
966      }      }
967      free_if_alloc (file);      free_if_alloc (file);
968    
969      sring = get_filename_dlg (hwnd, FILE_OPEN, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),
970                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);                                _("GPG Keyrings (*.gpg)\0*.gpg\0\0"), NULL);
971      if (!sring) {      if (!sring) {
972          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );
# Line 1048  get_backup_name (const char *templ) Line 1082  get_backup_name (const char *templ)
1082  }  }
1083    
1084    
1085    /* Make backups of all keyrings. The public key ring is
1086       rotated like this pubring-%d.gpg. */
1087  void  void
1088  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (void)
1089  {  {
# Line 1058  gnupg_backup_keyrings (void) Line 1094  gnupg_backup_keyrings (void)
1094      if (!reg_prefs.auto_backup)      if (!reg_prefs.auto_backup)
1095          return;          return;
1096      bakmode = reg_prefs.backup.mode;      bakmode = reg_prefs.backup.mode;
1097      srcpath =  get_gnupg_path ();      srcpath = get_gnupg_path ();
1098      check_keyring (&srcpath);      check_keyring (&srcpath);
1099      if (bakmode == 1) {      if (bakmode == 1) {
1100          dstpath = get_gnupg_path ();          dstpath = multi_gnupg_path (1);
1101          check_keyring (&dstpath);          check_keyring (&dstpath);
1102      }      }
1103      else if (bakmode == 2) {      else if (bakmode == 2) {
1104          char * tmpfile;          char *tmpfile;
1105          FILE * fp;          FILE *fp;
1106    
1107          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
1108          if (!dstpath)          if (!dstpath)
# Line 1080  gnupg_backup_keyrings (void) Line 1116  gnupg_backup_keyrings (void)
1116          else {          else {
1117              rc = 0;              rc = 0;
1118              fclose (fp);              fclose (fp);
1119              unlink (tmpfile);              remove (tmpfile);
1120          }          }
1121          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1122          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL)
# Line 1097  gnupg_backup_keyrings (void) Line 1133  gnupg_backup_keyrings (void)
1133      free_if_alloc (name);      free_if_alloc (name);
1134      free_if_alloc (srcpath);      free_if_alloc (srcpath);
1135      free_if_alloc (dstpath);      free_if_alloc (dstpath);
1136  } /* gnupg_backup_keyrings */  }
1137    
1138    
1139  /* Display GPG error from file if possible. */  /* Display GPG error from file if possible. */

Legend:
Removed from v.42  
changed lines
  Added in v.117

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26