Look for ~/.pwmd/pinentry.conf rather than ~/.pwmd/env. 'env' isn't
[pwmd.git] / src / cache.c
blobeced7c2862944696556e7f1ec585e97ecdbb3e11
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2007 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <glib.h>
21 #include <string.h>
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include "cache.h"
28 #include "mem.h"
30 static gboolean valid_key(const guchar *key, gsize len)
32 gint b;
34 for (b = 0; b < len; b++) {
35 if (key[b])
36 return TRUE;
39 return FALSE;
42 gboolean cache_get_mutex(const guchar *md5filename, pth_mutex_t **result)
44 void *p;
45 glong len;
46 file_cache_t f;
48 for (p = key_cache, len = 0; len <= cache_size;) {
49 memcpy(&f, p, sizeof(file_cache_t));
51 if (f.used == TRUE) {
52 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
53 *result = f.mutex;
54 memset(&f, 0, sizeof(file_cache_t));
55 return *result ? TRUE : FALSE;
59 p += sizeof(file_cache_t);
60 len += sizeof(file_cache_t);
62 if (len + sizeof(file_cache_t) > cache_size)
63 break;
66 memset(&f, 0, sizeof(file_cache_t));
67 return FALSE;
70 gint cache_file_count()
72 void *p;
73 gint n = 0;
74 glong len;
75 file_cache_t f;
77 for (p = key_cache, len = 0; len <= cache_size;) {
78 memcpy(&f, p, sizeof(file_cache_t));
80 if (f.used == TRUE && valid_key(f.key, sizeof(f.key)) == TRUE)
81 n++;
83 p += sizeof(file_cache_t);
84 len += sizeof(file_cache_t);
86 if (len + sizeof(file_cache_t) > cache_size)
87 break;
90 memset(&f, 0, sizeof(file_cache_t));
91 return n;
94 void cache_adjust_timer()
96 file_cache_t f;
97 void *p;
98 glong len;
100 for (p = key_cache, len = 0; len <= cache_size;) {
101 memcpy(&f, p, sizeof(file_cache_t));
103 if (f.used == TRUE && f.reset >= 0) {
104 if (f.timeout > 0)
105 f.timeout--;
107 if (f.timeout == 0) {
108 memset(&f.key, 0, sizeof(f.key));
109 f.timeout = -1;
110 send_cache_status_all();
113 memcpy(p, &f, sizeof(file_cache_t));
116 p += sizeof(file_cache_t);
117 len += sizeof(file_cache_t);
119 if (len + sizeof(file_cache_t) > cache_size)
120 break;
123 memset(&f, 0, sizeof(file_cache_t));
126 gboolean cache_add_file(const guchar *md5file, const guchar *shakey)
128 void *p;
129 file_cache_t f;
130 gint nfiles = cache_file_count();
131 glong len;
134 * Make sure there is enough secure memory.
136 if (!md5file || (nfiles + 1) * sizeof(file_cache_t) > cache_size)
137 return FALSE;
140 * Find the first available "slot".
142 for (p = key_cache, len = 0; len <= cache_size;) {
143 memcpy(&f, p, sizeof(file_cache_t));
145 if (f.used == FALSE) {
146 memset(&f, 0, sizeof(file_cache_t));
147 f.mutex = xmalloc(sizeof(pth_mutex_t));
149 if (!f.mutex)
150 return FALSE;
152 pth_mutex_init(f.mutex);
153 memcpy(&f.filename, md5file, sizeof(f.filename));
155 if (shakey)
156 memcpy(&f.key, shakey, sizeof(f.key));
158 f.used = TRUE;
159 f.reset = f.timeout = -2;
160 memcpy(p, &f, sizeof(file_cache_t));
161 memset(&f, 0, sizeof(file_cache_t));
162 return TRUE;
165 p += sizeof(file_cache_t);
166 len += sizeof(file_cache_t);
168 if (len + sizeof(file_cache_t) > cache_size)
169 break;
172 memset(&f, 0, sizeof(file_cache_t));
173 return FALSE;
176 static void reset_entry(file_cache_t *f)
178 pth_mutex_t *m = f->mutex;
180 if (!f->refcount && m) {
181 xfree(m);
182 memset(f, 0, sizeof(file_cache_t));
184 else
185 memset(f->key, 0, sizeof(f->key));
188 gboolean cache_clear(const guchar *md5filename, gint which)
190 void *p;
191 file_cache_t f;
192 glong len;
194 for (p = key_cache, len = 0; len <= cache_size;) {
195 memcpy(&f, p, sizeof(file_cache_t));
197 if (which == 2) {
198 reset_entry(&f);
199 memcpy(p, &f, sizeof(file_cache_t));
200 memset(&f, 0, sizeof(file_cache_t));
202 else if (f.used == TRUE && which == 1) {
203 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
204 reset_entry(&f);
205 memcpy(p, &f, sizeof(file_cache_t));
206 memset(&f, 0, sizeof(file_cache_t));
207 send_cache_status_all();
208 return TRUE;
212 p += sizeof(file_cache_t);
213 len += sizeof(file_cache_t);
215 if (len + sizeof(file_cache_t) > cache_size)
216 break;
219 memset(&f, 0, sizeof(file_cache_t));
221 if (which == 2) {
222 send_cache_status_all();
223 return TRUE;
226 return FALSE;
229 gboolean cache_iscached(const guchar *md5filename)
231 void *p;
232 file_cache_t f;
233 glong len;
234 gboolean ret = FALSE;
236 for (p = key_cache, len = 0; len <= cache_size;) {
237 memcpy(&f, p, sizeof(file_cache_t));
239 if (f.used == TRUE) {
240 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
241 ret = valid_key(f.key, sizeof(f.key));
242 memset(&f, 0, sizeof(file_cache_t));
243 return ret;
247 p += sizeof(file_cache_t);
248 len += sizeof(file_cache_t);
250 if (len + sizeof(file_cache_t) > cache_size)
251 break;
254 memset(&f, 0, sizeof(file_cache_t));
255 return FALSE;
258 gboolean cache_reset_timeout(const guchar *md5filename, glong timeout)
260 void *p;
261 file_cache_t f;
262 glong len;
263 glong t = -2;
265 if (!md5filename)
266 return FALSE;
268 for (p = key_cache, len = 0; len <= cache_size;) {
269 memcpy(&f, p, sizeof(file_cache_t));
271 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
272 t = f.reset;
273 break;
276 p += sizeof(file_cache_t);
277 len += sizeof(file_cache_t);
279 if (len + sizeof(file_cache_t) > cache_size)
280 break;
283 memset(&f, 0, sizeof(file_cache_t));
285 if (t == -2)
286 return cache_set_timeout(md5filename, timeout);
288 return cache_set_timeout(md5filename, t);
291 gboolean cache_set_timeout(const guchar *md5filename, glong timeout)
293 void *p;
294 file_cache_t f;
295 glong len;
297 for (p = key_cache, len = 0; len <= cache_size;) {
298 memcpy(&f, p, sizeof(file_cache_t));
300 if (md5filename) {
301 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
302 f.reset = f.timeout = timeout;
303 memcpy(p, &f, sizeof(file_cache_t));
304 memset(&f, 0, sizeof(file_cache_t));
305 return TRUE;
309 p += sizeof(file_cache_t);
310 len += sizeof(file_cache_t);
312 if (len + sizeof(file_cache_t) > cache_size)
313 break;
316 memset(&f, 0, sizeof(file_cache_t));
317 return (md5filename) ? FALSE : TRUE;
320 gboolean cache_update_key(const guchar *md5filename, const guchar *shakey)
322 void *p;
323 file_cache_t f;
324 glong len;
326 for (p = key_cache, len = 0; len <= cache_size;) {
327 memcpy(&f, p, sizeof(file_cache_t));
329 if (f.used == TRUE) {
330 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
331 memcpy(&f.key, shakey, sizeof(f.key));
332 memcpy(p, &f, sizeof(file_cache_t));
333 memset(&f, 0, sizeof(file_cache_t));
334 return TRUE;
338 p += sizeof(file_cache_t);
339 len += sizeof(file_cache_t);
341 if (len + sizeof(file_cache_t) > cache_size)
342 break;
345 memset(&f, 0, sizeof(file_cache_t));
346 return cache_add_file(md5filename, shakey);
349 gboolean cache_get_key(const guchar *md5file, guchar *shakey)
351 void *p;
352 file_cache_t f;
353 glong len;
355 for (p = key_cache, len = 0; len <= cache_size;) {
356 memcpy(&f, p, sizeof(file_cache_t));
359 * The slot may be used but not yet contain a key.
361 if (f.used == TRUE) {
362 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
363 if (valid_key(f.key, sizeof(f.key)) == FALSE)
364 goto fail;
366 memcpy(shakey, &f.key, sizeof(f.key));
367 memset(&f, 0, sizeof(file_cache_t));
368 return TRUE;
372 p += sizeof(file_cache_t);
373 len += sizeof(file_cache_t);
375 if (len + sizeof(file_cache_t) > cache_size)
376 break;
379 fail:
380 memset(&f, 0, sizeof(file_cache_t));
381 return FALSE;
384 gboolean cache_has_file(const guchar *md5file)
386 void *p;
387 file_cache_t f;
388 glong len;
390 for (p = key_cache, len = 0; len <= cache_size;) {
391 memcpy(&f, p, sizeof(file_cache_t));
393 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
394 memset(&f, 0, sizeof(file_cache_t));
395 return TRUE;
398 p += sizeof(file_cache_t);
399 len += sizeof(file_cache_t);
401 if (len + sizeof(file_cache_t) > cache_size)
402 break;
405 memset(&f, 0, sizeof(file_cache_t));
406 return FALSE;
409 gboolean cache_decr_refcount(const guchar *md5file)
411 void *p;
412 file_cache_t f;
413 glong len;
415 for (p = key_cache, len = 0; len <= cache_size;) {
416 memcpy(&f, p, sizeof(file_cache_t));
418 if (f.used == TRUE) {
419 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
420 f.refcount--;
422 if (f.refcount < 0)
423 f.refcount = 0;
425 memcpy(p, &f, sizeof(file_cache_t));
426 memset(&f, 0, sizeof(file_cache_t));
427 return TRUE;
431 p += sizeof(file_cache_t);
432 len += sizeof(file_cache_t);
434 if (len + sizeof(file_cache_t) > cache_size)
435 break;
438 memset(&f, 0, sizeof(file_cache_t));
439 return FALSE;
442 gboolean cache_incr_refcount(const guchar *md5file)
444 void *p;
445 file_cache_t f;
446 glong len;
448 for (p = key_cache, len = 0; len <= cache_size;) {
449 memcpy(&f, p, sizeof(file_cache_t));
451 if (f.used == TRUE) {
452 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
453 f.refcount++;
454 memcpy(p, &f, sizeof(file_cache_t));
455 memset(&f, 0, sizeof(file_cache_t));
456 return TRUE;
460 p += sizeof(file_cache_t);
461 len += sizeof(file_cache_t);
463 if (len + sizeof(file_cache_t) > cache_size)
464 break;
467 memset(&f, 0, sizeof(file_cache_t));
468 return FALSE;