agent: Include missing prototype.
[gnupg.git] / agent / cache.c
1 /* cache.c - keep a cache of passphrases
2  * Copyright (C) 2002, 2010 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26 #include <assert.h>
27 #include <npth.h>
28
29 #include "agent.h"
30
31 /* The size of the encryption key in bytes.  */
32 #define ENCRYPTION_KEYSIZE (128/8)
33
34 /* A mutex used to protect the encryption.  This is required because
35    we use one context to do all encryption and decryption.  */
36 static npth_mutex_t encryption_lock;
37 /* The encryption context.  This is the only place where the
38    encryption key for all cached entries is available.  It would be nice
39    to keep this (or just the key) in some hardware device, for example
40    a TPM.  Libgcrypt could be extended to provide such a service.
41    With the current scheme it is easy to retrieve the cached entries
42    if access to Libgcrypt's memory is available.  The encryption
43    merely avoids grepping for clear texts in the memory.  Nevertheless
44    the encryption provides the necessary infrastructure to make it
45    more secure.  */
46 static gcry_cipher_hd_t encryption_handle;
47
48
49 struct secret_data_s {
50   int  totallen; /* This includes the padding and space for AESWRAP. */
51   char data[1];  /* A string.  */
52 };
53
54 typedef struct cache_item_s *ITEM;
55 struct cache_item_s {
56   ITEM next;
57   time_t created;
58   time_t accessed;
59   int ttl;  /* max. lifetime given in seconds, -1 one means infinite */
60   struct secret_data_s *pw;
61   cache_mode_t cache_mode;
62   char key[1];
63 };
64
65 /* The cache himself.  */
66 static ITEM thecache;
67
68
69 /* This function must be called once to initialize this module. It
70    has to be done before a second thread is spawned.  */
71 void
72 initialize_module_cache (void)
73 {
74   int err;
75
76   err = npth_mutex_init (&encryption_lock, NULL);
77
78   if (err)
79     log_fatal ("error initializing cache module: %s\n", strerror (err));
80 }
81
82
83 void
84 deinitialize_module_cache (void)
85 {
86   gcry_cipher_close (encryption_handle);
87   encryption_handle = NULL;
88 }
89
90
91 /* We do the encryption init on the fly.  We can't do it in the module
92    init code because that is run before we listen for connections and
93    in case we are started on demand by gpg etc. it will only wait for
94    a few seconds to decide whether the agent may now accept
95    connections.  Thus we should get into listen state as soon as
96    possible.  */
97 static gpg_error_t
98 init_encryption (void)
99 {
100   gpg_error_t err;
101   void *key;
102   int res;
103
104   if (encryption_handle)
105     return 0; /* Shortcut - Already initialized.  */
106
107   res = npth_mutex_lock (&encryption_lock);
108   if (res)
109     log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res));
110
111   err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128,
112                           GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE);
113   if (!err)
114     {
115       key = gcry_random_bytes (ENCRYPTION_KEYSIZE, GCRY_STRONG_RANDOM);
116       if (!key)
117         err = gpg_error_from_syserror ();
118       else
119         {
120           err = gcry_cipher_setkey (encryption_handle, key, ENCRYPTION_KEYSIZE);
121           xfree (key);
122         }
123       if (err)
124         {
125           gcry_cipher_close (encryption_handle);
126           encryption_handle = NULL;
127         }
128     }
129   if (err)
130     log_error ("error initializing cache encryption context: %s\n",
131                gpg_strerror (err));
132
133   res = npth_mutex_unlock (&encryption_lock);
134   if (res)
135     log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
136
137   return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0;
138 }
139
140
141
142 static void
143 release_data (struct secret_data_s *data)
144 {
145    xfree (data);
146 }
147
148 static gpg_error_t
149 new_data (const char *string, struct secret_data_s **r_data)
150 {
151   gpg_error_t err;
152   struct secret_data_s *d, *d_enc;
153   size_t length;
154   int total;
155   int res;
156
157   *r_data = NULL;
158
159   err = init_encryption ();
160   if (err)
161     return err;
162
163   length = strlen (string) + 1;
164
165   /* We pad the data to 32 bytes so that it get more complicated
166      finding something out by watching allocation patterns.  This is
167      usally not possible but we better assume nothing about our secure
168      storage provider.  To support the AESWRAP mode we need to add 8
169      extra bytes as well. */
170   total = (length + 8) + 32 - ((length+8) % 32);
171
172   d = xtrymalloc_secure (sizeof *d + total - 1);
173   if (!d)
174     return gpg_error_from_syserror ();
175   memcpy (d->data, string, length);
176
177   d_enc = xtrymalloc (sizeof *d_enc + total - 1);
178   if (!d_enc)
179     {
180       err = gpg_error_from_syserror ();
181       xfree (d);
182       return err;
183     }
184
185   d_enc->totallen = total;
186   res = npth_mutex_lock (&encryption_lock);
187   if (res)
188     log_fatal ("failed to acquire cache encryption mutex: %s\n",
189                strerror (res));
190
191   err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total,
192                              d->data, total - 8);
193   xfree (d);
194   res = npth_mutex_unlock (&encryption_lock);
195   if (res)
196     log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res));
197   if (err)
198     {
199       xfree (d_enc);
200       return err;
201     }
202   *r_data = d_enc;
203   return 0;
204 }
205
206
207
208 /* Check whether there are items to expire.  */
209 static void
210 housekeeping (void)
211 {
212   ITEM r, rprev;
213   time_t current = gnupg_get_time ();
214
215   /* First expire the actual data */
216   for (r=thecache; r; r = r->next)
217     {
218       if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current)
219         {
220           if (DBG_CACHE)
221             log_debug ("  expired '%s' (%ds after last access)\n",
222                        r->key, r->ttl);
223           release_data (r->pw);
224           r->pw = NULL;
225           r->accessed = current;
226         }
227     }
228
229   /* Second, make sure that we also remove them based on the created stamp so
230      that the user has to enter it from time to time. */
231   for (r=thecache; r; r = r->next)
232     {
233       unsigned long maxttl;
234
235       switch (r->cache_mode)
236         {
237         case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break;
238         default: maxttl = opt.max_cache_ttl; break;
239         }
240       if (r->pw && r->created + maxttl < current)
241         {
242           if (DBG_CACHE)
243             log_debug ("  expired '%s' (%lus after creation)\n",
244                        r->key, opt.max_cache_ttl);
245           release_data (r->pw);
246           r->pw = NULL;
247           r->accessed = current;
248         }
249     }
250
251   /* Third, make sure that we don't have too many items in the list.
252      Expire old and unused entries after 30 minutes */
253   for (rprev=NULL, r=thecache; r; )
254     {
255       if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current)
256         {
257           ITEM r2 = r->next;
258           if (DBG_CACHE)
259             log_debug ("  removed '%s' (mode %d) (slot not used for 30m)\n",
260                        r->key, r->cache_mode);
261           xfree (r);
262           if (!rprev)
263             thecache = r2;
264           else
265             rprev->next = r2;
266           r = r2;
267         }
268       else
269         {
270           rprev = r;
271           r = r->next;
272         }
273     }
274 }
275
276
277 void
278 agent_flush_cache (void)
279 {
280   ITEM r;
281
282   if (DBG_CACHE)
283     log_debug ("agent_flush_cache\n");
284
285   for (r=thecache; r; r = r->next)
286     {
287       if (r->pw)
288         {
289           if (DBG_CACHE)
290             log_debug ("  flushing '%s'\n", r->key);
291           release_data (r->pw);
292           r->pw = NULL;
293           r->accessed = 0;
294         }
295     }
296 }
297
298
299
300 /* Store the string DATA in the cache under KEY and mark it with a
301    maximum lifetime of TTL seconds.  If there is already data under
302    this key, it will be replaced.  Using a DATA of NULL deletes the
303    entry.  A TTL of 0 is replaced by the default TTL and a TTL of -1
304    set infinite timeout.  CACHE_MODE is stored with the cache entry
305    and used to select different timeouts.  */
306 int
307 agent_put_cache (const char *key, cache_mode_t cache_mode,
308                  const char *data, int ttl)
309 {
310   gpg_error_t err = 0;
311   ITEM r;
312
313   if (DBG_CACHE)
314     log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n",
315                key, cache_mode, ttl);
316   housekeeping ();
317
318   if (!ttl)
319     {
320       switch(cache_mode)
321         {
322         case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break;
323         default: ttl = opt.def_cache_ttl; break;
324         }
325     }
326   if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE)
327     return 0;
328
329   for (r=thecache; r; r = r->next)
330     {
331       if (((cache_mode != CACHE_MODE_USER
332             && cache_mode != CACHE_MODE_NONCE)
333            || r->cache_mode == cache_mode)
334           && !strcmp (r->key, key))
335         break;
336     }
337   if (r) /* Replace.  */
338     {
339       if (r->pw)
340         {
341           release_data (r->pw);
342           r->pw = NULL;
343         }
344       if (data)
345         {
346           r->created = r->accessed = gnupg_get_time ();
347           r->ttl = ttl;
348           r->cache_mode = cache_mode;
349           err = new_data (data, &r->pw);
350           if (err)
351             log_error ("error replacing cache item: %s\n", gpg_strerror (err));
352         }
353     }
354   else if (data) /* Insert.  */
355     {
356       r = xtrycalloc (1, sizeof *r + strlen (key));
357       if (!r)
358         err = gpg_error_from_syserror ();
359       else
360         {
361           strcpy (r->key, key);
362           r->created = r->accessed = gnupg_get_time ();
363           r->ttl = ttl;
364           r->cache_mode = cache_mode;
365           err = new_data (data, &r->pw);
366           if (err)
367             xfree (r);
368           else
369             {
370               r->next = thecache;
371               thecache = r;
372             }
373         }
374       if (err)
375         log_error ("error inserting cache item: %s\n", gpg_strerror (err));
376     }
377   return err;
378 }
379
380
381 /* Try to find an item in the cache.  Note that we currently don't
382    make use of CACHE_MODE except for CACHE_MODE_NONCE and
383    CACHE_MODE_USER.  */
384 char *
385 agent_get_cache (const char *key, cache_mode_t cache_mode)
386 {
387   gpg_error_t err;
388   ITEM r;
389   char *value = NULL;
390   int res;
391
392   if (cache_mode == CACHE_MODE_IGNORE)
393     return NULL;
394
395   if (DBG_CACHE)
396     log_debug ("agent_get_cache '%s' (mode %d) ...\n", key, cache_mode);
397   housekeeping ();
398
399   for (r=thecache; r; r = r->next)
400     {
401       if (r->pw
402           && ((cache_mode != CACHE_MODE_USER
403                && cache_mode != CACHE_MODE_NONCE)
404               || r->cache_mode == cache_mode)
405           && !strcmp (r->key, key))
406         {
407           r->accessed = gnupg_get_time ();
408           if (DBG_CACHE)
409             log_debug ("... hit\n");
410           if (r->pw->totallen < 32)
411             err = gpg_error (GPG_ERR_INV_LENGTH);
412           else if ((err = init_encryption ()))
413             ;
414           else if (!(value = xtrymalloc_secure (r->pw->totallen - 8)))
415             err = gpg_error_from_syserror ();
416           else
417             {
418               res = npth_mutex_lock (&encryption_lock);
419               if (res)
420                 log_fatal ("failed to acquire cache encryption mutex: %s\n",
421                            strerror (res));
422               err = gcry_cipher_decrypt (encryption_handle,
423                                          value, r->pw->totallen - 8,
424                                          r->pw->data, r->pw->totallen);
425               res = npth_mutex_unlock (&encryption_lock);
426               if (res)
427                 log_fatal ("failed to release cache encryption mutex: %s\n",
428                            strerror (res));
429             }
430           if (err)
431             {
432               xfree (value);
433               value = NULL;
434               log_error ("retrieving cache entry '%s' failed: %s\n",
435                          key, gpg_strerror (err));
436             }
437           return value;
438         }
439     }
440   if (DBG_CACHE)
441     log_debug ("... miss\n");
442
443   return NULL;
444 }