/[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 248 by twoaday, Fri Jul 28 11:11:09 2006 UTC revision 255 by twoaday, Tue Aug 1 16:37:23 2006 UTC
# Line 43  Line 43 
43  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  /* Context to monitor GPG file changes. */
47      FILETIME    last_access;  struct gpg_monitor_s {
48        FILETIME    last_access;    /* last write access. */
49      FILETIME    access;      FILETIME    access;
50      char        *object;      char        *object;        /* name of the object. */
51      int         modified;      char        *fpath_object;  /* full path to the object. */
52        int         modified;       /* 1 = modified. */
53  };  };
54    typedef struct gpg_monitor_s *gpg_monitor_t;
55    
56    static const char *gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
57  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */  static gpg_monitor_s gpg_table[3];
 static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};  
 static gpg_watcher_s gpg_table[3];  
58  static int gpg_table_count = DIM (gpg_table);  static int gpg_table_count = DIM (gpg_table);
59    
60  int idea_available = 0;  int idea_available = 0; /* if the IDEA extension is available. */
61    
62    
63  static int check_keyring (char ** r_path);  static int check_keyring (char ** r_path);
64    
# Line 104  get_gnupg_path (void) Line 106  get_gnupg_path (void)
106     A value of NULL indicates an error. */     A value of NULL indicates an error. */
107  char*  char*
108  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
109  {      {
     char *p = NULL;  
110      char *optfile = NULL;      char *optfile = NULL;
111      char *path = NULL;      char *path = NULL;
112      size_t nlen = 0;      size_t nlen = 0;
# Line 120  get_gnupg_cfgfile (void) Line 121  get_gnupg_cfgfile (void)
121      _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);      _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);
122    
123      free_if_alloc (path);      free_if_alloc (path);
     free_if_alloc (p);  
124      return optfile;      return optfile;
125  }  }
126    
# Line 181  get_gnupg_prog (void) Line 181  get_gnupg_prog (void)
181  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
182     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
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;      gpgme_key_t key, pk;
# Line 211  default_key_from_cache (int *ret_no_usea Line 211  default_key_from_cache (int *ret_no_usea
211     Return value: 0 on success. */     Return value: 0 on success. */
212  int  int
213  gnupg_load_config (void)  gnupg_load_config (void)
214  {  {    
     int rc;  
215      gpg_optfile_t opt;      gpg_optfile_t opt;
216      gpg_option_t o;      gpg_option_t o;
217      char *conf;      char *conf;
# Line 220  gnupg_load_config (void) Line 219  gnupg_load_config (void)
219      conf = get_gnupg_cfgfile ();      conf = get_gnupg_cfgfile ();
220      if (!conf)      if (!conf)
221          return -1;          return -1;
222      rc = parse_gpg_options (conf, &opt);      if (parse_gpg_options (conf, &opt)) {
     if (rc) {  
223          free_if_alloc (conf);          free_if_alloc (conf);
224          return -1;          return -1;
225      }      }
# Line 261  get_gnupg_default_key (void) Line 259  get_gnupg_default_key (void)
259      gpg_optfile_t opt = NULL;      gpg_optfile_t opt = NULL;
260      gpg_option_t e;      gpg_option_t e;
261      char *keyid = NULL, *optfile = NULL;      char *keyid = NULL, *optfile = NULL;
262      int no_usable=0, rc = 0;      int no_usable=0;
263    
264      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
265      if (!optfile)      if (!optfile)
266          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
267      rc = parse_gpg_options (optfile, &opt);      if (parse_gpg_options (optfile, &opt)) {
     if (rc) {  
268          free_if_alloc (optfile);          free_if_alloc (optfile);
269          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
270      }      }
# Line 396  check_gnupg_engine (const char *need_gpg Line 393  check_gnupg_engine (const char *need_gpg
393  }  }
394    
395    
396  int  /* Count the keyring entries in the gpg.conf file.
397  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
398    static int
399    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
400  {  {
401      gpg_optfile_t opt;          gpg_optfile_t opt;    
402      gpg_option_t e;      gpg_option_t e;
# Line 468  gnupg_access_files (void) Line 467  gnupg_access_files (void)
467              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
468          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
469          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
470              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
471              if (!rc && secrings > 0 && pubrings > 0) {              if (!rc && secrings > 0 && pubrings > 0) {
472                  free_if_alloc (optfile);                  free_if_alloc (optfile);
473                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
# Line 489  gnupg_access_files (void) Line 488  gnupg_access_files (void)
488    
489    
490  static int  static int
491  create_gpg_options (void)  create_gpg_conf (void)
492  {  {
493      FILE *fp;      FILE *fp;
494      char *s, *optfile;      char *s, *optfile;
# Line 519  get_gnupg_config (void) Line 518  get_gnupg_config (void)
518  {  {
519      FILE *fp;      FILE *fp;
520      char *p = NULL, *optfile = NULL;      char *p = NULL, *optfile = NULL;
521      int fsize, rc = 0;      int fsize;
522                    
523      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
524      if (optfile == NULL)      if (!optfile)
525          return NULL;          return NULL;
526      fsize = get_file_size (optfile);      fsize = get_file_size (optfile);
527      if (!fsize) {      if (!fsize) {
528          rc = create_gpg_options ();          if (create_gpg_conf ())
         if (rc)  
529              return NULL;              return NULL;
530          fsize = get_file_size (optfile);          fsize = get_file_size (optfile);
531      }      }
# Line 593  int Line 591  int
591  set_gnupg_options (const char *buf, size_t buflen)  set_gnupg_options (const char *buf, size_t buflen)
592  {  {
593      FILE *fp;        FILE *fp;  
594      char *optfile = NULL;      char *optfile;
595    
596      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
597      if (!optfile)      if (!optfile)
# Line 611  set_gnupg_options (const char *buf, size Line 609  set_gnupg_options (const char *buf, size
609  }  }
610    
611    
612  /*  /* Check if the parameter for the option @buf is an existing file name.
613   * Check if the line contains a valid GPG argument.     Return value: 0 on success. */
614   */  static int
615    check_arg_file_exist (const char *buf)
616    {
617        const char *s = "load-extension ";
618    
619        /* XXX: this is a bit of a kludge because we just
620                detect errors for 'load-extension'. */
621        if (!strncmp (buf, s, strlen (s)))
622            buf += strlen (s);
623        else
624            return 0;
625        return file_exist_check (buf);
626    }
627    
628    
629    /* Check if the line contains a valid GPG argument. */
630  static int  static int
631  check_line (const char *buf)  check_line (const char *buf)
632  {  {
633      int j, len;      int j, len;
634      int rc = 0;      int rc;
635    
636      if (*buf == '#' || *buf == '\r' || *buf == '\n')      if (*buf == '#' || *buf == '\r' || *buf == '\n')
637          return 1;          return 1;
# Line 628  check_line (const char *buf) Line 641  check_line (const char *buf)
641          if (!strncmp (valid_gpg_args[j], buf, len))          if (!strncmp (valid_gpg_args[j], buf, len))
642              rc = 1;              rc = 1;
643      }      }
   
