1 |
/* wptPassCache.c - keep a cache of passphrases |
/* wptPassCache.c - keep a cache of passphrases |
2 |
* Copyright (C) 2002 Free Software Foundation, Inc. |
* Copyright (C) 2002 Free Software Foundation, Inc. |
3 |
* Copyright (C) 2003 Timo Schulz |
* Copyright (C) 2003 Timo Schulz |
4 |
* |
* |
5 |
* This file is part of WinPT. |
* This file is part of WinPT. |
15 |
* GNU General Public License for more details. |
* GNU General Public License for more details. |
16 |
* |
* |
17 |
* You should have received a copy of the GNU General Public License |
* You should have received a copy of the GNU General Public License |
18 |
* along with WinPT; if not, write to the Free Software Foundation, |
* along with WinPT; if not, write to the Free Software Foundation, |
19 |
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
20 |
*/ |
*/ |
21 |
|
#ifdef HAVE_CONFIG_H |
22 |
|
#include <config.h> |
23 |
|
#endif |
24 |
|
|
25 |
|
#include <windows.h> |
26 |
#include <windows.h> |
#include <windows.h> |
27 |
#include <stdio.h> |
#include <stdio.h> |
28 |
#include <stdlib.h> |
#include <stdlib.h> |
30 |
#include <time.h> |
#include <time.h> |
31 |
#include <assert.h> |
#include <assert.h> |
32 |
|
|
33 |
#include "wptTypes.h" |
#include "wptTypes.h" |
34 |
#include "wptErrors.h" |
#include "wptErrors.h" |
35 |
#include "wptAgent.h" |
#include "wptAgent.h" |
36 |
|
|
37 |
|
|
38 |
struct secret_data_s { |
struct secret_data_s { |
48 |
time_t accessed; |
time_t accessed; |
49 |
int ttl; /* max. lifetime given in seconds */ |
int ttl; /* max. lifetime given in seconds */ |
50 |
int lockcount; |
int lockcount; |
51 |
struct secret_data_s * pw; |
struct secret_data_s * pw; |
52 |
size_t pwlen; |
size_t pwlen; |
53 |
char key[1]; |
char key[1]; |
54 |
}; |
}; |
61 |
release_data (struct secret_data_s * data) |
release_data (struct secret_data_s * data) |
62 |
{ |
{ |
63 |
free (data); |
free (data); |
64 |
} |
} |
65 |
|
|
66 |
|
|
67 |
static void |
static void |
68 |
wipe_data (void * data, size_t dlen) |
wipe_data (void * data, size_t dlen) |
69 |
{ |
{ |
70 |
memset (data, 0xff, dlen); |
memset (data, 0xff, dlen); |
71 |
memset (data, 0xaa, dlen); |
memset (data, 0xaa, dlen); |
72 |
memset (data, 0x55, dlen); |
memset (data, 0x55, dlen); |
73 |
memset (data, 0x00, dlen); |
memset (data, 0x00, dlen); |
74 |
} |
} |
75 |
|
|
76 |
|
|
77 |
static struct secret_data_s * |
static struct secret_data_s * |
105 |
|
|
106 |
/* first expire the actual data */ |
/* first expire the actual data */ |
107 |
for( r=thecache; r; r = r->next ) { |
for( r=thecache; r; r = r->next ) { |
108 |
if( !r->lockcount && r->pw && r->accessed + r->ttl < current ) { |
if( !r->lockcount && r->pw && r->accessed + r->ttl < current ) { |
109 |
wipe_data( r->pw, r->pwlen ); |
wipe_data( r->pw, r->pwlen ); |
110 |
release_data( r->pw ); |
release_data( r->pw ); |
111 |
r->pw = NULL; |
r->pw = NULL; |
116 |
/* second, make sure that we also remove them based on the created stamp so |
/* second, make sure that we also remove them based on the created stamp so |
117 |
that the user has to enter it from time to time. We do this every hour */ |
that the user has to enter it from time to time. We do this every hour */ |
118 |
for( r=thecache; r; r = r->next ) { |
for( r=thecache; r; r = r->next ) { |
119 |
if( !r->lockcount && r->pw && r->created + 60*60 < current ) { |
if( !r->lockcount && r->pw && r->created + 60*60 < current ) { |
120 |
wipe_data( r->pw, r->pwlen ); |
wipe_data( r->pw, r->pwlen ); |
121 |
release_data( r->pw ); |
release_data( r->pw ); |
122 |
r->pw = NULL; |
r->pw = NULL; |
128 |
Expire old and unused entries after 30 minutes */ |
Expire old and unused entries after 30 minutes */ |
129 |
for( rprev=NULL, r=thecache; r; ) { |
for( rprev=NULL, r=thecache; r; ) { |
130 |
if (!r->pw && r->accessed + 60*30 < current) { |
if (!r->pw && r->accessed + 60*30 < current) { |
131 |
if (r->lockcount) { |
if (r->lockcount) { |
132 |
BUG( NULL ); |
BUG( NULL ); |
133 |
r->accessed += 60*10; /* next error message in 10 minutes */ |
r->accessed += 60*10; /* next error message in 10 minutes */ |
134 |
rprev = r; |
rprev = r; |
158 |
ITEM r; |
ITEM r; |
159 |
|
|
160 |
for (r=thecache; r; r = r->next) { |
for (r=thecache; r; r = r->next) { |
161 |
if( !r->lockcount && r->pw ) { |
if( !r->lockcount && r->pw ) { |
162 |
wipe_data (r->pw, r->pwlen); |
wipe_data (r->pw, r->pwlen); |
163 |
release_data (r->pw); |
release_data (r->pw); |
164 |
r->pw = NULL; |
r->pw = NULL; |
171 |
} |
} |
172 |
} |
} |
173 |
|
|
174 |
|
|
175 |
/* Try to find the item given by key and set the TTL value to zero. |
/* Try to find the item given by key and set the TTL value to zero. |
176 |
This means the item expires the next time the passphrase cache is used. */ |
This means the item expires the next time the passphrase cache is used. */ |
177 |
int |
int |
178 |
agent_del_cache( const char * key ) |
agent_del_cache( const char * key ) |
179 |
{ |
{ |
180 |
void * item; |
void * item; |
181 |
ITEM r; |
ITEM r; |
182 |
|
|
183 |
if( agent_get_cache( key, &item ) ) { |
if( agent_get_cache( key, &item ) ) { |
184 |
r = (ITEM)item; |
r = (ITEM)item; |
185 |
if( r ) |
if( r ) |
186 |
r->ttl = 0; |
r->ttl = 0; |
187 |
agent_unlock_cache_entry( &item ); |
agent_unlock_cache_entry( &item ); |
188 |
return 0; |
return 0; |
189 |
} |
} |
190 |
return -1; |
return -1; |
191 |
} |
} |
192 |
|
|
193 |
|
|
194 |
/* Store DATA of length DATALEN in the cache under KEY and mark it |
/* Store DATA of length DATALEN in the cache under KEY and mark it |
212 |
break; |
break; |
213 |
} |
} |
214 |
if( r ) { /* replace */ |
if( r ) { /* replace */ |
215 |
if( r->pw ) { |
if( r->pw ) { |
216 |
wipe_data( r->pw, r->pwlen ); |
wipe_data( r->pw, r->pwlen ); |
217 |
release_data( r->pw ); |
release_data( r->pw ); |
218 |
r->pw = NULL; |
r->pw = NULL; |
219 |
} |
} |
220 |
if (data) { |
if (data) { |
221 |
r->created = r->accessed = time( NULL ); |
r->created = r->accessed = time( NULL ); |
222 |
r->ttl = ttl; |
r->ttl = ttl; |
223 |
r->pwlen = strlen( data ); |
r->pwlen = strlen( data ); |
224 |
r->pw = new_data( data, r->pwlen+1 ); |
r->pw = new_data( data, r->pwlen+1 ); |
225 |
if (!r->pw) |
if (!r->pw) |
233 |
else { |
else { |
234 |
strcpy (r->key, key); |
strcpy (r->key, key); |
235 |
r->created = r->accessed = time( NULL ); |
r->created = r->accessed = time( NULL ); |
236 |
r->ttl = ttl; |
r->ttl = ttl; |
237 |
r->pwlen = strlen( data ); |
r->pwlen = strlen( data ); |
238 |
r->pw = new_data( data, r->pwlen+1 ); |
r->pw = new_data( data, r->pwlen+1 ); |
239 |
if (!r->pw) |
if (!r->pw) |
291 |
|
|
292 |
for( r=thecache; r; r = r->next ) { |
for( r=thecache; r; r = r->next ) { |
293 |
if( r == *cache_id ) { |
if( r == *cache_id ) { |
294 |
if( !r->lockcount ) |
if( !r->lockcount ) |
295 |
BUG( NULL ); |
BUG( NULL ); |
296 |
else |
else |
297 |
r->lockcount--; |
r->lockcount--; |