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

Annotation of /trunk/MyGPGME/keycache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Wed Jul 27 11:17:44 2005 UTC (19 years, 7 months ago) by twoaday
File MIME type: text/plain
File size: 8040 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.c (_gpgme_add_comment): Forgot to alloc an extra
        byte for the '0'. This fixes a lot of crashes related to
        file operations.
        * keylist.c (gpgme_op_keylist_getkey): Use the param for
        'pub' or 'sec' mode.
        * keycache.c (gpgme_keycache_update_key): If the key is
        not in the cache, add it and if the cache contain secret
        key, sync it with the pub cache.
        * editkey.c (edit_key_colon_handler): Allocate 1 byte for
        the NUL-char.  This also fixes a lot of reported crashes
        related to the showpref feature.
 


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 twoaday 21 gpgme_error_t
79     gpgme_keycache_add_key (gpgme_keycache_t ctx, gpgme_key_t key, void **opaque)
80 twoaday 2 {
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 twoaday 21 if (opaque)
98     *opaque = c;
99 twoaday 2 return 0;
100     } /* gpgme_keycache_add_key */
101    
102    
103     #define is_deleted_item(c) (((c)->flags & 0x01))
104     #define has_keyid_len(pattern) (\
105     strlen (pattern) == 8 || strlen (pattern) == 10 || \
106     strlen (pattern) == 16 || strlen (pattern) == 18)
107    
108    
109     static gpgme_error_t
110     keycache_find_key (gpgme_keycache_t ctx, const char * pattern, int flags,
111     gpgme_key_t * r_key, struct keycache_s ** r_item)
112     {
113     struct keycache_s * c;
114     struct subkey_s * s;
115     struct user_id_s * u;
116     const char *kid;
117    
118     if (!ctx || !r_key)
119     return mk_error (Invalid_Value);
120    
121     if (strstr (pattern, "0x"))
122     pattern += 2;
123 twoaday 17 /* XXX: this code is very slow, revamp it and use hash tables whenever
124     it is possible. */
125 twoaday 2 for (c = ctx->item; c; c = c->next) {
126     if (is_deleted_item (c))
127     continue;
128     for (s = &c->key->keys; s; s = s->next) {
129     for (u = c->key->uids; u; u = u->next) {
130     if (u->name && memistr (u->name, strlen (u->name), pattern)) {
131     if (r_item)
132     *r_item = c;
133     *r_key = flags? c->pubpart : c->key;
134     return 0;
135     }
136     }
137     if (has_keyid_len (pattern))
138     kid = s->keyid;
139     else
140     kid = s->fingerprint;
141    
142     if (kid && memistr (kid, strlen (kid), pattern)) {
143     if (r_item)
144     *r_item = c;
145     *r_key = flags? c->pubpart : c->key;
146     return 0;
147     }
148     }
149     }
150     *r_key = NULL;
151     return mk_error (General_Error);
152     } /* keycache_find_key */
153    
154    
155     gpgme_error_t
156     gpgme_keycache_find_key (gpgme_keycache_t ctx, const char * pattern,
157     int flags, gpgme_key_t * r_key)
158     {
159     return keycache_find_key (ctx, pattern, flags, r_key, NULL);
160     } /* gpgme_keycache_find_key */
161    
162    
163     gpgme_error_t
164 twoaday 21 gpgme_keycache_update_key (gpgme_keycache_t ctx, int is_sec, void *opaque,
165     const char *keyid)
166 twoaday 17 {
167     struct keycache_s *c = NULL;
168     gpgme_key_t key=NULL, fndkey=NULL;
169     gpgme_error_t err;
170    
171 twoaday 21 err = gpgme_op_keylist_getkey (is_sec, keyid, &key);
172 twoaday 17 if (err)
173     return err;
174     err = keycache_find_key (ctx, keyid, 0, &fndkey, &c);
175 twoaday 21 if (!err && c != NULL) {
176 twoaday 17 gpgme_key_release (c->key);
177     c->key = key;
178     c->flags = 0;
179     }
180 twoaday 21 else {
181     gpgme_keycache_t pub = (gpgme_keycache_t)opaque;
182     if (is_sec && !keycache_find_key (pub, keyid, 0, &fndkey, &c)) {
183     fndkey->gloflags.is_protected = c->key->gloflags.is_protected;
184     fndkey->gloflags.divert_to_card = c->key->gloflags.divert_to_card;
185     }
186     gpgme_keycache_add_key (ctx, key, &c);
187     DEBUG3 ("keycache update: is_sec=%d keyid=%s %p\r\n", is_sec, keyid, c);
188     if (is_sec)
189     c->pubpart = fndkey;
190     }
191 twoaday 17 return 0;
192     }
193    
194     gpgme_error_t
195 twoaday 2 gpgme_keycache_delete_key (gpgme_keycache_t ctx, const char * pattern)
196     {
197 twoaday 17 struct keycache_s *c = NULL;
198 twoaday 2 gpgme_key_t key;
199     gpgme_error_t rc;
200    
201     if (!ctx)
202     return mk_error (Invalid_Value);
203     rc = keycache_find_key (ctx, pattern, 0, &key, &c);
204     if (!rc)
205     c->flags |= 1;
206     return rc;
207     } /* gpgme_keycache_delete_key */
208    
209    
210     gpgme_error_t
211 twoaday 17 gpgme_keycache_init (gpgme_keycache_t ctx, const char *pattern, int secret)
212 twoaday 2 {
213     gpgme_error_t err;
214     gpgme_ctx_t c;
215     gpgme_key_t key;
216    
217     if (!ctx)
218     return mk_error( Invalid_Value );
219    
220     err = gpgme_new (&c);
221     if (err)
222     return err;
223     if (ctx->cb)
224     {
225     gpgme_control (c, GPGME_CTRL_CB_VAL, ctx->cb_value2);
226     gpgme_set_progress_cb (c, ctx->cb, ctx->cb_value);
227     }
228     gpgme_control (c, GPGME_CTRL_LOGGING, 1);
229     err = gpgme_op_keylist_start( c, pattern, secret );
230     while(!err)
231     {
232     err = gpgme_op_keylist_next (c, &key);
233     if (!err)
234 twoaday 21 err = gpgme_keycache_add_key (ctx, key, NULL);
235 twoaday 2 }
236     if (err == GPGME_EOF)
237     err = 0;
238     if (gpgme_get_process_rc (c))
239     err = gpgme_check_logging (c);
240     gpgme_release (c);
241     return err;
242     } /* gpgme_keycache_init */
243    
244    
245     gpgme_error_t
246     gpgme_keycache_sync (gpgme_keycache_t pub, gpgme_keycache_t sec)
247     {
248     struct keycache_s * c;
249     const char * s;
250     gpgme_key_t key;
251    
252     if (!pub || !sec)
253     return mk_error (Invalid_Value);
254     /* The GPG secret key listing does not contain much information
255     so we add some information to the public key cache. */
256     for (c=sec->item; c; c=c->next) {
257     s = gpgme_key_get_string_attr (c->key, GPGME_ATTR_KEYID, NULL, 0);
258     if (!gpgme_keycache_find_key (pub, s, 0, &key)) {
259     key->gloflags.is_protected = c->key->gloflags.is_protected;
260     key->gloflags.divert_to_card = c->key->gloflags.divert_to_card;
261     c->pubpart = key;
262     }
263     }
264     return 0;
265     }
266    
267    
268     void
269     gpgme_keycache_rewind (gpgme_keycache_t ctx)
270     {
271     if (ctx)
272     ctx->pos = 0;
273     } /* gpgme_keycache_rewind */
274    
275    
276     int
277     gpgme_keycache_count (gpgme_keycache_t ctx)
278     {
279 twoaday 17 struct keycache_s *c;
280 twoaday 2 int count = 0;
281    
282     if (!ctx)
283     return 0;
284     for (c = ctx->item; c; c = c->next) {
285     if (is_deleted_item (c))
286     continue;
287     count++;
288     }
289     return count;
290     } /* gpgme_keycache_count */
291    
292    
293     gpgme_error_t
294     gpgme_keycache_next_key (gpgme_keycache_t ctx, int flags, gpgme_key_t * r_key)
295     {
296     if (!ctx || !r_key)
297     return mk_error (Invalid_Value);
298    
299     if (!ctx->pos)
300     ctx->tmp = ctx->item;
301    
302     if (!ctx->tmp || !ctx->tmp->key) {
303     ctx->pos = 0;
304     *r_key = NULL;
305     return mk_error (Invalid_Value);
306     }
307    
308 twoaday 5 *r_key = flags? ctx->tmp->pubpart : ctx->tmp->key;
309 twoaday 2
310     ctx->tmp = ctx->tmp->next;
311     ctx->pos++;
312    
313     return 0;
314     } /* gpgme_keycache_next_key */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26