/[winpt]/trunk/Src/wptKeyCache.cpp
ViewVC logotype

Diff of /trunk/Src/wptKeyCache.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 209 by twoaday, Wed May 3 14:34:08 2006 UTC revision 340 by twoaday, Sun Nov 27 13:15:07 2011 UTC
# Line 1  Line 1 
1  /* wptKeyCache.cpp- Caching for the pub- and the secring  /* wptKeyCache.cpp- Caching for the pub- and the secring
2   *      Copyright (C) 2001-2006 Timo Schulz   *      Copyright (C) 2001-2006, 2009 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   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with this program; if not, write to the Free Software  
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  
15   */   */
16    
17  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
# Line 25  Line 21 
21  #include <windows.h>  #include <windows.h>
22  #include <stdio.h>  #include <stdio.h>
23  #include <string.h>  #include <string.h>
 #include <malloc.h>  
24  #include <ctype.h>  #include <ctype.h>
25  #include <assert.h>  #include <assert.h>
26  #include <gpgme.h>  #include <gpgme.h>
# Line 43  Line 38 
38  #include "wptUTF8.h"  #include "wptUTF8.h"
39    
40    
41    gpgme_error_t parse_keyserver_url (char **r_keyserver, unsigned short *r_port);
42    
43  /* Attribute list which holds the image data. */  /* Attribute list which holds the image data. */
44  struct attr_list_s {  struct attr_list_s {
45      struct attr_list_s *next;      struct attr_list_s *next;
# Line 54  struct attr_list_s { Line 51  struct attr_list_s {
51  typedef struct attr_list_s *attr_list_t;  typedef struct attr_list_s *attr_list_t;
52    
53    
54    static unsigned char*
55    safe_uchar_alloc (size_t n)
56    {
57        unsigned char *p = new unsigned char[n];
58        if (!p)
59            BUG (0);
60        return p;
61    }
62    
63    
64  /* Free attribute list @ctx. */  /* Free attribute list @ctx. */
65  void  static void
66  free_attr_list (attr_list_t ctx)  free_attr_list (attr_list_t ctx)
67  {  {
68      attr_list_t n;      attr_list_t n;
69    
70      while (ctx) {      while (ctx) {
71          n = ctx->next;          n = ctx->next;
72          safe_free (ctx->fpr);          free_if_alloc (ctx->fpr);
73          safe_free (ctx->d);          free_if_alloc (ctx->d);
74            free_if_alloc (ctx);
75          ctx = n;          ctx = n;
76      }      }
77  }  }
# Line 86  parse_attr_list (FILE *fp, const BYTE *d Line 95  parse_attr_list (FILE *fp, const BYTE *d
95              continue;              continue;
96          buffer = buf+9+10;          buffer = buf+9+10;
97          pos = 0;          pos = 0;
98          c = (attr_list_t)calloc (1, sizeof *c);          c = new attr_list_s;
99          if (!c)          if (!c)
100              BUG (0);              BUG (0);
101            memset (c, 0, sizeof *c);
102    
103          p = strtok (buffer, " ");          p = strtok (buffer, " ");
104          while (p != NULL) {          while (p != NULL) {
105              switch (pos) {              switch (pos) {
106              case 0:              case 0:
107                  c->fpr = strdup (p);                  c->fpr = m_strdup (p);
108                  break;                  break;
109                                    
110              case 1:              case 1:
# Line 117  parse_attr_list (FILE *fp, const BYTE *d Line 128  parse_attr_list (FILE *fp, const BYTE *d
128                  ;                  ;
129              t->next = c;              t->next = c;
130          }          }
131          c->d = (unsigned char*)malloc (c->octets);          c->d = safe_uchar_alloc (c->octets);
         if (!c->d)  
             BUG (0);  
132          memcpy (c->d, data, c->octets);          memcpy (c->d, data, c->octets);
133          data += c->octets;          data += c->octets;
134          datlen -= c->octets;          datlen -= c->octets;
# Line 149  parse_attr_data (const char *keyid, attr Line 158  parse_attr_data (const char *keyid, attr
158          fwrite (status, 1, strlen (status), tmp);          fwrite (status, 1, strlen (status), tmp);
159          fflush (tmp);          fflush (tmp);
160          rewind (tmp);          rewind (tmp);
   
161          ndata = parse_attr_list (tmp, data, ndata, list);          ndata = parse_attr_list (tmp, data, ndata, list);
         fclose (tmp);  
         DeleteFile (tmpnam);  
162      }      }
163      else      else
164          *list = NULL;          *list = NULL;
165        if (tmp != NULL) {
166            fclose (tmp);
167            DeleteFile (tmpnam);
168        }
169    
170      safe_free (status);      safe_free (status);
171      safe_free (data);      safe_free (data);
# Line 198  parse_secring (gpg_keycache_t cache, con Line 208  parse_secring (gpg_keycache_t cache, con
208                  goto next;                  goto next;
209              c->gloflags.is_protected = sk->is_protected;              c->gloflags.is_protected = sk->is_protected;
210              c->gloflags.divert_to_card = sk->protect.s2k.mode==1002? 1 : 0;              c->gloflags.divert_to_card = sk->protect.s2k.mode==1002? 1 : 0;
211              if (c->pubpart != NULL) {                  if (c->pubpart != NULL) {
212                  c->pubpart->gloflags.is_protected = sk->is_protected;                      c->pubpart->gloflags.is_protected = sk->is_protected;
213                  c->pubpart->gloflags.divert_to_card = sk->protect.s2k.mode==1002? 1 : 0;                  c->pubpart->gloflags.divert_to_card = sk->protect.s2k.mode==1002? 1 : 0;
214              }              }
215          }          }
# Line 223  keycache_update_photo (gpg_keycache_t ct Line 233  keycache_update_photo (gpg_keycache_t ct
233      gpg_keycache_find_key2 (ctx, fpr, 0, &key, &fnd);      gpg_keycache_find_key2 (ctx, fpr, 0, &key, &fnd);
234      if (!fnd)      if (!fnd)
235          return gpg_error (GPG_ERR_NOT_FOUND);          return gpg_error (GPG_ERR_NOT_FOUND);
236      safe_free (fnd->attrib.d);      free_if_alloc (fnd->attrib.d);
237      fnd->attrib.flags = dat->flags;      fnd->attrib.flags = dat->flags;
238      fnd->attrib.len = dat->octets;      fnd->attrib.len = dat->octets;
239      fnd->attrib.d = (unsigned char*)malloc (dat->octets);      fnd->attrib.d = safe_uchar_alloc (dat->octets);
     if (!fnd->attrib.d)  
         BUG (0);  
