summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-10-25 19:21:04 (GMT)
committer Nikos Mavrogiannopoulos <nmav@gnutls.org>2010-10-25 19:21:04 (GMT)
commite02dd8c03ce5b66c81a47830eebe73a21ce71002 (patch)
tree6b35cc9815eb90b4cf9d97d7f981aff764eeb0ea
parent62def2f82df4b35b03843063364533bd36646ee0 (diff)
indented code
-rw-r--r--src/gnutls_cache.c925
-rw-r--r--src/gnutls_config.c1039
-rw-r--r--src/gnutls_hooks.c1944
-rw-r--r--src/gnutls_io.c1367
-rw-r--r--src/gnutls_lua.c465
-rw-r--r--src/mod_gnutls.c253
6 files changed, 3101 insertions, 2892 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
46char *mgs_session_id2sz(unsigned char *id, int idlen, 46char *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 */
66static int mgs_session_id2dbm(conn_rec* c, unsigned char *id, int idlen, 66static int mgs_session_id2dbm(conn_rec * c, unsigned char *id, int idlen,
67 apr_datum_t* dbmkey) 67 apr_datum_t * dbmkey)
68{ 68{
69char buf[STR_SESSION_LEN]; 69 char buf[STR_SESSION_LEN];
70char *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"
83char *mgs_time2sz(time_t in_time, char *str, int strsize) 86char *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 */
102static char* mgs_session_id2mc(conn_rec* c, unsigned char *id, int idlen) 105static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen)
103{ 106{
104char buf[STR_SESSION_LEN]; 107 char buf[STR_SESSION_LEN];
105char *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 */
120static apr_memcache_t* mc; 125static apr_memcache_t *mc;
121 126
122static int mc_cache_child_init(apr_pool_t *p, server_rec *s, 127static 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
205static int mc_cache_store(void* baton, gnutls_datum_t key, 209static 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
232static gnutls_datum_t mc_cache_fetch(void* baton, gnutls_datum_t key) 237static 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
272static int mc_cache_delete(void* baton, gnutls_datum_t key) 277static 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
297const char* db_type(mgs_srvconf_rec * sc) 302const 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
307static void dbm_cache_expire(mgs_handle_t *ctxt) 312static 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
371static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) 379static 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
423static int dbm_cache_store(void* baton, gnutls_datum_t key, 432static 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
483static int dbm_cache_delete(void* baton, gnutls_datum_t key) 493static 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
519static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, 530static 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
555int mgs_cache_post_config(apr_pool_t *p, server_rec *s, 567int 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
564int mgs_cache_child_init(apr_pool_t *p, server_rec *s, 577int 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
580int mgs_cache_session_init(mgs_handle_t *ctxt) 594int 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}
diff --git a/src/gnutls_config.c b/src/gnutls_config.c
index ff8ec33..fc3e166 100644
--- a/src/gnutls_config.c
+++ b/src/gnutls_config.c
@@ -21,284 +21,308 @@
21static int load_datum_from_file(apr_pool_t * pool, 21static int load_datum_from_file(apr_pool_t * pool,
22 const char *file, gnutls_datum_t * data) 22 const char *file, gnutls_datum_t * data)
23{ 23{
24 apr_file_t *fp; 24 apr_file_t *fp;
25 apr_finfo_t finfo; 25 apr_finfo_t finfo;
26 apr_status_t rv; 26 apr_status_t rv;
27 apr_size_t br = 0; 27 apr_size_t br = 0;
28 28
29 rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT, 29 rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
30 pool); 30 APR_OS_DEFAULT, pool);
31 if (rv != APR_SUCCESS) { 31 if (rv != APR_SUCCESS) {
32 return rv; 32 return rv;
33 } 33 }
34 34
35 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); 35 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
36 36
37 if (rv != APR_SUCCESS) { 37 if (rv != APR_SUCCESS) {
38 return rv; 38 return rv;
39 } 39 }
40 40
41 data->data = apr_palloc(pool, finfo.size + 1); 41 data->data = apr_palloc(pool, finfo.size + 1);
42 rv = apr_file_read_full(fp, data->data, finfo.size, &br); 42 rv = apr_file_read_full(fp, data->data, finfo.size, &br);
43 43
44 if (rv != APR_SUCCESS) { 44 if (rv != APR_SUCCESS) {
45 return rv; 45 return rv;
46 } 46 }
47 apr_file_close(fp); 47 apr_file_close(fp);
48 48
49 data->data[br] = '\0'; 49 data->data[br] = '\0';
50 data->size = br; 50 data->size = br;
51 51
52 return 0; 52 return 0;
53} 53}
54 54
55const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, 55const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
56 const char *arg) 56 const char *arg)
57{ 57{
58 int ret; 58 int ret;
59 gnutls_datum_t data; 59 gnutls_datum_t data;
60 const char *file; 60 const char *file;
61 apr_pool_t *spool; 61 apr_pool_t *spool;
62 mgs_srvconf_rec *sc = 62 mgs_srvconf_rec *sc =
63 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 63 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
64 module_config, 64 module_config,
65 &gnutls_module); 65 &gnutls_module);
66 66
67 apr_pool_create(&spool, parms->pool); 67 apr_pool_create(&spool, parms->pool);
68 68
69 file = ap_server_root_relative(spool, arg); 69 file = ap_server_root_relative(spool, arg);
70 70
71 if (load_datum_from_file(spool, file, &data) != 0) { 71 if (load_datum_from_file(spool, file, &data) != 0) {
72 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 72 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
73 "DH params '%s'", file); 73 "DH params '%s'", file);
74 } 74 }
75 75
76 ret = gnutls_dh_params_init(&sc->dh_params); 76 ret = gnutls_dh_params_init(&sc->dh_params);
77 if (ret < 0) { 77 if (ret < 0) {
78 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" 78 return apr_psprintf(parms->pool,
79 ": (%d) %s", ret, gnutls_strerror(ret)); 79 "GnuTLS: Failed to initialize"
80 } 80 ": (%d) %s", ret,
81 81 gnutls_strerror(ret));
82 ret = 82 }
83 gnutls_dh_params_import_pkcs3(sc->dh_params, &data, GNUTLS_X509_FMT_PEM); 83
84 if (ret < 0) { 84 ret =
85 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 85 gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
86 "DH params '%s': (%d) %s", file, ret, 86 GNUTLS_X509_FMT_PEM);
87 gnutls_strerror(ret)); 87 if (ret < 0) {
88 } 88 return apr_psprintf(parms->pool,
89 89 "GnuTLS: Failed to Import "
90 apr_pool_destroy(spool); 90 "DH params '%s': (%d) %s", file, ret,
91 91 gnutls_strerror(ret));
92 return NULL; 92 }
93
94 apr_pool_destroy(spool);
95
96 return NULL;
93} 97}
94 98
95const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy, 99const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
96 const char *arg) 100 const char *arg)
97{ 101{
98 int ret; 102 int ret;
99 gnutls_datum_t data; 103 gnutls_datum_t data;
100 const char *file; 104 const char *file;
101 apr_pool_t *spool; 105 apr_pool_t *spool;
102 mgs_srvconf_rec *sc = 106 mgs_srvconf_rec *sc =
103 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 107 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
104 module_config, 108 module_config,
105 &gnutls_module); 109 &gnutls_module);
106 110
107 apr_pool_create(&spool, parms->pool); 111 apr_pool_create(&spool, parms->pool);
108 112
109 file = ap_server_root_relative(spool, arg); 113 file = ap_server_root_relative(spool, arg);
110 114
111 if (load_datum_from_file(spool, file, &data) != 0) { 115 if (load_datum_from_file(spool, file, &data) != 0) {
112 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 116 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
113 "RSA params '%s'", file); 117 "RSA params '%s'", file);
114 } 118 }
115 119
116 ret = gnutls_rsa_params_init(&sc->rsa_params); 120 ret = gnutls_rsa_params_init(&sc->rsa_params);
117 if (ret < 0) { 121 if (ret < 0) {
118 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" 122 return apr_psprintf(parms->pool,
119 ": (%d) %s", ret, gnutls_strerror(ret)); 123 "GnuTLS: Failed to initialize"
120 } 124 ": (%d) %s", ret,
121 125 gnutls_strerror(ret));
122 ret = 126 }
123 gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data, GNUTLS_X509_FMT_PEM); 127
124 if (ret != 0) { 128 ret =
125 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 129 gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data,
126 "RSA params '%s': (%d) %s", file, ret, 130 GNUTLS_X509_FMT_PEM);
127 gnutls_strerror(ret)); 131 if (ret != 0) {
128 } 132 return apr_psprintf(parms->pool,
129 133 "GnuTLS: Failed to Import "
130 apr_pool_destroy(spool); 134 "RSA params '%s': (%d) %s", file, ret,
131 return NULL; 135 gnutls_strerror(ret));
136 }
137
138 apr_pool_destroy(spool);
139 return NULL;
132} 140}
133 141
134 142
135const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, 143const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
136 const char *arg) 144 const char *arg)
137{ 145{
138 int ret; 146 int ret;
139 gnutls_datum_t data; 147 gnutls_datum_t data;
140 const char *file; 148 const char *file;
141 apr_pool_t *spool; 149 apr_pool_t *spool;
142 mgs_srvconf_rec *sc = 150 mgs_srvconf_rec *sc =
143 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 151 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
144 module_config, 152 module_config,
145 &gnutls_module); 153 &gnutls_module);
146 apr_pool_create(&spool, parms->pool); 154 apr_pool_create(&spool, parms->pool);
147 155
148 file = ap_server_root_relative(spool, arg); 156 file = ap_server_root_relative(spool, arg);
149 157
150 if (load_datum_from_file(spool, file, &data) != 0) { 158 if (load_datum_from_file(spool, file, &data) != 0) {
151 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 159 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
152 "Certificate '%s'", file); 160 "Certificate '%s'", file);
153 } 161 }
154 162
155 sc->certs_x509_num = MAX_CHAIN_SIZE; 163 sc->certs_x509_num = MAX_CHAIN_SIZE;
156 ret = 164 ret =
157 gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0); 165 gnutls_x509_crt_list_import(sc->certs_x509,
158 if (ret < 0) { 166 &sc->certs_x509_num, &data,
159 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 167 GNUTLS_X509_FMT_PEM, 0);
160 "Certificate '%s': (%d) %s", file, ret, 168 if (ret < 0) {
161 gnutls_strerror(ret)); 169 return apr_psprintf(parms->pool,
162 } 170 "GnuTLS: Failed to Import "
163 171 "Certificate '%s': (%d) %s", file, ret,
164 apr_pool_destroy(spool); 172 gnutls_strerror(ret));
165 return NULL; 173 }
174
175 apr_pool_destroy(spool);
176 return NULL;
166} 177}
167 178
168const char *mgs_set_key_file(cmd_parms * parms, void *dummy, 179const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
169 const char *arg) 180 const char *arg)
170{ 181{
171 int ret; 182 int ret;
172 gnutls_datum_t data; 183 gnutls_datum_t data;
173 const char *file; 184 const char *file;
174 apr_pool_t *spool; 185 apr_pool_t *spool;
175 mgs_srvconf_rec *sc = 186 mgs_srvconf_rec *sc =
176 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 187 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
177 module_config, 188 module_config,
178 &gnutls_module); 189 &gnutls_module);
179 apr_pool_create(&spool, parms->pool); 190 apr_pool_create(&spool, parms->pool);
180 191
181 file = ap_server_root_relative(spool, arg); 192 file = ap_server_root_relative(spool, arg);
182 193
183 if (load_datum_from_file(spool, file, &data) != 0) { 194 if (load_datum_from_file(spool, file, &data) != 0) {
184 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 195 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
185 "Private Key '%s'", file); 196 "Private Key '%s'", file);
186 } 197 }
187 198
188 ret = gnutls_x509_privkey_init(&sc->privkey_x509); 199 ret = gnutls_x509_privkey_init(&sc->privkey_x509);
189 if (ret < 0) { 200 if (ret < 0) {
190 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" 201 return apr_psprintf(parms->pool,
191 ": (%d) %s", ret, gnutls_strerror(ret)); 202 "GnuTLS: Failed to initialize"
192 } 203 ": (%d) %s", ret,
193 204 gnutls_strerror(ret));
194 ret = 205 }
195 gnutls_x509_privkey_import(sc->privkey_x509, &data, 206
196 GNUTLS_X509_FMT_PEM); 207 ret =
197 208 gnutls_x509_privkey_import(sc->privkey_x509, &data,
198 if (ret < 0) 209 GNUTLS_X509_FMT_PEM);
199 ret = gnutls_x509_privkey_import_pkcs8 (sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, 210
200 NULL, GNUTLS_PKCS_PLAIN); 211 if (ret < 0)
201 212 ret =
202 if (ret < 0) { 213 gnutls_x509_privkey_import_pkcs8(sc->privkey_x509,
203 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 214 &data,
204 "Private Key '%s': (%d) %s", file, ret, 215 GNUTLS_X509_FMT_PEM,
205 gnutls_strerror(ret)); 216 NULL,
206 } 217 GNUTLS_PKCS_PLAIN);
207 apr_pool_destroy(spool); 218
208 return NULL; 219 if (ret < 0) {
220 return apr_psprintf(parms->pool,
221 "GnuTLS: Failed to Import "
222 "Private Key '%s': (%d) %s", file, ret,
223 gnutls_strerror(ret));
224 }
225 apr_pool_destroy(spool);
226 return NULL;
209} 227}
210 228
211const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy, 229const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
212 const char *arg) 230 const char *arg)
213{ 231{
214 int ret; 232 int ret;
215 gnutls_datum_t data; 233 gnutls_datum_t data;
216 const char *file; 234 const char *file;
217 apr_pool_t *spool; 235 apr_pool_t *spool;
218 mgs_srvconf_rec *sc = 236 mgs_srvconf_rec *sc =
219 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 237 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
220 module_config, 238 module_config,
221 &gnutls_module); 239 &gnutls_module);
222 apr_pool_create(&spool, parms->pool); 240 apr_pool_create(&spool, parms->pool);
223 241
224 file = ap_server_root_relative(spool, arg); 242 file = ap_server_root_relative(spool, arg);
225 243
226 if (load_datum_from_file(spool, file, &data) != 0) { 244 if (load_datum_from_file(spool, file, &data) != 0) {
227 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 245 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
228 "Certificate '%s'", file); 246 "Certificate '%s'", file);
229 } 247 }
230 248
231 ret = gnutls_openpgp_crt_init( &sc->cert_pgp); 249 ret = gnutls_openpgp_crt_init(&sc->cert_pgp);
232 if (ret < 0) { 250 if (ret < 0) {
233 return apr_psprintf(parms->pool, "GnuTLS: Failed to Init " 251 return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
234 "PGP Certificate: (%d) %s", ret, 252 "PGP Certificate: (%d) %s", ret,
235 gnutls_strerror(ret)); 253 gnutls_strerror(ret));
236 } 254 }
237 255
238 ret = 256 ret =
239 gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64); 257 gnutls_openpgp_crt_import(sc->cert_pgp, &data,
240 if (ret < 0) { 258 GNUTLS_OPENPGP_FMT_BASE64);
241 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 259 if (ret < 0) {
242 "PGP Certificate '%s': (%d) %s", file, ret, 260 return apr_psprintf(parms->pool,
243 gnutls_strerror(ret)); 261 "GnuTLS: Failed to Import "
244 } 262 "PGP Certificate '%s': (%d) %s", file,
245 263 ret, gnutls_strerror(ret));
246 apr_pool_destroy(spool); 264 }
247 return NULL; 265
266 apr_pool_destroy(spool);
267 return NULL;
248} 268}
249 269
250const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy, 270const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
251 const char *arg) 271 const char *arg)
252{ 272{
253 int ret; 273 int ret;
254 gnutls_datum_t data; 274 gnutls_datum_t data;
255 const char *file; 275 const char *file;
256 apr_pool_t *spool; 276 apr_pool_t *spool;
257 mgs_srvconf_rec *sc = 277 mgs_srvconf_rec *sc =
258 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 278 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
259 module_config, 279 module_config,
260 &gnutls_module); 280 &gnutls_module);
261 apr_pool_create(&spool, parms->pool); 281 apr_pool_create(&spool, parms->pool);
262 282
263 file = ap_server_root_relative(spool, arg); 283 file = ap_server_root_relative(spool, arg);
264 284
265 if (load_datum_from_file(spool, file, &data) != 0) { 285 if (load_datum_from_file(spool, file, &data) != 0) {
266 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 286 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
267 "Private Key '%s'", file); 287 "Private Key '%s'", file);
268 } 288 }
269 289
270 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp); 290 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
271 if (ret < 0) { 291 if (ret < 0) {
272 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" 292 return apr_psprintf(parms->pool,
273 ": (%d) %s", ret, gnutls_strerror(ret)); 293 "GnuTLS: Failed to initialize"
274 } 294 ": (%d) %s", ret,
275 295 gnutls_strerror(ret));
276 ret = 296 }
277 gnutls_openpgp_privkey_import(sc->privkey_pgp, &data, 297
278 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); 298 ret =
279 if (ret != 0) { 299 gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
280 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 300 GNUTLS_OPENPGP_FMT_BASE64, NULL,
281 "PGP Private Key '%s': (%d) %s", file, ret, 301 0);
282 gnutls_strerror(ret)); 302 if (ret != 0) {
283 } 303 return apr_psprintf(parms->pool,
284 apr_pool_destroy(spool); 304 "GnuTLS: Failed to Import "
285 return NULL; 305 "PGP Private Key '%s': (%d) %s", file,
306 ret, gnutls_strerror(ret));
307 }
308 apr_pool_destroy(spool);
309 return NULL;
286} 310}
287 311
288const char *mgs_set_tickets(cmd_parms * parms, void *dummy, 312const char *mgs_set_tickets(cmd_parms * parms, void *dummy,
289 const char *arg) 313 const char *arg)
290{ 314{
291 mgs_srvconf_rec *sc = 315 mgs_srvconf_rec *sc =
292 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 316 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
293 module_config, 317 module_config,
294 &gnutls_module); 318 &gnutls_module);
295 319
296 sc->tickets = 0; 320 sc->tickets = 0;
297 if (strcasecmp("on", arg) == 0) { 321 if (strcasecmp("on", arg) == 0) {
298 sc->tickets = 1; 322 sc->tickets = 1;
299 } 323 }
300 324
301 return NULL; 325 return NULL;
302} 326}
303 327
304 328
@@ -307,27 +331,28 @@ const char *mgs_set_tickets(cmd_parms * parms, void *dummy,
307const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy, 331const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
308 const char *arg) 332 const char *arg)
309{ 333{
310 mgs_srvconf_rec *sc = 334 mgs_srvconf_rec *sc =
311 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 335 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
312 module_config, 336 module_config,
313 &gnutls_module); 337 &gnutls_module);
314 338
315 sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg); 339 sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
316 340
317 return NULL; 341 return NULL;
318} 342}
319 343
320const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy, 344const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
321 const char *arg) 345 const char *arg)
322{ 346{
323 mgs_srvconf_rec *sc = 347 mgs_srvconf_rec *sc =
324 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 348 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
325 module_config, 349 module_config,
326 &gnutls_module); 350 &gnutls_module);
327 351
328 sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg); 352 sc->srp_tpasswd_conf_file =
353 ap_server_root_relative(parms->pool, arg);
329 354
330 return NULL; 355 return NULL;
331} 356}
332 357
333#endif 358#endif
@@ -335,308 +360,326 @@ const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
335const char *mgs_set_cache(cmd_parms * parms, void *dummy, 360const char *mgs_set_cache(cmd_parms * parms, void *dummy,
336 const char *type, const char *arg) 361 const char *type, const char *arg)
337{ 362{
338 const char *err; 363 const char *err;
339 mgs_srvconf_rec *sc = ap_get_module_config(parms->server-> 364 mgs_srvconf_rec *sc =
340 module_config, 365 ap_get_module_config(parms->server->module_config,
341 &gnutls_module); 366 &gnutls_module);
342 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { 367 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
343 return err; 368 return err;
344 } 369 }
345 370
346 if (strcasecmp("none", type) == 0) { 371 if (strcasecmp("none", type) == 0) {
347 sc->cache_type = mgs_cache_none; 372 sc->cache_type = mgs_cache_none;
348 } else if (strcasecmp("dbm", type) == 0) { 373 } else if (strcasecmp("dbm", type) == 0) {
349 sc->cache_type = mgs_cache_dbm; 374 sc->cache_type = mgs_cache_dbm;
350 } 375 } else if (strcasecmp("gdbm", type) == 0) {
351 else if (strcasecmp("gdbm", type) == 0) { 376 sc->cache_type = mgs_cache_gdbm;
352 sc->cache_type = mgs_cache_gdbm; 377 }
353 }
354#if HAVE_APR_MEMCACHE 378#if HAVE_APR_MEMCACHE
355 else if (strcasecmp("memcache", type) == 0) { 379 else if (strcasecmp("memcache", type) == 0) {
356 sc->cache_type = mgs_cache_memcache; 380 sc->cache_type = mgs_cache_memcache;
357 } 381 }
358#endif 382#endif
359 else { 383 else {
360 return "Invalid Type for GnuTLSCache!"; 384 return "Invalid Type for GnuTLSCache!";
361 } 385 }
362 386
363 if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { 387 if (sc->cache_type == mgs_cache_dbm
364 sc->cache_config = ap_server_root_relative(parms->pool, arg); 388 || sc->cache_type == mgs_cache_gdbm) {
365 } else { 389 sc->cache_config =
366 sc->cache_config = apr_pstrdup(parms->pool, arg); 390 ap_server_root_relative(parms->pool, arg);
367 } 391 } else {
368 392 sc->cache_config = apr_pstrdup(parms->pool, arg);
369 return NULL; 393 }
394
395 return NULL;
370} 396}
371 397
372const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy, 398const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
373 const char *arg) 399 const char *arg)
374{ 400{
375 int argint; 401 int argint;
376 mgs_srvconf_rec *sc =
377 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
378 module_config,
379 &gnutls_module);
380
381 argint = atoi(arg);
382
383 if (argint < 0) {
384 return "GnuTLSCacheTimeout: Invalid argument";
385 } else if (argint == 0) {
386 sc->cache_timeout = 0;
387 } else {
388 sc->cache_timeout = apr_time_from_sec(argint);
389 }
390
391 return NULL;
392}
393
394const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
395 const char *arg)
396{
397 int mode;
398
399 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
400 mode = GNUTLS_CERT_IGNORE;
401 } else if (strcasecmp("optional", arg) == 0
402 || strcasecmp("request", arg) == 0) {
403 mode = GNUTLS_CERT_REQUEST;
404 } else if (strcasecmp("require", arg) == 0) {
405 mode = GNUTLS_CERT_REQUIRE;
406 } else {
407 return "GnuTLSClientVerify: Invalid argument";
408 }
409
410 /* This was set from a directory context */
411 if (parms->path) {
412 mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
413 dc->client_verify_mode = mode;
414 } else {
415 mgs_srvconf_rec *sc = 402 mgs_srvconf_rec *sc =
416 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 403 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
417 module_config, 404 module_config,
418 &gnutls_module); 405 &gnutls_module);
419 sc->client_verify_mode = mode;
420 }
421 406
422 return NULL; 407 argint = atoi(arg);
408
409 if (argint < 0) {
410 return "GnuTLSCacheTimeout: Invalid argument";
411 } else if (argint == 0) {
412 sc->cache_timeout = 0;
413 } else {
414 sc->cache_timeout = apr_time_from_sec(argint);
415 }
416
417 return NULL;
418}
419
420const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
421 const char *arg)
422{
423 int mode;
424
425 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
426 mode = GNUTLS_CERT_IGNORE;
427 } else if (strcasecmp("optional", arg) == 0
428 || strcasecmp("request", arg) == 0) {
429 mode = GNUTLS_CERT_REQUEST;
430 } else if (strcasecmp("require", arg) == 0) {
431 mode = GNUTLS_CERT_REQUIRE;
432 } else {
433 return "GnuTLSClientVerify: Invalid argument";
434 }
435
436 /* This was set from a directory context */
437 if (parms->path) {
438 mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
439 dc->client_verify_mode = mode;
440 } else {
441 mgs_srvconf_rec *sc =
442 (mgs_srvconf_rec *)
443 ap_get_module_config(parms->server->module_config,
444 &gnutls_module);
445 sc->client_verify_mode = mode;
446 }
447
448 return NULL;
423} 449}
424 450
425#define INIT_CA_SIZE 128 451#define INIT_CA_SIZE 128
426const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, 452const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
427 const char *arg) 453 const char *arg)
428{ 454{
429 int rv; 455 int rv;
430 const char *file; 456 const char *file;
431 apr_pool_t *spool; 457 apr_pool_t *spool;
432 gnutls_datum_t data; 458 gnutls_datum_t data;
433 459
434 mgs_srvconf_rec *sc = 460 mgs_srvconf_rec *sc =
435 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 461 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
436 module_config, 462 module_config,
437 &gnutls_module); 463 &gnutls_module);
438 apr_pool_create(&spool, parms->pool); 464 apr_pool_create(&spool, parms->pool);
439 465
440 file = ap_server_root_relative(spool, arg); 466 file = ap_server_root_relative(spool, arg);
441 467
442 if (load_datum_from_file(spool, file, &data) != 0) { 468 if (load_datum_from_file(spool, file, &data) != 0) {
443 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 469 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
444 "Client CA File '%s'", file); 470 "Client CA File '%s'", file);
445 } 471 }
446 472
447 sc->ca_list_size = INIT_CA_SIZE; 473 sc->ca_list_size = INIT_CA_SIZE;
448 sc->ca_list = malloc(sc->ca_list_size * sizeof(*sc->ca_list)); 474 sc->ca_list = malloc(sc->ca_list_size * sizeof(*sc->ca_list));
449 if (sc->ca_list == NULL) { 475 if (sc->ca_list == NULL) {
450 return apr_psprintf(parms->pool, "mod_gnutls: Memory allocation error"); 476 return apr_psprintf(parms->pool,
451 } 477 "mod_gnutls: Memory allocation error");
452 478 }
453 rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, 479
454 &data, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); 480 rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
455 if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) { 481 &data, GNUTLS_X509_FMT_PEM,
456 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 482 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
457 "Client CA File '%s': (%d) %s", file, rv, 483 if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) {
458 gnutls_strerror(rv)); 484 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
459 } 485 "Client CA File '%s': (%d) %s", file,
460 486 rv, gnutls_strerror(rv));
461 if (INIT_CA_SIZE < sc->ca_list_size) { 487 }
462 sc->ca_list = realloc(sc->ca_list, sc->ca_list_size*sizeof(*sc->ca_list)); 488
463 if (sc->ca_list == NULL) { 489 if (INIT_CA_SIZE < sc->ca_list_size) {
464 return apr_psprintf(parms->pool, "mod_gnutls: Memory allocation error"); 490 sc->ca_list =
465 } 491 realloc(sc->ca_list,
466 492 sc->ca_list_size * sizeof(*sc->ca_list));
467 /* re-read */ 493 if (sc->ca_list == NULL) {
468 rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, 494 return apr_psprintf(parms->pool,
469 &data, GNUTLS_X509_FMT_PEM, 0); 495 "mod_gnutls: Memory allocation error");
470 496 }
471 if (rv < 0) { 497
472 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 498 /* re-read */
473 "Client CA File '%s': (%d) %s", file, rv, 499 rv = gnutls_x509_crt_list_import(sc->ca_list,
474 gnutls_strerror(rv)); 500 &sc->ca_list_size, &data,
475 } 501 GNUTLS_X509_FMT_PEM, 0);
476 } 502
477 503 if (rv < 0) {
478 apr_pool_destroy(spool); 504 return apr_psprintf(parms->pool,
479 return NULL; 505 "GnuTLS: Failed to load "
506 "Client CA File '%s': (%d) %s",
507 file, rv, gnutls_strerror(rv));
508 }
509 }
510
511 apr_pool_destroy(spool);
512 return NULL;
480} 513}
481 514
482const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, 515const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
483 const char *arg) 516 const char *arg)
484{ 517{
485 int rv; 518 int rv;
486 const char *file; 519 const char *file;
487 apr_pool_t *spool; 520 apr_pool_t *spool;
488 gnutls_datum_t data; 521 gnutls_datum_t data;
489 522
490 mgs_srvconf_rec *sc = 523 mgs_srvconf_rec *sc =
491 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 524 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
492 module_config, 525 module_config,
493 &gnutls_module); 526 &gnutls_module);
494 apr_pool_create(&spool, parms->pool); 527 apr_pool_create(&spool, parms->pool);
495 528
496 file = ap_server_root_relative(spool, arg); 529 file = ap_server_root_relative(spool, arg);
497 530
498 if (load_datum_from_file(spool, file, &data) != 0) { 531 if (load_datum_from_file(spool, file, &data) != 0) {
499 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 532 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
500 "Keyring File '%s'", file); 533 "Keyring File '%s'", file);
501 } 534 }
502 535
503 rv = gnutls_openpgp_keyring_init(&sc->pgp_list); 536 rv = gnutls_openpgp_keyring_init(&sc->pgp_list);
504 if (rv < 0) { 537 if (rv < 0) {
505 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" 538 return apr_psprintf(parms->pool,
506 "keyring: (%d) %s", rv, gnutls_strerror(rv)); 539 "GnuTLS: Failed to initialize"
507 } 540 "keyring: (%d) %s", rv,
508 541 gnutls_strerror(rv));
509 rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64); 542 }
510 if (rv < 0) { 543
511 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 544 rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
512 "Keyring File '%s': (%d) %s", file, rv, 545 GNUTLS_OPENPGP_FMT_BASE64);
513 gnutls_strerror(rv)); 546 if (rv < 0) {
514 } 547 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
515 548 "Keyring File '%s': (%d) %s", file, rv,
516 apr_pool_destroy(spool); 549 gnutls_strerror(rv));
517 return NULL; 550 }
551
552 apr_pool_destroy(spool);
553 return NULL;
518} 554}
519 555
520const char *mgs_set_enabled(cmd_parms * parms, void *dummy, 556const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
521 const char *arg) 557 const char *arg)
522{ 558{
523 mgs_srvconf_rec *sc = 559 mgs_srvconf_rec *sc =
524 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 560 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
525 module_config, 561 module_config,
526 &gnutls_module); 562 &gnutls_module);
527 if (!strcasecmp(arg, "On")) { 563 if (!strcasecmp(arg, "On")) {
528 sc->enabled = GNUTLS_ENABLED_TRUE; 564 sc->enabled = GNUTLS_ENABLED_TRUE;
529 } else if (!strcasecmp(arg, "Off")) { 565 } else if (!strcasecmp(arg, "Off")) {
530 sc->enabled = GNUTLS_ENABLED_FALSE; 566 sc->enabled = GNUTLS_ENABLED_FALSE;
531 } else { 567 } else {
532 return "GnuTLSEnable must be set to 'On' or 'Off'"; 568 return "GnuTLSEnable must be set to 'On' or 'Off'";
533 } 569 }
534 570
535 return NULL; 571 return NULL;
536} 572}
537 573
538const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy, 574const char *mgs_set_export_certificates_enabled(cmd_parms * parms,
539 const char *arg) 575 void *dummy,
576 const char *arg)
540{ 577{
541 mgs_srvconf_rec *sc = 578 mgs_srvconf_rec *sc =
542 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 579 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
543 module_config, 580 module_config,
544 &gnutls_module); 581 &gnutls_module);
545 if (!strcasecmp(arg, "On")) { 582 if (!strcasecmp(arg, "On")) {
546 sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE; 583 sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;
547 } else if (!strcasecmp(arg, "Off")) { 584 } else if (!strcasecmp(arg, "Off")) {
548 sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE; 585 sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;
549 } else { 586 } else {
550 return "GnuTLSExportCertificates must be set to 'On' or 'Off'"; 587 return
551 } 588 "GnuTLSExportCertificates must be set to 'On' or 'Off'";
552 589 }
553 return NULL; 590
591 return NULL;
554} 592}
555 593
556 594
557const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg) 595const char *mgs_set_priorities(cmd_parms * parms, void *dummy,
596 const char *arg)
558{ 597{
559 int ret; 598 int ret;
560 const char *err; 599 const char *err;
561 mgs_srvconf_rec *sc = 600 mgs_srvconf_rec *sc =
562 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 601 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
563 module_config, 602 module_config,
564 &gnutls_module); 603 &gnutls_module);
565 604
566 605
567 ret = gnutls_priority_init( &sc->priorities, arg, &err); 606 ret = gnutls_priority_init(&sc->priorities, arg, &err);
568 if (ret < 0) { 607 if (ret < 0) {
569 if (ret == GNUTLS_E_INVALID_REQUEST) 608 if (ret == GNUTLS_E_INVALID_REQUEST)
570 return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err); 609 return apr_psprintf(parms->pool,
571 return "Error setting priorities"; 610 "GnuTLS: Syntax error parsing priorities string at: %s",
572 } 611 err);
573 612 return "Error setting priorities";
574 return NULL; 613 }
614
615 return NULL;
575} 616}
576 617
577void *mgs_config_server_create(apr_pool_t * p, server_rec * s) 618void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
578{ 619{
579 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); 620 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
580 int ret; 621 int ret;
581
582 sc->enabled = GNUTLS_ENABLED_FALSE;
583
584 ret = gnutls_certificate_allocate_credentials(&sc->certs);
585 if (ret < 0) {
586 return apr_psprintf(p, "GnuTLS: Failed to initialize"
587 ": (%d) %s", ret, gnutls_strerror(ret));
588 }
589
590 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
591 if (ret < 0) {
592 return apr_psprintf(p, "GnuTLS: Failed to initialize"
593 ": (%d) %s", ret, gnutls_strerror(ret));
594 }
595 622
623 sc->enabled = GNUTLS_ENABLED_FALSE;
624
625 ret = gnutls_certificate_allocate_credentials(&sc->certs);
626 if (ret < 0) {
627 return apr_psprintf(p, "GnuTLS: Failed to initialize"
628 ": (%d) %s", ret,
629 gnutls_strerror(ret));
630 }
631
632 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
633 if (ret < 0) {
634 return apr_psprintf(p, "GnuTLS: Failed to initialize"
635 ": (%d) %s", ret,
636 gnutls_strerror(ret));
637 }
596#ifdef ENABLE_SRP 638#ifdef ENABLE_SRP
597 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds); 639 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
598 if (ret < 0) { 640 if (ret < 0) {
599 return apr_psprintf(p, "GnuTLS: Failed to initialize" 641 return apr_psprintf(p, "GnuTLS: Failed to initialize"
600 ": (%d) %s", ret, gnutls_strerror(ret)); 642 ": (%d) %s", ret,
601 } 643 gnutls_strerror(ret));
602 644 }
603 sc->srp_tpasswd_conf_file = NULL; 645
604 sc->srp_tpasswd_file = NULL; 646 sc->srp_tpasswd_conf_file = NULL;
647 sc->srp_tpasswd_file = NULL;
605#endif 648#endif
606 649
607 sc->privkey_x509 = NULL; 650 sc->privkey_x509 = NULL;
608 memset( sc->certs_x509, 0, sizeof(sc->certs_x509)); 651 memset(sc->certs_x509, 0, sizeof(sc->certs_x509));
609 sc->certs_x509_num = 0; 652 sc->certs_x509_num = 0;
610 sc->cache_timeout = apr_time_from_sec(300); 653 sc->cache_timeout = apr_time_from_sec(300);
611 sc->cache_type = mgs_cache_none; 654 sc->cache_type = mgs_cache_none;
612 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); 655 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
613 sc->tickets = 1; /* by default enable session tickets */ 656 sc->tickets = 1; /* by default enable session tickets */
614 657
615 sc->client_verify_mode = GNUTLS_CERT_IGNORE; 658 sc->client_verify_mode = GNUTLS_CERT_IGNORE;
616 659
617 return sc; 660 return sc;
618} 661}
619 662
620void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) 663void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
621{ 664{
622 mgs_dirconf_rec *new; 665 mgs_dirconf_rec *new;
623/* mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */ 666/* mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
624 mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv; 667 mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
625 668
626 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec)); 669 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
627 new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode, 670 new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
628 add->lua_bytecode_len); 671 add->lua_bytecode_len);
629 new->lua_bytecode_len = add->lua_bytecode_len; 672 new->lua_bytecode_len = add->lua_bytecode_len;
630 new->client_verify_mode = add->client_verify_mode; 673 new->client_verify_mode = add->client_verify_mode;
631 return new; 674 return new;
632} 675}
633 676
634void *mgs_config_dir_create(apr_pool_t * p, char *dir) 677void *mgs_config_dir_create(apr_pool_t * p, char *dir)
635{ 678{
636 mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc)); 679 mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
637 680
638 dc->client_verify_mode = -1; 681 dc->client_verify_mode = -1;
639 dc->lua_bytecode = NULL; 682 dc->lua_bytecode = NULL;
640 dc->lua_bytecode_len = 0; 683 dc->lua_bytecode_len = 0;
641 return dc; 684 return dc;
642} 685}
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c
index 7c638fb..34c3585 100644
--- a/src/gnutls_hooks.c
+++ b/src/gnutls_hooks.c
@@ -40,179 +40,191 @@ static gnutls_datum session_ticket_key = { NULL, 0 };
40 40
41static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); 41static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
42/* use side==0 for server and side==1 for client */ 42/* use side==0 for server and side==1 for client */
43static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, 43static void mgs_add_common_cert_vars(request_rec * r,
44 int side, 44 gnutls_x509_crt_t cert, int side,
45 int export_certificates_enabled);
46static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
47 int side,
48 int export_certificates_enabled); 45 int export_certificates_enabled);
46static void mgs_add_common_pgpcert_vars(request_rec * r,
47 gnutls_openpgp_crt_t cert,
48 int side,
49 int export_certificates_enabled);
49 50
50static apr_status_t mgs_cleanup_pre_config(void *data) 51static apr_status_t mgs_cleanup_pre_config(void *data)
51{ 52{
52 gnutls_free(session_ticket_key.data); 53 gnutls_free(session_ticket_key.data);
53 session_ticket_key.data = NULL; 54 session_ticket_key.data = NULL;
54 session_ticket_key.size = 0; 55 session_ticket_key.size = 0;
55 gnutls_global_deinit(); 56 gnutls_global_deinit();
56 return APR_SUCCESS; 57 return APR_SUCCESS;
57} 58}
58 59
59#if MOD_GNUTLS_DEBUG 60#if MOD_GNUTLS_DEBUG
60static void gnutls_debug_log_all(int level, const char *str) 61static void gnutls_debug_log_all(int level, const char *str)
61{ 62{
62 apr_file_printf(debug_log_fp, "<%d> %s\n", level, str); 63 apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
63} 64}
65
64#define _gnutls_log apr_file_printf 66#define _gnutls_log apr_file_printf
65#else 67#else
66# define _gnutls_log(...) 68# define _gnutls_log(...)
67#endif 69#endif
68 70
69int 71int
70mgs_hook_pre_config(apr_pool_t * pconf, 72mgs_hook_pre_config(apr_pool_t * pconf,
71 apr_pool_t * plog, apr_pool_t * ptemp) 73 apr_pool_t * plog, apr_pool_t * ptemp)
72{ 74{
73int ret; 75 int ret;
74 76
75#if MOD_GNUTLS_DEBUG 77#if MOD_GNUTLS_DEBUG
76 apr_file_open(&debug_log_fp, "/tmp/gnutls_debug", 78 apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
77 APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, 79 APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
78 pconf); 80 pconf);
79 81
80 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 82 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
81 83
82 gnutls_global_set_log_level(9); 84 gnutls_global_set_log_level(9);
83 gnutls_global_set_log_function(gnutls_debug_log_all); 85 gnutls_global_set_log_function(gnutls_debug_log_all);
84 _gnutls_log(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL)); 86 _gnutls_log(debug_log_fp, "gnutls: %s\n",
87 gnutls_check_version(NULL));
85#endif 88#endif
86 89
87#if APR_HAS_THREADS 90#if APR_HAS_THREADS
88 ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded); 91 ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded);
89#if (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 11) || GNUTLS_VERSION_MAJOR < 2 92#if (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 11) || GNUTLS_VERSION_MAJOR < 2
90 if (mpm_is_threaded) { 93 if (mpm_is_threaded) {
91 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); 94 gcry_control(GCRYCTL_SET_THREAD_CBS,
92 } 95 &gcry_threads_pthread);
96 }
93#endif 97#endif
94#else 98#else
95 mpm_is_threaded = 0; 99 mpm_is_threaded = 0;
96#endif 100#endif
97 101
98 102
99 if (gnutls_check_version(LIBGNUTLS_VERSION)==NULL) { 103 if (gnutls_check_version(LIBGNUTLS_VERSION) == NULL) {
100 _gnutls_log(debug_log_fp, "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n", 104 _gnutls_log(debug_log_fp,
101 LIBGNUTLS_VERSION, gnutls_check_version(NULL)); 105 "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n",
102 return -3; 106 LIBGNUTLS_VERSION, gnutls_check_version(NULL));
103 } 107 return -3;
108 }
109
110 ret = gnutls_global_init();
111 if (ret < 0) {
112 _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n",
113 gnutls_strerror(ret));
114 return -3;
115 }
104 116
105 ret = gnutls_global_init(); 117 ret = gnutls_session_ticket_key_generate(&session_ticket_key);
106 if (ret < 0) { 118 if (ret < 0) {
107 _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n", gnutls_strerror(ret)); 119 _gnutls_log(debug_log_fp,
108 return -3; 120 "gnutls_session_ticket_key_generate: %s\n",
109 } 121 gnutls_strerror(ret));
110 122 }
111 ret = gnutls_session_ticket_key_generate( &session_ticket_key);
112 if (ret < 0) {
113 _gnutls_log(debug_log_fp, "gnutls_session_ticket_key_generate: %s\n", gnutls_strerror(ret));
114 }
115 123
116 apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, 124 apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
117 apr_pool_cleanup_null); 125 apr_pool_cleanup_null);
118 126
119 127
120 return OK; 128 return OK;
121} 129}
122 130
123static int mgs_select_virtual_server_cb(gnutls_session_t session) 131static int mgs_select_virtual_server_cb(gnutls_session_t session)
124{ 132{
125 mgs_handle_t *ctxt; 133 mgs_handle_t *ctxt;
126 mgs_srvconf_rec *tsc; 134 mgs_srvconf_rec *tsc;
127 int ret; 135 int ret;
128 int cprio[2]; 136 int cprio[2];
129 137
130 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 138 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
131 139
132 ctxt = gnutls_transport_get_ptr(session); 140 ctxt = gnutls_transport_get_ptr(session);
133 141
134 /* find the virtual server */ 142 /* find the virtual server */
135 tsc = mgs_find_sni_server(session); 143 tsc = mgs_find_sni_server(session);
136 144
137 if (tsc != NULL) 145 if (tsc != NULL)
138 ctxt->sc = tsc; 146 ctxt->sc = tsc;
139 147
140 gnutls_certificate_server_set_request(session, 148 gnutls_certificate_server_set_request(session,
141 ctxt->sc->client_verify_mode); 149 ctxt->
150 sc->client_verify_mode);
142 151
143 /* set the new server credentials 152 /* set the new server credentials
144 */ 153 */
145 154
146 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, 155 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
147 ctxt->sc->certs); 156 ctxt->sc->certs);
148 157
149 gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds); 158 gnutls_credentials_set(session, GNUTLS_CRD_ANON,
159 ctxt->sc->anon_creds);
150 160
151#ifdef ENABLE_SRP 161#ifdef ENABLE_SRP
152 if (ctxt->sc->srp_tpasswd_conf_file != NULL 162 if (ctxt->sc->srp_tpasswd_conf_file != NULL
153 && ctxt->sc->srp_tpasswd_file != NULL) { 163 && ctxt->sc->srp_tpasswd_file != NULL) {
154 gnutls_credentials_set(session, GNUTLS_CRD_SRP, 164 gnutls_credentials_set(session, GNUTLS_CRD_SRP,
155 ctxt->sc->srp_creds); 165 ctxt->sc->srp_creds);
156 } 166 }
157#endif 167#endif
158 168
159 /* update the priorities - to avoid negotiating a ciphersuite that is not 169 /* update the priorities - to avoid negotiating a ciphersuite that is not
160 * enabled on this virtual server. Note that here we ignore the version 170 * enabled on this virtual server. Note that here we ignore the version
161 * negotiation. 171 * negotiation.
162 */ 172 */
163 ret = gnutls_priority_set(session, ctxt->sc->priorities); 173 ret = gnutls_priority_set(session, ctxt->sc->priorities);
164 /* actually it shouldn't fail since we have checked at startup */ 174 /* actually it shouldn't fail since we have checked at startup */
165 if (ret < 0) 175 if (ret < 0)
166 return ret; 176 return ret;
167 177
168 /* If both certificate types are not present disallow them from 178 /* If both certificate types are not present disallow them from
169 * being negotiated. 179 * being negotiated.
170 */ 180 */
171 if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) { 181 if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) {
172 cprio[0] = GNUTLS_CRT_X509; 182 cprio[0] = GNUTLS_CRT_X509;
173 cprio[1] = 0; 183 cprio[1] = 0;
174 gnutls_certificate_type_set_priority( session, cprio); 184 gnutls_certificate_type_set_priority(session, cprio);
175 } else if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0]==NULL) { 185 } else if (ctxt->sc->cert_pgp != NULL
176 cprio[0] = GNUTLS_CRT_OPENPGP; 186 && ctxt->sc->certs_x509[0] == NULL) {
177 cprio[1] = 0; 187 cprio[0] = GNUTLS_CRT_OPENPGP;
178 gnutls_certificate_type_set_priority( session, cprio); 188 cprio[1] = 0;
179 } 189 gnutls_certificate_type_set_priority(session, cprio);
180 190 }
181 return 0; 191
192 return 0;
182} 193}
183 194
184static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret) 195static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret)
185{ 196{
186 mgs_handle_t *ctxt; 197 mgs_handle_t *ctxt;
198
199 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
200 ctxt = gnutls_transport_get_ptr(session);
187 201
188 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 202 if (ctxt == NULL)
189 ctxt = gnutls_transport_get_ptr(session); 203 return GNUTLS_E_INTERNAL_ERROR;
190 204
191 if (ctxt == NULL) 205 if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
192 return GNUTLS_E_INTERNAL_ERROR; 206 ret->type = GNUTLS_CRT_X509;
207 ret->ncerts = ctxt->sc->certs_x509_num;
208 ret->deinit_all = 0;
193 209
194 if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) { 210 ret->cert.x509 = ctxt->sc->certs_x509;
195 ret->type = GNUTLS_CRT_X509; 211 ret->key.x509 = ctxt->sc->privkey_x509;
196 ret->ncerts = ctxt->sc->certs_x509_num;
197 ret->deinit_all = 0;
198 212
199 ret->cert.x509 = ctxt->sc->certs_x509; 213 return 0;
200 ret->key.x509 = ctxt->sc->privkey_x509; 214 } else if (gnutls_certificate_type_get(session) ==
201 215 GNUTLS_CRT_OPENPGP) {
202 return 0; 216 ret->type = GNUTLS_CRT_OPENPGP;
203 } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) { 217 ret->ncerts = 1;
204 ret->type = GNUTLS_CRT_OPENPGP; 218 ret->deinit_all = 0;
205 ret->ncerts = 1;
206 ret->deinit_all = 0;
207 219
208 ret->cert.pgp = ctxt->sc->cert_pgp; 220 ret->cert.pgp = ctxt->sc->cert_pgp;
209 ret->key.pgp = ctxt->sc->privkey_pgp; 221 ret->key.pgp = ctxt->sc->privkey_pgp;
210 222
211 return 0; 223 return 0;
212
213 }
214 224
215 return GNUTLS_E_INTERNAL_ERROR; 225 }
226
227 return GNUTLS_E_INTERNAL_ERROR;
216} 228}
217 229
218/* 2048-bit group parameters from SRP specification */ 230/* 2048-bit group parameters from SRP specification */
@@ -233,78 +245,81 @@ const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
233static int read_crt_cn(server_rec * s, apr_pool_t * p, 245static int read_crt_cn(server_rec * s, apr_pool_t * p,
234 gnutls_x509_crt_t cert, char **cert_cn) 246 gnutls_x509_crt_t cert, char **cert_cn)
235{ 247{
236 int rv = 0, i; 248 int rv = 0, i;
237 size_t data_len; 249 size_t data_len;
238
239 250
240 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
241 *cert_cn = NULL;
242 251
243 data_len = 0; 252 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
244 rv = gnutls_x509_crt_get_dn_by_oid(cert, 253 *cert_cn = NULL;
245 GNUTLS_OID_X520_COMMON_NAME,
246 0, 0, NULL, &data_len);
247 254
248 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 255 data_len = 0;
249 *cert_cn = apr_palloc(p, data_len);
250 rv = gnutls_x509_crt_get_dn_by_oid(cert, 256 rv = gnutls_x509_crt_get_dn_by_oid(cert,
251 GNUTLS_OID_X520_COMMON_NAME, 0, 257 GNUTLS_OID_X520_COMMON_NAME,
252 0, *cert_cn, &data_len); 258 0, 0, NULL, &data_len);
253 } else { /* No CN return subject alternative name */ 259
254 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 260 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
255 "No common name found in certificate for '%s:%d'. Looking for subject alternative name...", 261 *cert_cn = apr_palloc(p, data_len);
256 s->server_hostname, s->port); 262 rv = gnutls_x509_crt_get_dn_by_oid(cert,
257 rv = 0; 263 GNUTLS_OID_X520_COMMON_NAME,
258 /* read subject alternative name */ 264 0, 0, *cert_cn,
259 for (i = 0; !(rv < 0); i++) { 265 &data_len);
260 data_len = 0; 266 } else { /* No CN return subject alternative name */
261 rv = gnutls_x509_crt_get_subject_alt_name(cert, i, 267 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
262 NULL, &data_len, 268 "No common name found in certificate for '%s:%d'. Looking for subject alternative name...",
263 NULL); 269 s->server_hostname, s->port);
264 270 rv = 0;
265 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 271 /* read subject alternative name */
266 /* FIXME: not very efficient. What if we have several alt names 272 for (i = 0; !(rv < 0); i++) {
267 * before DNSName? 273 data_len = 0;
268 */ 274 rv = gnutls_x509_crt_get_subject_alt_name(cert, i,
269 *cert_cn = apr_palloc(p, data_len + 1); 275 NULL,
270 276 &data_len,
271 rv = gnutls_x509_crt_get_subject_alt_name(cert, i, 277 NULL);
272 *cert_cn, 278
273 &data_len, NULL); 279 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER
274 (*cert_cn)[data_len] = 0; 280 && data_len > 1) {
275 281 /* FIXME: not very efficient. What if we have several alt names
276 if (rv == GNUTLS_SAN_DNSNAME) 282 * before DNSName?
277 break; 283 */
278 } 284 *cert_cn = apr_palloc(p, data_len + 1);
285
286 rv = gnutls_x509_crt_get_subject_alt_name
287 (cert, i, *cert_cn, &data_len, NULL);
288 (*cert_cn)[data_len] = 0;
289
290 if (rv == GNUTLS_SAN_DNSNAME)
291 break;
292 }
293 }
279 } 294 }
280 }
281 295
282 return rv; 296 return rv;
283} 297}
284 298
285static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p, 299static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p,
286 gnutls_openpgp_crt_t cert, char **cert_cn) 300 gnutls_openpgp_crt_t cert, char **cert_cn)
287{ 301{
288 int rv = 0; 302 int rv = 0;
289 size_t data_len; 303 size_t data_len;
290 304
291 305
292 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 306 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
293 *cert_cn = NULL; 307 *cert_cn = NULL;
294 308
295 data_len = 0; 309 data_len = 0;
296 rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len); 310 rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);
297 311
298 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 312 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
299 *cert_cn = apr_palloc(p, data_len); 313 *cert_cn = apr_palloc(p, data_len);
300 rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len); 314 rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn,
301 } else { /* No CN return subject alternative name */ 315 &data_len);
302 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 316 } else { /* No CN return subject alternative name */
303 "No name found in PGP certificate for '%s:%d'.", 317 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
304 s->server_hostname, s->port); 318 "No name found in PGP certificate for '%s:%d'.",
305 } 319 s->server_hostname, s->port);
320 }
306 321
307 return rv; 322 return rv;
308} 323}
309 324
310 325
@@ -312,27 +327,27 @@ int
312mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, 327mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
313 apr_pool_t * ptemp, server_rec * base_server) 328 apr_pool_t * ptemp, server_rec * base_server)
314{ 329{
315 int rv; 330 int rv;
316 server_rec *s; 331 server_rec *s;
317 gnutls_dh_params_t dh_params = NULL; 332 gnutls_dh_params_t dh_params = NULL;
318 gnutls_rsa_params_t rsa_params = NULL; 333 gnutls_rsa_params_t rsa_params = NULL;
319 mgs_srvconf_rec *sc; 334 mgs_srvconf_rec *sc;
320 mgs_srvconf_rec *sc_base; 335 mgs_srvconf_rec *sc_base;
321 void *data = NULL; 336 void *data = NULL;
322 int first_run = 0; 337 int first_run = 0;
323 const char *userdata_key = "mgs_init"; 338 const char *userdata_key = "mgs_init";
324 339
325 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 340 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
326 apr_pool_userdata_get(&data, userdata_key, base_server->process->pool); 341 apr_pool_userdata_get(&data, userdata_key,
327 if (data == NULL) {
328 first_run = 1;
329 apr_pool_userdata_set((const void *) 1, userdata_key,
330 apr_pool_cleanup_null,
331 base_server->process->pool); 342 base_server->process->pool);
332 } 343 if (data == NULL) {
344 first_run = 1;
345 apr_pool_userdata_set((const void *) 1, userdata_key,
346 apr_pool_cleanup_null,
347 base_server->process->pool);
348 }
333 349
334 350
335 {
336 s = base_server; 351 s = base_server;
337 sc_base = 352 sc_base =
338 (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 353 (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
@@ -341,545 +356,568 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
341 gnutls_dh_params_init(&dh_params); 356 gnutls_dh_params_init(&dh_params);
342 357
343 if (sc_base->dh_params == NULL) { 358 if (sc_base->dh_params == NULL) {
344 gnutls_datum pdata = { (void *) static_dh_params, sizeof(static_dh_params) }; 359 gnutls_datum pdata = {
345 /* loading defaults */ 360 (void *) static_dh_params,
346 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, 361 sizeof(static_dh_params)
347 GNUTLS_X509_FMT_PEM); 362 };
348 363 /* loading defaults */
349 if (rv < 0) { 364 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
350 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 365 GNUTLS_X509_FMT_PEM);
351 "GnuTLS: Unable to load DH Params: (%d) %s", 366
352 rv, gnutls_strerror(rv)); 367 if (rv < 0) {
353 exit(rv); 368 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
354 } 369 "GnuTLS: Unable to load DH Params: (%d) %s",
355 } else dh_params = sc_base->dh_params; 370 rv, gnutls_strerror(rv));
356 371 exit(rv);
357 if (sc_base->rsa_params != NULL) 372 }
358 rsa_params = sc_base->rsa_params; 373 } else
374 dh_params = sc_base->dh_params;
375
376 if (sc_base->rsa_params != NULL)
377 rsa_params = sc_base->rsa_params;
359 378
360 /* else not an error but RSA-EXPORT ciphersuites are not available 379 /* else not an error but RSA-EXPORT ciphersuites are not available
361 */ 380 */
362 381
363 rv = mgs_cache_post_config(p, s, sc_base); 382 rv = mgs_cache_post_config(p, s, sc_base);
364 if (rv != 0) { 383 if (rv != 0) {
365 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, 384 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
366 "GnuTLS: Post Config for GnuTLSCache Failed." 385 "GnuTLS: Post Config for GnuTLSCache Failed."
367 " Shutting Down."); 386 " Shutting Down.");
368 exit(-1); 387 exit(-1);
369 } 388 }
370 389
371 for (s = base_server; s; s = s->next) { 390 for (s = base_server; s; s = s->next) {
372 void *load = NULL; 391 void *load = NULL;
373 sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 392 sc = (mgs_srvconf_rec *)
374 &gnutls_module); 393 ap_get_module_config(s->module_config, &gnutls_module);
375 sc->cache_type = sc_base->cache_type; 394 sc->cache_type = sc_base->cache_type;
376 sc->cache_config = sc_base->cache_config; 395 sc->cache_config = sc_base->cache_config;
377 396
378 /* Check if the priorities have been set */ 397 /* Check if the priorities have been set */
379 if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 398 if (sc->priorities == NULL
380 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 399 && sc->enabled == GNUTLS_ENABLED_TRUE) {
381 "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!", 400 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
382 s->server_hostname, s->port); 401 "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!",
383 exit(-1); 402 s->server_hostname, s->port);
384 } 403 exit(-1);
385 404 }
386 /* Check if DH or RSA params have been set per host */ 405
387 if (sc->rsa_params != NULL) 406 /* Check if DH or RSA params have been set per host */
388 load = sc->rsa_params; 407 if (sc->rsa_params != NULL)
389 else if (rsa_params) load = rsa_params; 408 load = sc->rsa_params;
390 409 else if (rsa_params)
391 if (load != NULL) 410 load = rsa_params;
392 gnutls_certificate_set_rsa_export_params(sc->certs, load); 411
393 412 if (load != NULL)
394 413 gnutls_certificate_set_rsa_export_params(sc->certs,
395 load = NULL; 414 load);
396 if (sc->dh_params != NULL) 415
397 load = sc->dh_params; 416
398 else if (dh_params) load = dh_params; 417 load = NULL;
399 418 if (sc->dh_params != NULL)
400 if (load != NULL) { /* not needed but anyway */ 419 load = sc->dh_params;
401 gnutls_certificate_set_dh_params(sc->certs, load); 420 else if (dh_params)
402 gnutls_anon_set_server_dh_params(sc->anon_creds, load); 421 load = dh_params;
403 } 422
404 423 if (load != NULL) { /* not needed but anyway */
405 gnutls_certificate_server_set_retrieve_function(sc->certs, 424 gnutls_certificate_set_dh_params(sc->certs, load);
406 cert_retrieve_fn); 425 gnutls_anon_set_server_dh_params(sc->anon_creds,
426 load);
427 }
428
429 gnutls_certificate_server_set_retrieve_function(sc->certs,
430 cert_retrieve_fn);
407 431
408#ifdef ENABLE_SRP 432#ifdef ENABLE_SRP
409 if (sc->srp_tpasswd_conf_file != NULL 433 if (sc->srp_tpasswd_conf_file != NULL
410 && sc->srp_tpasswd_file != NULL) { 434 && sc->srp_tpasswd_file != NULL) {
411 rv = gnutls_srp_set_server_credentials_file(sc->srp_creds, 435 rv = gnutls_srp_set_server_credentials_file
412 sc-> 436 (sc->srp_creds, sc->srp_tpasswd_file,
413 srp_tpasswd_file, 437 sc->srp_tpasswd_conf_file);
414 sc-> 438
415 srp_tpasswd_conf_file); 439 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
416 440 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
417 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 441 s,
418 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 442 "[GnuTLS] - Host '%s:%d' is missing a "
419 "[GnuTLS] - Host '%s:%d' is missing a " 443 "SRP password or conf File!",
420 "SRP password or conf File!", 444 s->server_hostname, s->port);
421 s->server_hostname, s->port); 445 exit(-1);
422 exit(-1); 446 }
423 } 447 }
424 }
425#endif 448#endif
426 449
427 if (sc->certs_x509[0] == NULL && 450 if (sc->certs_x509[0] == NULL &&
428 sc->cert_pgp == NULL && 451 sc->cert_pgp == NULL &&
429 sc->enabled == GNUTLS_ENABLED_TRUE) { 452 sc->enabled == GNUTLS_ENABLED_TRUE) {
430 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 453 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
431 "[GnuTLS] - Host '%s:%d' is missing a " 454 "[GnuTLS] - Host '%s:%d' is missing a "
432 "Certificate File!", s->server_hostname, 455 "Certificate File!",
433 s->port); 456 s->server_hostname, s->port);
434 exit(-1); 457 exit(-1);
435 } 458 }
436
437 if (sc->enabled == GNUTLS_ENABLED_TRUE &&
438 ((sc->certs_x509[0] != NULL && sc->privkey_x509 == NULL) ||
439 (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) {
440 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
441 "[GnuTLS] - Host '%s:%d' is missing a "
442 "Private Key File!",
443 s->server_hostname, s->port);
444 exit(-1);
445 }
446 459
447 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 460 if (sc->enabled == GNUTLS_ENABLED_TRUE &&
448 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); 461 ((sc->certs_x509[0] != NULL
449 if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */ 462 && sc->privkey_x509 == NULL) || (sc->cert_pgp != NULL
450 rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn); 463 && sc->privkey_pgp
464 == NULL))) {
465 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
466 "[GnuTLS] - Host '%s:%d' is missing a "
467 "Private Key File!",
468 s->server_hostname, s->port);
469 exit(-1);
470 }
451 471
452 if (rv < 0) { 472 if (sc->enabled == GNUTLS_ENABLED_TRUE) {
453 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 473 rv = read_crt_cn(s, p, sc->certs_x509[0],
454 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", 474 &sc->cert_cn);
455 s->server_hostname, s->port); 475 if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */
456 sc->cert_cn = NULL; 476 rv = read_pgpcrt_cn(s, p, sc->cert_pgp,
457 continue; 477 &sc->cert_cn);
478
479 if (rv < 0) {
480 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
481 s,
482 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
483 s->server_hostname, s->port);
484 sc->cert_cn = NULL;
485 continue;
486 }
458 } 487 }
459 }
460 } 488 }
461 }
462 489
463 ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
464 490
465 return OK; 491 ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
492
493 return OK;
466} 494}
467 495
468void mgs_hook_child_init(apr_pool_t * p, server_rec * s) 496void mgs_hook_child_init(apr_pool_t * p, server_rec * s)
469{ 497{
470 apr_status_t rv = APR_SUCCESS; 498 apr_status_t rv = APR_SUCCESS;
471 mgs_srvconf_rec *sc = ap_get_module_config(s->module_config, 499 mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
472 &gnutls_module); 500 &gnutls_module);
473 501
474 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 502 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
475 if (sc->cache_type != mgs_cache_none) { 503 if (sc->cache_type != mgs_cache_none) {
476 rv = mgs_cache_child_init(p, s, sc); 504 rv = mgs_cache_child_init(p, s, sc);
477 if (rv != APR_SUCCESS) { 505 if (rv != APR_SUCCESS) {
478 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, 506 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
479 "[GnuTLS] - Failed to run Cache Init"); 507 "[GnuTLS] - Failed to run Cache Init");
508 }
509 } else {
510 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
511 "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
480 } 512 }
481 } else {
482 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
483 "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
484 }
485} 513}
486 514
487const char *mgs_hook_http_scheme(const request_rec * r) 515const char *mgs_hook_http_scheme(const request_rec * r)
488{ 516{
489 mgs_srvconf_rec *sc; 517 mgs_srvconf_rec *sc;
490
491 if (r == NULL)
492 return NULL;
493
494 sc =
495 (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
496 &gnutls_module);
497
498 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
499 if (sc->enabled == GNUTLS_ENABLED_FALSE) {
500 return NULL;
501 }
502 518
503 return "https"; 519 if (r == NULL)
520 return NULL;
521
522 sc = (mgs_srvconf_rec *) ap_get_module_config(r->
523 server->module_config,
524 &gnutls_module);
525
526 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
527 if (sc->enabled == GNUTLS_ENABLED_FALSE) {
528 return NULL;
529 }
530
531 return "https";
504} 532}
505 533
506apr_port_t mgs_hook_default_port(const request_rec * r) 534apr_port_t mgs_hook_default_port(const request_rec * r)
507{ 535{
508 mgs_srvconf_rec *sc; 536 mgs_srvconf_rec *sc;
509 537
510 if (r == NULL) 538 if (r == NULL)
511 return 0; 539 return 0;
512 540
513 sc = 541 sc = (mgs_srvconf_rec *) ap_get_module_config(r->
514 (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config, 542 server->module_config,
515 &gnutls_module); 543 &gnutls_module);
516 544
517 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 545 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
518 if (sc->enabled == GNUTLS_ENABLED_FALSE) { 546 if (sc->enabled == GNUTLS_ENABLED_FALSE) {
519 return 0; 547 return 0;
520 } 548 }
521 549
522 return 443; 550 return 443;
523} 551}
524 552
525#define MAX_HOST_LEN 255 553#define MAX_HOST_LEN 255
526 554
527#if USING_2_1_RECENT 555#if USING_2_1_RECENT
528typedef struct { 556typedef struct {
529 mgs_handle_t *ctxt; 557 mgs_handle_t *ctxt;
530 mgs_srvconf_rec *sc; 558 mgs_srvconf_rec *sc;
531 const char *sni_name; 559 const char *sni_name;
532} vhost_cb_rec; 560} vhost_cb_rec;
533 561
534static int vhost_cb(void *baton, conn_rec * conn, server_rec * s) 562static int vhost_cb(void *baton, conn_rec * conn, server_rec * s)
535{ 563{
536 mgs_srvconf_rec *tsc; 564 mgs_srvconf_rec *tsc;
537 vhost_cb_rec *x = baton; 565 vhost_cb_rec *x = baton;
538 566
539 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 567 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
540 tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 568 tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
541 &gnutls_module); 569 &gnutls_module);
542 570
543 if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) { 571 if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
544 return 0; 572 return 0;
545 } 573 }
546 574
547 /* The CN can contain a * -- this will match those too. */ 575 /* The CN can contain a * -- this will match those too. */
548 if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { 576 if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
549 /* found a match */ 577 /* found a match */
550#if MOD_GNUTLS_DEBUG 578#if MOD_GNUTLS_DEBUG
551 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 579 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
552 x->ctxt->c->base_server, 580 x->ctxt->c->base_server,
553 "GnuTLS: Virtual Host CB: " 581 "GnuTLS: Virtual Host CB: "
554 "'%s' == '%s'", tsc->cert_cn, x->sni_name); 582 "'%s' == '%s'", tsc->cert_cn, x->sni_name);
555#endif 583#endif
556 /* Because we actually change the server used here, we need to reset 584 /* Because we actually change the server used here, we need to reset
557 * things like ClientVerify. 585 * things like ClientVerify.
558 */ 586 */
559 x->sc = tsc; 587 x->sc = tsc;
560 /* Shit. Crap. Dammit. We *really* should rehandshake here, as our 588 /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
561 * certificate structure *should* change when the server changes. 589 * certificate structure *should* change when the server changes.
562 * acccckkkkkk. 590 * acccckkkkkk.
563 */ 591 */
564 return 1; 592 return 1;
565 } else { 593 } else {
566#if MOD_GNUTLS_DEBUG 594#if MOD_GNUTLS_DEBUG
567 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 595 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
568 x->ctxt->c->base_server, 596 x->ctxt->c->base_server,
569 "GnuTLS: Virtual Host CB: " 597 "GnuTLS: Virtual Host CB: "
570 "'%s' != '%s'", tsc->cert_cn, x->sni_name); 598 "'%s' != '%s'", tsc->cert_cn, x->sni_name);
571#endif 599#endif
572 600
573 } 601 }
574 return 0; 602 return 0;
575} 603}
576#endif 604#endif
577 605
578mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) 606mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
579{ 607{
580 int rv; 608 int rv;
581 unsigned int sni_type; 609 unsigned int sni_type;
582 size_t data_len = MAX_HOST_LEN; 610 size_t data_len = MAX_HOST_LEN;
583 char sni_name[MAX_HOST_LEN]; 611 char sni_name[MAX_HOST_LEN];
584 mgs_handle_t *ctxt; 612 mgs_handle_t *ctxt;
585#if USING_2_1_RECENT 613#if USING_2_1_RECENT
586 vhost_cb_rec cbx; 614 vhost_cb_rec cbx;
587#else 615#else
588 server_rec *s; 616 server_rec *s;
589 mgs_srvconf_rec *tsc; 617 mgs_srvconf_rec *tsc;
590#endif 618#endif
591 619
592 if (session == NULL) 620 if (session == NULL)
593 return NULL; 621 return NULL;
594 622
595 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 623 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
596 ctxt = gnutls_transport_get_ptr(session); 624 ctxt = gnutls_transport_get_ptr(session);
597 625
598 rv = gnutls_server_name_get(ctxt->session, sni_name, 626 rv = gnutls_server_name_get(ctxt->session, sni_name,
599 &data_len, &sni_type, 0); 627 &data_len, &sni_type, 0);
600 628
601 if (rv != 0) { 629 if (rv != 0) {
602 return NULL; 630 return NULL;
603 } 631 }
604 632
605 if (sni_type != GNUTLS_NAME_DNS) { 633 if (sni_type != GNUTLS_NAME_DNS) {
606 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, 634 ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
607 ctxt->c->base_server, 635 ctxt->c->base_server,
608 "GnuTLS: Unknown type '%d' for SNI: " 636 "GnuTLS: Unknown type '%d' for SNI: "
609 "'%s'", sni_type, sni_name); 637 "'%s'", sni_type, sni_name);
610 return NULL; 638 return NULL;
611 } 639 }
612 640
613 /** 641 /**
614 * Code in the Core already sets up the c->base_server as the base 642 * Code in the Core already sets up the c->base_server as the base
615 * for this IP/Port combo. Trust that the core did the 'right' thing. 643 * for this IP/Port combo. Trust that the core did the 'right' thing.
616 */ 644 */
617#if USING_2_1_RECENT 645#if USING_2_1_RECENT
618 cbx.ctxt = ctxt; 646 cbx.ctxt = ctxt;
619 cbx.sc = NULL; 647 cbx.sc = NULL;
620 cbx.sni_name = sni_name; 648 cbx.sni_name = sni_name;
621
622 rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
623 if (rv == 1) {
624 return cbx.sc;
625 }
626#else
627 for (s = ap_server_conf; s; s = s->next) {
628 649
629 tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 650 rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
630 &gnutls_module); 651 if (rv == 1) {
631 if (tsc->enabled != GNUTLS_ENABLED_TRUE) { 652 return cbx.sc;
632 continue;
633 } 653 }
654#else
655 for (s = ap_server_conf; s; s = s->next) {
656
657 tsc =
658 (mgs_srvconf_rec *)
659 ap_get_module_config(s->module_config, &gnutls_module);
660 if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
661 continue;
662 }
634#if MOD_GNUTLS_DEBUG 663#if MOD_GNUTLS_DEBUG
635 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 664 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
636 ctxt->c->base_server, 665 ctxt->c->base_server,
637 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", 666 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X",
638 tsc->cert_cn, rv, 667 tsc->cert_cn, rv,
639 gnutls_pk_algorithm_get_name 668 gnutls_pk_algorithm_get_name
640 (gnutls_x509_privkey_get_pk_algorithm 669 (gnutls_x509_privkey_get_pk_algorithm
641 (ctxt->sc->privkey_x509)), (unsigned int) s, 670 (ctxt->sc->privkey_x509)), (unsigned int) s,
642 (unsigned int) s->next, (unsigned int) tsc); 671 (unsigned int) s->next, (unsigned int) tsc);
643#endif 672#endif
644 /* The CN can contain a * -- this will match those too. */ 673 /* The CN can contain a * -- this will match those too. */
645 if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { 674 if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
646#if MOD_GNUTLS_DEBUG 675#if MOD_GNUTLS_DEBUG
647 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 676 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
648 ctxt->c->base_server, 677 ctxt->c->base_server,
649 "GnuTLS: Virtual Host: " 678 "GnuTLS: Virtual Host: "
650 "'%s' == '%s'", tsc->cert_cn, sni_name); 679 "'%s' == '%s'", tsc->cert_cn,
680 sni_name);
651#endif 681#endif
652 return tsc; 682 return tsc;
683 }
653 } 684 }
654 }
655#endif 685#endif
656 return NULL; 686 return NULL;
657} 687}
658 688
659 689
660static const int protocol_priority[] = { 690static const int protocol_priority[] = {
661 GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 691 GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0
662}; 692};
663 693
664 694
665static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c) 695static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c)
666{ 696{
667 mgs_handle_t *ctxt; 697 mgs_handle_t *ctxt;
668 mgs_srvconf_rec *sc = 698 mgs_srvconf_rec *sc =
669 (mgs_srvconf_rec *) ap_get_module_config(c->base_server-> 699 (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
670 module_config, 700 module_config,
671 &gnutls_module); 701 &gnutls_module);
672 702
673 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 703 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
674 ctxt = apr_pcalloc(pool, sizeof(*ctxt)); 704 ctxt = apr_pcalloc(pool, sizeof(*ctxt));
675 ctxt->c = c; 705 ctxt->c = c;
676 ctxt->sc = sc; 706 ctxt->sc = sc;
677 ctxt->status = 0; 707 ctxt->status = 0;
678 708
679 ctxt->input_rc = APR_SUCCESS; 709 ctxt->input_rc = APR_SUCCESS;
680 ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc); 710 ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc);
681 ctxt->input_cbuf.length = 0; 711 ctxt->input_cbuf.length = 0;
682 712
683 ctxt->output_rc = APR_SUCCESS; 713 ctxt->output_rc = APR_SUCCESS;
684 ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc); 714 ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc);
685 ctxt->output_blen = 0; 715 ctxt->output_blen = 0;
686 ctxt->output_length = 0; 716 ctxt->output_length = 0;
687 717
688 gnutls_init(&ctxt->session, GNUTLS_SERVER); 718 gnutls_init(&ctxt->session, GNUTLS_SERVER);
689 if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) 719 if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
690 gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key); 720 gnutls_session_ticket_enable_server(ctxt->session,
691 721 &session_ticket_key);
692 /* because we don't set any default priorities here (we set later at 722
693 * the user hello callback) we need to at least set this in order for 723 /* because we don't set any default priorities here (we set later at
694 * gnutls to be able to read packets. 724 * the user hello callback) we need to at least set this in order for
695 */ 725 * gnutls to be able to read packets.
696 gnutls_protocol_set_priority(ctxt->session, protocol_priority); 726 */
727 gnutls_protocol_set_priority(ctxt->session, protocol_priority);
697 728
698 gnutls_handshake_set_post_client_hello_function(ctxt->session, 729 gnutls_handshake_set_post_client_hello_function(ctxt->session,
699 mgs_select_virtual_server_cb); 730 mgs_select_virtual_server_cb);
700 731
701 mgs_cache_session_init(ctxt); 732 mgs_cache_session_init(ctxt);
702 733
703 return ctxt; 734 return ctxt;
704} 735}
705 736
706int mgs_hook_pre_connection(conn_rec * c, void *csd) 737int mgs_hook_pre_connection(conn_rec * c, void *csd)
707{ 738{
708 mgs_handle_t *ctxt; 739 mgs_handle_t *ctxt;
709 mgs_srvconf_rec *sc; 740 mgs_srvconf_rec *sc;
710 741
711 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 742 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
712 743
713 if (c == NULL) 744 if (c == NULL)
714 return DECLINED; 745 return DECLINED;
715
716 sc =
717 (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
718 module_config,
719 &gnutls_module);
720
721 if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
722 return DECLINED;
723 }
724 746
725 if(c->remote_addr->hostname) 747 sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
726 /* Connection initiated by Apache (mod_proxy) => ignore */ 748 module_config,
727 return OK; 749 &gnutls_module);
728 750
729 ctxt = create_gnutls_handle(c->pool, c); 751 if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
752 return DECLINED;
753 }
754
755 if (c->remote_addr->hostname)
756 /* Connection initiated by Apache (mod_proxy) => ignore */
757 return OK;
758
759 ctxt = create_gnutls_handle(c->pool, c);
730 760
731 ap_set_module_config(c->conn_config, &gnutls_module, ctxt); 761 ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
732 762
733 gnutls_transport_set_pull_function(ctxt->session, mgs_transport_read); 763 gnutls_transport_set_pull_function(ctxt->session,
734 gnutls_transport_set_push_function(ctxt->session, mgs_transport_write); 764 mgs_transport_read);
735 gnutls_transport_set_ptr(ctxt->session, ctxt); 765 gnutls_transport_set_push_function(ctxt->session,
766 mgs_transport_write);
767 gnutls_transport_set_ptr(ctxt->session, ctxt);
736 768
737 ctxt->input_filter = 769 ctxt->input_filter =
738 ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c); 770 ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
739 ctxt->output_filter = 771 ctxt->output_filter =
740 ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c); 772 ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
741 773
742 return OK; 774 return OK;
743} 775}
744 776
745int mgs_hook_fixups(request_rec * r) 777int mgs_hook_fixups(request_rec * r)
746{ 778{
747 unsigned char sbuf[GNUTLS_MAX_SESSION_ID]; 779 unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
748 char buf[AP_IOBUFSIZE]; 780 char buf[AP_IOBUFSIZE];
749 const char *tmp; 781 const char *tmp;
750 size_t len; 782 size_t len;
751 mgs_handle_t *ctxt; 783 mgs_handle_t *ctxt;
752 int rv = OK; 784 int rv = OK;
753 785
754 if (r == NULL) 786 if (r == NULL)
755 return DECLINED; 787 return DECLINED;
756 788
757 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 789 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
758 apr_table_t *env = r->subprocess_env; 790 apr_table_t *env = r->subprocess_env;
759 791
760 ctxt = 792 ctxt =
761 ap_get_module_config(r->connection->conn_config, &gnutls_module); 793 ap_get_module_config(r->connection->conn_config,
794 &gnutls_module);
762 795
763 if (!ctxt || ctxt->session == NULL) { 796 if (!ctxt || ctxt->session == NULL) {
764 return DECLINED; 797 return DECLINED;
765 } 798 }
766 799
767 apr_table_setn(env, "HTTPS", "on"); 800 apr_table_setn(env, "HTTPS", "on");
768 801
769 apr_table_setn(env, "SSL_VERSION_LIBRARY", 802 apr_table_setn(env, "SSL_VERSION_LIBRARY",
770 "GnuTLS/" LIBGNUTLS_VERSION); 803 "GnuTLS/" LIBGNUTLS_VERSION);
771 apr_table_setn(env, "SSL_VERSION_INTERFACE", 804 apr_table_setn(env, "SSL_VERSION_INTERFACE",
772 "mod_gnutls/" MOD_GNUTLS_VERSION); 805 "mod_gnutls/" MOD_GNUTLS_VERSION);
773 806
774 apr_table_setn(env, "SSL_PROTOCOL", 807 apr_table_setn(env, "SSL_PROTOCOL",
775 gnutls_protocol_get_name(gnutls_protocol_get_version 808 gnutls_protocol_get_name(gnutls_protocol_get_version
776 (ctxt->session))); 809 (ctxt->session)));
777 810
778 /* should have been called SSL_CIPHERSUITE instead */ 811 /* should have been called SSL_CIPHERSUITE instead */
779 apr_table_setn(env, "SSL_CIPHER", 812 apr_table_setn(env, "SSL_CIPHER",
780 gnutls_cipher_suite_get_name(gnutls_kx_get 813 gnutls_cipher_suite_get_name(gnutls_kx_get
781 (ctxt->session), 814 (ctxt->session),
782 gnutls_cipher_get(ctxt-> 815 gnutls_cipher_get
783 session), 816 (ctxt->session),
784 gnutls_mac_get(ctxt-> 817 gnutls_mac_get
785 session))); 818 (ctxt->session)));
786 819
787 apr_table_setn(env, "SSL_COMPRESS_METHOD", 820 apr_table_setn(env, "SSL_COMPRESS_METHOD",
788 gnutls_compression_get_name(gnutls_compression_get 821 gnutls_compression_get_name(gnutls_compression_get
789 (ctxt->session))); 822 (ctxt->session)));
790 823
791#ifdef ENABLE_SRP 824#ifdef ENABLE_SRP
792 tmp = gnutls_srp_server_get_username(ctxt->session); 825 tmp = gnutls_srp_server_get_username(ctxt->session);
793 apr_table_setn(env, "SSL_SRP_USER", (tmp!=NULL)?tmp:""); 826 apr_table_setn(env, "SSL_SRP_USER", (tmp != NULL) ? tmp : "");
794#endif 827#endif
795 828
796 if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL) 829 if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL)
797 apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE"); 830 apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
798 831
799 unsigned int key_size = 832 unsigned int key_size =
800 8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)); 833 8 *
801 tmp = apr_psprintf(r->pool, "%u", key_size); 834 gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session));
835 tmp = apr_psprintf(r->pool, "%u", key_size);
802 836
803 apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp); 837 apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
804 838
805 apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp); 839 apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
806 840
807 apr_table_setn(env, "SSL_CIPHER_EXPORT", 841 apr_table_setn(env, "SSL_CIPHER_EXPORT",
808 (key_size <= 40) ? "true" : "false"); 842 (key_size <= 40) ? "true" : "false");
809 843
810 len = sizeof(sbuf); 844 len = sizeof(sbuf);
811 gnutls_session_get_id(ctxt->session, sbuf, &len); 845 gnutls_session_get_id(ctxt->session, sbuf, &len);
812 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); 846 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
813 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); 847 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
814 848
815 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 849 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509)
816 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, 850 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
817 ctxt->sc->export_certificates_enabled); 851 ctxt->
818 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) 852 sc->export_certificates_enabled);
819 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, 853 else if (gnutls_certificate_type_get(ctxt->session) ==
820 ctxt->sc->export_certificates_enabled); 854 GNUTLS_CRT_OPENPGP)
855 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
856 ctxt->
857 sc->export_certificates_enabled);
821 858
822 return rv; 859 return rv;
823} 860}
824 861
825int mgs_hook_authz(request_rec * r) 862int mgs_hook_authz(request_rec * r)
826{ 863{
827 int rv; 864 int rv;
828 mgs_handle_t *ctxt; 865 mgs_handle_t *ctxt;
829 mgs_dirconf_rec *dc; 866 mgs_dirconf_rec *dc;
830 867
831 if (r == NULL) 868 if (r == NULL)
832 return DECLINED; 869 return DECLINED;
833 870
834 dc = ap_get_module_config(r->per_dir_config, 871 dc = ap_get_module_config(r->per_dir_config, &gnutls_module);
835 &gnutls_module); 872
836 873 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
837 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 874 ctxt =
838 ctxt = 875 ap_get_module_config(r->connection->conn_config,
839 ap_get_module_config(r->connection->conn_config, &gnutls_module); 876 &gnutls_module);
840 877
841 if (!ctxt || ctxt->session == NULL) { 878 if (!ctxt || ctxt->session == NULL) {
842 return DECLINED; 879 return DECLINED;
843 } 880 }
844 881
845 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { 882 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
846 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 883 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
847 "GnuTLS: Directory set to Ignore Client Certificate!"); 884 "GnuTLS: Directory set to Ignore Client Certificate!");
848 } else { 885 } else {
849 if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { 886 if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
850 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 887 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
851 "GnuTLS: Attempting to rehandshake with peer. %d %d", 888 "GnuTLS: Attempting to rehandshake with peer. %d %d",
852 ctxt->sc->client_verify_mode, 889 ctxt->sc->client_verify_mode,
853 dc->client_verify_mode); 890 dc->client_verify_mode);
854 891
855 /* If we already have a client certificate, there's no point in 892 /* If we already have a client certificate, there's no point in
856 * re-handshaking... */ 893 * re-handshaking... */
857 rv = mgs_cert_verify(r, ctxt); 894 rv = mgs_cert_verify(r, ctxt);
858 if (rv != DECLINED && rv != HTTP_FORBIDDEN) 895 if (rv != DECLINED && rv != HTTP_FORBIDDEN)
859 return rv; 896 return rv;
860 897
861 gnutls_certificate_server_set_request(ctxt->session, 898 gnutls_certificate_server_set_request
862 dc->client_verify_mode); 899 (ctxt->session, dc->client_verify_mode);
863 900
864 if (mgs_rehandshake(ctxt) != 0) { 901 if (mgs_rehandshake(ctxt) != 0) {
865 return HTTP_FORBIDDEN; 902 return HTTP_FORBIDDEN;
866 } 903 }
867 } else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) { 904 } else if (ctxt->sc->client_verify_mode ==
905 GNUTLS_CERT_IGNORE) {
868#if MOD_GNUTLS_DEBUG 906#if MOD_GNUTLS_DEBUG
869 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 907 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
870 "GnuTLS: Peer is set to IGNORE"); 908 "GnuTLS: Peer is set to IGNORE");
871#endif 909#endif
872 return DECLINED; 910 return DECLINED;
873 } 911 }
874 rv = mgs_cert_verify(r, ctxt); 912 rv = mgs_cert_verify(r, ctxt);
875 if (rv != DECLINED && 913 if (rv != DECLINED &&
876 (rv != HTTP_FORBIDDEN || 914 (rv != HTTP_FORBIDDEN ||
877 dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) { 915 dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
878 return rv; 916 return rv;
917 }
879 } 918 }
880 }
881 919
882 return DECLINED; 920 return DECLINED;
883} 921}
884 922
885/* variables that are not sent by default: 923/* variables that are not sent by default:
@@ -895,359 +933,413 @@ static void
895mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, 933mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side,
896 int export_certificates_enabled) 934 int export_certificates_enabled)
897{ 935{
898 unsigned char sbuf[64]; /* buffer to hold serials */ 936 unsigned char sbuf[64]; /* buffer to hold serials */
899 char buf[AP_IOBUFSIZE]; 937 char buf[AP_IOBUFSIZE];
900 const char *tmp; 938 const char *tmp;
901 char *tmp2; 939 char *tmp2;
902 size_t len; 940 size_t len;
903 int ret, i; 941 int ret, i;
904 942
905 if (r == NULL) 943 if (r == NULL)
906 return; 944 return;
907 945
908 apr_table_t *env = r->subprocess_env; 946 apr_table_t *env = r->subprocess_env;
909 947
910 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 948 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
911 if (export_certificates_enabled != 0) { 949 if (export_certificates_enabled != 0) {
912 char cert_buf[10 * 1024]; 950 char cert_buf[10 * 1024];
913 len = sizeof(cert_buf); 951 len = sizeof(cert_buf);
914 952
915 if (gnutls_x509_crt_export 953 if (gnutls_x509_crt_export
916 (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) 954 (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0)
917 apr_table_setn(env, 955 apr_table_setn(env,
918 apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 956 apr_pstrcat(r->pool, MGS_SIDE,
919 apr_pstrmemdup(r->pool, cert_buf, len)); 957 "_CERT", NULL),
920 958 apr_pstrmemdup(r->pool, cert_buf,
921 } 959 len));
922 960
923 len = sizeof(buf); 961 }
924 gnutls_x509_crt_get_dn(cert, buf, &len); 962
925 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL), 963 len = sizeof(buf);
926 apr_pstrmemdup(r->pool, buf, len)); 964 gnutls_x509_crt_get_dn(cert, buf, &len);
927 965 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL),
928 len = sizeof(buf); 966 apr_pstrmemdup(r->pool, buf, len));
929 gnutls_x509_crt_get_issuer_dn(cert, buf, &len); 967
930 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL), 968 len = sizeof(buf);
931 apr_pstrmemdup(r->pool, buf, len)); 969 gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
932 970 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL),
933 len = sizeof(sbuf); 971 apr_pstrmemdup(r->pool, buf, len));
934 gnutls_x509_crt_get_serial(cert, sbuf, &len); 972
935 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); 973 len = sizeof(sbuf);
936 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), 974 gnutls_x509_crt_get_serial(cert, sbuf, &len);
937 apr_pstrdup(r->pool, tmp)); 975 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
938
939 ret = gnutls_x509_crt_get_version(cert);
940 if (ret > 0)
941 apr_table_setn(env, 976 apr_table_setn(env,
942 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), 977 apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL),
943 apr_psprintf(r->pool, "%u", ret)); 978 apr_pstrdup(r->pool, tmp));
944 979
945 apr_table_setn(env, 980 ret = gnutls_x509_crt_get_version(cert);
946 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "X.509"); 981 if (ret > 0)
947
948 tmp =
949 mgs_time2sz(gnutls_x509_crt_get_expiration_time
950 (cert), buf, sizeof(buf));
951 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
952 apr_pstrdup(r->pool, tmp));
953
954 tmp =
955 mgs_time2sz(gnutls_x509_crt_get_activation_time
956 (cert), buf, sizeof(buf));
957 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
958 apr_pstrdup(r->pool, tmp));
959
960 ret = gnutls_x509_crt_get_signature_algorithm(cert);
961 if (ret >= 0) {
962 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL),
963 gnutls_sign_algorithm_get_name(ret));
964 }
965
966 ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
967 if (ret >= 0) {
968 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
969 gnutls_pk_algorithm_get_name(ret));
970 }
971
972 /* export all the alternative names (DNS, RFC822 and URI) */
973 for (i = 0; !(ret < 0); i++) {
974 len = 0;
975 ret = gnutls_x509_crt_get_subject_alt_name(cert, i,
976 NULL, &len, NULL);
977
978 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) {
979 tmp2 = apr_palloc(r->pool, len + 1);
980
981 ret =
982 gnutls_x509_crt_get_subject_alt_name(cert, i, tmp2, &len,
983 NULL);
984 tmp2[len] = 0;
985
986 if (ret == GNUTLS_SAN_DNSNAME) {
987 apr_table_setn(env,
988 apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i),
989 apr_psprintf(r->pool, "DNSNAME:%s", tmp2));
990 } else if (ret == GNUTLS_SAN_RFC822NAME) {
991 apr_table_setn(env, 982 apr_table_setn(env,
992 apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), 983 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION",
993 apr_psprintf(r->pool, "RFC822NAME:%s", tmp2)); 984 NULL), apr_psprintf(r->pool,
994 } else if (ret == GNUTLS_SAN_URI) { 985 "%u", ret));
986
987 apr_table_setn(env,
988 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL),
989 "X.509");
990
991 tmp =
992 mgs_time2sz(gnutls_x509_crt_get_expiration_time
993 (cert), buf, sizeof(buf));
994 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
995 apr_pstrdup(r->pool, tmp));
996
997 tmp =
998 mgs_time2sz(gnutls_x509_crt_get_activation_time
999 (cert), buf, sizeof(buf));
1000 apr_table_setn(env,
1001 apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
1002 apr_pstrdup(r->pool, tmp));
1003
1004 ret = gnutls_x509_crt_get_signature_algorithm(cert);
1005 if (ret >= 0) {
995 apr_table_setn(env, 1006 apr_table_setn(env,
996 apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), 1007 apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG",
997 apr_psprintf(r->pool, "URI:%s", tmp2)); 1008 NULL),
998 } else { 1009 gnutls_sign_algorithm_get_name(ret));
1010 }
1011
1012 ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
1013 if (ret >= 0) {
999 apr_table_setn(env, 1014 apr_table_setn(env,
1000 apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), 1015 apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY",
1001 "UNSUPPORTED"); 1016 NULL),
1002 } 1017 gnutls_pk_algorithm_get_name(ret));
1018 }
1019
1020 /* export all the alternative names (DNS, RFC822 and URI) */
1021 for (i = 0; !(ret < 0); i++) {
1022 len = 0;
1023 ret = gnutls_x509_crt_get_subject_alt_name(cert, i,
1024 NULL, &len,
1025 NULL);
1026
1027 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) {
1028 tmp2 = apr_palloc(r->pool, len + 1);
1029
1030 ret =
1031 gnutls_x509_crt_get_subject_alt_name(cert, i,
1032 tmp2,
1033 &len,
1034 NULL);
1035 tmp2[len] = 0;
1036
1037 if (ret == GNUTLS_SAN_DNSNAME) {
1038 apr_table_setn(env,
1039 apr_psprintf(r->pool,
1040 "%s_S_AN%u",
1041 MGS_SIDE, i),
1042 apr_psprintf(r->pool,
1043 "DNSNAME:%s",
1044 tmp2));
1045 } else if (ret == GNUTLS_SAN_RFC822NAME) {
1046 apr_table_setn(env,
1047 apr_psprintf(r->pool,
1048 "%s_S_AN%u",
1049 MGS_SIDE, i),
1050 apr_psprintf(r->pool,
1051 "RFC822NAME:%s",
1052 tmp2));
1053 } else if (ret == GNUTLS_SAN_URI) {
1054 apr_table_setn(env,
1055 apr_psprintf(r->pool,
1056 "%s_S_AN%u",
1057 MGS_SIDE, i),
1058 apr_psprintf(r->pool,
1059 "URI:%s",
1060 tmp2));
1061 } else {
1062 apr_table_setn(env,
1063 apr_psprintf(r->pool,
1064 "%s_S_AN%u",
1065 MGS_SIDE, i),
1066 "UNSUPPORTED");
1067 }
1068 }
1003 } 1069 }
1004<