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

Contents of /trunk/MyGPGME/keycache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show 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 /* 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 gpgme_error_t
79 gpgme_keycache_add_key (gpgme_keycache_t ctx, gpgme_key_t key, void **opaque)
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 if (opaque)
98 *opaque = c;
99 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 /* XXX: this code is very slow, revamp it and use hash tables whenever
124 it is possible. */
125 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 gpgme_keycache_update_key (gpgme_keycache_t ctx, int is_sec, void *opaque,
165 const char *keyid)
166 {
167 struct keycache_s *c = NULL;
168 gpgme_key_t key=NULL, fndkey=NULL;
169 gpgme_error_t err;
170
171 err = gpgme_op_keylist_getkey (is_sec, keyid, &key);
172 if (err)
173 return err;
174 err = keycache_find_key (ctx, keyid, 0, &fndkey, &c);
175 if (!err && c != NULL) {
176 gpgme_key_release (c->key);
177 c->key = key;
178 c->flags = 0;
179 }
180 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 return 0;
192 }
193
194 gpgme_error_t
195 gpgme_keycache_delete_key (gpgme_keycache_t ctx, const char * pattern)
196 {
197 struct keycache_s *c = NULL;
198 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 gpgme_keycache_init (gpgme_keycache_t ctx, const char *pattern, int secret)
212 {
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 err = gpgme_keycache_add_key (ctx, key, NULL);
235 }
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 struct keycache_s *c;
280 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 *r_key = flags? ctx->tmp->pubpart : ctx->tmp->key;
309
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