2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
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/>.
31 #include "pwmd-error.h"
37 #include "util-misc.h"
38 #include "util-string.h"
45 static pthread_mutex_t cache_mutex
;
46 static struct slist_s
*key_cache
;
47 static unsigned char *cache_iv
;
48 static unsigned char *cache_key
;
49 static size_t cache_blocksize
;
50 static size_t cache_keysize
;
51 struct agent_s
*cache_agent
;
53 extern void log_write (const char *fmt
, ...);
55 static gpg_error_t
clear_once (file_cache_t
* p
, int agent
);
56 static int remove_entry (const char *);
57 static void free_entry (file_cache_t
* p
, int agent
);
60 get_entry (const char *filename
)
62 int t
= slist_length (key_cache
);
68 for (i
= 0; i
< t
; i
++)
70 file_cache_t
*p
= slist_nth_data (key_cache
, i
);
72 if (!strcmp (p
->filename
, filename
))
80 cache_lock_mutex (void *ctx
, const char *filename
, long lock_timeout
, int add
,
83 MUTEX_LOCK (&cache_mutex
);
85 file_cache_t
*p
= get_entry (filename
);
87 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
91 MUTEX_UNLOCK (&cache_mutex
);
92 MUTEX_TRYLOCK (ctx
, p
->mutex
, rc
, lock_timeout
);
96 rc
= cache_add_file (filename
, NULL
, timeout
);
99 p
= get_entry (filename
);
100 MUTEX_UNLOCK (&cache_mutex
);
101 MUTEX_TRYLOCK (ctx
, p
->mutex
, rc
, lock_timeout
);
105 MUTEX_UNLOCK (&cache_mutex
);
110 MUTEX_UNLOCK (&cache_mutex
);
113 pthread_cleanup_pop (0);
114 return !p
&& !rc
? GPG_ERR_NO_DATA
: rc
;
118 remove_entry (const char *filename
)
120 MUTEX_LOCK (&cache_mutex
);
121 file_cache_t
*p
= get_entry (filename
);
123 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
126 /* Keep a refcount because another client maybe editing this same new
127 * file. The entry needs to be kept in case the other client SAVE's.
134 pthread_cleanup_pop (1);
139 free_cache_data (file_cache_t
* cache
)
141 gpg_error_t rc
= GPG_ERR_NO_DATA
;
143 struct client_thread_s
*found
= NULL
;
149 MUTEX_LOCK (&cache_mutex
);
150 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
151 MUTEX_LOCK (&cn_mutex
);
152 pthread_cleanup_push (release_mutex_cb
, &cn_mutex
);
154 t
= slist_length (cn_thread_list
);
155 for (i
= 0; i
< t
; i
++)
157 struct client_thread_s
*thd
= slist_nth_data (cn_thread_list
, i
);
162 self
= pthread_equal (pthread_self (), thd
->tid
);
164 if (thd
->cl
->filename
&& !strcmp (thd
->cl
->filename
, cache
->filename
))
172 /* Continue trying to find a client who has the same file open and
173 * also has a lock. */
174 rc
= cache_lock_mutex (thd
->cl
->ctx
, thd
->cl
->filename
, -1, 0, -1);
183 if (self
&& (!rc
|| rc
== GPG_ERR_NO_DATA
) && found
)
184 rc
= cache_lock_mutex (found
->cl
->ctx
, found
->cl
->filename
, -1, 0, -1);
186 if (exiting
|| !rc
|| rc
== GPG_ERR_NO_DATA
)
188 cache_free_data_once (cache
->data
);
190 cache
->defer_clear
= 0;
194 cache_unlock_mutex (found
->cl
->filename
, 0);
200 cache
->defer_clear
= 1;
202 pthread_cleanup_pop (1);
203 pthread_cleanup_pop (1);
208 cache_unlock_mutex (const char *filename
, int remove
)
210 MUTEX_LOCK (&cache_mutex
);
211 file_cache_t
*p
= get_entry (filename
);
213 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
217 MUTEX_UNLOCK (p
->mutex
);
219 remove_entry (filename
);
222 pthread_cleanup_pop (1);
223 return p
? 0 : GPG_ERR_NO_DATA
;
227 test_agent_cache_once (file_cache_t
*p
, const char *grip
)
232 rc
= agent_command (cache_agent
, &line
, NULL
, "KEYINFO --data %s", grip
);
235 char **fields
= str_split (line
, " ", 0);
238 if (*fields
[1] == 'T')
239 rc
= GPG_ERR_NO_DATA
;
241 rc
= isdigit (*fields
[4]) || *fields
[5] == 'C' ? 0 : GPG_ERR_NO_DATA
;
250 /* Test each keygrip in data->(sig)grip for gpg-agent cache status. The file is
251 * considered cached if at least one grip is cached in the agent or one siggrip
252 * is cached in the case of 'sign'.
255 test_agent_cache (file_cache_t
*data
, int sign
)
260 if ((!data
->grip
&& !sign
) || (!data
->siggrip
&& sign
))
261 return GPG_ERR_NO_DATA
;
263 for (p
= data
->grip
; !sign
&& p
&& *p
; p
++)
265 rc
= test_agent_cache_once (data
, *p
);
266 if (!rc
|| rc
!= GPG_ERR_NO_DATA
)
272 for (p
= data
->siggrip
; p
&& *p
; p
++)
274 rc
= test_agent_cache_once (data
, *p
);
275 if (!rc
|| rc
!= GPG_ERR_NO_DATA
)
284 extract_keygrip_once (struct crypto_s
*crypto
, char **keyids
, int sign
,
292 rc
= crypto_list_keys (crypto
, keyids
, sign
, &result
);
296 for (i
= 0; result
[i
]; i
++)
300 for (s
= result
[i
]->subkeys
; s
; s
= s
->next
)
304 if (sign
&& !s
->can_sign
)
307 for (k
= keyids
; *k
; k
++)
309 if (!strcmp (*k
, s
->keyid
) && s
->keygrip
)
312 size_t len
= strv_length (grips
);
314 tmp
= xrealloc (grips
, len
+2 * sizeof (char *));
322 grips
[len
] = str_dup (s
->keygrip
);
346 crypto_free_key_list (result
);
347 return rc
? rc
: grips
? rc
: GPG_ERR_NO_DATA
;
351 extract_keygrips (file_cache_t
*data
)
354 struct crypto_s
*crypto
;
355 char **grips
= NULL
, **siggrips
= NULL
;
357 if (!data
|| !data
->data
)
360 rc
= crypto_init (&crypto
, NULL
, NULL
, 0, NULL
);
364 pthread_cleanup_push ((void *)crypto_free
, crypto
);
366 if (data
->data
->pubkey
)
367 rc
= extract_keygrip_once (crypto
, data
->data
->pubkey
, 0, &grips
);
369 if (!rc
&& data
->data
->sigkey
)
370 rc
= extract_keygrip_once (crypto
, data
->data
->sigkey
, 1, &siggrips
);
374 strv_free (data
->grip
);
376 strv_free (data
->siggrip
);
377 data
->siggrip
= siggrips
;
382 strv_free (siggrips
);
385 pthread_cleanup_pop (1);
390 iscached (const char *filename
, int *defer
, int agent
, int sign
)
392 file_cache_t
*p
= get_entry (filename
);
398 return GPG_ERR_NO_DATA
;
401 *defer
= p
->defer_clear
;
407 return GPG_ERR_NO_DATA
;
410 *defer
= p
->defer_clear
;
412 if (!rc
&& (p
->grip
|| p
->siggrip
))
413 rc
= test_agent_cache (p
, sign
);
415 rc
= GPG_ERR_NO_DATA
;
423 MUTEX_LOCK (&cache_mutex
);
424 unsigned total
= 0, i
, n
;
426 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
427 n
= slist_length (key_cache
);
428 for (i
= 0; i
< n
; i
++)
430 file_cache_t
*p
= slist_nth_data (key_cache
, i
);
432 if (!iscached (p
->filename
, NULL
, 0, 0))
436 pthread_cleanup_pop (1);
441 cache_adjust_timeout ()
443 MUTEX_LOCK (&cache_mutex
);
444 int t
= slist_length (key_cache
);
447 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
449 for (i
= 0; i
< t
; i
++)
451 file_cache_t
*p
= slist_nth_data (key_cache
, i
);
456 if (!p
->timeout
|| (p
->defer_clear
&& p
->timeout
!= -1))
458 /* The file associated with this cache entry may be locked by a
459 * client. Defer freeing this cache entry until the next timeout
461 if (!clear_once (p
, 1))
462 send_status_all (STATUS_CACHE
, NULL
);
466 pthread_cleanup_pop (1);
470 set_timeout (const char *filename
, int timeout
, int defer
, int force
)
472 MUTEX_LOCK (&cache_mutex
);
473 file_cache_t
*p
= get_entry (filename
);
476 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
480 MUTEX_UNLOCK (&cache_mutex
);
481 return GPG_ERR_NOT_FOUND
;
485 if (!p
->defer_clear
&& (p
->timeout
== -1 || force
))
486 p
->timeout
= timeout
;
488 if (!timeout
|| defer
)
490 rc
= clear_once (p
, 1);
492 send_status_all (STATUS_CACHE
, NULL
);
495 pthread_cleanup_pop (1);
500 cache_set_data (const char *filename
, struct cache_data_s
* data
)
502 MUTEX_LOCK (&cache_mutex
);
503 gpg_error_t rc
= GPG_ERR_NO_DATA
;
504 file_cache_t
*p
= get_entry (filename
);
506 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
511 rc
= set_timeout (filename
, p
->reset
, p
->defer_clear
, 0);
512 if (!rc
&& !p
->reset
)
515 send_status_all (STATUS_CACHE
, NULL
);
518 rc
= extract_keygrips (p
);
521 pthread_cleanup_pop (1);
522 return p
&& !rc
? 0 : rc
;
525 struct cache_data_s
*
526 cache_get_data (const char *filename
)
528 MUTEX_LOCK (&cache_mutex
);
529 file_cache_t
*p
= get_entry (filename
);
531 MUTEX_UNLOCK (&cache_mutex
);
532 return p
? p
->data
: NULL
;
536 cache_add_file (const char *filename
, struct cache_data_s
*data
, int timeout
)
538 MUTEX_LOCK (&cache_mutex
);
539 file_cache_t
*p
= get_entry (filename
);
543 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
549 rc
= set_timeout (filename
, timeout
, p
->defer_clear
, 0);
550 MUTEX_UNLOCK (&cache_mutex
);
551 send_status_all (STATUS_CACHE
, NULL
);
554 rc
= extract_keygrips (p
);
559 p
= xcalloc (1, sizeof (file_cache_t
));
562 MUTEX_UNLOCK (&cache_mutex
);
563 return GPG_ERR_ENOMEM
;
566 p
->mutex
= (pthread_mutex_t
*) xmalloc (sizeof (pthread_mutex_t
));
570 MUTEX_UNLOCK (&cache_mutex
);
571 return GPG_ERR_ENOMEM
;
574 pthread_mutexattr_t attr
;
575 pthread_mutexattr_init (&attr
);
576 pthread_mutexattr_settype (&attr
, PTHREAD_MUTEX_RECURSIVE
);
577 pthread_mutex_init (p
->mutex
, &attr
);
578 pthread_mutexattr_destroy (&attr
);
579 p
->filename
= str_dup (filename
);
582 new = slist_append (key_cache
, p
);
585 pthread_mutex_destroy (p
->mutex
);
588 MUTEX_UNLOCK (&cache_mutex
);
589 return GPG_ERR_ENOMEM
;
593 rc
= cache_set_timeout(filename
, timeout
);
594 pthread_cleanup_pop (1);
595 send_status_all (STATUS_CACHE
, NULL
);
598 rc
= extract_keygrips (p
);
604 cache_clear_agent_keys (const char *filename
, int decrypt
, int sign
)
606 MUTEX_LOCK (&cache_mutex
);
609 file_cache_t
*p
= get_entry (filename
);
611 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
615 MUTEX_UNLOCK (&cache_mutex
);
616 return GPG_ERR_NOT_FOUND
;
619 for (key
= p
->grip
; decrypt
&& key
&& *key
; key
++)
621 rc
= agent_command (cache_agent
, NULL
, NULL
,
622 "CLEAR_PASSPHRASE --mode=normal %s", *key
);
627 for (key
= p
->siggrip
; sign
&& key
&& *key
; key
++)
629 rc
= agent_command (cache_agent
, NULL
, NULL
,
630 "CLEAR_PASSPHRASE --mode=normal %s", *key
);
635 pthread_cleanup_pop (1);
640 clear_once (file_cache_t
*p
, int agent
)
642 gpg_error_t rc
= 0, trc
;
645 rc
= cache_clear_agent_keys (p
->filename
, 1, 1);
647 trc
= free_cache_data (p
);
648 return rc
? rc
: trc
;
652 free_entry (file_cache_t
*p
, int agent
)
659 rc
= clear_once (p
, agent
);
661 log_write ("%s(): %s", __FUNCTION__
, pwmd_strerror (rc
));
665 pthread_mutex_destroy (p
->mutex
);
670 strv_free (p
->siggrip
);
672 key_cache
= slist_remove (key_cache
, p
);
677 cache_clear (struct client_s
*client
, const char *filename
, int agent
)
680 gpg_error_t rc
= 0, all_rc
= 0;
683 MUTEX_LOCK (&cache_mutex
);
684 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
688 p
= get_entry (filename
);
691 MUTEX_UNLOCK (&cache_mutex
);
695 rc
= clear_once (p
, agent
);
696 MUTEX_UNLOCK (&cache_mutex
);
698 log_write ("%s(): %s", __FUNCTION__
, pwmd_strerror (rc
));
703 t
= slist_length (key_cache
);
704 for (i
= 0; i
< t
; i
++)
706 p
= slist_nth_data (key_cache
, i
);
710 assuan_peercred_t peer
;
711 int n
= client
->no_access_param
;
713 client
->no_access_param
= 1;
714 rc
= do_validate_peer (client
->ctx
, p
->filename
, &peer
);
715 client
->no_access_param
= n
;
716 if (rc
== GPG_ERR_FORBIDDEN
)
717 rc
= peer_is_invoker (client
);
721 all_rc
= !all_rc
? rc
: all_rc
;
726 clear_once (p
, agent
);
729 pthread_cleanup_pop (1);
734 cache_iscached (const char *filename
, int *defer
, int agent
, int sign
)
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
);
765 pthread_cleanup_pop (1);
770 cache_defer_clear (const char *filename
)
772 MUTEX_LOCK (&cache_mutex
);
773 file_cache_t
*p
= get_entry (filename
);
777 rc
= GPG_ERR_NOT_FOUND
;
781 MUTEX_UNLOCK (&cache_mutex
);
786 cache_set_timeout (const char *filename
, int timeout
)
788 return set_timeout (filename
, timeout
, 0, 1);
794 MUTEX_LOCK (&cache_mutex
);
795 int i
, t
= slist_length (key_cache
);
797 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
798 for (i
= 0; i
< t
; i
++)
800 file_cache_t
*p
= slist_nth_data (key_cache
, i
);
803 t
= slist_length (key_cache
);
807 gcry_free (cache_key
);
811 agent_free (cache_agent
);
813 pthread_cleanup_pop (1);
814 pthread_mutex_destroy (&cache_mutex
);
820 pthread_mutexattr_t attr
;
822 pthread_mutexattr_init (&attr
);
823 pthread_mutexattr_settype (&attr
, PTHREAD_MUTEX_RECURSIVE
);
824 pthread_mutex_init (&cache_mutex
, &attr
);
825 pthread_mutexattr_destroy (&attr
);
833 rc
= agent_init (&cache_agent
);
842 rc
= gcry_cipher_algo_info (GCRY_CIPHER_AES
, GCRYCTL_GET_BLKLEN
, NULL
,
847 rc
= gcry_cipher_algo_info (GCRY_CIPHER_AES
, GCRYCTL_GET_KEYLEN
, NULL
,
852 cache_key
= gcry_malloc (cache_keysize
);
854 return GPG_ERR_ENOMEM
;
856 cache_iv
= xmalloc (cache_blocksize
);
859 gcry_free (cache_key
);
861 return GPG_ERR_ENOMEM
;
864 gcry_create_nonce (cache_key
, cache_keysize
);
865 gcry_create_nonce (cache_iv
, cache_blocksize
);
876 MUTEX_LOCK (&cache_mutex
);
882 MUTEX_UNLOCK (&cache_mutex
);
886 cache_free_data_once (struct cache_data_s
*data
)
891 strv_free (data
->pubkey
);
892 strv_free (data
->sigkey
);
899 release_cipher (void *arg
)
901 gcry_cipher_close ((gcry_cipher_hd_t
) arg
);
905 cache_encrypt (struct crypto_s
*crypto
)
909 size_t len
= crypto
->plaintext_size
;
911 rc
= gcry_cipher_open (&h
, GCRY_CIPHER_AES128
, GCRY_CIPHER_MODE_CBC
, 0);
915 if (len
% cache_blocksize
)
919 len
+= cache_blocksize
- (len
% cache_blocksize
);
920 p
= xrealloc (crypto
->plaintext
, len
* sizeof (unsigned char));
923 gcry_cipher_close (h
);
924 return GPG_ERR_ENOMEM
;
927 crypto
->plaintext
= p
;
928 memset (&crypto
->plaintext
[crypto
->plaintext_size
], 0,
929 len
- crypto
->plaintext_size
);
932 pthread_cleanup_push (release_cipher
, h
);
933 rc
= gcry_cipher_setiv (h
, cache_iv
, cache_blocksize
);
936 rc
= gcry_cipher_setkey (h
, cache_key
, cache_keysize
);
939 unsigned char *buf
= xmalloc (len
);
941 pthread_cleanup_push (xfree
, buf
);
948 rc
= gcry_cipher_encrypt (h
, buf
, len
, crypto
->plaintext
, len
);
951 xfree (crypto
->plaintext
);
952 crypto
->plaintext
= buf
;
953 crypto
->plaintext_size
= len
;
957 pthread_cleanup_pop (rc
!= 0);
961 pthread_cleanup_pop (1);
966 cache_decrypt (struct crypto_s
*crypto
)
968 gcry_cipher_hd_t h
= NULL
;
971 rc
= gcry_cipher_open (&h
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_CBC
, 0);
976 rc
= gcry_cipher_setiv (h
, cache_iv
, cache_blocksize
);
979 rc
= gcry_cipher_setkey (h
, cache_key
, cache_keysize
);
981 pthread_cleanup_push (release_cipher
, h
);
985 rc
= gcry_cipher_decrypt (h
, crypto
->plaintext
, crypto
->plaintext_size
,
987 if (rc
|| strncmp ((char *)crypto
->plaintext
, "<?xml ", 6))
990 rc
= GPG_ERR_BAD_DATA
;
994 pthread_cleanup_pop (1);
1003 MUTEX_LOCK (&cache_mutex
);
1004 pthread_cleanup_push (release_mutex_cb
, &cache_mutex
);
1005 rc
= agent_kill_scd (cache_agent
);
1006 pthread_cleanup_pop (1);
1011 cache_release_mutex ()
1013 MUTEX_UNLOCK (&cache_mutex
);