summaryrefslogtreecommitdiffstatsabout
path: root/src/mod_gnutls.c
diff options
context:
space:
mode:
authorPaul Querna <chip@outoforder.cc>2005-04-24 22:21:50 (GMT)
committer Paul Querna <chip@outoforder.cc>2005-04-24 22:21:50 (GMT)
commitc301152dbbdf13c4bf212c7982b948c21149468d (patch)
tree311447345aca9ee56f930428843aef6a7e48569d /src/mod_gnutls.c
parent46b85d8e3634f34c0142823d92b037dd33b67898 (diff)
- move hooks to gnutls_hooks.c
- use 'mgs_' as the prefix for all symbols, instead of mixed prefixes.
Diffstat (limited to 'src/mod_gnutls.c')
-rw-r--r--src/mod_gnutls.c665
1 files changed, 17 insertions, 648 deletions
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c
index fbcbc52..a2c36ee 100644
--- a/src/mod_gnutls.c
+++ b/src/mod_gnutls.c
@@ -16,676 +16,45 @@
16 */ 16 */
17 17
18#include "mod_gnutls.h" 18#include "mod_gnutls.h"
19#include "http_vhost.h"
20 19
21extern server_rec *ap_server_conf;
22
23#if APR_HAS_THREADS
24GCRY_THREAD_OPTION_PTHREAD_IMPL;
25#endif
26
27#if MOD_GNUTLS_DEBUG
28static apr_file_t* debug_log_fp;
29#endif
30
31static apr_status_t mod_gnutls_cleanup_pre_config(void *data)
32{
33 gnutls_global_deinit();
34 return APR_SUCCESS;
35}
36
37#if MOD_GNUTLS_DEBUG
38static void gnutls_debug_log_all( int level, const char* str)
39{
40 apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
41}
42#endif
43
44static int mod_gnutls_hook_pre_config(apr_pool_t * pconf,
45 apr_pool_t * plog, apr_pool_t * ptemp)
46{
47
48#if APR_HAS_THREADS
49 /* TODO: Check MPM Type here */
50 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
51#endif
52
53 gnutls_global_init();
54
55 apr_pool_cleanup_register(pconf, NULL, mod_gnutls_cleanup_pre_config,
56 apr_pool_cleanup_null);
57
58#if MOD_GNUTLS_DEBUG
59 apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
60 APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, pconf);
61
62 gnutls_global_set_log_level(9);
63 gnutls_global_set_log_function(gnutls_debug_log_all);
64#endif
65
66 return OK;
67}
68
69
70static gnutls_datum load_params(const char* file, server_rec* s,
71 apr_pool_t* pool)
72{
73 gnutls_datum ret = { NULL, 0 };
74 apr_file_t* fp;
75 apr_finfo_t finfo;
76 apr_status_t rv;
77 apr_size_t br = 0;
78
79 rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT,
80 pool);
81 if (rv != APR_SUCCESS) {
82 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
83 "GnuTLS failed to load params file at: %s", file);
84 return ret;
85 }
86
87 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
88
89 if (rv != APR_SUCCESS) {
90 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
91 "GnuTLS failed to stat params file at: %s", file);
92 return ret;
93 }
94
95 ret.data = apr_palloc(pool, finfo.size+1);
96 rv = apr_file_read_full(fp, ret.data, finfo.size, &br);
97
98 if (rv != APR_SUCCESS) {
99 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
100 "GnuTLS failed to read params file at: %s", file);
101 return ret;
102 }
103 apr_file_close(fp);
104 ret.data[br] = '\0';
105 ret.size = br;
106
107 return ret;
108}
109
110static int mod_gnutls_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
111 apr_pool_t * ptemp,
112 server_rec * base_server)
113{
114 int rv;
115 int data_len;
116 server_rec *s;
117 gnutls_dh_params_t dh_params;
118 gnutls_rsa_params_t rsa_params;
119 mod_gnutls_srvconf_rec *sc;
120 mod_gnutls_srvconf_rec *sc_base;
121 void *data = NULL;
122 int first_run = 0;
123 const char *userdata_key = "mod_gnutls_init";
124
125 apr_pool_userdata_get(&data, userdata_key, base_server->process->pool);
126 if (data == NULL) {
127 first_run = 1;
128 apr_pool_userdata_set((const void *)1, userdata_key,
129 apr_pool_cleanup_null,
130 base_server->process->pool);
131 }
132
133
134 {
135 gnutls_datum pdata;
136 apr_pool_t* tpool;
137 s = base_server;
138 sc_base = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config,
139 &gnutls_module);
140
141 apr_pool_create(&tpool, p);
142
143 gnutls_dh_params_init(&dh_params);
144
145 pdata = load_params(sc_base->dh_params_file, s, tpool);
146
147 if (pdata.size != 0) {
148 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
149 GNUTLS_X509_FMT_PEM);
150 if (rv != 0) {
151 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
152 "GnuTLS: Unable to load DH Params: (%d) %s",
153 rv, gnutls_strerror(rv));
154 exit(rv);
155 }
156 }
157 else {
158 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
159 "GnuTLS: Unable to load DH Params."
160 " Shutting Down.");
161 exit(-1);
162 }
163 apr_pool_clear(tpool);
164
165 gnutls_rsa_params_init(&rsa_params);
166
167 pdata = load_params(sc_base->rsa_params_file, s, tpool);
168
169 if (pdata.size != 0) {
170 rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata,
171 GNUTLS_X509_FMT_PEM);
172 if (rv != 0) {
173 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
174 "GnuTLS: Unable to load RSA Params: (%d) %s",
175 rv, gnutls_strerror(rv));
176 exit(rv);
177 }
178 }
179 else {
180 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
181 "GnuTLS: Unable to load RSA Params."
182 " Shutting Down.");
183 exit(-1);
184 }
185
186 apr_pool_destroy(tpool);
187 rv = mod_gnutls_cache_post_config(p, s, sc_base);
188 if (rv != 0) {
189 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
190 "GnuTLS: Post Config for GnuTLSCache Failed."
191 " Shutting Down.");
192 exit(-1);
193 }
194
195 for (s = base_server; s; s = s->next) {
196 sc = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config,
197 &gnutls_module);
198 sc->cache_type = sc_base->cache_type;
199 sc->cache_config = sc_base->cache_config;
200
201 gnutls_certificate_set_rsa_export_params(sc->certs,
202 rsa_params);
203 gnutls_certificate_set_dh_params(sc->certs, dh_params);
204
205 if (sc->cert_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
206 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
207 "[GnuTLS] - Host '%s:%d' is missing a "
208 "Certificate File!",
209 s->server_hostname, s->port);
210 exit(-1);
211 }
212
213 if (sc->privkey_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
214 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
215 "[GnuTLS] - Host '%s:%d' is missing a "
216 "Private Key File!",
217 s->server_hostname, s->port);
218 exit(-1);
219 }
220
221 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
222 GNUTLS_OID_X520_COMMON_NAME, 0, 0,
223 NULL, &data_len);
224
225 if (data_len < 1) {
226 sc->enabled = GNUTLS_ENABLED_FALSE;
227 sc->cert_cn = NULL;
228 continue;
229 }
230
231 sc->cert_cn = apr_palloc(p, data_len);
232 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
233 GNUTLS_OID_X520_COMMON_NAME, 0, 0,
234 sc->cert_cn, &data_len);
235 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
236 s,
237 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X sc: 0x%08X", sc->cert_cn, rv,
238 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(sc->privkey_x509)),
239 (unsigned int)s, (unsigned int)sc);
240 }
241 }
242
243 ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
244
245 return OK;
246}
247
248static void mod_gnutls_hook_child_init(apr_pool_t *p, server_rec *s)
249{
250 apr_status_t rv = APR_SUCCESS;
251 mod_gnutls_srvconf_rec *sc = ap_get_module_config(s->module_config,
252 &gnutls_module);
253
254 if (sc->cache_type != mod_gnutls_cache_none) {
255 rv = mod_gnutls_cache_child_init(p, s, sc);
256 if(rv != APR_SUCCESS) {
257 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
258 "[GnuTLS] - Failed to run Cache Init");
259 }
260 }
261 else {
262 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
263 "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
264 }
265}
266
267static const char *mod_gnutls_hook_http_scheme(const request_rec * r)
268{
269 mod_gnutls_srvconf_rec *sc =
270 (mod_gnutls_srvconf_rec *) ap_get_module_config(r->server->
271 module_config,
272 &gnutls_module);
273
274 if (sc->enabled == GNUTLS_ENABLED_FALSE) {
275 return NULL;
276 }
277
278 return "https";
279}
280
281static apr_port_t mod_gnutls_hook_default_port(const request_rec * r)
282{
283 mod_gnutls_srvconf_rec *sc =
284 (mod_gnutls_srvconf_rec *) ap_get_module_config(r->server->
285 module_config,
286 &gnutls_module);
287
288 if (sc->enabled == GNUTLS_ENABLED_FALSE) {
289 return 0;
290 }
291
292 return 443;
293}
294
295#define MAX_HOST_LEN 255
296
297#if USING_2_1_RECENT
298typedef struct
299{
300 mod_gnutls_handle_t *ctxt;
301 gnutls_retr_st* ret;
302 const char* sni_name;
303} vhost_cb_rec;
304
305int vhost_cb (void* baton, conn_rec* conn, server_rec* s)
306{
307 mod_gnutls_srvconf_rec *tsc;
308 vhost_cb_rec* x = baton;
309
310 tsc = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config,
311 &gnutls_module);
312
313 if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
314 return 0;
315 }
316
317 /* The CN can contain a * -- this will match those too. */
318 if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
319 /* found a match */
320 x->ret->cert.x509 = &tsc->cert_x509;
321 x->ret->key.x509 = tsc->privkey_x509;
322#if MOD_GNUTLS_DEBUG
323 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
324 x->ctxt->c->base_server,
325 "GnuTLS: Virtual Host CB: "
326 "'%s' == '%s'", tsc->cert_cn, x->sni_name);
327#endif
328 /* Because we actually change the server used here, we need to reset
329 * things like ClientVerify.
330 */
331 x->ctxt->sc = tsc;
332 /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
333 * certificate structure *should* change when the server changes.
334 * acccckkkkkk.
335 */
336 gnutls_certificate_server_set_request(x->ctxt->session, x->ctxt->sc->client_verify_mode);
337 return 1;
338 }
339 return 0;
340}
341#endif
342
343static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret)
344{
345 int rv;
346 int sni_type;
347 int data_len = MAX_HOST_LEN;
348 char sni_name[MAX_HOST_LEN];
349 mod_gnutls_handle_t *ctxt;
350#if USING_2_1_RECENT
351 vhost_cb_rec cbx;
352#else
353 server_rec* s;
354 mod_gnutls_srvconf_rec *tsc;
355#endif
356
357 ctxt = gnutls_transport_get_ptr(session);
358
359 sni_type = gnutls_certificate_type_get(session);
360 if (sni_type != GNUTLS_CRT_X509) {
361 /* In theory, we could support OpenPGP Certificates. Theory != code. */
362 ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
363 ctxt->c->base_server,
364 "GnuTLS: Only x509 Certificates are currently supported.");
365 return -1;
366 }
367
368 ret->type = GNUTLS_CRT_X509;
369 ret->ncerts = 1;
370 ret->deinit_all = 0;
371
372 rv = gnutls_server_name_get(ctxt->session, sni_name,
373 &data_len, &sni_type, 0);
374
375 if (rv != 0) {
376 goto use_default_crt;
377 }
378
379 if (sni_type != GNUTLS_NAME_DNS) {
380 ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
381 ctxt->c->base_server,
382 "GnuTLS: Unknown type '%d' for SNI: "
383 "'%s'", sni_type, sni_name);
384 goto use_default_crt;
385 }
386
387 /**
388 * Code in the Core already sets up the c->base_server as the base
389 * for this IP/Port combo. Trust that the core did the 'right' thing.
390 */
391#if USING_2_1_RECENT
392 cbx.ctxt = ctxt;
393 cbx.ret = ret;
394 cbx.sni_name = sni_name;
395
396 rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
397 if (rv == 1) {
398 return 0;
399 }
400#else
401 for (s = ap_server_conf; s; s = s->next) {
402
403 tsc = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config,
404 &gnutls_module);
405 if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
406 continue;
407 }
408#if MOD_GNUTLS_DEBUG
409 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
410 ctxt->c->base_server,
411 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", tsc->cert_cn, rv,
412 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)),
413 (unsigned int)s, (unsigned int)s->next, (unsigned int)tsc);
414#endif
415 /* The CN can contain a * -- this will match those too. */
416 if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
417 /* found a match */
418 ret->cert.x509 = &tsc->cert_x509;
419 ret->key.x509 = tsc->privkey_x509;
420#if MOD_GNUTLS_DEBUG
421 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
422 ctxt->c->base_server,
423 "GnuTLS: Virtual Host: "
424 "'%s' == '%s'", tsc->cert_cn, sni_name);
425#endif
426 ctxt->sc = tsc;
427 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
428 return 0;
429 }
430 }
431#endif
432
433 /**
434 * If the client does not support the Server Name Indication, give the default
435 * certificate for this server.
436 */
437use_default_crt:
438 ret->cert.x509 = &ctxt->sc->cert_x509;
439 ret->key.x509 = ctxt->sc->privkey_x509;
440#if MOD_GNUTLS_DEBUG
441 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
442 ctxt->c->base_server,
443 "GnuTLS: Using Default Certificate.");
444#endif
445 return 0;
446}
447
448static mod_gnutls_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c)
449{
450 mod_gnutls_handle_t *ctxt;
451 mod_gnutls_srvconf_rec *sc =
452 (mod_gnutls_srvconf_rec *) ap_get_module_config(c->base_server->
453 module_config,
454 &gnutls_module);
455
456 ctxt = apr_pcalloc(pool, sizeof(*ctxt));
457 ctxt->c = c;
458 ctxt->sc = sc;
459 ctxt->status = 0;
460
461 ctxt->input_rc = APR_SUCCESS;
462 ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc);
463 ctxt->input_cbuf.length = 0;
464
465 ctxt->output_rc = APR_SUCCESS;
466 ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc);
467 ctxt->output_blen = 0;
468 ctxt->output_length = 0;
469
470 gnutls_init(&ctxt->session, GNUTLS_SERVER);
471
472 gnutls_protocol_set_priority(ctxt->session, sc->protocol);
473 gnutls_cipher_set_priority(ctxt->session, sc->ciphers);
474 gnutls_compression_set_priority(ctxt->session, sc->compression);
475 gnutls_kx_set_priority(ctxt->session, sc->key_exchange);
476 gnutls_mac_set_priority(ctxt->session, sc->macs);
477 gnutls_certificate_type_set_priority(ctxt->session, sc->cert_types);
478
479 mod_gnutls_cache_session_init(ctxt);
480
481 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
482
483 gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn);
484 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
485 return ctxt;
486}
487
488static int mod_gnutls_hook_pre_connection(conn_rec * c, void *csd)
489{
490 mod_gnutls_handle_t *ctxt;
491 mod_gnutls_srvconf_rec *sc =
492 (mod_gnutls_srvconf_rec *) ap_get_module_config(c->base_server->
493 module_config,
494 &gnutls_module);
495
496 if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
497 return DECLINED;
498 }
499
500 ctxt = create_gnutls_handle(c->pool, c);
501
502 ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
503
504 gnutls_transport_set_pull_function(ctxt->session,
505 mod_gnutls_transport_read);
506 gnutls_transport_set_push_function(ctxt->session,
507 mod_gnutls_transport_write);
508 gnutls_transport_set_ptr(ctxt->session, ctxt);
509
510 ctxt->input_filter = ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt,
511 NULL, c);
512 ctxt->output_filter = ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt,
513 NULL, c);
514
515 return OK;
516}
517
518static int mod_gnutls_hook_fixups(request_rec *r)
519{
520 unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
521 char buf[GNUTLS_SESSION_ID_STRING_LEN];
522 const char* tmp;
523 int len;
524 mod_gnutls_handle_t *ctxt;
525 apr_table_t *env = r->subprocess_env;
526
527 ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
528
529 if(!ctxt) {
530 return DECLINED;
531 }
532
533 apr_table_setn(env, "HTTPS", "on");
534
535 apr_table_setn(env, "GNUTLS_VERSION_INTERFACE", MOD_GNUTLS_VERSION);
536 apr_table_setn(env, "GNUTLS_VERSION_LIBRARY", LIBGNUTLS_VERSION);
537
538 apr_table_setn(env, "SSL_PROTOCOL",
539 gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session)));
540
541 apr_table_setn(env, "SSL_CIPHER",
542 gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session)));
543
544 apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
545
546 tmp = apr_psprintf(r->pool, "%d",
547 8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)));
548
549 apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
550
551 apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
552
553 len = sizeof(sbuf);
554 gnutls_session_get_id(ctxt->session, sbuf, &len);
555 tmp = mod_gnutls_session_id2sz(sbuf, len, buf, sizeof(buf));
556 apr_table_setn(env, "SSL_SESSION_ID", tmp);
557
558 return OK;
559}
560
561int mod_gnutls_hook_authz(request_rec *r)
562{
563 int rv;
564 int status;
565 mod_gnutls_handle_t *ctxt;
566 mod_gnutls_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
567 &gnutls_module);
568
569 ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
570
571 if (!ctxt) {
572 return DECLINED;
573 }
574
575 if (!dc) {
576 dc = mgs_config_dir_create(r->pool, NULL);
577 }
578
579 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
580 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
581 "GnuTLS: Directory set to Ignore Client Certificate!");
582 return DECLINED;
583 }
584
585 if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
586 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
587 "GnuTLS: Attempting to rehandshake with peer. %d %d",
588 ctxt->sc->client_verify_mode, dc->client_verify_mode);
589
590 gnutls_certificate_server_set_request(ctxt->session,
591 dc->client_verify_mode);
592
593 if (mod_gnutls_rehandshake(ctxt) != 0) {
594 return HTTP_FORBIDDEN;
595 }
596 }
597 else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) {
598#if MOD_GNUTLS_DEBUG
599 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
600 "GnuTLS: Peer is set to IGNORE");
601#endif
602 return DECLINED;
603 }
604
605 rv = gnutls_certificate_verify_peers2(ctxt->session, &status);
606
607 if (rv < 0) {
608 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
609 "GnuTLS: Failed to Verify Peer: (%d) %s",
610 rv, gnutls_strerror(rv));
611 return HTTP_FORBIDDEN;
612 }
613
614 if (status < 0) {
615 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
616 "GnuTLS: Peer Status is invalid.");
617 return HTTP_FORBIDDEN;
618 }
619
620 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
621 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
622 "GnuTLS: Could not find Signer for Peer Certificate");
623 }
624
625 if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
626 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
627 "GnuTLS: Could not find CA for Peer Certificate");
628 }
629
630 if (status & GNUTLS_CERT_INVALID) {
631 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
632 "GnuTLS: Peer Certificate is invalid.");
633 return HTTP_FORBIDDEN;
634 }
635 else if (status & GNUTLS_CERT_REVOKED) {
636 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
637 "GnuTLS: Peer Certificate is revoked.");
638 return HTTP_FORBIDDEN;
639 }
640
641 /* TODO: OpenPGP Certificates */
642 if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) {
643 ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
644 "GnuTLS: Only x509 is supported for client certificates");
645 return HTTP_FORBIDDEN;
646 }
647 /* TODO: Further Verification. */
648 ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
649 "GnuTLS: Verified Peer.");
650 return OK;
651}
652 20
653static void gnutls_hooks(apr_pool_t * p) 21static void gnutls_hooks(apr_pool_t * p)
654{ 22{
655 ap_hook_pre_connection(mod_gnutls_hook_pre_connection, NULL, NULL, 23 ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL,
656 APR_HOOK_MIDDLE); 24 APR_HOOK_MIDDLE);
657 ap_hook_post_config(mod_gnutls_hook_post_config, NULL, NULL, 25 ap_hook_post_config(mgs_hook_post_config, NULL, NULL,
658 APR_HOOK_MIDDLE);
659 ap_hook_child_init(mod_gnutls_hook_child_init, NULL, NULL,
660 APR_HOOK_MIDDLE); 26 APR_HOOK_MIDDLE);
27 ap_hook_child_init(mgs_hook_child_init, NULL, NULL,
28 APR_HOOK_MIDDLE);
661#if USING_2_1_RECENT 29#if USING_2_1_RECENT
662 ap_hook_http_scheme(mod_gnutls_hook_http_scheme, NULL, NULL, 30 ap_hook_http_scheme(mgs_hook_http_scheme, NULL, NULL,
663 APR_HOOK_MIDDLE); 31 APR_HOOK_MIDDLE);
664#else 32#else
665 ap_hook_http_method(mod_gnutls_hook_http_scheme, NULL, NULL, 33 ap_hook_http_method(mgs_hook_http_scheme, NULL, NULL,
666 APR_HOOK_MIDDLE); 34 APR_HOOK_MIDDLE);
667#endif 35#endif
668 ap_hook_default_port(mod_gnutls_hook_default_port, NULL, NULL, 36 ap_hook_default_port(mgs_hook_default_port, NULL, NULL,
669 APR_HOOK_MIDDLE); 37 APR_HOOK_MIDDLE);
670 ap_hook_pre_config(mod_gnutls_hook_pre_config, NULL, NULL, 38 ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL,
671 APR_HOOK_MIDDLE); 39 APR_HOOK_MIDDLE);
672 40
673 ap_hook_access_checker(mod_gnutls_hook_authz, NULL, NULL, APR_HOOK_REALLY_FIRST); 41 ap_hook_access_checker(mgs_hook_authz, NULL, NULL, APR_HOOK_REALLY_FIRST);
674 42
675 ap_hook_fixups(mod_gnutls_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST); 43 ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST);
676 44
677 /* TODO: HTTP Upgrade Filter */ 45 /* TODO: HTTP Upgrade Filter */
678 /* ap_register_output_filter ("UPGRADE_FILTER", 46 /* ap_register_output_filter ("UPGRADE_FILTER",
679 * ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); 47 * ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5);
680 */ 48*/
681 ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, 49 ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME,
682 mod_gnutls_filter_input, NULL, 50 mgs_filter_input, NULL,
683 AP_FTYPE_CONNECTION + 5); 51 AP_FTYPE_CONNECTION + 5);
684 ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, 52 ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME,
685 mod_gnutls_filter_output, NULL, 53 mgs_filter_output, NULL,
686 AP_FTYPE_CONNECTION + 5); 54 AP_FTYPE_CONNECTION + 5);
687} 55}
688 56
57
689static const command_rec mgs_config_cmds[] = { 58static const command_rec mgs_config_cmds[] = {
690 AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify, 59 AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify,
691 NULL, 60 NULL,