/[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 147 by twoaday, Fri Jan 13 14:21:16 2006 UTC revision 187 by twoaday, Wed Mar 22 11:04:20 2006 UTC
# 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    
41    
42  /* Attribute list which holds the image data. */  /* Attribute list which holds the image data. */
# Line 49  struct attr_list_s { Line 50  struct attr_list_s {
50  typedef struct attr_list_s *attr_list_t;  typedef struct attr_list_s *attr_list_t;
51    
52    
53    /* Free attribute list @ctx. */
54  void  void
55  free_attr_list (attr_list_t ctx)  free_attr_list (attr_list_t ctx)
56  {  {
# Line 81  parse_attr_list (FILE *fp, const BYTE *d Line 83  parse_attr_list (FILE *fp, const BYTE *d
83          buffer = buf+9+10;          buffer = buf+9+10;
84          pos = 0;          pos = 0;
85          c = (attr_list_t)calloc (1, sizeof *c);          c = (attr_list_t)calloc (1, sizeof *c);
86            if (!c)
87                BUG (0);
88          p = strtok (buffer, " ");          p = strtok (buffer, " ");
89          while (p != NULL) {          while (p != NULL) {
90              switch (pos) {              switch (pos) {
# Line 102  parse_attr_list (FILE *fp, const BYTE *d Line 106  parse_attr_list (FILE *fp, const BYTE *d
106              pos++;              pos++;
107              p = strtok (NULL, " ");              p = strtok (NULL, " ");
108          }          }
         /*printf ("id=%s octets=%d flags=%d\n", c->fpr, c->octets, c->flags);*/  
109          if (!*ctx)          if (!*ctx)
110              *ctx = c;              *ctx = c;
111          else {          else {
# Line 111  parse_attr_list (FILE *fp, const BYTE *d Line 114  parse_attr_list (FILE *fp, const BYTE *d
114              t->next = c;              t->next = c;
115          }          }
116          c->d = (unsigned char*)malloc (c->octets);          c->d = (unsigned char*)malloc (c->octets);
117            if (!c->d)
118                BUG (0);
119          memcpy (c->d, data, c->octets);          memcpy (c->d, data, c->octets);
120          data += c->octets;          data += c->octets;
121          datlen -= c->octets;          datlen -= c->octets;
# Line 125  static int Line 130  static int
130  parse_attr_data (const char *keyid, attr_list_t *list)  parse_attr_data (const char *keyid, attr_list_t *list)
131  {  {
132      gpgme_error_t err;      gpgme_error_t err;
133      FILE *tmp;      FILE *tmp;    
     char *status;  
134      BYTE *data;      BYTE *data;
135      DWORD ndata;      char *status, tmpnam[MAX_PATH+1];
136        DWORD ndata = 0;
137    
138      err = gpg_get_photoid_data (keyid, &status, &data, &ndata);      err = gpg_get_photoid_data (keyid, &status, &data, &ndata);
139      if (err)      if (err)
140          return err;          return err;
141    
142      if (ndata > 0) {      get_temp_name (tmpnam, MAX_PATH, NULL);
143          tmp = tmpfile ();      tmp = fopen (tmpnam, "w+b");
144        if (ndata > 0 && tmp != NULL) {
145          fwrite (status, 1, strlen (status), tmp);          fwrite (status, 1, strlen (status), tmp);
146          fflush (tmp);          fflush (tmp);
147          rewind (tmp);          rewind (tmp);
148    
149          ndata = parse_attr_list (tmp, data, ndata, list);          ndata = parse_attr_list (tmp, data, ndata, list);
150          fclose (tmp);          fclose (tmp);
151            DeleteFile (tmpnam);
152      }      }
153      else      else
154          *list = NULL;          *list = NULL;
# Line 171  parse_secring (gpg_keycache_t cache, con Line 178  parse_secring (gpg_keycache_t cache, con
178    
179      gpg_iobuf_ioctl (inp, 3, 1, NULL);      gpg_iobuf_ioctl (inp, 3, 1, NULL);
180      pkt = (PACKET*)calloc (1, sizeof *pkt);      pkt = (PACKET*)calloc (1, sizeof *pkt);
181        if (!pkt)
182            BUG (0);
183      gpg_init_packet (pkt);      gpg_init_packet (pkt);
184      while (gpg_parse_packet (inp, pkt) != -1) {      while (gpg_parse_packet (inp, pkt) != -1) {
185          if (pkt->pkttype == PKT_SECRET_KEY) {          if (pkt->pkttype == PKT_SECRET_KEY) {
# Line 214  keycache_update_photo (gpg_keycache_t ct Line 223  keycache_update_photo (gpg_keycache_t ct
223      fnd->attrib.flags = dat->flags;      fnd->attrib.flags = dat->flags;
224      fnd->attrib.len = dat->octets;      fnd->attrib.len = dat->octets;
225      fnd->attrib.d = (unsigned char*)malloc (dat->octets);      fnd->attrib.d = (unsigned char*)malloc (dat->octets);
226        if (!fnd->attrib.d)
227            BUG (0);
228      memcpy (fnd->attrib.d, dat->d, dat->octets);      memcpy (fnd->attrib.d, dat->d, dat->octets);
229      return 0;      return 0;
230  }  }
# Line 265  keycache_prepare2 (gpg_keycache_t ctx, c Line 276  keycache_prepare2 (gpg_keycache_t ctx, c
276      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
277    
278      pkt = (PACKET*)calloc (1, sizeof * pkt);      pkt = (PACKET*)calloc (1, sizeof * pkt);
279        if (!pkt)
280            BUG (0);
281      gpg_init_packet (pkt);      gpg_init_packet (pkt);
282      while (gpg_parse_packet (inp, pkt) != -1) {      while (gpg_parse_packet (inp, pkt) != -1) {
283          if (pkt->pkttype == PKT_PUBLIC_KEY) {          if (pkt->pkttype == PKT_PUBLIC_KEY) {
# Line 300  keycache_prepare2 (gpg_keycache_t ctx, c Line 313  keycache_prepare2 (gpg_keycache_t ctx, c
313              else if (nsym > 0) {              else if (nsym > 0) {
314                  c->sym_prefs = (unsigned char*)calloc (1, nsym+1);                  c->sym_prefs = (unsigned char*)calloc (1, nsym+1);
315                  if (!c->sym_prefs)                  if (!c->sym_prefs)
316                      return gpg_error (GPG_ERR_ENOMEM);                      BUG (0);
317                  memcpy (c->sym_prefs, sym_prefs, nsym);                  memcpy (c->sym_prefs, sym_prefs, nsym);
318              }              }
319          }          }
# Line 342  gpg_keycache_new (gpg_keycache_t *r_ctx) Line 355  gpg_keycache_new (gpg_keycache_t *r_ctx)
355          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
356      ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);      ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);
357      if (!ctx)      if (!ctx)
358          return gpg_error (GPG_ERR_ENOMEM);          BUG (0);
359      ctx->secret = 0;      ctx->secret = 0;
360      ctx->pos = 0;      ctx->pos = 0;
361      *r_ctx = ctx;      *r_ctx = ctx;
# Line 363  gpg_keycache_release (gpg_keycache_t ctx Line 376  gpg_keycache_release (gpg_keycache_t ctx
376          c2 = c->next;          c2 = c->next;
377          gpgme_key_release (c->key);          gpgme_key_release (c->key);
378          c->key = NULL;          c->key = NULL;
379            safe_free (c->pref_keyserver);
380          safe_free (c->sym_prefs);          safe_free (c->sym_prefs);
381          safe_free (c->attrib.d);          safe_free (c->attrib.d);
382          safe_free (c->card_type);          safe_free (c->card_type);
# Line 402  gpg_keycache_add_key (gpg_keycache_t ctx Line 416  gpg_keycache_add_key (gpg_keycache_t ctx
416            
417      c = (struct keycache_s*)calloc (1, sizeof *c);      c = (struct keycache_s*)calloc (1, sizeof *c);
418      if (!c)      if (!c)
419          return gpg_error (GPG_ERR_ENOMEM);          BUG (0);
420      c->gloflags.is_protected = 1; /*default: assume protection. */      c->gloflags.is_protected = 1; /*default: assume protection. */
421      c->key = key;      c->key = key;
422      if (!ctx->item)      if (!ctx->item)
# Line 503  keycache_reload_photo (gpg_keycache_t ct Line 517  keycache_reload_photo (gpg_keycache_t ct
517    
518  /* Return the next key which was updated. Before it is  /* Return the next key which was updated. Before it is
519     returned the update flag is cleared.     returned the update flag is cleared.
520       @r_status is 1 for a new key and 2 for an updated key.
521     Return value: 0 on success. */     Return value: 0 on success. */
522  gpgme_error_t  gpgme_error_t
523  gpg_keycache_next_updated_key (gpg_keycache_t ctx,  gpg_keycache_next_updated_key (gpg_keycache_t ctx,
524                                 struct keycache_s **r_obj)                                 struct keycache_s **r_obj,
525                                   int *r_status)
526  {  {
527      struct keycache_s *c;      struct keycache_s *c;
528    
529      for (c = ctx->item; c; c = c->next) {      for (c = ctx->item; c; c = c->next) {
530          if (c->flags == 1) {          if (c->flags != 0) {
531              c->flags = 0;              *r_status = c->flags;
532              *r_obj = c;              *r_obj = c;
533                c->flags = 0;
534              return 0;              return 0;
535          }          }
536      }      }
# Line 535  gpg_keycache_update_key (gpg_keycache_t Line 552  gpg_keycache_update_key (gpg_keycache_t
552      err = gpgme_new (&gctx);      err = gpgme_new (&gctx);
553      if (err)      if (err)
554          return err;          return err;
555        gpgme_set_keylist_mode  (gctx, GPGME_KEYLIST_MODE_SIGS);
556      err = gpgme_get_key (gctx, keyid, &key, is_sec);      err = gpgme_get_key (gctx, keyid, &key, is_sec);
557      gpgme_release (gctx);      gpgme_release (gctx);
558      if (err)      if (err)
# Line 544  gpg_keycache_update_key (gpg_keycache_t Line 562  gpg_keycache_update_key (gpg_keycache_t
562          log_debug ("keycache update: keyid=%s %p\r\n", keyid, pub);          log_debug ("keycache update: keyid=%s %p\r\n", keyid, pub);
563          gpgme_key_release (fndkey);          gpgme_key_release (fndkey);
564          c->key = key;          c->key = key;
565          c->flags = 1;          c->flags = KC_FLAG_UPD;
566          if (is_sec && pub != NULL &&          if (is_sec && pub != NULL &&
567              !gpg_keycache_find_key (pub, keyid, 0, &fndkey)) {              !gpg_keycache_find_key (pub, keyid, 0, &fndkey)) {
568              log_debug ("keycache update: set public part %p\r\n", fndkey);              log_debug ("keycache update: set public part %p\r\n", fndkey);
# Line 568  gpg_keycache_update_key (gpg_keycache_t Line 586  gpg_keycache_update_key (gpg_keycache_t
586              }              }
587          }          }
588          if (c)          if (c)
589              c->flags = 1;              c->flags = KC_FLAG_ADD;
590      }      }
591      return 0;      return 0;
592  }  }
# Line 592  gpg_keycache_delete_key (gpg_keycache_t Line 610  gpg_keycache_delete_key (gpg_keycache_t
610      c = ctx->item;      c = ctx->item;
611      if (c->next == NULL) {      if (c->next == NULL) {
612          gpgme_key_release (itm->key);          gpgme_key_release (itm->key);
613          if (itm)          safe_free (itm);
             free (itm);  
614          ctx->item = NULL;          ctx->item = NULL;
615      }      }
616      else {      else {
617          while (c && c->next != itm)          for (; c != NULL; c = c->next) {
618              c = c->next;              if (c->next == itm)
619                    break;
620            }
621            assert (c != NULL); /* XXX: sometimes access violation. */
622          c->next = c->next->next;          c->next = c->next->next;
623          gpgme_key_release (itm->key);          gpgme_key_release (itm->key);
624          if (itm)          safe_free (itm);
             free (itm);  
625      }      }
626      return 0;      return 0;
627  }  }
# Line 676  copy_uid_prefs (const unsigned char *pre Line 695  copy_uid_prefs (const unsigned char *pre
695          pos++;          pos++;
696      p = (unsigned char*)calloc (1, pos+1);      p = (unsigned char*)calloc (1, pos+1);
697      if (!p)      if (!p)
698          abort ();          BUG (0);
699      memcpy (p, prefs, pos);      memcpy (p, prefs, pos);
700      return p;      return p;
701  }  }
# Line 697  gpg_keycache_sync (gpg_keycache_t pub, g Line 716  gpg_keycache_sync (gpg_keycache_t pub, g
716              c_sec->gloflags.divert_to_card = c->gloflags.divert_to_card;              c_sec->gloflags.divert_to_card = c->gloflags.divert_to_card;
717              if (!c->gloflags.divert_to_card)              if (!c->gloflags.divert_to_card)
718                  c->gloflags.divert_to_card = key_divert_to_card (key);                  c->gloflags.divert_to_card = key_divert_to_card (key);
719              c->sym_prefs = copy_uid_prefs (c_sec->sym_prefs);              if (c_sec->sym_prefs)
720                    c->sym_prefs = copy_uid_prefs (c_sec->sym_prefs);
721              c->pubpart = c_sec;              c->pubpart = c_sec;
722              c->pubpart->key = key;              c->pubpart->key = key;
723          }          }
# Line 746  keycache_next_key (gpg_keycache_t ctx, i Line 766  keycache_next_key (gpg_keycache_t ctx, i
766          *r_key = NULL;          *r_key = NULL;
767          return gpg_error (GPG_ERR_EOF);          return gpg_error (GPG_ERR_EOF);
768      }      }
769            if (ctx->tmp->flags != 0)
770            ctx->tmp->flags = 0; /* reset the 'updated' status. */
771        /* it might be possible there is no public key. */
772        if (flags && ctx->tmp->pubpart == NULL)
773            flags = 0;
774      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;      *r_key = flags? ctx->tmp->pubpart->key : ctx->tmp->key;
775      *c = ctx->tmp = ctx->tmp->next;      *c = ctx->tmp = ctx->tmp->next;
776      ctx->pos++;      ctx->pos++;
# Line 767  gpg_keycache_next_key (gpg_keycache_t ct Line 791  gpg_keycache_next_key (gpg_keycache_t ct
791      err = keycache_next_key (ctx, flags, &c, r_key);      err = keycache_next_key (ctx, flags, &c, r_key);
792      return err;      return err;
793  }  }
794    
795    
796    /* Search for a key with the pattern @pattern and mark
797       this key as the default signing key if found.
798       Return value: 0 on success. */
799    gpgme_error_t
800    gpg_keycache_set_default_key (gpg_keycache_t ctx,
801                                  const char *pattern)
802    {
803        gpgme_error_t err;
804        gpgme_key_t key;
805        struct keycache_s *itm;
806    
807        err = gpg_keycache_find_key2 (ctx, pattern, 0, &key, &itm);
808        if (err)
809            return err;
810    
811        if (itm)
812            itm->default_key = 1;
813        return 0;
814    }
815    
816    /* Return the default key from the cache. If no was
817       marked before, NULL is returned in @r_key.
818       Return value: 0 on success. */
819    gpgme_error_t
820    gpg_keycache_get_default_key (gpg_keycache_t ctx,
821                                  gpgme_key_t *r_key)
822    {
823        struct keycache_s *itm;
824    
825        *r_key = NULL;
826        for (itm = ctx->item; itm; itm = itm->next) {
827            if (itm->default_key) {
828                *r_key = itm->key;
829                break;
830            }
831        }
832        if (!*r_key)
833            return gpgme_error (GPG_ERR_NOT_FOUND);
834        return 0;
835    }
836    
837    
838    static gpgme_error_t
839    decode_subpacket (const char *subpkt_data, int *type,
840                      char **out, WORD *outlen)
841    {
842        char tmp[128], *p = tmp, *val;
843        char *enc = NULL;
844        size_t pos = 0, i=0;
845    
846        /* example: spk:24:1:21:http%3A//subkeys.pgp.de */
847        *outlen = 0;
848        *out = NULL;
849        
850        if (strncmp (subpkt_data, "spk:", 4))
851            return gpg_error (GPG_ERR_NO_DATA);
852    
853        strncpy (tmp, subpkt_data, 62);
854        val = strtok (tmp, ":");
855        while (val != NULL) {
856            switch (pos++) {
857            case 0:
858                break;
859    
860            case 1:
861                if (type)
862                    *type = atoi (val);
863                break;
864    
865            case 2:
866                break;
867    
868            case 3:
869                *outlen = atoi (val);
870                break;
871    
872            case 4:
873                enc = strdup (val);
874                break;
875            }
876            val = strtok (NULL, ":");
877        }
878        if (!enc)
879            return gpg_error (GPG_ERR_NO_DATA);;
880        *out = (char*)calloc (1, strlen (enc)+1);
881        for (pos = 0; pos < strlen (enc); pos++) {
882            if (enc[pos] == '%' && enc[pos+1] == '%')
883                (*out)[i++] = '%';
884            else if (enc[pos] == '%') {
885                char tmp[3];
886                tmp[0] = enc[++pos];
887                tmp[1] = enc[++pos];
888                tmp[2] = 0;
889                (*out)[i++] = (char)strtoul (tmp, NULL, 16);
890            }
891            else
892                (*out)[i++] = enc[pos];
893        }
894        (*out)[i] = 0;
895        free (enc);
896        return 0;
897    }
898    
899    
900    /* If the attribute given in @attr is not set in the
901       key cache object, try to update it. */
902    gpgme_error_t
903    gpg_keycache_update_attr (struct keycache_s *item,
904                              int attr, int force)
905    {
906        gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
907        char *val = NULL;
908        WORD n = 0;    
909    
910        switch (attr) {
911        case KC_ATTR_PREFSYM:
912            if (!force && item->sym_prefs)
913                break;
914            safe_free (item->sym_prefs);
915            err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
916            if (!err && val != NULL)
917                err = decode_subpacket (val, NULL, (char**)&item->sym_prefs, &n);
918            break;
919    
920        case KC_ATTR_PREFKSERV:
921            if (!force && item->pref_keyserver)
922                break;
923            safe_free (item->pref_keyserver);
924            err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
925            if (!err && val != NULL)
926                err = decode_subpacket (val, NULL, &item->pref_keyserver, &n);
927            break;
928        }
929        safe_free (val);
930        return err;
931    }
932    

Legend:
Removed from v.147  
changed lines
  Added in v.187

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26