/[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 255 by twoaday, Tue Aug 1 16:37:23 2006 UTC revision 304 by twoaday, Wed Mar 21 10:59:31 2007 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2006 Timo Schulz   *      Copyright (C) 2001-2007 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 12  Line 12 
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.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
15   */   */
16  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
17  #include <config.h>  #include <config.h>
# Line 67  static int check_keyring (char ** r_path Line 63  static int check_keyring (char ** r_path
63  char*  char*
64  multi_gnupg_path (int strict)  multi_gnupg_path (int strict)
65  {  {
66      static char buf[256+64];      static char buf[MAX_PATH+64];
67      BOOL ec;      BOOL ec;
68    
69      /* MSDN: buf must be at least MAX_PATH=256 bytes */      /* MSDN: buf must be at least MAX_PATH=256 bytes */
# Line 97  get_gnupg_path (void) Line 93  get_gnupg_path (void)
93      if (path && dir_exist_check (path) == 0)      if (path && dir_exist_check (path) == 0)
94          return path;          return path;
95      free_if_alloc (path);      free_if_alloc (path);
96      path = multi_gnupg_path (1);      return multi_gnupg_path (1);
     return path;  
97  }  }
98    
99    
# Line 107  get_gnupg_path (void) Line 102  get_gnupg_path (void)
102  char*  char*
103  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
104  {  {
105      char *optfile = NULL;      char *optfile;
106      char *path = NULL;      char *path;
     size_t nlen = 0;  
107    
108      path = get_gnupg_path ();      path = get_gnupg_path ();
109      if (!path)      if (!path)
110          return NULL;          return NULL;
111      nlen = strlen (path) + 64;      optfile = make_filename (path, GPG_CONF, NULL);
     optfile = new char[nlen + 1];  
     if (!optfile)  
         BUG (NULL);      
     _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);  
   
112      free_if_alloc (path);      free_if_alloc (path);
113    
114      return optfile;      return optfile;
115  }  }
116    
117    
118    static char*
119    get_keyring_from_conf (const char *fname, int pub)
120    {
121        config_file_t opt;
122        conf_option_t e;
123        char *kring = NULL;
124        int rc;
125    
126        rc = parse_config (fname, &opt);
127        if (rc)
128            return NULL;
129        if (pub)
130            e = conf_find_option (opt, "keyring");
131        else
132            e = conf_find_option (opt, "secret-keyring");
133        if (e != NULL)
134            kring = m_strdup (e->val);
135        release_config (opt);
136    
137        return kring;
138    }
139    
140    
141  /* Return the full path of the keyring. If @pub is 1, the public  /* Return the full path of the keyring. If @pub is 1, the public
142     keyring is return, otherwise the secret keyring. */     keyring is return, otherwise the secret keyring. */
143  char*  char*
144  get_gnupg_keyring (int pub, int strict)  get_gnupg_keyring (int pub, int strict)
145  {      {    
146      char *optfile = NULL;      char *optfile;
147      char *path = NULL;      char *path;
148      char *keyring = NULL;      char *keyring;
149    
150      path = get_gnupg_path ();      path = get_gnupg_path ();
151      if (!path)      if (!path)
# Line 146  get_gnupg_keyring (int pub, int strict) Line 159  get_gnupg_keyring (int pub, int strict)
159          free_if_alloc (path);          free_if_alloc (path);
160          return keyring;          return keyring;
161      }      }
162      if (file_exist_check (keyring) || pub && get_file_size (keyring) == 0) {      if (file_exist_check (keyring) ||
163            pub && get_file_size (keyring) == 0) {
164          free_if_alloc (keyring);          free_if_alloc (keyring);
165          optfile = make_filename (path, GPG_CONF, NULL);          optfile = make_filename (path, GPG_CONF, NULL);
166          keyring = get_gnupg_keyring_from_options (optfile, pub);          keyring = get_keyring_from_conf (optfile, pub);
167            free_if_alloc (optfile);
168      }      }
169      free_if_alloc (path);      free_if_alloc (path);
170      free_if_alloc (optfile);      
171      return keyring;      return keyring;
172  }  }
173    
# Line 173  get_gnupg_prog (void) Line 188  get_gnupg_prog (void)
188      if (!path)      if (!path)
189          return NULL;              return NULL;    
190      pgm = make_filename (path, "gpg", "exe");      pgm = make_filename (path, "gpg", "exe");
191      free_if_alloc (path);          free_if_alloc (path);
192      return pgm;      return pgm;
193  }  }
194    
# Line 212  default_key_from_cache (int *ret_no_usea Line 227  default_key_from_cache (int *ret_no_usea
227  int  int
228  gnupg_load_config (void)  gnupg_load_config (void)
229  {      {    
230      gpg_optfile_t opt;      config_file_t opt;
     gpg_option_t o;  
231      char *conf;      char *conf;
232        int rc = 0;
233            
234      conf = get_gnupg_cfgfile ();      conf = get_gnupg_cfgfile ();
235      if (!conf)      if (!conf)
236          return -1;          return -1;
237      if (parse_gpg_options (conf, &opt)) {      if (parse_config (conf, &opt)) {
238          free_if_alloc (conf);          free_if_alloc (conf);
239          return -1;          return -1;
240      }      }
241      o = find_option (opt, "ask-cert-level");      free_if_alloc (conf);
242      if (o)      if (conf_find_option (opt, "ask-cert-level"))
243          reg_prefs.gpg.ask_cert_level = 1;          reg_prefs.gpg.ask_cert_level = 1;
244      o = find_option (opt, "ask-cert-expire");      if (conf_find_option (opt, "ask-cert-expire"))
     if (o)  
245          reg_prefs.gpg.ask_cert_expire = 1;          reg_prefs.gpg.ask_cert_expire = 1;
246      release_gpg_options (opt);      /* The 'textmode' option for GPG is useful for text files
247      free_if_alloc (conf);         but it breaks the output of any binary data. Thus we return
248      return 0;         a warning here to inform the user that binary output is broken. */
249        if (conf_find_option (opt, "textmode"))
250            rc = -2;
251        release_config (opt);
252    
253        return rc;
254  }  }
255    
256    
# Line 241  extract_keyid (const char *val) Line 260  extract_keyid (const char *val)
260  {      {    
261      size_t len = strlen (val);      size_t len = strlen (val);
262    
263      if (len > 1 && val[len-1] == '!') {      if (len > 1 && val[len-1] == '!')
264          char *p = new char[len+1];          return substr (val, 0, len-1);
         if (!p)  
             BUG (0);  
         memset (p, 0, len+1);  
         memcpy (p, val, len-1);  
         return p;  
     }  
265      return m_strdup (val);      return m_strdup (val);
266  }  }
267    
268    
269    /* Return the default key.
270       This can be either a substring or a key ID. */
271  char*  char*
272  get_gnupg_default_key (void)  get_gnupg_default_key (void)
273  {      {    
274      gpg_optfile_t opt = NULL;      config_file_t opt = NULL;
275      gpg_option_t e;      conf_option_t e;
276      char *keyid = NULL, *optfile = NULL;      char *keyid = NULL, *optfile = NULL;
277      int no_usable=0;      int no_usable=0;
278    
279      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
280      if (!optfile)      if (!optfile)
281          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
282      if (parse_gpg_options (optfile, &opt)) {      if (parse_config (optfile, &opt)) {
283          free_if_alloc (optfile);          free_if_alloc (optfile);
284          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
285      }      }
286      e = find_option (opt, "default-key");      /* First we search for config entries which specify a default key. */
287        e = conf_find_option (opt, "default-key");
288      if (!e)      if (!e)
289          e = find_option (opt, "local-user");          e = conf_find_option (opt, "local-user");
290      if (e)      if (e)
291          keyid = extract_keyid (e->val);          keyid = extract_keyid (e->val);
292    
293      free_if_alloc (optfile);      free_if_alloc (optfile);
294      release_gpg_options (opt);      release_config (opt);
295    
296        /* If no entry in the config has been found, we get a key
297           from the key cache. */
298      if (!keyid)      if (!keyid)
299          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
300      return keyid;      return keyid;
# Line 398  check_gnupg_engine (const char *need_gpg Line 417  check_gnupg_engine (const char *need_gpg
417  static int  static int
418  cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)  cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
419  {  {
420      gpg_optfile_t opt;          config_file_t opt;    
421      gpg_option_t e;      conf_option_t e;
422    
423      *r_secrings = 0;      *r_secrings = 0;
424      *r_pubrings = 0;      *r_pubrings = 0;
425    
426      if (parse_gpg_options (fname, &opt))      if (parse_config (fname, &opt))
427          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
428      for (e = opt->list; e; e = e->next) {      for (e = opt->list; e; e = e->next) {
429          if (!strcmp( e->name, "secret-keyring")) {          if (!strcmp (e->name, "secret-keyring")) {
430              if (!file_exist_check (e->val))              if (!file_exist_check (e->val))
431                  r_secrings[0]++;                  r_secrings[0]++;
432          }          }
# Line 416  cfgfile_count_keyrings (const char *fnam Line 435  cfgfile_count_keyrings (const char *fnam
435                  r_pubrings[0]++;                  r_pubrings[0]++;
436          }          }
437      }      }
438      release_gpg_options (opt);      release_config (opt);
439      return 0;      return 0;
440  }  }
441    
# Line 554  leave: Line 573  leave:
573  int  int
574  set_gnupg_default_key (const char *key)  set_gnupg_default_key (const char *key)
575  {  {
576      gpg_optfile_t opt;      config_file_t opt;
577      gpg_option_t e;      conf_option_t e;
578      char *optfile = NULL;      char *optfile = NULL;
579      int rc = 0;      int rc = 0;
580    
581      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
582      if (!optfile)      if (!optfile)
583          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
584      rc = parse_gpg_options (optfile, &opt);      rc = parse_config (optfile, &opt);
585      if (rc) {      if (rc) {
586          free_if_alloc (optfile);          free_if_alloc (optfile);
587          return WPTERR_GENERAL;          return WPTERR_GENERAL;
588      }      }
589      e = find_option (opt, "default-key");      e = conf_find_option (opt, "default-key");
590      if (e && !key)      if (e && !key)
591          e->used = 0;          e->used = 0;
592      else if (e) {      else if (e) {
# Line 576  set_gnupg_default_key (const char *key) Line 595  set_gnupg_default_key (const char *key)
595          e->used = 1;          e->used = 1;
596      }      }
597      else if (key)      else if (key)
598          add_entry (opt, ENTRY_MULTI, "default-key", key);          conf_add_entry (opt, ENTRY_MULTI, "default-key", key);
599      rc = commit_gpg_options (optfile, opt);      rc = commit_config (optfile, opt);
600    
601      free_if_alloc (optfile);      free_if_alloc (optfile);
602      release_gpg_options (opt);      release_config (opt);
   
603      return rc;      return rc;
604  }  }
605    
# Line 631  static int Line 649  static int
649  check_line (const char *buf)  check_line (const char *buf)
650  {  {
651      int j, len;      int j, len;
652      int rc;      int rc = 0;
653    
654      if (*buf == '#' || *buf == '\r' || *buf == '\n')      if (*buf == '#' || *buf == '\r' || *buf == '\n')
655          return 1;          return 1;
     rc = 0;  
656      for (j = 0; valid_gpg_args[j]; j++) {      for (j = 0; valid_gpg_args[j]; j++) {
657          len = strlen (valid_gpg_args[j]);          len = strlen (valid_gpg_args[j]);
658          if (!strncmp (valid_gpg_args[j], buf, len))          if (!strncmp (valid_gpg_args[j], buf, len))
# Line 652  check_gnupg_options (const char *buf, in Line 669  check_gnupg_options (const char *buf, in
669      int nbytes = 0, lineno=0;      int nbytes = 0, lineno=0;
670      unsigned j;      unsigned j;
671                    
672      for  (j = 0; j < strlen (buf) && j < sizeof (line); j++) {      for  (j = 0; j < strlen (buf) && j < DIM (line); j++) {
673          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
674          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
675              line[nbytes] = '\0';              line[nbytes] = '\0';
# Line 680  get_last_gnupg_access (gpg_monitor_t ctx Line 697  get_last_gnupg_access (gpg_monitor_t ctx
697      HANDLE fd;      HANDLE fd;
698    
699      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
700                       NULL, OPEN_ALWAYS, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
701      if (fd == INVALID_HANDLE_VALUE)      if (fd == INVALID_HANDLE_VALUE)
702          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
703      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
# Line 787  gnupg_check_file_ext (const char *fname, Line 804  gnupg_check_file_ext (const char *fname,
804  }  }
805    
806    
807  char*  /* Check if the device where file @fname is stored on, is write-protected. */
 get_gnupg_keyring_from_options (const char *fname, int pub)  
 {  
     gpg_optfile_t opt;  
     gpg_option_t e;  
     char *kring = NULL;  
     int rc;  
   
     rc = parse_gpg_options (fname, &opt);  
     if (rc)  
         return NULL;  
     if (pub)  
         e = find_option (opt, "keyring");  
     else  
         e = find_option (opt, "secret-keyring");  
     if (e)  
         kring = m_strdup (e->val);  
     release_gpg_options (opt);  
   
     return kring;  
 }  
   
   
 /* Check if the device file @fname is stored on, is write-protected. */  
808  static int  static int
809  my_access (const char *fname)  check_file_access (const char *fname, int mode)
810  {  {
811      HANDLE hd;      HANDLE hd;
812    
813      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,      if (!mode)
814            mode = FILE_SHARE_WRITE;
815        hd = CreateFile (fname, GENERIC_WRITE, mode,
816                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
817      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
818          return -1;          return -1;
# Line 824  my_access (const char *fname) Line 820  my_access (const char *fname)
820      return 0;      return 0;
821  }  }
822    
823        
824    /* Check the device where the file @fname is stored on, is either
825       write-protected or if the file is already opened by another process
826       exclusively. And as a result, we cannot use the file for output. */
827    int
828    gpg_check_file_permissions (const char *fname, int mode)
829    {
830        int api_mode;
831        
832        switch (mode) {
833        case 0: api_mode = FILE_SHARE_READ; break;
834        case 1: api_mode = FILE_SHARE_WRITE; break;
835        case 2: api_mode = FILE_SHARE_WRITE|FILE_SHARE_READ; break;
836        default: api_mode = FILE_SHARE_READ; break;
837        }
838    
839        return check_file_access (fname, api_mode);
840    }
841    
842    
843  /* Check the file permissions of the public keyring.  /* Check the file permissions of the public keyring.
844     If @showmsg is 1 output a message in case of errors.     If @showmsg is 1 output a message in case of errors.
# Line 858  gpg_check_permissions (int showmsg) Line 873  gpg_check_permissions (int showmsg)
873                  failed = 1;                  failed = 1;
874              }              }
875          }          }
876          if (my_access (name)) {          if (gpg_check_file_permissions (name, 1)) {
877              if (showmsg)              if (showmsg)
878                  msg_box (NULL,                  msg_box (NULL,
879                  _("You do not have file access to modify the contents of\n"                  _("You do not have file access to modify the contents of\n"
# Line 885  gnupg_check_homedir (void) Line 900  gnupg_check_homedir (void)
900      int val;      int val;
901      int rc = 0;      int rc = 0;
902    
903    #ifdef WINPT_MOBILE
904        return 0;
905    #endif
906    
907      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
908      if (!homedir)      if (!homedir)
909          homedir = multi_gnupg_path (0);          homedir = multi_gnupg_path (0);
# Line 1021  check_keyring (char **r_path) Line 1040  check_keyring (char **r_path)
1040      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
1041      if (!opt)      if (!opt)
1042          BUG (0);          BUG (0);
1043      name = get_gnupg_keyring_from_options (opt, 1);      name = get_keyring_from_conf (opt, 1);
1044      free_if_alloc (opt);      free_if_alloc (opt);
1045      free_if_alloc (p);      free_if_alloc (p);
1046      if (!name)      if (!name)
# Line 1045  static char* Line 1064  static char*
1064  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1065  {  {
1066      struct tm *tm;      struct tm *tm;
1067        const char *fmt;
1068      char *p;      char *p;
1069      time_t t;      time_t t;
1070    
1071      t = time (NULL);      t = time (NULL);
1072      tm = localtime (&t);      tm = localtime (&t);
1073      p = new char [strlen (templ) + 8 + 1];      fmt = "%s-%d";
1074        p = new char [strlen (templ) + strlen (fmt) + 8 + 1];
1075      if (!p)      if (!p)
1076          BUG (0);          BUG (0);
1077      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);      sprintf (p, fmt, templ, tm->tm_wday % 3);
1078      return p;      return p;
1079  }  }
1080    
# Line 1065  get_backup_name (const char *templ) Line 1086  get_backup_name (const char *templ)
1086  void  void
1087  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1088  {  {
1089      char *srcpath = NULL, *dstpath = NULL;      char *srcpath, *dstpath;
1090      char *name=NULL;      char *name;
1091      int rc;      int rc;
1092    
1093      if (!auto_backup)      if (!auto_backup)
# Line 1074  gnupg_backup_keyrings (int auto_backup, Line 1095  gnupg_backup_keyrings (int auto_backup,
1095      srcpath = get_gnupg_path ();      srcpath = get_gnupg_path ();
1096      check_keyring (&srcpath);      check_keyring (&srcpath);
1097      if (backup_mode == 1) {      if (backup_mode == 1) {
1098          dstpath = multi_gnupg_path (1);          /* If the backup mode uses the home directory the source
1099               and destination folder will be the same. */
1100            dstpath = get_gnupg_path ();
1101          check_keyring (&dstpath);          check_keyring (&dstpath);
1102      }      }
1103      else if (backup_mode == 2) {      else if (backup_mode == 2) {
# Line 1094  gnupg_backup_keyrings (int auto_backup, Line 1117  gnupg_backup_keyrings (int auto_backup,
1117              DeleteFile (tmpfile);              DeleteFile (tmpfile);
1118          }          }
1119          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1120          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL) {
1121                free_if_alloc (dstpath);
1122                free_if_alloc (srcpath);
1123              return;              return;
1124            }
1125      }      }
1126      else {      else {
1127          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1128            free_if_alloc (srcpath);
1129          return;          return;
1130      }      }
1131      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26