diff options
Diffstat (limited to 'src/gnutls_cache.c')
-rw-r--r-- | src/gnutls_cache.c | 925 |
1 files changed, 473 insertions, 452 deletions
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c index 90ea440..cbf879c 100644 --- a/src/gnutls_cache.c +++ b/src/gnutls_cache.c | |||
@@ -44,18 +44,18 @@ | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | char *mgs_session_id2sz(unsigned char *id, int idlen, | 46 | char *mgs_session_id2sz(unsigned char *id, int idlen, |
47 | char *str, int strsize) | 47 | char *str, int strsize) |
48 | { | 48 | { |
49 | char *cp; | 49 | char *cp; |
50 | int n; | 50 | int n; |
51 | 51 | ||
52 | cp = str; | 52 | cp = str; |
53 | for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) { | 53 | for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) { |
54 | apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]); | 54 | apr_snprintf(cp, strsize - (cp - str), "%02X", id[n]); |
55 | cp += 2; | 55 | cp += 2; |
56 | } | 56 | } |
57 | *cp = '\0'; | 57 | *cp = '\0'; |
58 | return str; | 58 | return str; |
59 | } | 59 | } |
60 | 60 | ||
61 | 61 | ||
@@ -63,35 +63,38 @@ char *mgs_session_id2sz(unsigned char *id, int idlen, | |||
63 | * server:port.SessionID | 63 | * server:port.SessionID |
64 | * to disallow resuming sessions on different servers | 64 | * to disallow resuming sessions on different servers |
65 | */ | 65 | */ |
66 | static int mgs_session_id2dbm(conn_rec* c, unsigned char *id, int idlen, | 66 | static int mgs_session_id2dbm(conn_rec * c, unsigned char *id, int idlen, |
67 | apr_datum_t* dbmkey) | 67 | apr_datum_t * dbmkey) |
68 | { | 68 | { |
69 | char buf[STR_SESSION_LEN]; | 69 | char buf[STR_SESSION_LEN]; |
70 | char *sz; | 70 | char *sz; |
71 | 71 | ||
72 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); | 72 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); |
73 | if (sz == NULL) | 73 | if (sz == NULL) |
74 | return -1; | 74 | return -1; |
75 | 75 | ||
76 | dbmkey->dptr = apr_psprintf(c->pool, "%s:%d.%s", c->base_server->server_hostname, c->base_server->port, sz); | 76 | dbmkey->dptr = |
77 | dbmkey->dsize = strlen( dbmkey->dptr); | 77 | apr_psprintf(c->pool, "%s:%d.%s", |
78 | 78 | c->base_server->server_hostname, | |
79 | return 0; | 79 | c->base_server->port, sz); |
80 | dbmkey->dsize = strlen(dbmkey->dptr); | ||
81 | |||
82 | return 0; | ||
80 | } | 83 | } |
81 | 84 | ||
82 | #define CTIME "%b %d %k:%M:%S %Y %Z" | 85 | #define CTIME "%b %d %k:%M:%S %Y %Z" |
83 | char *mgs_time2sz(time_t in_time, char *str, int strsize) | 86 | char *mgs_time2sz(time_t in_time, char *str, int strsize) |
84 | { | 87 | { |
85 | apr_time_exp_t vtm; | 88 | apr_time_exp_t vtm; |
86 | apr_size_t ret_size; | 89 | apr_size_t ret_size; |
87 | apr_time_t t; | 90 | apr_time_t t; |
88 | 91 | ||
89 | 92 | ||
90 | apr_time_ansi_put (&t, in_time); | 93 | apr_time_ansi_put(&t, in_time); |
91 | apr_time_exp_gmt (&vtm, t); | 94 | apr_time_exp_gmt(&vtm, t); |
92 | apr_strftime(str, &ret_size, strsize-1, CTIME, &vtm); | 95 | apr_strftime(str, &ret_size, strsize - 1, CTIME, &vtm); |
93 | 96 | ||
94 | return str; | 97 | return str; |
95 | } | 98 | } |
96 | 99 | ||
97 | #if HAVE_APR_MEMCACHE | 100 | #if HAVE_APR_MEMCACHE |
@@ -99,16 +102,18 @@ char *mgs_time2sz(time_t in_time, char *str, int strsize) | |||
99 | * server:port.SessionID | 102 | * server:port.SessionID |
100 | * to disallow resuming sessions on different servers | 103 | * to disallow resuming sessions on different servers |
101 | */ | 104 | */ |
102 | static char* mgs_session_id2mc(conn_rec* c, unsigned char *id, int idlen) | 105 | static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen) |
103 | { | 106 | { |
104 | char buf[STR_SESSION_LEN]; | 107 | char buf[STR_SESSION_LEN]; |
105 | char *sz; | 108 | char *sz; |
106 | 109 | ||
107 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); | 110 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); |
108 | if (sz == NULL) | 111 | if (sz == NULL) |
109 | return NULL; | 112 | return NULL; |
110 | 113 | ||
111 | return apr_psprintf(c->pool, MC_TAG"%s:%d.%s", c->base_server->server_hostname, c->base_server->port, sz); | 114 | return apr_psprintf(c->pool, MC_TAG "%s:%d.%s", |
115 | c->base_server->server_hostname, | ||
116 | c->base_server->port, sz); | ||
112 | } | 117 | } |
113 | 118 | ||
114 | /** | 119 | /** |
@@ -117,482 +122,498 @@ char *sz; | |||
117 | */ | 122 | */ |
118 | 123 | ||
119 | /* The underlying apr_memcache system is thread safe... woohoo */ | 124 | /* The underlying apr_memcache system is thread safe... woohoo */ |
120 | static apr_memcache_t* mc; | 125 | static apr_memcache_t *mc; |
121 | 126 | ||
122 | static int mc_cache_child_init(apr_pool_t *p, server_rec *s, | 127 | static int mc_cache_child_init(apr_pool_t * p, server_rec * s, |
123 | mgs_srvconf_rec *sc) | 128 | mgs_srvconf_rec * sc) |
124 | { | 129 | { |
125 | apr_status_t rv = APR_SUCCESS; | 130 | apr_status_t rv = APR_SUCCESS; |
126 | int thread_limit = 0; | 131 | int thread_limit = 0; |
127 | int nservers = 0; | 132 | int nservers = 0; |
128 | char* cache_config; | 133 | char *cache_config; |
129 | char* split; | 134 | char *split; |
130 | char* tok; | 135 | char *tok; |
131 | 136 | ||
132 | ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); | 137 | ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); |
133 | 138 | ||
134 | /* Find all the servers in the first run to get a total count */ | 139 | /* Find all the servers in the first run to get a total count */ |
135 | cache_config = apr_pstrdup(p, sc->cache_config); | 140 | cache_config = apr_pstrdup(p, sc->cache_config); |
136 | split = apr_strtok(cache_config, " ", &tok); | 141 | split = apr_strtok(cache_config, " ", &tok); |
137 | while (split) { | 142 | while (split) { |
138 | nservers++; | 143 | nservers++; |
139 | split = apr_strtok(NULL," ", &tok); | 144 | split = apr_strtok(NULL, " ", &tok); |
140 | } | 145 | } |
141 | 146 | ||
142 | rv = apr_memcache_create(p, nservers, 0, &mc); | 147 | rv = apr_memcache_create(p, nservers, 0, &mc); |
143 | if (rv != APR_SUCCESS) { | 148 | if (rv != APR_SUCCESS) { |
144 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 149 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
145 | "[gnutls_cache] Failed to create Memcache Object of '%d' size.", | 150 | "[gnutls_cache] Failed to create Memcache Object of '%d' size.", |
146 | nservers); | 151 | nservers); |
147 | return rv; | 152 | return rv; |
148 | } | 153 | } |
149 | 154 | ||
150 | /* Now add each server to the memcache */ | 155 | /* Now add each server to the memcache */ |
151 | cache_config = apr_pstrdup(p, sc->cache_config); | 156 | cache_config = apr_pstrdup(p, sc->cache_config); |
152 | split = apr_strtok(cache_config, " ", &tok); | 157 | split = apr_strtok(cache_config, " ", &tok); |
153 | while (split) { | 158 | while (split) { |
154 | apr_memcache_server_t* st; | 159 | apr_memcache_server_t *st; |
155 | char* host_str; | 160 | char *host_str; |
156 | char* scope_id; | 161 | char *scope_id; |
157 | apr_port_t port; | 162 | apr_port_t port; |
158 | 163 | ||
159 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p); | 164 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, |
160 | if (rv != APR_SUCCESS) { | 165 | split, p); |
161 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 166 | if (rv != APR_SUCCESS) { |
162 | "[gnutls_cache] Failed to Parse Server: '%s'", split); | 167 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
163 | return rv; | 168 | "[gnutls_cache] Failed to Parse Server: '%s'", |
164 | } | 169 | split); |
165 | 170 | return rv; | |
166 | if (host_str == NULL) { | 171 | } |
167 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 172 | |
168 | "[gnutls_cache] Failed to Parse Server, " | 173 | if (host_str == NULL) { |
169 | "no hostname specified: '%s'", split); | 174 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
170 | return rv; | 175 | "[gnutls_cache] Failed to Parse Server, " |
171 | } | 176 | "no hostname specified: '%s'", split); |
172 | 177 | return rv; | |
173 | if (port == 0) { | 178 | } |
174 | port = 11211; /* default port */ | 179 | |
175 | } | 180 | if (port == 0) { |
176 | 181 | port = 11211; /* default port */ | |
177 | /* Should Max Conns be (thread_limit / nservers) ? */ | 182 | } |
178 | rv = apr_memcache_server_create(p, | 183 | |
179 | host_str, port, | 184 | /* Should Max Conns be (thread_limit / nservers) ? */ |
180 | 0, | 185 | rv = apr_memcache_server_create(p, |
181 | 1, | 186 | host_str, port, |
182 | thread_limit, | 187 | 0, |
183 | 600, | 188 | 1, thread_limit, 600, &st); |
184 | &st); | 189 | if (rv != APR_SUCCESS) { |
185 | if (rv != APR_SUCCESS) { | 190 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
186 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 191 | "[gnutls_cache] Failed to Create Server: %s:%d", |
187 | "[gnutls_cache] Failed to Create Server: %s:%d", | 192 | host_str, port); |
188 | host_str, port); | 193 | return rv; |
189 | return rv; | 194 | } |
190 | } | 195 | |
191 | 196 | rv = apr_memcache_add_server(mc, st); | |
192 | rv = apr_memcache_add_server(mc, st); | 197 | if (rv != APR_SUCCESS) { |
193 | if (rv != APR_SUCCESS) { | 198 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
194 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 199 | "[gnutls_cache] Failed to Add Server: %s:%d", |
195 | "[gnutls_cache] Failed to Add Server: %s:%d", | 200 | host_str, port); |
196 | host_str, port); | 201 | return rv; |
197 | return rv; | 202 | } |
198 | } | 203 | |
199 | 204 | split = apr_strtok(NULL, " ", &tok); | |
200 | split = apr_strtok(NULL," ", &tok); | 205 | } |
201 | } | 206 | return rv; |
202 | return rv; | ||
203 | } | 207 | } |
204 | 208 | ||
205 | static int mc_cache_store(void* baton, gnutls_datum_t key, | 209 | static int mc_cache_store(void *baton, gnutls_datum_t key, |
206 | gnutls_datum_t data) | 210 | gnutls_datum_t data) |
207 | { | 211 | { |
208 | apr_status_t rv = APR_SUCCESS; | 212 | apr_status_t rv = APR_SUCCESS; |
209 | mgs_handle_t *ctxt = baton; | 213 | mgs_handle_t *ctxt = baton; |
210 | char* strkey = NULL; | 214 | char *strkey = NULL; |
211 | apr_uint32_t timeout; | 215 | apr_uint32_t timeout; |
212 | 216 | ||
213 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 217 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
214 | if(!strkey) | 218 | if (!strkey) |
215 | return -1; | 219 | return -1; |
216 | 220 | ||
217 | timeout = apr_time_sec(ctxt->sc->cache_timeout); | 221 | timeout = apr_time_sec(ctxt->sc->cache_timeout); |
218 | 222 | ||
219 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); | 223 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, |
224 | 0); | ||
220 | 225 | ||
221 | if (rv != APR_SUCCESS) { | 226 | if (rv != APR_SUCCESS) { |
222 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, | 227 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, |
223 | ctxt->c->base_server, | 228 | ctxt->c->base_server, |
224 | "[gnutls_cache] error setting key '%s' " | 229 | "[gnutls_cache] error setting key '%s' " |
225 | "with %d bytes of data", strkey, data.size); | 230 | "with %d bytes of data", strkey, data.size); |
226 | return -1; | 231 | return -1; |
227 | } | 232 | } |
228 | 233 | ||
229 | return 0; | 234 | return 0; |
230 | } | 235 | } |
231 | 236 | ||
232 | static gnutls_datum_t mc_cache_fetch(void* baton, gnutls_datum_t key) | 237 | static gnutls_datum_t mc_cache_fetch(void *baton, gnutls_datum_t key) |
233 | { | 238 | { |
234 | apr_status_t rv = APR_SUCCESS; | 239 | apr_status_t rv = APR_SUCCESS; |
235 | mgs_handle_t *ctxt = baton; | 240 | mgs_handle_t *ctxt = baton; |
236 | char* strkey = NULL; | 241 | char *strkey = NULL; |
237 | char* value; | 242 | char *value; |
238 | apr_size_t value_len; | 243 | apr_size_t value_len; |
239 | gnutls_datum_t data = { NULL, 0 }; | 244 | gnutls_datum_t data = { NULL, 0 }; |
240 | 245 | ||
241 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 246 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
242 | if (!strkey) { | 247 | if (!strkey) { |
243 | return data; | 248 | return data; |
244 | } | 249 | } |
245 | 250 | ||
246 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, | 251 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, |
247 | &value, &value_len, NULL); | 252 | &value, &value_len, NULL); |
248 | 253 | ||
249 | if (rv != APR_SUCCESS) { | 254 | if (rv != APR_SUCCESS) { |
250 | #if MOD_GNUTLS_DEBUG | 255 | #if MOD_GNUTLS_DEBUG |
251 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 256 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
252 | ctxt->c->base_server, | 257 | ctxt->c->base_server, |
253 | "[gnutls_cache] error fetching key '%s' ", | 258 | "[gnutls_cache] error fetching key '%s' ", |
254 | strkey); | 259 | strkey); |
255 | #endif | 260 | #endif |
256 | data.size = 0; | 261 | data.size = 0; |
257 | data.data = NULL; | 262 | data.data = NULL; |
258 | return data; | 263 | return data; |
259 | } | 264 | } |
260 | 265 | ||
261 | /* TODO: Eliminate this memcpy. gnutls-- */ | 266 | /* TODO: Eliminate this memcpy. gnutls-- */ |
262 | data.data = gnutls_malloc(value_len); | 267 | data.data = gnutls_malloc(value_len); |
263 | if (data.data == NULL) | 268 | if (data.data == NULL) |
264 | return data; | 269 | return data; |
265 | 270 | ||
266 | data.size = value_len; | 271 | data.size = value_len; |
267 | memcpy(data.data, value, value_len); | 272 | memcpy(data.data, value, value_len); |
268 | 273 | ||
269 | return data; | 274 | return data; |
270 | } | 275 | } |
271 | 276 | ||
272 | static int mc_cache_delete(void* baton, gnutls_datum_t key) | 277 | static int mc_cache_delete(void *baton, gnutls_datum_t key) |
273 | { | 278 | { |
274 | apr_status_t rv = APR_SUCCESS; | 279 | apr_status_t rv = APR_SUCCESS; |
275 | mgs_handle_t *ctxt = baton; | 280 | mgs_handle_t *ctxt = baton; |
276 | char* strkey = NULL; | 281 | char *strkey = NULL; |
277 | 282 | ||
278 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 283 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
279 | if(!strkey) | 284 | if (!strkey) |
280 | return -1; | 285 | return -1; |
281 | 286 | ||
282 | rv = apr_memcache_delete(mc, strkey, 0); | 287 | rv = apr_memcache_delete(mc, strkey, 0); |
283 | 288 | ||
284 | if (rv != APR_SUCCESS) { | 289 | if (rv != APR_SUCCESS) { |
285 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 290 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
286 | ctxt->c->base_server, | 291 | ctxt->c->base_server, |
287 | "[gnutls_cache] error deleting key '%s' ", | 292 | "[gnutls_cache] error deleting key '%s' ", |
288 | strkey); | 293 | strkey); |
289 | return -1; | 294 | return -1; |
290 | } | 295 | } |
291 | 296 | ||
292 | return 0; | 297 | return 0; |
293 | } | 298 | } |
294 | 299 | ||
295 | #endif /* have_apr_memcache */ | 300 | #endif /* have_apr_memcache */ |
296 | 301 | ||
297 | const char* db_type(mgs_srvconf_rec * sc) | 302 | const char *db_type(mgs_srvconf_rec * sc) |
298 | { | 303 | { |
299 | if (sc->cache_type == mgs_cache_gdbm) | 304 | if (sc->cache_type == mgs_cache_gdbm) |
300 | return "gdbm"; | 305 | return "gdbm"; |
301 | else | 306 | else |
302 | return "db"; | 307 | return "db"; |
303 | } | 308 | } |
304 | 309 | ||
305 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) | 310 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) |
306 | 311 | ||
307 | static void dbm_cache_expire(mgs_handle_t *ctxt) | 312 | static void dbm_cache_expire(mgs_handle_t * ctxt) |
308 | { | 313 | { |
309 | apr_status_t rv; | 314 | apr_status_t rv; |
310 | apr_dbm_t *dbm; | 315 | apr_dbm_t *dbm; |
311 | apr_datum_t dbmkey; | 316 | apr_datum_t dbmkey; |
312 | apr_datum_t dbmval; | 317 | apr_datum_t dbmval; |
313 | apr_time_t now; | 318 | apr_time_t now; |
314 | apr_time_t dtime; | 319 | apr_time_t dtime; |
315 | apr_pool_t* spool; | 320 | apr_pool_t *spool; |
316 | int total, deleted; | 321 | int total, deleted; |
317 | 322 | ||
318 | now = apr_time_now(); | 323 | now = apr_time_now(); |
319 | 324 | ||
320 | if (now - ctxt->sc->last_cache_check < (ctxt->sc->cache_timeout)/2) | 325 | if (now - ctxt->sc->last_cache_check < |
321 | return; | 326 | (ctxt->sc->cache_timeout) / 2) |
322 | 327 | return; | |
323 | ctxt->sc->last_cache_check = now; | 328 | |
324 | 329 | ctxt->sc->last_cache_check = now; | |
325 | apr_pool_create(&spool, ctxt->c->pool); | 330 | |
326 | 331 | apr_pool_create(&spool, ctxt->c->pool); | |
327 | total = 0; | 332 | |
328 | deleted = 0; | 333 | total = 0; |
329 | 334 | deleted = 0; | |
330 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, APR_DBM_RWCREATE, | 335 | |
331 | SSL_DBM_FILE_MODE, spool); | 336 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
332 | if (rv != APR_SUCCESS) { | 337 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
333 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 338 | SSL_DBM_FILE_MODE, spool); |
334 | ctxt->c->base_server, | 339 | if (rv != APR_SUCCESS) { |
335 | "[gnutls_cache] error opening cache searcher '%s'", | 340 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
336 | ctxt->sc->cache_config); | 341 | ctxt->c->base_server, |
337 | apr_pool_destroy(spool); | 342 | "[gnutls_cache] error opening cache searcher '%s'", |
338 | return; | 343 | ctxt->sc->cache_config); |
339 | } | 344 | apr_pool_destroy(spool); |
340 | 345 | return; | |
341 | apr_dbm_firstkey(dbm, &dbmkey); | 346 | } |
342 | while (dbmkey.dptr != NULL) { | 347 | |
343 | apr_dbm_fetch(dbm, dbmkey, &dbmval); | 348 | apr_dbm_firstkey(dbm, &dbmkey); |
344 | if (dbmval.dptr != NULL && dbmval.dsize >= sizeof(apr_time_t)) { | 349 | while (dbmkey.dptr != NULL) { |
345 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); | 350 | apr_dbm_fetch(dbm, dbmkey, &dbmval); |
346 | 351 | if (dbmval.dptr != NULL | |
347 | if (now >= dtime) { | 352 | && dbmval.dsize >= sizeof(apr_time_t)) { |
348 | apr_dbm_delete(dbm, dbmkey); | 353 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); |
349 | deleted++; | 354 | |
350 | } | 355 | if (now >= dtime) { |
351 | apr_dbm_freedatum( dbm, dbmval); | 356 | apr_dbm_delete(dbm, dbmkey); |
352 | } else { | 357 | deleted++; |
353 | apr_dbm_delete(dbm, dbmkey); | 358 | } |
354 | deleted++; | 359 | apr_dbm_freedatum(dbm, dbmval); |
355 | } | 360 | } else { |
356 | total++; | 361 | apr_dbm_delete(dbm, dbmkey); |
357 | apr_dbm_nextkey(dbm, &dbmkey); | 362 | deleted++; |
358 | } | 363 | } |
359 | apr_dbm_close(dbm); | 364 | total++; |
360 | 365 | apr_dbm_nextkey(dbm, &dbmkey); | |
361 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 366 | } |
362 | ctxt->c->base_server, | 367 | apr_dbm_close(dbm); |
363 | "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d", | 368 | |
364 | ctxt->sc->cache_config, deleted, total-deleted); | 369 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
365 | 370 | ctxt->c->base_server, | |
366 | apr_pool_destroy(spool); | 371 | "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d", |
367 | 372 | ctxt->sc->cache_config, deleted, total - deleted); | |
368 | return; | 373 | |
374 | apr_pool_destroy(spool); | ||
375 | |||
376 | return; | ||
369 | } | 377 | } |
370 | 378 | ||
371 | static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | 379 | static gnutls_datum_t dbm_cache_fetch(void *baton, gnutls_datum_t key) |
372 | { | 380 | { |
373 | gnutls_datum_t data = { NULL, 0 }; | 381 | gnutls_datum_t data = { NULL, 0 }; |
374 | apr_dbm_t *dbm; | 382 | apr_dbm_t *dbm; |
375 | apr_datum_t dbmkey; | 383 | apr_datum_t dbmkey; |
376 | apr_datum_t dbmval; | 384 | apr_datum_t dbmval; |
377 | mgs_handle_t *ctxt = baton; | 385 | mgs_handle_t *ctxt = baton; |
378 | apr_status_t rv; | 386 | apr_status_t rv; |
379 | 387 | ||
380 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 388 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
381 | return data; | 389 | return data; |
382 | 390 | ||
383 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 391 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
384 | APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool); | 392 | ctxt->sc->cache_config, APR_DBM_READONLY, |
385 | if (rv != APR_SUCCESS) { | 393 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
386 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 394 | if (rv != APR_SUCCESS) { |
387 | ctxt->c->base_server, | 395 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
388 | "[gnutls_cache] error opening cache '%s'", | 396 | ctxt->c->base_server, |
389 | ctxt->sc->cache_config); | 397 | "[gnutls_cache] error opening cache '%s'", |
390 | return data; | 398 | ctxt->sc->cache_config); |
391 | } | 399 | return data; |
392 | 400 | } | |
393 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | 401 | |
394 | 402 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | |
395 | if (rv != APR_SUCCESS) { | 403 | |
396 | apr_dbm_close(dbm); | 404 | if (rv != APR_SUCCESS) { |
397 | return data; | 405 | apr_dbm_close(dbm); |
398 | } | 406 | return data; |
399 | 407 | } | |
400 | if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) { | 408 | |
401 | apr_dbm_freedatum( dbm, dbmval); | 409 | if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) { |
402 | apr_dbm_close(dbm); | 410 | apr_dbm_freedatum(dbm, dbmval); |
403 | return data; | 411 | apr_dbm_close(dbm); |
404 | } | 412 | return data; |
405 | 413 | } | |
406 | data.size = dbmval.dsize - sizeof(apr_time_t); | 414 | |
407 | 415 | data.size = dbmval.dsize - sizeof(apr_time_t); | |
408 | data.data = gnutls_malloc(data.size); | 416 | |
409 | if (data.data == NULL) { | 417 | data.data = gnutls_malloc(data.size); |
410 | apr_dbm_freedatum( dbm, dbmval); | 418 | if (data.data == NULL) { |
411 | apr_dbm_close(dbm); | 419 | apr_dbm_freedatum(dbm, dbmval); |
412 | return data; | 420 | apr_dbm_close(dbm); |
413 | } | 421 | return data; |
414 | 422 | } | |
415 | memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); | 423 | |
416 | 424 | memcpy(data.data, dbmval.dptr + sizeof(apr_time_t), data.size); | |
417 | apr_dbm_freedatum( dbm, dbmval); | 425 | |
418 | apr_dbm_close(dbm); | 426 | apr_dbm_freedatum(dbm, dbmval); |
419 | 427 | apr_dbm_close(dbm); | |
420 | return data; | 428 | |
429 | return data; | ||
421 | } | 430 | } |
422 | 431 | ||
423 | static int dbm_cache_store(void* baton, gnutls_datum_t key, | 432 | static int dbm_cache_store(void *baton, gnutls_datum_t key, |
424 | gnutls_datum_t data) | 433 | gnutls_datum_t data) |
425 | { | 434 | { |
426 | apr_dbm_t *dbm; | 435 | apr_dbm_t *dbm; |
427 | apr_datum_t dbmkey; | 436 | apr_datum_t dbmkey; |
428 | apr_datum_t dbmval; | 437 | apr_datum_t dbmval; |
429 | mgs_handle_t *ctxt = baton; | 438 | mgs_handle_t *ctxt = baton; |
430 | apr_status_t rv; | 439 | apr_status_t rv; |
431 | apr_time_t expiry; | 440 | apr_time_t expiry; |
432 | apr_pool_t* spool; | 441 | apr_pool_t *spool; |
433 | 442 | ||
434 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 443 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
435 | return -1; | 444 | return -1; |
436 | 445 | ||
437 | /* we expire dbm only on every store | 446 | /* we expire dbm only on every store |
438 | */ | 447 | */ |
439 | dbm_cache_expire(ctxt); | 448 | dbm_cache_expire(ctxt); |
440 | 449 | ||
441 | apr_pool_create(&spool, ctxt->c->pool); | 450 | apr_pool_create(&spool, ctxt->c->pool); |
442 | 451 | ||
443 | /* create DBM value */ | 452 | /* create DBM value */ |
444 | dbmval.dsize = data.size + sizeof(apr_time_t); | 453 | dbmval.dsize = data.size + sizeof(apr_time_t); |
445 | dbmval.dptr = (char *)apr_palloc(spool, dbmval.dsize); | 454 | dbmval.dptr = (char *) apr_palloc(spool, dbmval.dsize); |
446 | 455 | ||
447 | expiry = apr_time_now() + ctxt->sc->cache_timeout; | 456 | expiry = apr_time_now() + ctxt->sc->cache_timeout; |
448 | 457 | ||
449 | memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t)); | 458 | memcpy((char *) dbmval.dptr, &expiry, sizeof(apr_time_t)); |
450 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), | 459 | memcpy((char *) dbmval.dptr + sizeof(apr_time_t), |
451 | data.data, data.size); | 460 | data.data, data.size); |
452 | 461 | ||
453 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 462 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
454 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 463 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
455 | if (rv != APR_SUCCESS) { | 464 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
456 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 465 | if (rv != APR_SUCCESS) { |
457 | ctxt->c->base_server, | 466 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
458 | "[gnutls_cache] error opening cache '%s'", | 467 | ctxt->c->base_server, |
459 | ctxt->sc->cache_config); | 468 | "[gnutls_cache] error opening cache '%s'", |
460 | apr_pool_destroy(spool); | 469 | ctxt->sc->cache_config); |
461 | return -1; | 470 | apr_pool_destroy(spool); |
462 | } | 471 | return -1; |
463 | 472 | } | |
464 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | 473 | |
465 | 474 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | |
466 | if (rv != APR_SUCCESS) { | 475 | |
467 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 476 | if (rv != APR_SUCCESS) { |
468 | ctxt->c->base_server, | 477 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
469 | "[gnutls_cache] error storing in cache '%s'", | 478 | ctxt->c->base_server, |
470 | ctxt->sc->cache_config); | 479 | "[gnutls_cache] error storing in cache '%s'", |
471 | apr_dbm_close(dbm); | 480 | ctxt->sc->cache_config); |
472 | apr_pool_destroy(spool); | 481 | apr_dbm_close(dbm); |
473 | return -1; | 482 | apr_pool_destroy(spool); |
474 | } | 483 | return -1; |
475 | 484 | } | |
476 | apr_dbm_close(dbm); | 485 | |
477 | 486 | apr_dbm_close(dbm); | |
478 | apr_pool_destroy(spool); | 487 | |
479 | 488 | apr_pool_destroy(spool); | |
480 | return 0; | 489 | |
490 | return 0; | ||
481 | } | 491 | } |
482 | 492 | ||
483 | static int dbm_cache_delete(void* baton, gnutls_datum_t key) | 493 | static int dbm_cache_delete(void *baton, gnutls_datum_t key) |
484 | { | 494 | { |
485 | apr_dbm_t *dbm; | 495 | apr_dbm_t *dbm; |
486 | apr_datum_t dbmkey; | 496 | apr_datum_t dbmkey; |
487 | mgs_handle_t *ctxt = baton; | 497 | mgs_handle_t *ctxt = baton; |
488 | apr_status_t rv; | 498 | apr_status_t rv; |
489 | 499 | ||
490 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 500 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
491 | return -1; | 501 | return -1; |
492 | 502 | ||
493 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 503 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
494 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 504 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
495 | if (rv != APR_SUCCESS) { | 505 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
496 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 506 | if (rv != APR_SUCCESS) { |
497 | ctxt->c->base_server, | 507 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
498 | "[gnutls_cache] error opening cache '%s'", | 508 | ctxt->c->base_server, |
499 | ctxt->sc->cache_config); | 509 | "[gnutls_cache] error opening cache '%s'", |
500 | return -1; | 510 | ctxt->sc->cache_config); |
501 | } | 511 | return -1; |
502 | 512 | } | |
503 | rv = apr_dbm_delete(dbm, dbmkey); | 513 | |
504 | 514 | rv = apr_dbm_delete(dbm, dbmkey); | |
505 | if (rv != APR_SUCCESS) { | 515 | |
506 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 516 | if (rv != APR_SUCCESS) { |
507 | ctxt->c->base_server, | 517 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
508 | "[gnutls_cache] error deleting from cache '%s'", | 518 | ctxt->c->base_server, |
509 | ctxt->sc->cache_config); | 519 | "[gnutls_cache] error deleting from cache '%s'", |
510 | apr_dbm_close(dbm); | 520 | ctxt->sc->cache_config); |
511 | return -1; | 521 | apr_dbm_close(dbm); |
512 | } | 522 | return -1; |
513 | 523 | } | |
514 | apr_dbm_close(dbm); | 524 | |
515 | 525 | apr_dbm_close(dbm); | |
516 | return 0; | 526 | |
527 | return 0; | ||
517 | } | 528 | } |
518 | 529 | ||
519 | static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, | 530 | static int dbm_cache_post_config(apr_pool_t * p, server_rec * s, |
520 | mgs_srvconf_rec *sc) | 531 | mgs_srvconf_rec * sc) |
521 | { | 532 | { |
522 | apr_status_t rv; | 533 | apr_status_t rv; |
523 | apr_dbm_t *dbm; | 534 | apr_dbm_t *dbm; |
524 | const char* path1; | 535 | const char *path1; |
525 | const char* path2; | 536 | const char *path2; |
526 | 537 | ||
527 | rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config, APR_DBM_RWCREATE, | 538 | rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config, |
528 | SSL_DBM_FILE_MODE, p); | 539 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p); |
529 | 540 | ||
530 | if (rv != APR_SUCCESS) { | 541 | if (rv != APR_SUCCESS) { |
531 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, | 542 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, |
532 | "GnuTLS: Cannot create DBM Cache at `%s'", | 543 | "GnuTLS: Cannot create DBM Cache at `%s'", |
533 | sc->cache_config); | 544 | sc->cache_config); |
534 | return rv; | 545 | return rv; |
535 | } | 546 | } |
536 | 547 | ||
537 | apr_dbm_close(dbm); | 548 | apr_dbm_close(dbm); |
538 | 549 | ||
539 | apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1, &path2); | 550 | apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1, |
551 | &path2); | ||
540 | 552 | ||
541 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ | 553 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ |
542 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) | 554 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) |
543 | /* Running as Root */ | 555 | /* Running as Root */ |
544 | if (path1 && geteuid() == 0) { | 556 | if (path1 && geteuid() == 0) { |
545 | chown(path1, ap_unixd_config.user_id, -1); | 557 | chown(path1, ap_unixd_config.user_id, -1); |
546 | if (path2 != NULL) { | 558 | if (path2 != NULL) { |
547 | chown(path2, ap_unixd_config.user_id, -1); | 559 | chown(path2, ap_unixd_config.user_id, -1); |
548 | } | 560 | } |
549 | } | 561 | } |
550 | #endif | 562 | #endif |
551 | 563 | ||
552 | return rv; | 564 | return rv; |
553 | } | 565 | } |
554 | 566 | ||
555 | int mgs_cache_post_config(apr_pool_t *p, server_rec *s, | 567 | int mgs_cache_post_config(apr_pool_t * p, server_rec * s, |
556 | mgs_srvconf_rec *sc) | 568 | mgs_srvconf_rec * sc) |
557 | { | 569 | { |
558 | if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { | 570 | if (sc->cache_type == mgs_cache_dbm |
559 | return dbm_cache_post_config(p, s, sc); | 571 | || sc->cache_type == mgs_cache_gdbm) { |
560 | } | 572 | return dbm_cache_post_config(p, s, sc); |
561 | return 0; | 573 | } |
574 | return 0; | ||
562 | } | 575 | } |
563 | 576 | ||
564 | int mgs_cache_child_init(apr_pool_t *p, server_rec *s, | 577 | int mgs_cache_child_init(apr_pool_t * p, server_rec * s, |
565 | mgs_srvconf_rec *sc) | 578 | mgs_srvconf_rec * sc) |
566 | { | 579 | { |
567 | if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { | 580 | if (sc->cache_type == mgs_cache_dbm |
568 | return 0; | 581 | || sc->cache_type == mgs_cache_gdbm) { |
569 | } | 582 | return 0; |
583 | } | ||
570 | #if HAVE_APR_MEMCACHE | 584 | #if HAVE_APR_MEMCACHE |
571 | else if (sc->cache_type == mgs_cache_memcache) { | 585 | else if (sc->cache_type == mgs_cache_memcache) { |
572 | return mc_cache_child_init(p, s, sc); | 586 | return mc_cache_child_init(p, s, sc); |
573 | } | 587 | } |
574 | #endif | 588 | #endif |
575 | return 0; | 589 | return 0; |
576 | } | 590 | } |
577 | 591 | ||
578 | #include <assert.h> | 592 | #include <assert.h> |
579 | 593 | ||
580 | int mgs_cache_session_init(mgs_handle_t *ctxt) | 594 | int mgs_cache_session_init(mgs_handle_t * ctxt) |
581 | { | 595 | { |
582 | if (ctxt->sc->cache_type == mgs_cache_dbm || ctxt->sc->cache_type == mgs_cache_gdbm) { | 596 | if (ctxt->sc->cache_type == mgs_cache_dbm |
583 | gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); | 597 | || ctxt->sc->cache_type == mgs_cache_gdbm) { |
584 | gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); | 598 | gnutls_db_set_retrieve_function(ctxt->session, |
585 | gnutls_db_set_store_function(ctxt->session, dbm_cache_store); | 599 | dbm_cache_fetch); |
586 | gnutls_db_set_ptr(ctxt->session, ctxt); | 600 | gnutls_db_set_remove_function(ctxt->session, |
587 | } | 601 | dbm_cache_delete); |
602 | gnutls_db_set_store_function(ctxt->session, | ||
603 | dbm_cache_store); | ||
604 | gnutls_db_set_ptr(ctxt->session, ctxt); | ||
605 | } | ||
588 | #if HAVE_APR_MEMCACHE | 606 | #if HAVE_APR_MEMCACHE |
589 | else if (ctxt->sc->cache_type == mgs_cache_memcache) { | 607 | else if (ctxt->sc->cache_type == mgs_cache_memcache) { |
590 | gnutls_db_set_retrieve_function(ctxt->session, mc_cache_fetch); | 608 | gnutls_db_set_retrieve_function(ctxt->session, |
591 | gnutls_db_set_remove_function(ctxt->session, mc_cache_delete); | 609 | mc_cache_fetch); |
592 | gnutls_db_set_store_function(ctxt->session, mc_cache_store); | 610 | gnutls_db_set_remove_function(ctxt->session, |
593 | gnutls_db_set_ptr(ctxt->session, ctxt); | 611 | mc_cache_delete); |
594 | } | 612 | gnutls_db_set_store_function(ctxt->session, |
613 | mc_cache_store); | ||
614 | gnutls_db_set_ptr(ctxt->session, ctxt); | ||
615 | } | ||
595 | #endif | 616 | #endif |
596 | 617 | ||
597 | return 0; | 618 | return 0; |
598 | } | 619 | } |