KEYINFO: Add --learn.
[pwmd.git] / src / cache.c
blob3b0f7a2ba3829f93ab6fe1557827b7d82c75dcf5
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 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)
276 for (p = data->siggrip; p && *p; p++)
278 rc = test_agent_cache_once (data, *p);
279 if (!rc || rc != GPG_ERR_NO_DATA)
280 break;
284 return rc;
287 static gpg_error_t
288 extract_keygrip_once (struct crypto_s *crypto, char **keyids, int sign,
289 char ***dst)
291 gpgme_key_t *result;
292 gpgme_error_t rc;
293 int i;
294 char **grips = NULL;
296 rc = crypto_list_keys (crypto, keyids, sign, &result);
297 if (rc)
298 return rc;
300 for (i = 0; result[i]; i++)
302 gpgme_subkey_t s;
304 for (s = result[i]->subkeys; s; s = s->next)
306 char **k;
308 if (sign && !s->can_sign)
309 continue;
311 for (k = keyids; *k; k++)
313 if (!strcmp (*k, s->keyid) && s->keygrip)
315 char **tmp;
316 size_t len = strv_length (grips);
318 tmp = xrealloc (grips, len+2 * sizeof (char *));
319 if (!tmp)
321 rc = GPG_ERR_ENOMEM;
322 break;
325 grips = tmp;
326 grips[len] = str_dup (s->keygrip);
327 if (!grips[len])
329 rc = GPG_ERR_ENOMEM;
330 break;
333 grips[++len] = NULL;
339 if (!rc)
341 strv_free (*dst);
342 *dst = grips;
344 else
346 strv_free (grips);
347 grips = NULL;
350 crypto_free_key_list (result);
351 return rc ? rc : grips ? rc : GPG_ERR_NO_DATA;
354 static gpg_error_t
355 extract_keygrips (file_cache_t *data)
357 gpg_error_t rc = 0;
358 struct crypto_s *crypto;
359 char **grips = NULL, **siggrips = NULL;
361 if (!data || !data->data)
362 return 0;
364 rc = crypto_init (&crypto, NULL, NULL, 0, NULL);
365 if (rc)
366 return rc;
368 pthread_cleanup_push ((void *)crypto_free, crypto);
370 if (data->data->pubkey)
371 rc = extract_keygrip_once (crypto, data->data->pubkey, 0, &grips);
373 if (!rc && data->data->sigkey)
374 rc = extract_keygrip_once (crypto, data->data->sigkey, 1, &siggrips);
376 if (!rc)
378 strv_free (data->grip);
379 data->grip = grips;
380 strv_free (data->siggrip);
381 data->siggrip = siggrips;
383 else
385 strv_free (grips);
386 strv_free (siggrips);
389 pthread_cleanup_pop (1);
390 return rc;
393 static gpg_error_t
394 iscached (const char *filename, int *defer, int agent, int sign)
396 file_cache_t *p = get_entry (filename);
397 gpg_error_t rc = 0;
399 if (!agent)
401 if (!p || !p->data)
402 return GPG_ERR_NO_DATA;
404 if (defer)
405 *defer = p->defer_clear;
407 return 0;
410 if (!p)
411 return GPG_ERR_NO_DATA;
413 if (defer)
414 *defer = p->defer_clear;
416 if (!rc && (p->grip || p->siggrip))
417 rc = test_agent_cache (p, sign);
418 else if (!rc)
419 rc = GPG_ERR_NO_DATA;
421 return rc;
424 unsigned
425 cache_file_count ()
427 MUTEX_LOCK (&cache_mutex);
428 unsigned total = 0, i, n;
430 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
431 n = slist_length (key_cache);
432 for (i = 0; i < n; i++)
434 file_cache_t *p = slist_nth_data (key_cache, i);
436 if (!iscached (p->filename, NULL, 0, 0))
437 total++;
440 pthread_cleanup_pop (1);
441 return total;
444 void
445 cache_adjust_timeout ()
447 MUTEX_LOCK (&cache_mutex);
448 int t = slist_length (key_cache);
449 int i;
451 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
453 for (i = 0; i < t; i++)
455 file_cache_t *p = slist_nth_data (key_cache, i);
457 if (p->timeout > 0)
458 p->timeout--;
460 if (!p->timeout || (p->defer_clear && p->timeout != -1))
462 /* The file associated with this cache entry may be locked by a
463 * client. Defer freeing this cache entry until the next timeout
464 * check. */
465 if (!clear_once (p, 1))
466 send_status_all (STATUS_CACHE, NULL);
470 pthread_cleanup_pop (1);
473 static gpg_error_t
474 set_timeout (const char *filename, int timeout, int defer, int force)
476 MUTEX_LOCK (&cache_mutex);
477 file_cache_t *p = get_entry (filename);
478 gpg_error_t rc = 0;
480 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
482 if (p)
484 p->reset = timeout;
485 if (!p->defer_clear && (p->timeout == -1 || force))
486 p->timeout = timeout;
488 if (!timeout || defer)
490 rc = clear_once (p, 1);
491 if (!rc)
492 send_status_all (STATUS_CACHE, NULL);
495 else
496 rc = GPG_ERR_NOT_FOUND;
498 pthread_cleanup_pop (1);
499 return rc;
502 gpg_error_t
503 cache_set_data (const char *filename, struct cache_data_s * data)
505 MUTEX_LOCK (&cache_mutex);
506 gpg_error_t rc = GPG_ERR_NO_DATA;
507 file_cache_t *p = get_entry (filename);
509 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
511 if (p)
513 p->data = data;
514 rc = set_timeout (filename, p->reset, p->defer_clear, 0);
515 if (!rc && !p->reset)
517 clear_once (p, 0);
518 send_status_all (STATUS_CACHE, NULL);
520 else if (!rc)
521 rc = extract_keygrips (p);
524 pthread_cleanup_pop (1);
525 return p && !rc ? 0 : rc;
528 struct cache_data_s *
529 cache_get_data (const char *filename)
531 MUTEX_LOCK (&cache_mutex);
532 file_cache_t *p = get_entry (filename);
534 MUTEX_UNLOCK (&cache_mutex);
535 return p ? p->data : NULL;
538 gpg_error_t
539 cache_add_file (const char *filename, struct cache_data_s *data, int timeout)
541 MUTEX_LOCK (&cache_mutex);
542 file_cache_t *p = get_entry (filename);
543 struct slist_s *new;
544 gpg_error_t rc = 0;
546 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
548 if (p)
550 p->data = data;
551 p->refcount++;
552 rc = set_timeout (filename, timeout, p->defer_clear, 0);
554 else
556 p = xcalloc (1, sizeof (file_cache_t));
557 if (p)
559 p->mutex = (pthread_mutex_t *) xmalloc (sizeof (pthread_mutex_t));
560 if (p->mutex)
562 pthread_mutexattr_t attr;
563 pthread_mutexattr_init (&attr);
564 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
565 pthread_mutex_init (p->mutex, &attr);
566 pthread_mutexattr_destroy (&attr);
567 p->filename = str_dup (filename);
568 p->data = data;
569 p->refcount++;
570 new = slist_append (key_cache, p);
571 if (new)
573 key_cache = new;
574 rc = cache_set_timeout(filename, timeout);
576 else
578 pthread_mutex_destroy (p->mutex);
579 xfree (p->mutex);
580 xfree (p->filename);
581 xfree (p);
582 p = NULL;
583 rc = GPG_ERR_ENOMEM;
586 else
588 xfree (p);
589 p = NULL;
590 rc = GPG_ERR_ENOMEM;
593 else
594 rc = GPG_ERR_ENOMEM;
597 if (!rc)
598 rc = extract_keygrips (p);
600 pthread_cleanup_pop (1);
602 if (!rc)
603 send_status_all (STATUS_CACHE, NULL);
605 return rc;
608 gpg_error_t
609 cache_clear_agent_keys (const char *filename, int decrypt, int sign)
611 MUTEX_LOCK (&cache_mutex);
612 gpg_error_t rc = 0;
613 char **key;
614 file_cache_t *p = get_entry (filename);
616 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
618 if (p)
620 for (key = p->grip; decrypt && key && *key; key++)
622 rc = agent_command (cache_agent, NULL, NULL,
623 "CLEAR_PASSPHRASE --mode=normal %s", *key);
624 if (rc)
625 break;
628 for (key = p->siggrip; sign && key && *key; key++)
630 rc = agent_command (cache_agent, NULL, NULL,
631 "CLEAR_PASSPHRASE --mode=normal %s", *key);
632 if (rc)
633 break;
636 else
637 rc = GPG_ERR_NOT_FOUND;
639 pthread_cleanup_pop (1);
640 return rc;
643 static gpg_error_t
644 clear_once (file_cache_t *p, int agent)
646 gpg_error_t rc = 0, trc;
648 if (agent)
649 rc = cache_clear_agent_keys (p->filename, 1, 1);
651 trc = free_cache_data (p);
652 return rc ? rc : trc;
655 static void
656 free_entry (file_cache_t *p, int agent)
658 gpg_error_t rc;
660 if (!p)
661 return;
663 rc = clear_once (p, agent);
664 if (rc)
665 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
667 if (p->mutex)
669 pthread_mutex_destroy (p->mutex);
670 xfree (p->mutex);
673 strv_free (p->grip);
674 strv_free (p->siggrip);
675 xfree (p->filename);
676 key_cache = slist_remove (key_cache, p);
677 xfree (p);
680 gpg_error_t
681 cache_clear (struct client_s *client, const char *filename, int agent)
683 file_cache_t *p;
684 gpg_error_t rc = 0, all_rc = 0;
685 int i, t;
687 MUTEX_LOCK (&cache_mutex);
688 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
690 if (filename)
692 p = get_entry (filename);
693 if (p)
695 rc = clear_once (p, agent);
696 if (rc)
697 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
700 else
702 t = slist_length (key_cache);
703 for (i = 0; i < t; i++)
705 p = slist_nth_data (key_cache, i);
707 if (client)
709 assuan_peercred_t peer;
710 int n = client->no_access_param;
712 client->no_access_param = 1;
713 rc = do_validate_peer (client->ctx, p->filename, &peer);
714 client->no_access_param = n;
715 if (rc == GPG_ERR_FORBIDDEN)
716 rc = peer_is_invoker (client);
718 if (rc)
720 all_rc = !all_rc ? rc : all_rc;
721 continue;
725 clear_once (p, agent);
729 pthread_cleanup_pop (1);
730 return filename ? rc : all_rc;
733 gpg_error_t
734 cache_iscached (const char *filename, int *defer, int agent, int sign)
736 gpg_error_t rc;
738 if (!filename)
739 return GPG_ERR_INV_PARAMETER;
741 MUTEX_LOCK (&cache_mutex);
742 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
743 rc = iscached (filename, defer, agent, sign);
745 /* Test if the data file disappeared from the filesystem. */
746 if ((!rc || gpg_err_code (rc) == GPG_ERR_NO_DATA)
747 && access (filename, R_OK) == -1)
749 rc = gpg_error_from_errno (errno);
750 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
752 /* Fixes clearing the cache entry that was created during OPEN when
753 * SAVE'ing a new file. */
754 if ((defer && *defer == 1) || !defer)
756 rc = cache_defer_clear (filename);
757 if (!rc && defer)
758 *defer = 1;
761 rc = GPG_ERR_ENOENT;
765 pthread_cleanup_pop (1);
766 return rc;
769 gpg_error_t
770 cache_defer_clear (const char *filename)
772 MUTEX_LOCK (&cache_mutex);
773 file_cache_t *p = get_entry (filename);
774 gpg_error_t rc = 0;
776 if (!p)
777 rc = GPG_ERR_NOT_FOUND;
778 else
779 p->defer_clear = 1;
781 MUTEX_UNLOCK (&cache_mutex);
782 return rc;
785 gpg_error_t
786 cache_set_timeout (const char *filename, int timeout)
788 return set_timeout (filename, timeout, 0, 1);
791 void
792 cache_deinit ()
794 exiting = 1;
795 MUTEX_LOCK (&cache_mutex);
796 int i, t = slist_length (key_cache);
798 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
799 for (i = 0; i < t; i++)
801 file_cache_t *p = slist_nth_data (key_cache, i);
803 free_entry (p, 1);
804 t = slist_length (key_cache);
805 i = -1;
808 gcry_free (cache_key);
809 xfree (cache_iv);
810 cache_key = NULL;
811 cache_iv = NULL;
812 agent_free (cache_agent);
813 cache_agent = NULL;
814 pthread_cleanup_pop (1);
815 pthread_mutex_destroy (&cache_mutex);
818 void
819 cache_mutex_init ()
821 pthread_mutexattr_t attr;
823 pthread_mutexattr_init (&attr);
824 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
825 pthread_mutex_init (&cache_mutex, &attr);
826 pthread_mutexattr_destroy (&attr);
829 gpg_error_t
830 cache_init ()
832 gpg_error_t rc = 0;
834 rc = agent_init (&cache_agent);
835 if (rc)
837 cache_agent = NULL;
838 return rc;
841 if (!cache_key)
843 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_BLKLEN, NULL,
844 &cache_blocksize);
845 if (rc)
846 return rc;
848 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_KEYLEN, NULL,
849 &cache_keysize);
850 if (rc)
851 return rc;
853 cache_key = gcry_malloc (cache_keysize);
854 if (!cache_key)
855 return GPG_ERR_ENOMEM;
857 cache_iv = xmalloc (cache_blocksize);
858 if (!cache_iv)
860 gcry_free (cache_key);
861 cache_key = NULL;
862 return GPG_ERR_ENOMEM;
865 gcry_create_nonce (cache_key, cache_keysize);
866 gcry_create_nonce (cache_iv, cache_blocksize);
870 cache_mutex_init ();
871 return rc;
874 void
875 cache_lock ()
877 MUTEX_LOCK (&cache_mutex);
880 void
881 cache_unlock ()
883 MUTEX_UNLOCK (&cache_mutex);
886 void
887 cache_free_data_once (struct cache_data_s *data)
889 if (!data)
890 return;
892 strv_free (data->pubkey);
893 strv_free (data->sigkey);
894 xfree (data->crc);
895 xfree (data->doc);
896 xfree (data);
899 static void
900 release_cipher (void *arg)
902 gcry_cipher_close ((gcry_cipher_hd_t) arg);
905 gpg_error_t
906 cache_encrypt (struct crypto_s *crypto)
908 gpg_error_t rc;
909 gcry_cipher_hd_t h;
910 size_t len = crypto->plaintext_size;
912 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
913 if (rc)
914 return rc;
916 if (len % cache_blocksize)
918 unsigned char *p;
920 len += cache_blocksize - (len % cache_blocksize);
921 p = xrealloc (crypto->plaintext, len * sizeof (unsigned char));
922 if (!p)
924 gcry_cipher_close (h);
925 return GPG_ERR_ENOMEM;
928 crypto->plaintext = p;
929 memset (&crypto->plaintext[crypto->plaintext_size], 0,
930 len - crypto->plaintext_size);
933 pthread_cleanup_push (release_cipher, h);
934 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
935 if (!rc)
937 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
938 if (!rc)
940 unsigned char *buf = xmalloc (len);
942 pthread_cleanup_push (xfree, buf);
944 if (!buf)
945 rc = GPG_ERR_ENOMEM;
947 if (!rc)
949 rc = gcry_cipher_encrypt (h, buf, len, crypto->plaintext, len);
950 if (!rc)
952 xfree (crypto->plaintext);
953 crypto->plaintext = buf;
954 crypto->plaintext_size = len;
958 pthread_cleanup_pop (rc != 0);
962 pthread_cleanup_pop (1);
963 return rc;
966 gpg_error_t
967 cache_decrypt (struct crypto_s *crypto)
969 gcry_cipher_hd_t h = NULL;
970 gpg_error_t rc;
972 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
973 if (rc)
974 return rc;
976 if (!rc)
977 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
979 if (!rc)
980 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
982 pthread_cleanup_push (release_cipher, h);
984 if (!rc)
986 rc = gcry_cipher_decrypt (h, crypto->plaintext, crypto->plaintext_size,
987 NULL, 0);
988 if (rc || strncmp ((char *)crypto->plaintext, "<?xml ", 6))
990 if (!rc)
991 rc = GPG_ERR_BAD_DATA;
995 pthread_cleanup_pop (1);
996 return rc;
999 gpg_error_t
1000 cache_kill_scd ()
1002 gpg_error_t rc;
1004 MUTEX_LOCK (&cache_mutex);
1005 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1006 rc = agent_kill_scd (cache_agent);
1007 pthread_cleanup_pop (1);
1008 return rc;
1011 gpg_error_t
1012 cache_agent_command (const char *cmd)
1014 gpg_error_t rc;
1016 MUTEX_LOCK (&cache_mutex);
1017 rc = agent_command (cache_agent, NULL, NULL, "%s", cmd);
1018 MUTEX_UNLOCK (&cache_mutex);
1019 return rc;
1022 void
1023 cache_release_mutex ()
1025 MUTEX_UNLOCK (&cache_mutex);