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

Contents of /trunk/MyGPGME/keycache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File MIME type: text/plain
File size: 8746 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26