240      memcpy (fnd->attrib.d, dat->d, dat->octets);      memcpy (fnd->attrib.d, dat->d, dat->octets);
241      return 0;      return 0;
242  }  }
# Line 254  keycache_update_photos (gpg_keycache_t c Line 262  keycache_update_photos (gpg_keycache_t c
262  }  }
263    
264    
265  static void  void
266  keycache_decode_uid (struct keycache_s *ctx)  keycache_decode_uid (struct keycache_s *ctx)
267  {  {
268      gpgme_user_id_t u;      gpgme_user_id_t u;
269      struct native_uid_s *n, *t;      struct native_uid_s *n, *t;
270    
271      for (u = ctx->key->uids; u; u = u->next) {      for (u = ctx->key->uids; u; u = u->next) {
272          n = (struct native_uid_s*)calloc (1, sizeof *n);          n = new native_uid_s;
273          if (!n)          if (!n)
274              BUG (0);              BUG (0);
275            memset (n, 0, sizeof *n);
276          if (is_8bit_string (u->uid)) {          if (is_8bit_string (u->uid)) {
277              n->malloced = 1;              n->malloced = 1;
278              n->uid = utf8_to_native (u->uid);              n->uid = utf8_to_native (u->uid);
279              if (u->name != NULL)              if (u->name != NULL)
280                  n->name = utf8_to_native (u->name);                  n->name = utf8_to_native (u->name);
281              if (u->email != NULL)              if (u->email != NULL)
282                  n->email = strdup (u->email);                  n->email = m_strdup (u->email);
283              if (u->comment != NULL)              if (u->comment != NULL)
284                  n->comment = utf8_to_native (u->comment);                  n->comment = utf8_to_native (u->comment);
285          }          }
# Line 315  free_native_uids (struct native_uid_s ** Line 324  free_native_uids (struct native_uid_s **
324      while (n != NULL) {      while (n != NULL) {
325          t = n->next;          t = n->next;
326          if (n->malloced) {          if (n->malloced) {
327              safe_free (n->uid);              free_if_alloc (n->uid);
328              safe_free (n->name);              free_if_alloc (n->name);
329              safe_free (n->comment);              free_if_alloc (n->comment);
330              safe_free (n->email);              free_if_alloc (n->email);
             safe_free (n->uid);  
331          }          }
332          safe_free (n);          free_if_alloc (n);
333          n = t;          n = t;
334      }      }
335      *r_n = NULL;      *r_n = NULL;
# Line 339  keycache_prepare2 (gpg_keycache_t ctx, c Line 347  keycache_prepare2 (gpg_keycache_t ctx, c
347      gpg_iobuf_t inp;      gpg_iobuf_t inp;
348      PACKET *pkt;      PACKET *pkt;
349      struct keycache_s *c;      struct keycache_s *c;
350      const byte *sym_prefs;      const BYTE *sym_prefs;
351      char keyid[16+1];      char keyid[16+1];
352      int key_seen = 0;      int key_seen = 0;
353      size_t nsym =0;      size_t nsym =0;
# Line 377  keycache_prepare2 (gpg_keycache_t ctx, c Line 385  keycache_prepare2 (gpg_keycache_t ctx, c
385              c->gloflags.has_desig_rev = 1;              c->gloflags.has_desig_rev = 1;
386          }          }
387          if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1 && c != NULL) {          if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1 && c != NULL) {
             if (c->sym_prefs) /* only use the prefs from the primary uid. */  
                 goto next;  
388              sym_prefs = gpg_parse_sig_subpkt (pkt->pkt.signature->hashed,              sym_prefs = gpg_parse_sig_subpkt (pkt->pkt.signature->hashed,
389                                                SIGSUBPKT_PREF_SYM, &nsym);                                                SIGSUBPKT_PREF_SYM, &nsym);
390              if (!sym_prefs)              if (!sym_prefs)
# Line 388  keycache_prepare2 (gpg_keycache_t ctx, c Line 394  keycache_prepare2 (gpg_keycache_t ctx, c
394              if (kid && strcmp (kid, keyid) != 0)              if (kid && strcmp (kid, keyid) != 0)
395                  goto next;                  goto next;
396              err = gpg_keycache_find_key2 (ctx, keyid, 0, &key, &c);              err = gpg_keycache_find_key2 (ctx, keyid, 0, &key, &c);
397              if (err)              if (err || !c)
398                    goto next;
399                if (c->sym_prefs) // only use the prefs from the primary uid.
400                  goto next;                  goto next;
401              else if (nsym > 0) {              else if (nsym > 0) {
402                  c->sym_prefs = (unsigned char*)calloc (1, nsym+1);                  c->sym_prefs = safe_uchar_alloc (nsym+1);
403                  if (!c->sym_prefs)                  memset (c->sym_prefs, 0, nsym+1);
                     BUG (0);  
404                  memcpy (c->sym_prefs, sym_prefs, nsym);                  memcpy (c->sym_prefs, sym_prefs, nsym);
405              }              }
406          }          }
# Line 433  gpg_keycache_new (gpg_keycache_t *r_ctx) Line 440  gpg_keycache_new (gpg_keycache_t *r_ctx)
440            
441      if (!r_ctx)      if (!r_ctx)
442          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
443      ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);      ctx = new gpg_keycache_s;    
444      if (!ctx)      if (!ctx)
445          BUG (0);          BUG (0);
446        memset (ctx, 0, sizeof *ctx);
447      ctx->secret = 0;      ctx->secret = 0;
448      ctx->pos = 0;      ctx->pos = 0;
449      *r_ctx = ctx;      *r_ctx = ctx;
# Line 443  gpg_keycache_new (gpg_keycache_t *r_ctx) Line 451  gpg_keycache_new (gpg_keycache_t *r_ctx)
451  }  }
452    
453    
454    void
455    gpg_keycache_item_release (struct keycache_s *c)
456    {
457        if (c->key)
458            gpgme_key_release (c->key);    
459        c->key = NULL;      
460        if (c->rev != NULL)    
461            gpg_desig_rev_release (c->rev);
462        c->rev = NULL;
463        free_if_alloc (c->pref_keyserver);
464        free_if_alloc (c->sym_prefs);
465        free_if_alloc (c->attrib.d);
466        free_if_alloc (c->card_type);
467        free_native_uids (&c->uids);
468        free_if_alloc (c);
469    }
470    
471    
472  /* Release keycache object @ctx. */  /* Release keycache object @ctx. */
473  void  void
474  gpg_keycache_release (gpg_keycache_t ctx)  gpg_keycache_release (gpg_keycache_t ctx)
# Line 454  gpg_keycache_release (gpg_keycache_t ctx Line 480  gpg_keycache_release (gpg_keycache_t ctx
480    
481      for (c = ctx->item; c; c = c2) {      for (c = ctx->item; c; c = c2) {
482          c2 = c->next;          c2 = c->next;
483          gpgme_key_release (c->key);          gpg_keycache_item_release (c);
         c->key = NULL;  
         if (c->rev != NULL)  
             gpg_desig_rev_release (c->rev);  
         c->rev = NULL;  
         safe_free (c->pref_keyserver);  
         safe_free (c->sym_prefs);  
         safe_free (c->attrib.d);  
         safe_free (c->card_type);  
         free_native_uids (&c->uids);  
         safe_free (c);  
484      }      }
485      safe_free (ctx);      free_if_alloc (ctx);
486  }  }
487    
488    
# Line 498  gpg_keycache_add_key (gpg_keycache_t ctx Line 514  gpg_keycache_add_key (gpg_keycache_t ctx
514      if (!ctx)      if (!ctx)
515          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
516            
517      c = (struct keycache_s*)calloc (1, sizeof *c);      c = new keycache_s;
518      if (!c)      if (!c)
519          BUG (0);          BUG (0);
520        memset (c, 0, sizeof *c);
521      c->gloflags.is_protected = 1; /*default: assume protection. */      c->gloflags.is_protected = 1; /*default: assume protection. */
522      c->key = key;      c->key = key;
523      if (!ctx->item)      if (!ctx->item)
# Line 614  gpg_keycache_next_updated_key (gpg_keyca Line 631  gpg_keycache_next_updated_key (gpg_keyca
631          if (c->flags != 0) {          if (c->flags != 0) {
632              *r_status = c->flags;              *r_status = c->flags;
633              *r_obj = c;              *r_obj = c;
634              c->flags = 0;              c->flags = 0; /* reset update flag. */
635              return 0;              return 0;
636          }          }
637      }      }
# Line 622  gpg_keycache_next_updated_key (gpg_keyca Line 639  gpg_keycache_next_updated_key (gpg_keyca
639  }  }
640    
641    
642    /* Helper to retrieve a GPG key. */
643    static gpgme_error_t
644    get_gpg_key (const char *keyid, int is_sec, gpgme_key_t *r_key)
645    {
646        gpgme_ctx_t ctx;
647        gpgme_error_t err;
648    
649        err = gpgme_new (&ctx);
650        if (err)
651            return err;
652        gpgme_set_keylist_mode  (ctx, GPGME_KEYLIST_MODE_SIGS);
653        err = gpgme_get_key (ctx, keyid, r_key, is_sec);
654        gpgme_release (ctx);
655        return err;
656    }
657    
658    
659    /* Fetch a key directly from gpg but without adding
660       it to the key cache. Caller must free @r_ctx. */
661    gpgme_error_t
662    gpg_keycache_fetch_key (const char *keyid, int is_sec,
663                            gpgme_key_t *r_key, struct keycache_s **r_c)
664    {
665        gpgme_error_t err;
666        gpgme_key_t key;
667        struct keycache_s *c;
668    
669        *r_key = NULL;
670        *r_c = NULL;
671        err = get_gpg_key (keyid, is_sec, &key);
672        if (err)
673            return err;
674    
675        c = new keycache_s;
676        if (!c)
677            BUG (0);
678        memset (c, 0, sizeof *c);
679        c->gloflags.is_protected = 1; /*default: assume protection. */
680        c->key = key;    
681        keycache_decode_uid (c);
682        *r_key = key;
683        *r_c = c;
684        return 0;
685    }
686    
687    
688    /* Update the key with the keyid @key in the key cache.
689       If the key does not exist, it is added otherwise all
690       parts are first freed and then replaced with the updated data. */
691  gpgme_error_t  gpgme_error_t
692  gpg_keycache_update_key (gpg_keycache_t ctx, int is_sec,  gpg_keycache_update_key (gpg_keycache_t ctx, int is_sec,
693                           void *opaque, const char *keyid)                           void *opaque, const char *keyid)
694  {  {    
     struct keycache_s *c = NULL, *c_new=NULL;  
695      gpgme_key_t key=NULL, fndkey=NULL;      gpgme_key_t key=NULL, fndkey=NULL;
696      gpgme_error_t err;      gpgme_error_t err;
697      gpgme_ctx_t gctx;      struct keycache_s *c = NULL, *c_new=NULL;
698      gpg_keycache_t pub = (gpg_keycache_t)opaque;      gpg_keycache_t pub = (gpg_keycache_t)opaque;
699    
700      err = gpgme_new (&gctx);      err = get_gpg_key (keyid, is_sec, &key);
     if (err)  
         return err;  
     gpgme_set_keylist_mode  (gctx, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/);  
     err = gpgme_get_key (gctx, keyid, &key, is_sec);  
     gpgme_release (gctx);  
701      if (err)      if (err)
702          return err;          return err;
703      err = gpg_keycache_find_key2 (ctx, keyid, 0, &fndkey, &c);      err = gpg_keycache_find_key2 (ctx, keyid, 0, &fndkey, &c);
# Line 669  gpg_keycache_update_key (gpg_keycache_t Line 728  gpg_keycache_update_key (gpg_keycache_t
728                  c->gloflags.divert_to_card = c_new->gloflags.divert_to_card;                  c->gloflags.divert_to_card = c_new->gloflags.divert_to_card;
729              }              }
730          }          }
731          if (c)          if (c != NULL)
732              c->flags = KC_FLAG_ADD;              c->flags = KC_FLAG_ADD;
   
