/[winpt]/trunk/MyGPGME/keycache.c
ViewVC logotype

Annotation of /trunk/MyGPGME/keycache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (hide annotations)
Fri May 20 08:38:32 2005 UTC (19 years, 9 months ago) by twoaday
File MIME type: text/plain
File size: 7519 byte(s)
2005-05-20      Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.h: s/cliptype/pgptype. Suggested by Kurt Fitzner.
        s/CLIP/PGP. Likewise.
        * w32-io.c (_gpgme_io_select): Increment the right loop variable.
        Kudos to Kurt.
        * keylist.c (gpgme_op_keylist_getkey): New. Handy function to
        retrieve a single key.
        * verify.c (gpgme_get_sig_key): Use it here.
        * keycache.c (gpgme_keycache_update_key): Update a single key.
 


1 twoaday 2 /* keycache.c - Caching for the pub- and the secring
2     * Copyright (C) 2001-2004 Timo Schulz
3     *
4     * This file is part of MyGPGME.
5     *
6     * MyGPGME is free software; you can redistribute it and/or modify
7     * 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
9     * (at your option) any later version.
10     *
11     * MyGPGME is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #include <stdio.h>
22     #include <string.h>
23    
24     #include "context.h"
25     #include "ops.h"
26     #include "key.h"
27     #include "util.h"
28    
29    
30     gpgme_error_t
31     gpgme_keycache_new( gpgme_keycache_t *r_ctx )
32     {
33     gpgme_keycache_t ctx;
34    
35     if( !r_ctx )
36     return mk_error( Invalid_Value );
37     ctx = calloc( 1, sizeof *ctx );
38     if( !ctx )
39     return mk_error( Out_Of_Core );
40     ctx->secret = 0;
41     ctx->pos = 0;
42     *r_ctx = ctx;
43     return 0;
44     } /* gpgme_keycache_new */
45    
46    
47     void
48     gpgme_keycache_release (gpgme_keycache_t ctx)
49     {
50     struct keycache_s * c, * c2;
51    
52     if (!ctx)
53     return;
54    
55     for( c = ctx->item; c; c = c2 ) {
56     c2 = c->next;
57     gpgme_key_release( c->key );
58     c->key = NULL;
59     safe_free( c );
60     }
61     safe_free( ctx );
62     } /* gpgme_keycache_release */
63    
64    
65     void
66     gpgme_keycache_set_cb (gpgme_keycache_t ctx,
67     void (*cb)(void *, const char *, int, unsigned, unsigned),
68     void * cb_value1, int cb_value2)
69     {
70     if (!ctx)
71     return;
72     ctx->cb = cb;
73     ctx->cb_value = cb_value1;
74     ctx->cb_value2 = cb_value2;
75     }
76    
77    
78     int
79     gpgme_keycache_add_key( gpgme_keycache_t ctx, gpgme_key_t key )
80     {
81     struct keycache_s * c, * n1;
82    
83     if( !ctx )
84     return mk_error(Invalid_Value);
85    
86     c = calloc( 1, sizeof *c );
87     if( !c )
88     return mk_error( Out_Of_Core );
89     c->key = key;
90     if( !ctx->item )
91     ctx->item = c;
92     else {
93     for( n1 = ctx->item; n1 && n1->next; n1 = n1->next )
94     ;
95     n1->next = c;
96     }
97     return 0;
98     } /* gpgme_keycache_add_key */
99    
100    
101     #define is_deleted_item(c) (((c)->flags & 0x01))
102     #define has_keyid_len(pattern) (\
103     strlen (pattern) == 8 || strlen (pattern) == 10 || \
104     strlen (pattern) == 16 || strlen (pattern) == 18)
105    
106    
107     static gpgme_error_t
108     keycache_find_key (gpgme_keycache_t ctx, const char * pattern, int flags,
109     gpgme_key_t * r_key, struct keycache_s ** r_item)
110     {
111     struct keycache_s * c;
112     struct subkey_s * s;
113     struct user_id_s * u;
114     const char *kid;
115    
116     if (!ctx || !r_key)
117     return mk_error (Invalid_Value);
118    
119     if (strstr (pattern, "0x"))
120     pattern += 2;
121 twoaday 17 /* XXX: this code is very slow, revamp it and use hash tables whenever
122     it is possible. */
123 twoaday 2 for (c = ctx->item; c; c = c->next) {
124     if (is_deleted_item (c))
125     continue;
126     for (s = &c->key->keys; s; s = s->next) {
127     for (u = c->key->uids; u; u = u->next) {
128     if (u->name && memistr (u->name, strlen (u->name), pattern)) {
129     if (r_item)
130     *r_item = c;
131     *r_key = flags? c->pubpart : c->key;
132     return 0;
133     }
134     }
135     if (has_keyid_len (pattern))
136     kid = s->keyid;
137     else
138     kid = s->fingerprint;
139    
140     if (kid && memistr (kid, strlen (kid), pattern)) {
141     if (r_item)
142     *r_item = c;
143     *r_key = flags? c->pubpart : c->key;
144     return 0;
145     }
146     }
147     }
148     *r_key = NULL;
149     return mk_error (General_Error);
150     } /* keycache_find_key */
151    
152    
153     gpgme_error_t
154     gpgme_keycache_find_key (gpgme_keycache_t ctx, const char * pattern,
155     int flags, gpgme_key_t * r_key)
156     {
157     return keycache_find_key (ctx, pattern, flags, r_key, NULL);
158     } /* gpgme_keycache_find_key */
159    
160    
161     gpgme_error_t
162 twoaday 17 gpgme_keycache_update_key (gpgme_keycache_t ctx, const char *keyid)
163     {
164     struct keycache_s *c = NULL;
165     gpgme_key_t key=NULL, fndkey=NULL;
166     gpgme_error_t err;
167    
168     err = gpgme_op_keylist_getkey (0, keyid, &key);
169     if (err)
170     return err;
171     err = keycache_find_key (ctx, keyid, 0, &fndkey, &c);
172     if (err)
173     return err;
174     if (c != NULL) {
175     gpgme_key_release (c->key);
176     c->key = key;
177     c->flags = 0;
178     }
179     return 0;
180     }
181    
182     gpgme_error_t
183 twoaday 2 gpgme_keycache_delete_key (gpgme_keycache_t ctx, const char * pattern)
184     {
185 twoaday 17 struct keycache_s *c = NULL;
186 twoaday 2 gpgme_key_t key;
187     gpgme_error_t rc;
188    
189     if (!ctx)
190     return mk_error (Invalid_Value);
191     rc = keycache_find_key (ctx, pattern, 0, &key, &c);
192     if (!rc)
193     c->flags |= 1;
194     return rc;
195     } /* gpgme_keycache_delete_key */
196    
197    
198     gpgme_error_t
199 twoaday 17 gpgme_keycache_init (gpgme_keycache_t ctx, const char *pattern, int secret)
200 twoaday 2 {
201     gpgme_error_t err;
202     gpgme_ctx_t c;
203     gpgme_key_t key;
204    
205     if (!ctx)
206     return mk_error( Invalid_Value );
207    
208     err = gpgme_new (&c);
209     if (err)
210     return err;
211     if (ctx->cb)
212     {
213     gpgme_control (c, GPGME_CTRL_CB_VAL, ctx->cb_value2);
214     gpgme_set_progress_cb (c, ctx->cb, ctx->cb_value);
215     }
216     gpgme_control (c, GPGME_CTRL_LOGGING, 1);
217     err = gpgme_op_keylist_start( c, pattern, secret );
218     while(!err)
219     {
220     err = gpgme_op_keylist_next (c, &key);
221     if (!err)
222     err = gpgme_keycache_add_key (ctx, key);
223     }
224     if (err == GPGME_EOF)
225     err = 0;
226     if (gpgme_get_process_rc (c))
227     err = gpgme_check_logging (c);
228     gpgme_release (c);
229     return err;
230     } /* gpgme_keycache_init */
231    
232    
233     gpgme_error_t
234     gpgme_keycache_sync (gpgme_keycache_t pub, gpgme_keycache_t sec)
235     {
236     struct keycache_s * c;
237     const char * s;
238     gpgme_key_t key;
239    
240     if (!pub || !sec)
241     return mk_error (Invalid_Value);
242     /* The GPG secret key listing does not contain much information
243     so we add some information to the public key cache. */
244     for (c=sec->item; c; c=c->next) {
245     s = gpgme_key_get_string_attr (c->key, GPGME_ATTR_KEYID, NULL, 0);
246     if (!gpgme_keycache_find_key (pub, s, 0, &key)) {
247     key->gloflags.is_protected = c->key->gloflags.is_protected;
248     key->gloflags.divert_to_card = c->key->gloflags.divert_to_card;
249     c->pubpart = key;
250     }
251     }
252     return 0;
253     }
254    
255    
256     void
257     gpgme_keycache_rewind (gpgme_keycache_t ctx)
258     {
259     if (ctx)
260     ctx->pos = 0;
261     } /* gpgme_keycache_rewind */
262    
263    
264     int
265     gpgme_keycache_count (gpgme_keycache_t ctx)
266     {
267 twoaday 17 struct keycache_s *c;
268 twoaday 2 int count = 0;
269    
270     if (!ctx)
271     return 0;
272     for (c = ctx->item; c; c = c->next) {
273     if (is_deleted_item (c))
274     continue;
275     count++;
276     }
277     return count;
278     } /* gpgme_keycache_count */
279    
280    
281     gpgme_error_t
282     gpgme_keycache_next_key (gpgme_keycache_t ctx, int flags, gpgme_key_t * r_key)
283     {
284     if (!ctx || !r_key)
285     return mk_error (Invalid_Value);
286    
287     if (!ctx->pos)
288     ctx->tmp = ctx->item;
289    
290     if (!ctx->tmp || !ctx->tmp->key) {
291     ctx->pos = 0;
292     *r_key = NULL;
293     return mk_error (Invalid_Value);
294     }
295    
296 twoaday 5 *r_key = flags? ctx->tmp->pubpart : ctx->tmp->key;
297 twoaday 2
298     ctx->tmp = ctx->tmp->next;
299     ctx->pos++;
300    
301     return 0;
302     } /* gpgme_keycache_next_key */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26