644      return rc;      return rc;
645  }  }
646    
647    
648  int  int
649  check_gnupg_options (const char *buf)  check_gnupg_options (const char *buf, int showerr)
650  {  {
651      char line[1024];      char line[1024];
652      int nbytes = 0;      int nbytes = 0, lineno=0;
653      unsigned j;      unsigned j;
654                    
655      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < sizeof (line); j++) {
656          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
657          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
658              line[nbytes] = '\0';              line[nbytes] = '\0';
659              if( !check_line( line ) ) {              lineno++;
660                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
661                    if (showerr)
662                        log_box ("GPG Config File", MB_ERR,
663                                 "gpg.conf:%d: invalid keyword '%s'",
664                                 lineno, line);
665                  return 1;                        return 1;      
666              }              }
667                if (check_arg_file_exist (line))
668                    return WPTERR_FILE_EXIST;
669              nbytes = 0;              nbytes = 0;
670          }                }
671      }      }
   
672      return 0;      return 0;
673  }  }
674    
675    
676  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
677  static int  static int
678  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
679  {  {
680      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
681    
682      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
683      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_ALWAYS, 0, NULL);
684      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,      if (fd == INVALID_HANDLE_VALUE)
                      OPEN_ALWAYS, 0, NULL);  
     if (fd == INVALID_HANDLE_VALUE) {  
         free_if_alloc (path);  
         free_if_alloc (file);  
685          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
686      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
687      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
688      return 0;      return 0;
689  }  }
690    
691    
692  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
693  static void  static void
694  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
695  {                {              
696      ctx->modified = 0;      ctx->modified = 0;
697    
698      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
699          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
700          ctx->modified = 1;          ctx->modified = 1;
701        
     /* XXX: find a better way. without it, winpt --keymanager loads  
             the key cache twice. */  
702      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
703          ctx->modified = 0;          ctx->modified = 0;
704    
# Line 701  check_last_gnupg_access (gpg_watcher_s * Line 707  check_last_gnupg_access (gpg_watcher_s *
707  }  }
708    
709    
710  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
711  void  void
712  init_gnupg_table (void)  init_gnupg_table (void)
713  {        {      
714      char *p;      char *path;
715      int j;      int j;
716    
717        path = get_gnupg_path ();
718      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
719          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
720            gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
721          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
722          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
723          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
724      }      }
725        free_if_alloc (path);
726  }  }
727    
728    
729    /* Release the GPG monitor table. */
730  void  void
731  free_gnupg_table (void)  free_gnupg_table (void)
732  {  {
733      int j;      int j;
734    
735      for (j=0; j < gpg_table_count; j++)      for (j=0; j < gpg_table_count; j++) {
736          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
737            free_if_alloc (gpg_table[j].fpath_object);
738        }
739  }  }
740    
741    
742  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
743  int  int
744  keyring_check_last_access (void)  keyring_check_last_access (void)
745  {        {
746      int rc, j;      int nfiles;
747        int pos;
748    
749      rc = 0;      nfiles = 0;
750      for (j = 0; j < gpg_table_count; j++) {      for (pos = 0; pos < gpg_table_count; pos++) {
751          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
752          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
753          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
754              rc++;                    nfiles++;
755      }      }
756    
757      return rc;      return nfiles;
758  }  }
759    
760    
# Line 764  gnupg_check_file_ext (const char *fname, Line 777  gnupg_check_file_ext (const char *fname,
777              *r_type = PGP_SIG;              *r_type = PGP_SIG;
778          return "SIGNED";          return "SIGNED";
779      }      }
780      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
781                  !stricmp (file_ext, ".pgp")) {
782          if (r_type)          if (r_type)
783              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
784          return "ENCRYPTED";          return "ENCRYPTED";
# Line 774  gnupg_check_file_ext (const char *fname, Line 788  gnupg_check_file_ext (const char *fname,
788    
789    
790  char*  char*
791  get_gnupg_keyring_from_options (const char * fname, int pub)  get_gnupg_keyring_from_options (const char *fname, int pub)
792  {  {
793      gpg_optfile_t opt;      gpg_optfile_t opt;
794      gpg_option_t e;      gpg_option_t e;
795      char * kring = NULL;      char *kring = NULL;
796      int rc = 0;      int rc;
797    
798      rc = parse_gpg_options (fname, &opt);      rc = parse_gpg_options (fname, &opt);
799      if (rc)      if (rc)
# Line 796  get_gnupg_keyring_from_options (const ch Line 810  get_gnupg_keyring_from_options (const ch
810  }  }
811    
812    
813    /* Check if the device file @fname is stored on, is write-protected. */
 /* XXX: does not work with write-protected floppies */  
814  static int  static int
815  my_access (const char *fname)  my_access (const char *fname)
816  {  {
817      HANDLE hd;      HANDLE hd;
818    
819      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,
820                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
821      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
# Line 867  gpg_check_permissions (int showmsg) Line 881  gpg_check_permissions (int showmsg)
881  int  int
882  gnupg_check_homedir (void)  gnupg_check_homedir (void)
883  {        {      
884      char *homedir = NULL;      char *homedir;
885      int val = 0;      int val;
886      int rc = 0;      int rc = 0;
887    
888      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
# Line 895  gnupg_check_homedir (void) Line 909  gnupg_check_homedir (void)
909  int  int
910  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
911  {  {
912      const char * pring, * sring;      const char *pring, *sring;
913      char * file = NULL, * path = NULL;      char *file = NULL, *path = NULL;
914      int id = 0, rc = 0;      int id = 0, rc = 0;
915      HWND hwnd;      HWND hwnd;
916            
# Line 957  fail: Line 971  fail:
971  void  void
972  gnupg_backup_options (void)  gnupg_backup_options (void)
973  {  {
974      char *cfgfile = NULL;      char *cfgfile;
975      char bak[512];      char bak[MAX_PATH+32];
976    
977      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
978      if (!cfgfile)      if (!cfgfile)
# Line 977  backup_one_file (const char *srcpath, co Line 991  backup_one_file (const char *srcpath, co
991      BOOL rc;      BOOL rc;
992    
993      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
994      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
995      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
996      free_if_alloc (src);      free_if_alloc (src);
997      free_if_alloc (dst);      free_if_alloc (dst);
# Line 1005  check_keyring (char **r_path) Line 1015  check_keyring (char **r_path)
1015      if (!*r_path)      if (!*r_path)
1016          return 0;          return 0;
1017      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1018      if (!p || get_file_size (p) <= 0)      if (get_file_size (p) <= 0)
1019          return 0;          return 0;
1020    
1021      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
# Line 1081  gnupg_backup_keyrings (int auto_backup, Line 1091  gnupg_backup_keyrings (int auto_backup,
1091          else {          else {
1092              rc = 0;              rc = 0;
1093              fclose (fp);              fclose (fp);
1094              remove (tmpfile);              DeleteFile (tmpfile);
1095          }          }
1096          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1097          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL)
# Line 1101  gnupg_backup_keyrings (int auto_backup, Line 1111  gnupg_backup_keyrings (int auto_backup,
1111  }  }
1112    
1113    
 /* Display GPG error from file if possible. */  
 void  
 gnupg_display_error (void)  
 {        
     char tmpath[512], *errstr;  
     size_t size = 0;  
     FILE *fp;  
   
     get_temp_name (tmpath, sizeof (tmpath), "gpg_stderr");  
     size = get_file_size (tmpath);  
     if (file_exist_check (tmpath) || size <= 0)  
         return;  
     fp = fopen( tmpath, "rb" );  
     if (!fp) {  
         msg_box (NULL, _("No GPG error description available."),  
                  _("GPG Error"), MB_INFO);  
         return;  
     }  
     errstr = new char[size+1];  
     if (!errstr)  
         BUG (0);  
     fread (errstr, 1, size, fp);  
     errstr[size] = '\0';  
     fclose (fp);  
     msg_box (NULL, errstr, _("GPG Error"), MB_INFO);  
     free_if_alloc (errstr);  
 }  
   
   
   
1114  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1115     Return value: 0 for success. */     Return value: 0 for success. */
1116  int  int

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26