733      }      }
734    
735      /* refresh utf8 user ID list. */      /* refresh utf8 user ID list. */
736      if (c != NULL) {      if (c != NULL && c->key) {
737          free_native_uids (&c->uids);          free_native_uids (&c->uids);
738          keycache_decode_uid (c);          keycache_decode_uid (c);
739      }      }
# Line 700  gpg_keycache_delete_key (gpg_keycache_t Line 758  gpg_keycache_delete_key (gpg_keycache_t
758          return rc;          return rc;
759            
760      c = ctx->item;      c = ctx->item;
761      if (c->next == NULL) {      if (!c) /* empty */
762          gpgme_key_release (itm->key);          return 0;
763          safe_free (itm);      else if (c->next == NULL) {
764            if (itm->key)
765                gpgme_key_release (itm->key);
766            itm->key = NULL;
767            free_if_alloc (itm);
768            /* the cache has no other items, so we set the context to NULL
769               to indicate that the entire cache is empty. */
770          ctx->item = NULL;          ctx->item = NULL;
771      }      }
772      else {      else {
# Line 712  gpg_keycache_delete_key (gpg_keycache_t Line 776  gpg_keycache_delete_key (gpg_keycache_t
776          }          }
777          assert (c != NULL); /* XXX: sometimes access violation. */          assert (c != NULL); /* XXX: sometimes access violation. */
778          c->next = c->next->next;          c->next = c->next->next;
779          gpgme_key_release (itm->key);          if (itm->key)
780          safe_free (itm);              gpgme_key_release (itm->key);
781            itm->key = NULL;
782            free_if_alloc (itm);
783      }      }
784      return 0;      return 0;
785  }  }
# Line 738  gpg_keycache_init (gpg_keycache_t ctx, c Line 804  gpg_keycache_init (gpg_keycache_t ctx, c
804          return err;          return err;
805    
806      /* XXX: GPGME_KEYLIST_MODE_SIG_NOTATIONS causes an internal error! */      /* XXX: GPGME_KEYLIST_MODE_SIG_NOTATIONS causes an internal error! */
807      gpgme_set_keylist_mode  (c, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/);      gpgme_set_keylist_mode  (c, GPGME_KEYLIST_MODE_SIGS);
808      err = gpgme_op_keylist_start (c, pattern, secret);      err = gpgme_op_keylist_start (c, pattern, secret);
809      while(!err) {      while(!err) {
810          err = gpgme_op_keylist_next (c, &key);          err = gpgme_op_keylist_next (c, &key);
# Line 752  gpg_keycache_init (gpg_keycache_t ctx, c Line 818  gpg_keycache_init (gpg_keycache_t ctx, c
818          err = gpg_error (GPG_ERR_NO_ERROR);          err = gpg_error (GPG_ERR_NO_ERROR);
819      keycache_update_photos (ctx);      keycache_update_photos (ctx);
820      keycache_decode_uids (ctx);      keycache_decode_uids (ctx);
     /* XXX: make sure the progress dialog is closed. */  
821      gpgme_op_keylist_end (c);      gpgme_op_keylist_end (c);
822      gpgme_release (c);      gpgme_release (c);
823      return err;      return err;
824  }  }
825    
826    
827  /* XXX: kludge to see if the key is stored on a card. */  /* Return 1 if we can assume that the actual private key is
828       stored on a smart card. This is not bullet proof, but the
829       card provides 3 keys (RSA) and each key for a different purpose. */
830  static int  static int
831  key_divert_to_card (gpgme_key_t key)  key_divert_to_card (gpgme_key_t key)
832  {  {
833      gpgme_subkey_t k;      gpgme_subkey_t k;
834      int n=0, n_alg=0, can_auth = 0;      int n=0;
835        int can_auth = 0, can_encr = 0;
836    
837      for (k = key->subkeys; k; k = k->next) {      for (k = key->subkeys; k; k = k->next) {
838          n++;          n++;
839          if (k->pubkey_algo == GPGME_PK_RSA && k->length == 1024)          if (k->pubkey_algo != GPGME_PK_RSA || k->length != 1024) {
840              n_alg++;              return 0;
841                break;
842            }
843          if (k->can_authenticate)          if (k->can_authenticate)
844              can_auth++;              can_auth++;
845            if (k->can_encrypt)
846                can_encr++;
847      }      }
848      if (n == 3 && n_alg == 3 && can_auth == 1)      if (n >= 3 && can_auth >= 1 && can_encr >= 1)
849          return 1;          return 1;
850      return 0;      return 0;
851  }  }
# Line 787  copy_uid_prefs (const unsigned char *pre Line 859  copy_uid_prefs (const unsigned char *pre
859    
860      while (prefs[pos] != 0)      while (prefs[pos] != 0)
861          pos++;          pos++;
862      p = (unsigned char*)calloc (1, pos+1);      p = safe_uchar_alloc (pos+1);
863      if (!p)      memset (p, 0, pos+1);
         BUG (0);  
