Add --userid, --algo, --expire and --no-passphrase.
[pwmd.git] / src / cache.c
blobacfb8d0eb5753374c58bd2671c012054b8940157
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
3 2016
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of pwmd.
8 Pwmd is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 Pwmd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <pthread.h>
28 #include <ctype.h>
29 #include <errno.h>
31 #include "pwmd-error.h"
32 #include <gcrypt.h>
33 #include "mutex.h"
34 #include "cache.h"
35 #include "status.h"
36 #include "mem.h"
37 #include "util-misc.h"
38 #include "util-string.h"
39 #include "agent.h"
40 #include "acl.h"
42 #ifdef HAVE_TIME_H
43 #include <time.h>
44 #endif
46 static pthread_mutex_t cache_mutex;
47 static struct slist_s *key_cache;
48 static unsigned char *cache_iv;
49 static unsigned char *cache_key;
50 static size_t cache_blocksize;
51 static size_t cache_keysize;
52 static struct agent_s *cache_agent;
53 static int exiting;
55 extern void log_write (const char *fmt, ...);
57 static gpg_error_t clear_once (file_cache_t * p, int agent);
58 static int remove_entry (const char *);
59 static void free_entry (file_cache_t * p, int agent);
61 static file_cache_t *
62 get_entry (const char *filename)
64 int t = slist_length (key_cache);
65 int i;
67 if (!filename)
68 return NULL;
70 for (i = 0; i < t; i++)
72 file_cache_t *p = slist_nth_data (key_cache, i);
74 if (!strcmp (p->filename, filename))
75 return p;
78 return NULL;
81 gpg_error_t
82 cache_lock_mutex (void *ctx, const char *filename, long lock_timeout, int add,
83 int timeout)
85 MUTEX_LOCK (&cache_mutex);
86 gpg_error_t rc = 0;
87 file_cache_t *p = get_entry (filename);
89 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
91 if (p)
93 MUTEX_UNLOCK (&cache_mutex);
94 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
96 else if (add)
98 rc = cache_add_file (filename, NULL, timeout);
99 if (!rc)
101 p = get_entry (filename);
102 MUTEX_UNLOCK (&cache_mutex);
103 if (p)
104 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
106 else
108 MUTEX_UNLOCK (&cache_mutex);
111 else
113 MUTEX_UNLOCK (&cache_mutex);
116 pthread_cleanup_pop (0);
117 return !p && !rc ? GPG_ERR_NO_DATA : rc;
120 static int
121 remove_entry (const char *filename)
123 MUTEX_LOCK (&cache_mutex);
124 file_cache_t *p = get_entry (filename);
126 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
127 if (p)
129 /* Keep a refcount because another client maybe editing this same new
130 * file. The entry needs to be kept in case the other client SAVE's.
132 p->refcount--;
133 if (!p->refcount)
134 free_entry (p, 0);
137 pthread_cleanup_pop (1);
138 return p ? 1 : 0;
141 static gpg_error_t
142 free_cache_data (file_cache_t * cache)
144 gpg_error_t rc = GPG_ERR_NO_DATA;
145 int i, t;
146 struct client_thread_s *found = NULL;
147 int self = 0;
149 if (!cache->data)
150 return 0;
152 MUTEX_LOCK (&cache_mutex);
153 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
154 MUTEX_LOCK (&cn_mutex);
155 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
157 t = slist_length (cn_thread_list);
158 for (i = 0; i < t; i++)
160 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
162 if (!thd->cl)
163 continue;
165 self = pthread_equal (pthread_self (), thd->tid);
167 if (thd->cl->filename && !strcmp (thd->cl->filename, cache->filename))
169 if (self)
171 found = thd;
172 continue;
175 /* Continue trying to find a client who has the same file open and
176 * also has a lock. */
177 rc = cache_lock_mutex (thd->cl->ctx, thd->cl->filename, -1, 0, -1);
178 if (!rc)
180 found = thd;
181 break;
186 if (self && (!rc || rc == GPG_ERR_NO_DATA) && found)
187 rc = cache_lock_mutex (found->cl->ctx, found->cl->filename, -1, 0, -1);
189 if (exiting || !rc || rc == GPG_ERR_NO_DATA)
191 cache_free_data_once (cache->data);
192 cache->data = NULL;
193 cache->defer_clear = 0;
194 cache->timeout = -1;
196 if (found)
197 cache_unlock_mutex (found->cl->filename, 0);
199 rc = 0;
202 if (rc)
203 cache->defer_clear = 1;
205 pthread_cleanup_pop (1);
206 pthread_cleanup_pop (1);
207 return rc;
210 gpg_error_t
211 cache_unlock_mutex (const char *filename, int remove)
213 MUTEX_LOCK (&cache_mutex);
214 file_cache_t *p = get_entry (filename);
216 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
218 if (p)
220 MUTEX_UNLOCK (p->mutex);
221 if (remove)
222 remove_entry (filename);
225 pthread_cleanup_pop (1);
226 return p ? 0 : GPG_ERR_NO_DATA;
229 static gpg_error_t
230 test_agent_cache_once (file_cache_t *p, const char *grip)
232 gpg_error_t rc;
233 char *line;
235 (void)p;
236 rc = agent_command (cache_agent, &line, NULL, "KEYINFO --data %s", grip);
237 if (!rc)
239 char **fields = str_split (line, " ", 0);
241 /* Smartcard. */
242 if (*fields[1] == 'T')
243 rc = GPG_ERR_NO_DATA;
244 else
245 rc = isdigit (*fields[4]) || *fields[5] == 'C' ? 0 : GPG_ERR_NO_DATA;
247 strv_free (fields);
248 xfree (line);
251 return rc;
254 /* Test each keygrip in data->(sig)grip for gpg-agent cache status. The file is
255 * considered cached if at least one grip is cached in the agent or one siggrip
256 * is cached in the case of 'sign'.
258 static gpg_error_t
259 test_agent_cache (file_cache_t *data, int sign)
261 gpg_error_t rc = 0;
262 char **p;
264 if ((!data->grip && !sign) || (!data->siggrip && sign))
265 return GPG_ERR_NO_DATA;
267 for (p = data->grip; !sign && p && *p; p++)
269 rc = test_agent_cache_once (data, *p);
270 if (!rc || rc != GPG_ERR_NO_DATA)
271 break;
274 if (!rc && sign)
275 rc = test_agent_cache_once (data, data->siggrip);
277 return rc;
280 static gpg_error_t
281 extract_keygrip_once (struct crypto_s *crypto, char **keyids, int sign,
282 char ***dst)
284 gpgme_key_t *result;
285 gpgme_error_t rc;
286 int i;
287 char **grips = NULL;
289 rc = crypto_list_keys (crypto, keyids, sign, &result);
290 if (rc)
291 return rc;
293 for (i = 0; result[i]; i++)
295 gpgme_subkey_t s;
297 for (s = result[i]->subkeys; s; s = s->next)
299 char **k;
301 if (sign && !s->can_sign)
302 continue;
304 for (k = keyids; *k; k++)
306 if (!strcmp (*k, s->keyid) && s->keygrip)
308 char **tmp;
309 size_t len = strv_length (grips);
311 tmp = xrealloc (grips, len+2 * sizeof (char *));
312 if (!tmp)
314 rc = GPG_ERR_ENOMEM;
315 break;
318 grips = tmp;
319 grips[len] = str_dup (s->keygrip);
320 if (!grips[len])
322 rc = GPG_ERR_ENOMEM;
323 break;
326 grips[++len] = NULL;
332 if (!rc)
334 strv_free (*dst);
335 *dst = grips;
337 else
339 strv_free (grips);
340 grips = NULL;
343 crypto_free_key_list (result);
344 return rc ? rc : grips ? rc : GPG_ERR_NO_DATA;
347 static gpg_error_t
348 extract_keygrips (file_cache_t *data)
350 gpg_error_t rc = 0;
351 struct crypto_s *crypto;
352 char **grips = NULL, **siggrips = NULL;
354 if (!data || !data->data)
355 return 0;
357 rc = crypto_init (&crypto, NULL, NULL, 0, NULL);
358 if (rc)
359 return rc;
361 pthread_cleanup_push ((void *)crypto_free, crypto);
363 if (data->data->pubkey)
364 rc = extract_keygrip_once (crypto, data->data->pubkey, 0, &grips);
366 if (!rc && data->data->sigkey)
368 char **tmp = NULL;
370 strv_printf (&tmp, "%s", data->data->sigkey);
371 rc = extract_keygrip_once (crypto, tmp, 1, &siggrips);
372 strv_free (tmp);
375 if (!rc)
377 strv_free (data->grip);
378 data->grip = grips;
379 xfree (data->siggrip);
380 data->siggrip = NULL;
381 if (siggrips && *siggrips)
382 data->siggrip = str_dup (*siggrips);
383 strv_free (siggrips);
385 else
387 strv_free (grips);
388 strv_free (siggrips);
391 pthread_cleanup_pop (1);
392 return rc;
395 static gpg_error_t
396 iscached (const char *filename, int *defer, int agent, int sign)
398 file_cache_t *p = get_entry (filename);
399 gpg_error_t rc = 0;
401 if (!agent)
403 if (!p || !p->data)
404 return GPG_ERR_NO_DATA;
406 if (defer)
407 *defer = p->defer_clear;
409 return 0;
412 if (!p)
413 return GPG_ERR_NO_DATA;
415 if (defer)
416 *defer = p->defer_clear;
418 if (!rc && (p->grip || p->siggrip))
419 rc = test_agent_cache (p, sign);
420 else if (!rc)
421 rc = GPG_ERR_NO_DATA;
423 return rc;
426 unsigned
427 cache_file_count ()
429 MUTEX_LOCK (&cache_mutex);
430 unsigned total = 0, i, n;
432 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
433 n = slist_length (key_cache);
434 for (i = 0; i < n; i++)
436 file_cache_t *p = slist_nth_data (key_cache, i);
438 if (!iscached (p->filename, NULL, 0, 0))
439 total++;
442 pthread_cleanup_pop (1);
443 return total;
446 void
447 cache_adjust_timeout ()
449 MUTEX_LOCK (&cache_mutex);
450 int t = slist_length (key_cache);
451 int i;
453 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
455 for (i = 0; i < t; i++)
457 file_cache_t *p = slist_nth_data (key_cache, i);
459 if (p->timeout > 0)
460 p->timeout--;
462 if (!p->timeout || (p->defer_clear && p->timeout != -1))
464 /* The file associated with this cache entry may be locked by a
465 * client. Defer freeing this cache entry until the next timeout
466 * check. */
467 if (!clear_once (p, 1))
468 send_status_all (STATUS_CACHE, NULL);
472 pthread_cleanup_pop (1);
475 static gpg_error_t
476 set_timeout (const char *filename, int timeout, int defer, int force)
478 MUTEX_LOCK (&cache_mutex);
479 file_cache_t *p = get_entry (filename);
480 gpg_error_t rc = 0;
482 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
484 if (p)
486 p->reset = timeout;
487 if (!p->defer_clear && (p->timeout == -1 || force))
488 p->timeout = timeout;
490 if (!timeout || defer)
492 rc = clear_once (p, 1);
493 if (!rc)
494 send_status_all (STATUS_CACHE, NULL);
497 else
498 rc = GPG_ERR_NOT_FOUND;
500 pthread_cleanup_pop (1);
501 return rc;
504 gpg_error_t
505 cache_set_data (const char *filename, struct cache_data_s * data)
507 MUTEX_LOCK (&cache_mutex);
508 gpg_error_t rc = GPG_ERR_NO_DATA;
509 file_cache_t *p = get_entry (filename);
511 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
513 if (p)
515 p->data = data;
516 rc = set_timeout (filename, p->reset, p->defer_clear, 0);
517 if (!rc && !p->reset)
519 clear_once (p, 0);
520 send_status_all (STATUS_CACHE, NULL);
522 else if (!rc)
523 rc = extract_keygrips (p);
526 pthread_cleanup_pop (1);
527 return p && !rc ? 0 : rc;
530 struct cache_data_s *
531 cache_get_data (const char *filename)
533 MUTEX_LOCK (&cache_mutex);
534 file_cache_t *p = get_entry (filename);
536 MUTEX_UNLOCK (&cache_mutex);
537 return p ? p->data : NULL;
540 gpg_error_t
541 cache_add_file (const char *filename, struct cache_data_s *data, int timeout)
543 MUTEX_LOCK (&cache_mutex);
544 file_cache_t *p = get_entry (filename);
545 struct slist_s *new;
546 gpg_error_t rc = 0;
548 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
550 if (p)
552 p->data = data;
553 p->refcount++;
554 rc = set_timeout (filename, timeout, p->defer_clear, 0);
556 else
558 p = xcalloc (1, sizeof (file_cache_t));
559 if (p)
561 p->mutex = (pthread_mutex_t *) xmalloc (sizeof (pthread_mutex_t));
562 if (p->mutex)
564 pthread_mutexattr_t attr;
565 pthread_mutexattr_init (&attr);
566 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
567 pthread_mutex_init (p->mutex, &attr);
568 pthread_mutexattr_destroy (&attr);
569 p->filename = str_dup (filename);
570 p->data = data;
571 p->refcount++;
572 new = slist_append (key_cache, p);
573 if (new)
575 key_cache = new;
576 rc = cache_set_timeout(filename, timeout);
578 else
580 pthread_mutex_destroy (p->mutex);
581 xfree (p->mutex);
582 xfree (p->filename);
583 xfree (p);
584 p = NULL;
585 rc = GPG_ERR_ENOMEM;
588 else
590 xfree (p);
591 p = NULL;
592 rc = GPG_ERR_ENOMEM;
595 else
596 rc = GPG_ERR_ENOMEM;
599 if (!rc)
600 rc = extract_keygrips (p);
602 pthread_cleanup_pop (1);
604 if (!rc)
605 send_status_all (STATUS_CACHE, NULL);
607 return rc;
610 gpg_error_t
611 cache_clear_agent_keys (const char *filename, int decrypt, int sign)
613 MUTEX_LOCK (&cache_mutex);
614 gpg_error_t rc = 0;
615 char **key;
616 file_cache_t *p = get_entry (filename);
618 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
620 if (p)
622 for (key = p->grip; decrypt && key && *key; key++)
624 rc = agent_command (cache_agent, NULL, NULL,
625 "CLEAR_PASSPHRASE --mode=normal %s", *key);
626 if (rc)
627 break;
630 if (p->siggrip && sign)
632 rc = agent_command (cache_agent, NULL, NULL,
633 "CLEAR_PASSPHRASE --mode=normal %s", p->siggrip);
634 if (rc)
635 break;
638 else
639 rc = GPG_ERR_NOT_FOUND;
641 pthread_cleanup_pop (1);
642 return rc;
645 static gpg_error_t
646 clear_once (file_cache_t *p, int agent)
648 gpg_error_t rc = 0, trc;
650 if (agent)
651 rc = cache_clear_agent_keys (p->filename, 1, 1);
653 trc = free_cache_data (p);
654 return rc ? rc : trc;
657 static void
658 free_entry (file_cache_t *p, int agent)
660 gpg_error_t rc;
662 if (!p)
663 return;
665 rc = clear_once (p, agent);
666 if (rc)
667 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
669 if (p->mutex)
671 pthread_mutex_destroy (p->mutex);
672 xfree (p->mutex);
675 strv_free (p->grip);
676 xfree (p->siggrip);
677 xfree (p->filename);
678 key_cache = slist_remove (key_cache, p);
679 xfree (p);
682 gpg_error_t
683 cache_clear (struct client_s *client, const char *filename, int agent)
685 file_cache_t *p;
686 gpg_error_t rc = 0, all_rc = 0;
687 int i, t;
689 MUTEX_LOCK (&cache_mutex);
690 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
692 if (filename)
694 p = get_entry (filename);
695 if (p)
697 rc = clear_once (p, agent);
698 if (rc)
699 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
702 else
704 t = slist_length (key_cache);
705 for (i = 0; i < t; i++)
707 p = slist_nth_data (key_cache, i);
709 if (client)
711 assuan_peercred_t peer;
712 int n = client->no_access_param;
714 client->no_access_param = 1;
715 rc = do_validate_peer (client->ctx, p->filename, &peer);
716 client->no_access_param = n;
717 if (rc == GPG_ERR_FORBIDDEN)
718 rc = peer_is_invoker (client);
720 if (rc)
722 all_rc = !all_rc ? rc : all_rc;
723 continue;
727 clear_once (p, agent);
731 pthread_cleanup_pop (1);
732 return filename ? rc : all_rc;
735 gpg_error_t
736 cache_iscached (const char *filename, int *defer, int agent, int sign)
738 gpg_error_t rc;
740 if (!filename)
741 return GPG_ERR_INV_PARAMETER;
743 MUTEX_LOCK (&cache_mutex);
744 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
745 rc = iscached (filename, defer, agent, sign);
747 /* Test if the data file disappeared from the filesystem. */
748 if ((!rc || gpg_err_code (rc) == GPG_ERR_NO_DATA)
749 && access (filename, R_OK) == -1)
751 rc = gpg_error_from_errno (errno);
752 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
754 /* Fixes clearing the cache entry that was created during OPEN when
755 * SAVE'ing a new file. */
756 if ((defer && *defer == 1) || !defer)
758 rc = cache_defer_clear (filename);
759 if (!rc && defer)
760 *defer = 1;
763 rc = GPG_ERR_ENOENT;
767 pthread_cleanup_pop (1);
768 return rc;
771 gpg_error_t
772 cache_defer_clear (const char *filename)
774 MUTEX_LOCK (&cache_mutex);
775 file_cache_t *p = get_entry (filename);
776 gpg_error_t rc = 0;
778 if (!p)
779 rc = GPG_ERR_NOT_FOUND;
780 else
781 p->defer_clear = 1;
783 MUTEX_UNLOCK (&cache_mutex);
784 return rc;
787 gpg_error_t
788 cache_set_timeout (const char *filename, int timeout)
790 return set_timeout (filename, timeout, 0, 1);
793 void
794 cache_deinit ()
796 exiting = 1;
797 MUTEX_LOCK (&cache_mutex);
798 int i, t = slist_length (key_cache);
800 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
801 for (i = 0; i < t; i++)
803 file_cache_t *p = slist_nth_data (key_cache, i);
805 free_entry (p, 1);
806 t = slist_length (key_cache);
807 i = -1;
810 gcry_free (cache_key);
811 xfree (cache_iv);
812 cache_key = NULL;
813 cache_iv = NULL;
814 agent_free (cache_agent);
815 cache_agent = NULL;
816 pthread_cleanup_pop (1);
817 pthread_mutex_destroy (&cache_mutex);
820 void
821 cache_mutex_init ()
823 pthread_mutexattr_t attr;
825 pthread_mutexattr_init (&attr);
826 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
827 pthread_mutex_init (&cache_mutex, &attr);
828 pthread_mutexattr_destroy (&attr);
831 gpg_error_t
832 cache_init ()
834 gpg_error_t rc = 0;
836 rc = agent_init (&cache_agent);
837 if (rc)
839 cache_agent = NULL;
840 return rc;
843 if (!cache_key)
845 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_BLKLEN, NULL,
846 &cache_blocksize);
847 if (rc)
848 return rc;
850 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_KEYLEN, NULL,
851 &cache_keysize);
852 if (rc)
853 return rc;
855 cache_key = gcry_malloc (cache_keysize);
856 if (!cache_key)
857 return GPG_ERR_ENOMEM;
859 cache_iv = xmalloc (cache_blocksize);
860 if (!cache_iv)
862 gcry_free (cache_key);
863 cache_key = NULL;
864 return GPG_ERR_ENOMEM;
867 gcry_create_nonce (cache_key, cache_keysize);
868 gcry_create_nonce (cache_iv, cache_blocksize);
872 cache_mutex_init ();
873 return rc;
876 void
877 cache_lock ()
879 MUTEX_LOCK (&cache_mutex);
882 void
883 cache_unlock ()
885 MUTEX_UNLOCK (&cache_mutex);
888 void
889 cache_free_data_once (struct cache_data_s *data)
891 if (!data)
892 return;
894 strv_free (data->pubkey);
895 xfree (data->sigkey);
896 xfree (data->crc);
897 xfree (data->doc);
898 xfree (data);
901 static void
902 release_cipher (void *arg)
904 gcry_cipher_close ((gcry_cipher_hd_t) arg);
907 gpg_error_t
908 cache_encrypt (struct crypto_s *crypto)
910 gpg_error_t rc;
911 gcry_cipher_hd_t h;
912 size_t len = crypto->plaintext_size;
914 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
915 if (rc)
916 return rc;
918 if (len % cache_blocksize)
920 unsigned char *p;
922 len += cache_blocksize - (len % cache_blocksize);
923 p = xrealloc (crypto->plaintext, len * sizeof (unsigned char));
924 if (!p)
926 gcry_cipher_close (h);
927 return GPG_ERR_ENOMEM;
930 crypto->plaintext = p;
931 memset (&crypto->plaintext[crypto->plaintext_size], 0,
932 len - crypto->plaintext_size);
935 pthread_cleanup_push (release_cipher, h);
936 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
937 if (!rc)
939 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
940 if (!rc)
942 unsigned char *buf = xmalloc (len);
944 pthread_cleanup_push (xfree, buf);
946 if (!buf)
947 rc = GPG_ERR_ENOMEM;
949 if (!rc)
951 rc = gcry_cipher_encrypt (h, buf, len, crypto->plaintext, len);
952 if (!rc)
954 xfree (crypto->plaintext);
955 crypto->plaintext = buf;
956 crypto->plaintext_size = len;
960 pthread_cleanup_pop (rc != 0);
964 pthread_cleanup_pop (1);
965 return rc;
968 gpg_error_t
969 cache_decrypt (struct crypto_s *crypto)
971 gcry_cipher_hd_t h = NULL;
972 gpg_error_t rc;
974 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
975 if (rc)
976 return rc;
978 if (!rc)
979 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
981 if (!rc)
982 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
984 pthread_cleanup_push (release_cipher, h);
986 if (!rc)
988 rc = gcry_cipher_decrypt (h, crypto->plaintext, crypto->plaintext_size,
989 NULL, 0);
990 if (rc || strncmp ((char *)crypto->plaintext, "<?xml ", 6))
992 if (!rc)
993 rc = GPG_ERR_BAD_DATA;
997 pthread_cleanup_pop (1);
998 return rc;
1001 gpg_error_t
1002 cache_kill_scd ()
1004 gpg_error_t rc;
1006 MUTEX_LOCK (&cache_mutex);
1007 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1008 rc = agent_kill_scd (cache_agent);
1009 pthread_cleanup_pop (1);
1010 return rc;
1013 gpg_error_t
1014 cache_agent_command (const char *cmd)
1016 gpg_error_t rc;
1018 MUTEX_LOCK (&cache_mutex);
1019 rc = agent_command (cache_agent, NULL, NULL, "%s", cmd);
1020 MUTEX_UNLOCK (&cache_mutex);
1021 return rc;
1024 void
1025 cache_release_mutex ()
1027 MUTEX_UNLOCK (&cache_mutex);