/[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 168 by twoaday, Fri Jan 27 10:08:10 2006 UTC revision 214 by twoaday, Sun May 14 18:40:36 2006 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 Timo Schulz
3   *   *
4   * This file is part of MyGPGME.   * This file is part of WinPT.
5   *   *
6   * MyGPGME is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
7   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
8   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * MyGPGME is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
# Line 36  Line 36 
36  #include "wptErrors.h"  #include "wptErrors.h"
37  #include "wptW32API.h"  #include "wptW32API.h"
38  #include "wptGPG.h"  #include "wptGPG.h"
39    #include "wptTypes.h"
40    #include "wptCommonCtl.h"
41    #include "wptContext.h"
42    #include "wptKeyEdit.h"
43    #include "wptUTF8.h"
44    
45    
46    gpgme_error_t parse_keyserver_url (char **r_keyserver, unsigned short *r_port);
47    
48  /* Attribute list which holds the image data. */  /* Attribute list which holds the image data. */
49  struct attr_list_s {  struct attr_list_s {
50      struct attr_list_s *next;      struct attr_list_s *next;
# Line 49  struct attr_list_s { Line 56  struct attr_list_s {
56  typedef struct attr_list_s *attr_list_t;  typedef struct attr_list_s *attr_list_t;
57    
58    
59    /* Free attribute list @ctx. */
60  void  void
61  free_attr_list (attr_list_t ctx)  free_attr_list (attr_list_t ctx)
62  {  {
63      attr_list_t n;      attr_list_t n;
64      while (ctx) {      while (ctx) {
65          n = ctx->next;          n = ctx->next;
66          free (ctx->fpr);          safe_free (ctx->fpr);
67          free (ctx->d);          safe_free (ctx->d);
68          ctx = n;          ctx = n;
69      }      }
70  }  }
# Line 81  parse_attr_list (FILE *fp, const BYTE *d Line 89  parse_attr_list (FILE *fp, const BYTE *d
89          buffer = buf+9+10;          buffer = buf+9+10;
90          pos = 0;          pos = 0;
91          c = (attr_list_t)calloc (1, sizeof *c);          c = (attr_list_t)calloc (1, sizeof *c);
92            if (!c)
93                BUG (0);
94          p = strtok (buffer, " ");          p = strtok (buffer, " ");
95          while (p != NULL) {          while (p != NULL) {
96              switch (pos) {              switch (pos) {
# Line 102  parse_attr_list (FILE *fp, const BYTE *d Line 112  parse_attr_list (FILE *fp, const BYTE *d
112              pos++;              pos++;
113              p = strtok (NULL, " ");              p = strtok (NULL, " ");
114          }          }
         /*printf ("id=%s octets=%d flags=%d\n", c->fpr, c->octets, c->flags);*/  
115          if (!*ctx)          if (!*ctx)
116              *ctx = c;              *ctx = c;
117          else {          else {
# Line 111  parse_attr_list (FILE *fp, const BYTE *d Line 120  parse_attr_list (FILE *fp, const BYTE *d
120              t->next = c;              t->next = c;
121          }          }
122          c->d = (unsigned char*)malloc (c->octets);          c->d = (unsigned char*)malloc (c->octets);
123            if (!c->d)
124                BUG (0);
125          memcpy (c->d, data, c->octets);          memcpy (c->d, data, c->octets);
126          data += c->octets;          data += c->octets;
127          datlen -= c->octets;          datlen -= c->octets;
# Line 121  parse_attr_list (FILE *fp, const BYTE *d Line 132  parse_attr_list (FILE *fp, const BYTE *d
132  }  }
133    
134    
 /* Always use the $users temp folder. */  
 static FILE*  
 w32_tmpfile (char *tmp, DWORD tmplen)  
 {  
     char id[16];  
   
     if (!GetTempPath (tmplen-17, tmp))  
         return NULL;  
     if (tmp[strlen (tmp)-1] != '\\')  
         strcat (tmp, "\\");  
     _snprintf (id, sizeof (id)-1, "%lu", GetTickCount ());  
     strcat (tmp, id);  
     return fopen (tmp, "w+b");  
 }  
   
   
135  static int  static int
136  parse_attr_data (const char *keyid, attr_list_t *list)  parse_attr_data (const char *keyid, attr_list_t *list)
137  {  {
138      gpgme_error_t err;      gpgme_error_t err;
139      FILE *tmp;      FILE *tmp;    
     char *status, tmpnam[MAX_PATH+1];  
140      BYTE *data;      BYTE *data;
141      DWORD ndata;      char *status, tmpnam[MAX_PATH+1];
142        DWORD ndata = 0;
143    
144      err = gpg_get_photoid_data (keyid, &status, &data, &ndata);      err = gpg_get_photoid_data (keyid, &status, &data, &ndata);
145      if (err)      if (err)
146          return err;          return err;
147    
148      if (ndata > 0 && (tmp = w32_tmpfile (tmpnam, MAX_PATH)) != NULL) {      get_temp_name (tmpnam, MAX_PATH, NULL);
149        tmp = fopen (tmpnam, "w+b");
150        if (ndata > 0 && tmp != NULL) {
151          fwrite (status, 1, strlen (status), tmp);          fwrite (status, 1, strlen (status), tmp);
152          fflush (tmp);          fflush (tmp);
153          rewind (tmp);          rewind (tmp);
# Line 187  parse_secring (gpg_keycache_t cache, con Line 184  parse_secring (gpg_keycache_t cache, con
184    
185      gpg_iobuf_ioctl (inp, 3, 1, NULL);      gpg_iobuf_ioctl (inp, 3, 1, NULL);
186      pkt = (PACKET*)calloc (1, sizeof *pkt);      pkt = (PACKET*)calloc (1, sizeof *pkt);
187        if (!pkt)
188            BUG (0);
189      gpg_init_packet (pkt);      gpg_init_packet (pkt);
190      while (gpg_parse_packet (inp, pkt) != -1) {      while (gpg_parse_packet (inp, pkt) != -1) {
191          if (pkt->pkttype == PKT_SECRET_KEY) {          if (pkt->pkttype == PKT_SECRET_KEY) {
# Line 230  keycache_update_photo (gpg_keycache_t ct Line 229  keycache_update_photo (gpg_keycache_t ct
229      fnd->attrib.flags = dat->flags;      fnd->attrib.flags = dat->flags;
230      fnd->attrib.len = dat->octets;      fnd->attrib.len = dat->octets;
231      fnd->attrib.d = (unsigned char*)malloc (dat->octets);      fnd->attrib.d = (unsigned char*)malloc (dat->octets);
232        if (!fnd->attrib.d)
233            BUG (0);
234      memcpy (fnd->attrib.d, dat->d, dat->octets);      memcpy (fnd->attrib.d, dat->d, dat->octets);
235      return 0;      return 0;
236  }  }
# Line 255  keycache_update_photos (gpg_keycache_t c Line 256  keycache_update_photos (gpg_keycache_t c
256  }  }
257    
258    
259    static void
260    keycache_decode_uid (struct keycache_s *ctx)
261    {
262        gpgme_user_id_t u;
263        struct native_uid_s *n, *t;
264    
265        for (u = ctx->key->uids; u; u = u->next) {
266            n = (struct native_uid_s*)calloc (1, sizeof *n);
267            if (!n)
268                BUG (0);
269            if (is_8bit_string (u->uid)) {
270                n->malloced = 1;
271                n->uid = utf8_to_native (u->uid);
272                if (u->name != NULL)
273                    n->name = utf8_to_native (u->name);
274                if (u->email != NULL)
275                    n->email = strdup (u->email);
276                if (u->comment != NULL)
277                    n->comment = utf8_to_native (u->comment);
278            }
279            else {
280                n->malloced = 0;
281                n->uid = u->uid;
282                n->name = u->name;
283                n->comment = u->comment;
284                n->email = u->email;
285            }
286            n->signatures = u->signatures;
287            n->validity = u->validity;
288            n->revoked = u->revoked;
289            if (!ctx->uids)
290                ctx->uids = n;
291            else {
292                for (t = ctx->uids; t->next; t=t->next)
293                    ;
294                t->next = n;          
295            }
296        }
297    }
298    
299    
300    /* Store utf8 decoded user IDs in the code to avoid in-place decoding. */
301    static void
302    keycache_decode_uids (gpg_keycache_t ctx)
303    {
304        struct keycache_s *c;
305    
306        for (c = ctx->item; c; c = c->next)
307            keycache_decode_uid (c);
308    }
309    
310    
311    static void
312    free_native_uids (struct native_uid_s **r_n)
313    {
314        struct native_uid_s *t;
315        struct native_uid_s *n = *r_n;
316    
317        while (n != NULL) {
318            t = n->next;
319            if (n->malloced) {
320                safe_free (n->uid);
321                safe_free (n->name);
322                safe_free (n->comment);
323                safe_free (n->email);
324                safe_free (n->uid);
325            }
326            safe_free (n);
327            n = t;
328        }
329        *r_n = NULL;
330    }
331    
332    
333    
334  /* Merge the information from the keyrings into the key cache structure. */  /* Merge the information from the keyrings into the key cache structure. */
335  gpgme_error_t  static gpgme_error_t
336  keycache_prepare2 (gpg_keycache_t ctx, const char *kid,  keycache_prepare2 (gpg_keycache_t ctx, const char *kid,
337                     const char *pubring, const char *secring)                     const char *pubring, const char *secring)
338  {  {
# Line 281  keycache_prepare2 (gpg_keycache_t ctx, c Line 357  keycache_prepare2 (gpg_keycache_t ctx, c
357      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
358    
359      pkt = (PACKET*)calloc (1, sizeof * pkt);      pkt = (PACKET*)calloc (1, sizeof * pkt);
360        if (!pkt)
361            BUG (0);
362      gpg_init_packet (pkt);      gpg_init_packet (pkt);
363      while (gpg_parse_packet (inp, pkt) != -1) {      while (gpg_parse_packet (inp, pkt) != -1) {
364          if (pkt->pkttype == PKT_PUBLIC_KEY) {          if (pkt->pkttype == PKT_PUBLIC_KEY) {
365              strcpy (keyid, "");              strcpy (keyid, "");
366              key_seen = 1;              key_seen = 1;
367          }          }
   
368          if (pkt->pkttype == PKT_SIGNATURE &&          if (pkt->pkttype == PKT_SIGNATURE &&
369              pkt->pkt.signature->sig_class == 0x1F) {              pkt->pkt.signature->sig_class == 0x1F) {
370              if (pkt->pkt.signature->numrevkeys == 0)              if (pkt->pkt.signature->numrevkeys == 0)
# Line 301  keycache_prepare2 (gpg_keycache_t ctx, c Line 378  keycache_prepare2 (gpg_keycache_t ctx, c
378                  goto next;                  goto next;
379              c->gloflags.has_desig_rev = 1;              c->gloflags.has_desig_rev = 1;
380          }          }
381          if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1 ) {          if (pkt->pkttype == PKT_SIGNATURE && key_seen == 1) {
382              sym_prefs = gpg_parse_sig_subpkt (pkt->pkt.signature->hashed,              sym_prefs = gpg_parse_sig_subpkt (pkt->pkt.signature->hashed,
383                                                SIGSUBPKT_PREF_SYM, &nsym);                                                SIGSUBPKT_PREF_SYM, &nsym);
384              if (!sym_prefs)              if (!sym_prefs)
# Line 311  keycache_prepare2 (gpg_keycache_t ctx, c Line 388  keycache_prepare2 (gpg_keycache_t ctx, c
388              if (kid && strcmp (kid, keyid) != 0)              if (kid && strcmp (kid, keyid) != 0)
389                  goto next;                  goto next;
390              err = gpg_keycache_find_key2 (ctx, keyid, 0, &key, &c);              err = gpg_keycache_find_key2 (ctx, keyid, 0, &key, &c);
391              if (err)              if (err || !c)
392                    goto next;
393                if (c->sym_prefs) /* only use the prefs from the primary uid. */
394                  goto next;                  goto next;
395              else if (nsym > 0) {              else if (nsym > 0) {
396                  c->sym_prefs = (unsigned char*)calloc (1, nsym+1);                  c->sym_prefs = (unsigned char*)calloc (1, nsym+1);
397                  if (!c->sym_prefs)                  if (!c->sym_prefs)
398                      return gpg_error (GPG_ERR_ENOMEM);                      BUG (0);
399                  memcpy (c->sym_prefs, sym_prefs, nsym);                  memcpy (c->sym_prefs, sym_prefs, nsym);
400              }              }
401          }          }
# Line 358  gpg_keycache_new (gpg_keycache_t *r_ctx) Line 437  gpg_keycache_new (gpg_keycache_t *r_ctx)
437          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
438      ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);      ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);
439      if (!ctx)      if (!ctx)
440          return gpg_error (GPG_ERR_ENOMEM);          BUG (0);
441      ctx->secret = 0;      ctx->secret = 0;
442      ctx->pos = 0;      ctx->pos = 0;
443      *r_ctx = ctx;      *r_ctx = ctx;
# Line 379  gpg_keycache_release (gpg_keycache_t ctx Line 458  gpg_keycache_release (gpg_keycache_t ctx
458          c2 = c->next;          c2 = c->next;
459          gpgme_key_release (c->key);          gpgme_key_release (c->key);
460          c->key = NULL;          c->key = NULL;
461            if (c->rev != NULL)
462                gpg_desig_rev_release (c->rev);
463            c->rev = NULL;
464            safe_free (c->pref_keyserver);
465          safe_free (c->sym_prefs);          safe_free (c->sym_prefs);
466          safe_free (c->attrib.d);          safe_free (c->attrib.d);
467          safe_free (c->card_type);          safe_free (c->card_type);
468          free (c);          free_native_uids (&c->uids);
469            safe_free (c);
470      }      }
471      safe_free (ctx);      safe_free (ctx);
472  }  }
# Line 418  gpg_keycache_add_key (gpg_keycache_t ctx Line 502  gpg_keycache_add_key (gpg_keycache_t ctx
502            
503      c = (struct keycache_s*)calloc (1, sizeof *c);      c = (struct keycache_s*)calloc (1, sizeof *c);
504      if (!c)      if (!c)
505          return gpg_error (GPG_ERR_ENOMEM);          BUG (0);
506      c->gloflags.is_protected = 1; /*default: assume protection. */      c->gloflags.is_protected = 1; /*default: assume protection. */
507      c->key = key;      c->key = key;
508      if (!ctx->item)      if (!ctx->item)
# Line 531  gpg_keycache_next_updated_key (gpg_keyca Line 615  gpg_keycache_next_updated_key (gpg_keyca
615      for (c = ctx->item; c; c = c->next) {      for (c = ctx->item; c; c = c->next) {
616          if (c->flags != 0) {          if (c->flags != 0) {
617              *r_status = c->flags;              *r_status = c->flags;
             c->flags = 0;  
618              *r_obj = c;              *r_obj = c;
619                c->flags = 0;
620              return 0;              return 0;
621          }          }
622      }      }
# Line 554  gpg_keycache_update_key (gpg_keycache_t Line 638  gpg_keycache_update_key (gpg_keycache_t
638      err = gpgme_new (&gctx);      err = gpgme_new (&gctx);
639      if (err)      if (err)
640          return err;          return err;
641      gpgme_set_keylist_mode  (gctx, GPGME_KEYLIST_MODE_SIGS);      gpgme_set_keylist_mode  (gctx, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/);
642      err = gpgme_get_key (gctx, keyid, &key, is_sec);      err = gpgme_get_key (gctx, keyid, &key, is_sec);
643      gpgme_release (gctx);      gpgme_release (gctx);
644      if (err)      if (err)
# Line 589  gpg_keycache_update_key (gpg_keycache_t Line 673  gpg_keycache_update_key (gpg_keycache_t
673          }          }
674          if (c)          if (c)
675              c->flags = KC_FLAG_ADD;              c->flags = KC_FLAG_ADD;
676    
677        }
678    
679        /* refresh utf8 user ID list. */
680        if (c != NULL) {
681            free_native_uids (&c->uids);
682            keycache_decode_uid (c);
683      }      }
684    
685      return 0;      return 0;
686  }  }
687    
# Line 612  gpg_keycache_delete_key (gpg_keycache_t Line 704  gpg_keycache_delete_key (gpg_keycache_t
704      c = ctx->item;      c = ctx->item;
705      if (c->next == NULL) {      if (c->next == NULL) {
706          gpgme_key_release (itm->key);          gpgme_key_release (itm->key);
707          if (itm)          safe_free (itm);
             free (itm);  
708          ctx->item = NULL;          ctx->item = NULL;
709      }      }
710      else {      else {
711          while (c && c->next != itm)          for (; c != NULL; c = c->next) {
712              c = c->next;              if (c->next == itm)
713                    break;
714            }
715            assert (c != NULL); /* XXX: sometimes access violation. */
716          c->next = c->next->next;          c->next = c->next->next;
717          gpgme_key_release (itm->key);          gpgme_key_release (itm->key);
718          if (itm)          safe_free (itm);
             free (itm);  
719      }      }
720      return 0;      return 0;
721  }  }
# Line 646  gpg_keycache_init (gpg_keycache_t ctx, c Line 739  gpg_keycache_init (gpg_keycache_t ctx, c
739      if (err)      if (err)
740          return err;          return err;
741    
742      gpgme_set_keylist_mode  (c, GPGME_KEYLIST_MODE_SIGS);      /* XXX: GPGME_KEYLIST_MODE_SIG_NOTATIONS causes an internal error! */
743        gpgme_set_keylist_mode  (c, GPGME_KEYLIST_MODE_SIGS/*|GPGME_KEYLIST_MODE_SIG_NOTATIONS*/);
744      err = gpgme_op_keylist_start (c, pattern, secret);      err = gpgme_op_keylist_start (c, pattern, secret);
745      while(!err) {      while(!err) {
746          err = gpgme_op_keylist_next (c, &key);          err = gpgme_op_keylist_next (c, &key);
# Line 659  gpg_keycache_init (gpg_keycache_t ctx, c Line 753  gpg_keycache_init (gpg_keycache_t ctx, c
753      if (gpgme_err_code (err) == GPG_ERR_EOF)      if (gpgme_err_code (err) == GPG_ERR_EOF)
754          err = gpg_error (GPG_ERR_NO_ERROR);          err = gpg_error (GPG_ERR_NO_ERROR);
755      keycache_update_photos (ctx);      keycache_update_photos (ctx);
756        keycache_decode_uids (ctx);
757      /* XXX: make sure the progress dialog is closed. */      /* XXX: make sure the progress dialog is closed. */
758      gpgme_op_keylist_end (c);      gpgme_op_keylist_end (c);
759      gpgme_release (c);      gpgme_release (c);
# Line 696  copy_uid_prefs (const unsigned char *pre Line 791  copy_uid_prefs (const unsigned char *pre
791          pos++;          pos++;
792      p = (unsigned char*)calloc (1, pos+1);      p = (unsigned char*)calloc (1, pos+1);
793      if (!p)      if (!p)
794          abort ();          BUG (0);
795      memcpy (p, prefs, pos);      memcpy (p, prefs, pos);
796      return p;      return p;
797  }  }
# Line 773  keycache_next_key (gpg_keycache_t ctx, i Line 868  keycache_next_key (gpg_keycache_t ctx, i
868      if (flags && ctx->tmp->pubpart == NULL)      if (flags && ctx->tmp->pubpart == NULL)
869          flags = 0;          flags = 0;
870      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;
871      *c = ctx->tmp = ctx->tmp->next;      *c = ctx->tmp;
872        ctx->tmp = ctx->tmp->next;    
873      ctx->pos++;      ctx->pos++;
874    
875      return 0;      return 0;
# Line 787  gpgme_error_t Line 883  gpgme_error_t
883  gpg_keycache_next_key (gpg_keycache_t ctx, int flags, gpgme_key_t *r_key)  gpg_keycache_next_key (gpg_keycache_t ctx, int flags, gpgme_key_t *r_key)
884  {  {
885      struct keycache_s *c=NULL;      struct keycache_s *c=NULL;
886      gpgme_error_t err = 0;      gpgme_error_t err;
887    
888      err = keycache_next_key (ctx, flags, &c, r_key);      err = keycache_next_key (ctx, flags, &c, r_key);
889      return err;      return err;
890  }  }
891    
892    gpgme_error_t
893    gpg_keycache_next_key2 (gpg_keycache_t ctx, int flags,
894                            struct keycache_s **c, gpgme_key_t *r_key)
895    {
896        return keycache_next_key (ctx, flags, c, r_key);
897    }
898    
899    
900  /* Search for a key with the pattern @pattern and mark  /* Search for a key with the pattern @pattern and mark
901     this key as the default signing key if found.     this key as the default signing key if found.
902     Return value: 0 on success. */     Return value: 0 on success. */
# Line 835  gpg_keycache_get_default_key (gpg_keycac Line 939  gpg_keycache_get_default_key (gpg_keycac
939  }  }
940    
941    
942    static gpgme_error_t
943    decode_subpacket (const char *subpkt_data, int *type,
944                      char **out, WORD *outlen)
945    {
946        char tmp[128], *val;
947        char *enc = NULL;
948        size_t pos = 0, i=0;
949    
950        /* example: spk:24:1:21:http%3A//subkeys.pgp.de */
951        *outlen = 0;
952        *out = NULL;
953        
954        if (strncmp (subpkt_data, "spk:", 4))
955            return gpg_error (GPG_ERR_NO_DATA);
956    
957        strncpy (tmp, subpkt_data, 62);
958        val = strtok (tmp, ":");
959        while (val != NULL) {
960            switch (pos++) {
961            case 0:
962                break;
963    
964            case 1:
965                if (type)
966                    *type = atoi (val);
967                break;
968    
969            case 2:
970                break;
971    
972            case 3:
973                *outlen = atoi (val);
974                break;
975    
976            case 4:
977                enc = strdup (val);
978                break;
979            }
980            val = strtok (NULL, ":");
981        }
982        if (!enc)
983            return gpg_error (GPG_ERR_NO_DATA);;
984        *out = (char*)calloc (1, strlen (enc)+1);
985        if (!*out)
986            BUG (0);
987        for (pos = 0; pos < strlen (enc); pos++) {
988            if (enc[pos] == '%' && enc[pos+1] == '%')
989                (*out)[i++] = '%';
990            else if (enc[pos] == '%') {
991                char temp[3];
992                temp[0] = enc[++pos];
993                temp[1] = enc[++pos];
994                temp[2] = 0;
995                (*out)[i++] = (char)strtoul (temp, NULL, 16);
996            }
997            else
998                (*out)[i++] = enc[pos];
999        }
1000        (*out)[i] = 0;
1001        safe_free (enc);
1002        return 0;
1003    }
1004    
1005    
1006    /* If the attribute given in @attr is not set in the
1007       key cache object, try to update it. */
1008    gpgme_error_t
1009    gpg_keycache_update_attr (struct keycache_s *item,
1010                              int attr, int force)
1011    {
1012        gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
1013        char *val = NULL;
1014        WORD n = 0;    
1015    
1016        switch (attr) {
1017        case KC_ATTR_PREFSYM:
1018            if (!force && item->sym_prefs)
1019                break;
1020            safe_free (item->sym_prefs);
1021            err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
1022            if (!err && val != NULL)
1023                err = decode_subpacket (val, NULL, (char**)&item->sym_prefs, &n);
1024            break;
1025    
1026        case KC_ATTR_PREFKSERV:
1027            if (!force && item->pref_keyserver)
1028                break;
1029            safe_free (item->pref_keyserver);
1030            err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
1031            if (!err && val != NULL)
1032                err = decode_subpacket (val, NULL, &item->pref_keyserver, &n);
1033            if (!err && item->pref_keyserver)
1034                err = parse_keyserver_url (&item->pref_keyserver,
1035                                           &item->pref_keyserver_port);
1036            break;
1037        }
1038        safe_free (val);
1039        return err;
1040    }

Legend:
Removed from v.168  
changed lines
  Added in v.214

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26