864      memcpy (p, prefs, pos);      memcpy (p, prefs, pos);
865      return p;      return p;
866  }  }
867    
868    
869    /* Sync the secret and the public key cache information. */
870  gpgme_error_t  gpgme_error_t
871  gpg_keycache_sync (gpg_keycache_t pub, gpg_keycache_t sec)  gpg_keycache_sync (gpg_keycache_t pub, gpg_keycache_t sec)
872  {  {
# Line 804  gpg_keycache_sync (gpg_keycache_t pub, g Line 876  gpg_keycache_sync (gpg_keycache_t pub, g
876      if (!pub || !sec)      if (!pub || !sec)
877          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
878            
879      for (c=sec->item; c; c=c->next) {        for (c=sec->item; c; c=c->next) {
880          if (!gpg_keycache_find_key2 (pub, c->key->subkeys->keyid, 0, &key, &c_sec)) {          if (!gpg_keycache_find_key2 (pub, c->key->subkeys->keyid, 0,
881                                         &key, &c_sec)) {
882              c_sec->gloflags.is_protected = c->gloflags.is_protected;              c_sec->gloflags.is_protected = c->gloflags.is_protected;
883              c_sec->gloflags.divert_to_card = c->gloflags.divert_to_card;              c_sec->gloflags.divert_to_card = c->gloflags.divert_to_card;
884              if (!c->gloflags.divert_to_card)              if (!c->gloflags.divert_to_card)
# Line 862  keycache_next_key (gpg_keycache_t ctx, i Line 935  keycache_next_key (gpg_keycache_t ctx, i
935      }      }
936      if (ctx->tmp->flags != 0)      if (ctx->tmp->flags != 0)
937          ctx->tmp->flags = 0; /* reset the 'updated' status. */          ctx->tmp->flags = 0; /* reset the 'updated' status. */
938    
939      /* it might be possible there is no public key. */      /* it might be possible there is no public key. */
940      if (flags && ctx->tmp->pubpart == NULL)      if (flags && ctx->tmp->pubpart == NULL)
941          flags = 0;          flags = 0;
942      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;
943      *c = ctx->tmp;      *c = ctx->tmp;
944      ctx->tmp = ctx->tmp->next;          ctx->tmp = ctx->tmp->next;
945      ctx->pos++;      ctx->pos++;
946    
947      return 0;      return 0;
# Line 887  gpg_keycache_next_key (gpg_keycache_t ct Line 961  gpg_keycache_next_key (gpg_keycache_t ct
961      return err;      return err;
962  }  }
963    
964    
965  gpgme_error_t  gpgme_error_t
966  gpg_keycache_next_key2 (gpg_keycache_t ctx, int flags,  gpg_keycache_next_key2 (gpg_keycache_t ctx, int flags,
967                          struct keycache_s **c, gpgme_key_t *r_key)                          struct keycache_s **c, gpgme_key_t *r_key)
# Line 937  gpg_keycache_get_default_key (gpg_keycac Line 1012  gpg_keycache_get_default_key (gpg_keycac
1012  }  }
1013    
1014    
1015    /* FIXME: rewrite the subpacket part */
1016    void unhexify_buffer (const char *in, char **r_out);
1017    
1018  static gpgme_error_t  static gpgme_error_t
1019  decode_subpacket (const char *subpkt_data, int *type,  decode_subpacket (const char *subpkt_data, int *type,
1020                    char **out, WORD *outlen)                    char **out, WORD *outlen)
1021  {  {
1022      char tmp[128], *val;      char tmp[128], *val;
1023      char *enc = NULL;      char *enc = NULL;      
1024      size_t pos = 0, i=0;      size_t pos = 0;
1025    
1026      /* example: spk:24:1:21:http%3A//subkeys.pgp.de */      /* example: spk:24:1:21:http%3A//subkeys.pgp.de */
1027      *outlen = 0;      *outlen = 0;
# Line 952  decode_subpacket (const char *subpkt_dat Line 1030  decode_subpacket (const char *subpkt_dat
1030      if (strncmp (subpkt_data, "spk:", 4))      if (strncmp (subpkt_data, "spk:", 4))
1031          return gpg_error (GPG_ERR_NO_DATA);          return gpg_error (GPG_ERR_NO_DATA);
1032    
1033      strncpy (tmp, subpkt_data, 62);      /* XXX: do not use static buffer sizes. */
1034        strncpy (tmp, subpkt_data, DIM (tmp)-4);
1035      val = strtok (tmp, ":");      val = strtok (tmp, ":");
1036      while (val != NULL) {      while (val != NULL) {
1037          switch (pos++) {          switch (pos++) {
# Line 972  decode_subpacket (const char *subpkt_dat Line 1051  decode_subpacket (const char *subpkt_dat
1051              break;              break;
1052    
1053          case 4:          case 4:
1054              enc = strdup (val);              enc = m_strdup (val);
1055              break;              break;
1056          }          }
1057          val = strtok (NULL, ":");          val = strtok (NULL, ":");
1058      }      }
1059      if (!enc)      if (!enc)
1060          return gpg_error (GPG_ERR_NO_DATA);;          return gpg_error (GPG_ERR_NO_DATA);
1061      *out = (char*)calloc (1, strlen (enc)+1);      unhexify_buffer (enc, out);
1062      if (!*out)      free_if_alloc (enc);
         BUG (0);  
     for (pos = 0; pos < strlen (enc); pos++) {  
         if (enc[pos] == '%' && enc[pos+1] == '%')  
             (*out)[i++] = '%';  
         else if (enc[pos] == '%') {  
             char temp[3];  
             temp[0] = enc[++pos];  
             temp[1] = enc[++pos];  
             temp[2] = 0;  
             (*out)[i++] = (char)strtoul (temp, NULL, 16);  
         }  
         else  
             (*out)[i++] = enc[pos];  
     }  
     (*out)[i] = 0;  
     safe_free (enc);  
1063      return 0;      return 0;
1064  }  }
1065    
# Line 1015  gpg_keycache_update_attr (struct keycach Line 1078  gpg_keycache_update_attr (struct keycach
1078      case KC_ATTR_PREFSYM:      case KC_ATTR_PREFSYM:
1079          if (!force && item->sym_prefs)          if (!force && item->sym_prefs)
1080              break;              break;
1081          safe_free (item->sym_prefs);          free_if_alloc (item->sym_prefs);
1082          err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);          err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
1083          if (!err && val != NULL)          if (!err && val != NULL)
1084              err = decode_subpacket (val, NULL, (char**)&item->sym_prefs, &n);              err = decode_subpacket (val, NULL, (char**)&item->sym_prefs, &n);
# Line 1024  gpg_keycache_update_attr (struct keycach Line 1087  gpg_keycache_update_attr (struct keycach
1087      case KC_ATTR_PREFKSERV:      case KC_ATTR_PREFKSERV:
1088          if (!force && item->pref_keyserver)          if (!force && item->pref_keyserver)
1089              break;              break;
1090          safe_free (item->pref_keyserver);          free_if_alloc (item->pref_keyserver);
1091          err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);          err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
1092          if (!err && val != NULL)          if (!err && val != NULL)
1093              err = decode_subpacket (val, NULL, &item->pref_keyserver, &n);              err = decode_subpacket (val, NULL, &item->pref_keyserver, &n);
1094            if (!err && item->pref_keyserver)
1095                err = parse_keyserver_url (&item->pref_keyserver,
1096                                           &item->pref_keyserver_port);
1097          break;          break;
1098      }      }
1099      safe_free (val);      safe_free (val);

Legend:
Removed from v.209  
changed lines
  Added in v.340

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26