summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorPaul Querna <chip@outoforder.cc>2005-04-24 22:01:46 (GMT)
committer Paul Querna <chip@outoforder.cc>2005-04-24 22:01:46 (GMT)
commit46b85d8e3634f34c0142823d92b037dd33b67898 (patch)
treef954816da40604a387447dd688d3655c07abc58a
parent316bd8cab0ab97335f2b0e36c3a240ff7967ed1a (diff)
move config functions to their own file.
-rw-r--r--include/mod_gnutls.h.in27
-rw-r--r--mod_gnutls.xcode/project.pbxproj10
-rw-r--r--src/Makefile.am2
-rw-r--r--src/gnutls_cache.c2
-rw-r--r--src/gnutls_config.c328
-rw-r--r--src/mod_gnutls.c402
6 files changed, 415 insertions, 356 deletions
diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in
index 62cae02..61b0198 100644
--- a/include/mod_gnutls.h.in
+++ b/include/mod_gnutls.h.in
@@ -212,4 +212,31 @@ int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt);
212char *mod_gnutls_session_id2sz(unsigned char *id, int idlen, 212char *mod_gnutls_session_id2sz(unsigned char *id, int idlen,
213 char *str, int strsize); 213 char *str, int strsize);
214 214
215/* Configuration Functions */
216
217const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
218 const char *arg);
219
220const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
221 const char *arg);
222
223const char *mgs_set_cache(cmd_parms * parms, void *dummy,
224 const char *type, const char* arg);
225
226const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
227 const char *arg);
228
229const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
230 const char *arg);
231
232const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
233 const char *arg);
234
235const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
236 const char *arg);
237
238void *mgs_config_server_create(apr_pool_t * p, server_rec * s);
239
240void *mgs_config_dir_create(apr_pool_t *p, char *dir);
241
215#endif /* __mod_gnutls_h_inc */ 242#endif /* __mod_gnutls_h_inc */
diff --git a/mod_gnutls.xcode/project.pbxproj b/mod_gnutls.xcode/project.pbxproj
index 7b9c1e0..fd24bb2 100644
--- a/mod_gnutls.xcode/project.pbxproj
+++ b/mod_gnutls.xcode/project.pbxproj
@@ -5,8 +5,18 @@
5 }; 5 };
6 objectVersion = 39; 6 objectVersion = 39;
7 objects = { 7 objects = {
8 4541F3BA081C4B1A007457C1 = {
9 fileEncoding = 30;
10 isa = PBXFileReference;
11 lastKnownFileType = sourcecode.c.c;
12 name = gnutls_config.c;
13 path = src/gnutls_config.c;
14 refType = 2;
15 sourceTree = SOURCE_ROOT;
16 };
8 45B624630802F1E200CBFD9A = { 17 45B624630802F1E200CBFD9A = {
9 children = ( 18 children = (
19 4541F3BA081C4B1A007457C1,
10 45B6246D0802F20D00CBFD9A, 20 45B6246D0802F20D00CBFD9A,
11 45B6247D0802F85B00CBFD9A, 21 45B6247D0802F85B00CBFD9A,
12 45B6247A0802F84500CBFD9A, 22 45B6247A0802F84500CBFD9A,
diff --git a/src/Makefile.am b/src/Makefile.am
index 30315a1..a15fc57 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
1CLEANFILES = .libs/libmod_gnutls *~ 1CLEANFILES = .libs/libmod_gnutls *~
2 2
3libmod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c 3libmod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c gnutls_config.c
4libmod_gnutls_la_CFLAGS = -Wall ${MODULE_CFLAGS} 4libmod_gnutls_la_CFLAGS = -Wall ${MODULE_CFLAGS}
5libmod_gnutls_la_LDFLAGS = -rpath ${AP_LIBEXECDIR} -module -avoid-version ${MODULE_LIBS} 5libmod_gnutls_la_LDFLAGS = -rpath ${AP_LIBEXECDIR} -module -avoid-version ${MODULE_LIBS}
6 6
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c
index eaeeea6..8499b84 100644
--- a/src/gnutls_cache.c
+++ b/src/gnutls_cache.c
@@ -79,7 +79,7 @@ char *mod_gnutls_session_id2sz(unsigned char *id, int idlen,
79/* The underlying apr_memcache system is thread safe... woohoo */ 79/* The underlying apr_memcache system is thread safe... woohoo */
80static apr_memcache_t* mc; 80static apr_memcache_t* mc;
81 81
82int mc_cache_child_init(apr_pool_t *p, server_rec *s, 82static int mc_cache_child_init(apr_pool_t *p, server_rec *s,
83 mod_gnutls_srvconf_rec *sc) 83 mod_gnutls_srvconf_rec *sc)
84{ 84{
85 apr_status_t rv = APR_SUCCESS; 85 apr_status_t rv = APR_SUCCESS;
diff --git a/src/gnutls_config.c b/src/gnutls_config.c
new file mode 100644
index 0000000..2c29ccb
--- /dev/null
+++ b/src/gnutls_config.c
@@ -0,0 +1,328 @@
1/**
2 * Copyright 2004-2005 Paul Querna
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#include "mod_gnutls.h"
19
20static int load_datum_from_file(apr_pool_t* pool,
21 const char* file,
22 gnutls_datum_t* data)
23{
24 apr_file_t* fp;
25 apr_finfo_t finfo;
26 apr_status_t rv;
27 apr_size_t br = 0;
28
29 rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT,
30 pool);
31 if (rv != APR_SUCCESS) {
32 return rv;
33 }
34
35 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
36
37 if (rv != APR_SUCCESS) {
38 return rv;
39 }
40
41 data->data = apr_palloc(pool, finfo.size+1);
42 rv = apr_file_read_full(fp, data->data, finfo.size, &br);
43
44 if (rv != APR_SUCCESS) {
45 return rv;
46 }
47 apr_file_close(fp);
48
49 data->data[br] = '\0';
50 data->size = br;
51
52 return 0;
53}
54
55const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
56 const char *arg)
57{
58 int ret;
59 gnutls_datum_t data;
60 const char* file;
61 apr_pool_t* spool;
62 mod_gnutls_srvconf_rec *sc =
63 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
64 module_config,
65 &gnutls_module);
66 apr_pool_create(&spool, parms->pool);
67
68 file = ap_server_root_relative(spool, arg);
69
70 if (load_datum_from_file(spool, file, &data) != 0) {
71 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
72 "Certificate '%s'", file);
73 }
74
75 gnutls_x509_crt_init(&sc->cert_x509);
76 ret = gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
77 if (ret != 0) {
78 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
79 "Certificate'%s': (%d) %s", file, ret,
80 gnutls_strerror(ret));
81 }
82
83 apr_pool_destroy(spool);
84 return NULL;
85}
86
87const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
88 const char *arg)
89{
90 int ret;
91 gnutls_datum_t data;
92 const char* file;
93 apr_pool_t* spool;
94 mod_gnutls_srvconf_rec *sc =
95 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
96 module_config,
97 &gnutls_module);
98 apr_pool_create(&spool, parms->pool);
99
100 file = ap_server_root_relative(spool, arg);
101
102 if (load_datum_from_file(spool, file, &data) != 0) {
103 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
104 "Private Key '%s'", file);
105 }
106
107 gnutls_x509_privkey_init(&sc->privkey_x509);
108 ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
109 if (ret != 0) {
110 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
111 "Private Key '%s': (%d) %s", file, ret,
112 gnutls_strerror(ret));
113 }
114 apr_pool_destroy(spool);
115 return NULL;
116}
117
118const char *mgs_set_cache(cmd_parms * parms, void *dummy,
119 const char *type, const char* arg)
120{
121 const char* err;
122 mod_gnutls_srvconf_rec *sc = ap_get_module_config(parms->server->
123 module_config,
124 &gnutls_module);
125 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
126 return err;
127 }
128
129 if (strcasecmp("none", type) == 0) {
130 sc->cache_type = mod_gnutls_cache_none;
131 }
132 else if (strcasecmp("dbm", type) == 0) {
133 sc->cache_type = mod_gnutls_cache_dbm;
134 }
135#if HAVE_APR_MEMCACHE
136 else if (strcasecmp("memcache", type) == 0) {
137 sc->cache_type = mod_gnutls_cache_memcache;
138 }
139#endif
140 else {
141 return "Invalid Type for GnuTLSCache!";
142 }
143
144 if (sc->cache_type == mod_gnutls_cache_dbm) {
145 sc->cache_config = ap_server_root_relative(parms->pool, arg);
146 }
147 else {
148 sc->cache_config = apr_pstrdup(parms->pool, arg);
149 }
150
151 return NULL;
152}
153
154const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
155 const char *arg)
156{
157 int argint;
158 mod_gnutls_srvconf_rec *sc =
159 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
160 module_config,
161 &gnutls_module);
162
163 argint = atoi(arg);
164
165 if (argint < 0) {
166 return "GnuTLSCacheTimeout: Invalid argument";
167 }
168 else if (argint == 0) {
169 sc->cache_timeout = 0;
170 }
171 else {
172 sc->cache_timeout = apr_time_from_sec(argint);
173 }
174
175 return NULL;
176}
177
178const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
179 const char *arg)
180{
181 int mode;
182
183 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
184 mode = GNUTLS_CERT_IGNORE;
185 }
186 else if (strcasecmp("optional", arg) == 0 || strcasecmp("request", arg) == 0) {
187 mode = GNUTLS_CERT_REQUEST;
188 }
189 else if (strcasecmp("require", arg) == 0) {
190 mode = GNUTLS_CERT_REQUIRE;
191 }
192 else {
193 return "GnuTLSClientVerify: Invalid argument";
194 }
195
196 /* This was set from a directory context */
197 if (parms->path) {
198 mod_gnutls_dirconf_rec *dc = (mod_gnutls_dirconf_rec *)dummy;
199 dc->client_verify_mode = mode;
200 }
201 else {
202 mod_gnutls_srvconf_rec *sc =
203 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
204 module_config,
205 &gnutls_module);
206 sc->client_verify_mode = mode;
207 }
208
209 return NULL;
210}
211
212const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
213 const char *arg)
214{
215 int rv;
216 const char* file;
217 mod_gnutls_srvconf_rec *sc =
218 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
219 module_config,
220 &gnutls_module);
221 file = ap_server_root_relative(parms->pool, arg);
222 rv = gnutls_certificate_set_x509_trust_file(sc->certs,
223 file, GNUTLS_X509_FMT_PEM);
224
225 if (rv < 0) {
226 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
227 "Client CA File '%s': (%d) %s", file, rv,
228 gnutls_strerror(rv));
229 }
230 return NULL;
231}
232
233const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
234 const char *arg)
235{
236 mod_gnutls_srvconf_rec *sc =
237 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
238 module_config,
239 &gnutls_module);
240 if (!strcasecmp(arg, "On")) {
241 sc->enabled = GNUTLS_ENABLED_TRUE;
242 }
243 else if (!strcasecmp(arg, "Off")) {
244 sc->enabled = GNUTLS_ENABLED_FALSE;
245 }
246 else {
247 return "GnuTLSEnable must be set to 'On' or 'Off'";
248 }
249
250 return NULL;
251}
252
253void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
254{
255 int i;
256 mod_gnutls_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
257
258 sc->enabled = GNUTLS_ENABLED_FALSE;
259
260 gnutls_certificate_allocate_credentials(&sc->certs);
261 sc->privkey_x509 = NULL;
262 sc->cert_x509 = NULL;
263 sc->cache_timeout = apr_time_from_sec(300);
264 sc->cache_type = mod_gnutls_cache_dbm;
265 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
266
267 /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */
268 sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile");
269 sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile");
270
271 /* Finish SSL Client Certificate Support */
272 sc->client_verify_mode = GNUTLS_CERT_IGNORE;
273
274 /* TODO: Make this Configurable ! */
275 /* mod_ssl uses a flex based parser for this part.. sigh */
276 i = 0;
277 sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC;
278 sc->ciphers[i++] = GNUTLS_CIPHER_AES_128_CBC;
279 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128;
280 sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC;
281 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
282 sc->ciphers[i] = 0;
283
284 i = 0;
285 sc->key_exchange[i++] = GNUTLS_KX_RSA;
286 sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
287 sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
288 sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
289 sc->key_exchange[i++] = GNUTLS_KX_ANON_DH;
290 sc->key_exchange[i++] = GNUTLS_KX_SRP;
291 sc->key_exchange[i++] = GNUTLS_KX_SRP_RSA;
292 sc->key_exchange[i++] = GNUTLS_KX_SRP_DSS;
293 sc->key_exchange[i] = 0;
294
295 i = 0;
296 sc->macs[i++] = GNUTLS_MAC_SHA;
297 sc->macs[i++] = GNUTLS_MAC_MD5;
298 sc->macs[i++] = GNUTLS_MAC_RMD160;
299 sc->macs[i] = 0;
300
301 i = 0;
302 sc->protocol[i++] = GNUTLS_TLS1_1;
303 sc->protocol[i++] = GNUTLS_TLS1;
304 sc->protocol[i++] = GNUTLS_SSL3;
305 sc->protocol[i] = 0;
306
307 i = 0;
308 sc->compression[i++] = GNUTLS_COMP_NULL;
309 sc->compression[i++] = GNUTLS_COMP_ZLIB;
310 sc->compression[i++] = GNUTLS_COMP_LZO;
311 sc->compression[i] = 0;
312
313 i = 0;
314 sc->cert_types[i++] = GNUTLS_CRT_X509;
315 sc->cert_types[i] = 0;
316
317 return sc;
318}
319
320void *mgs_config_dir_create(apr_pool_t *p, char *dir)
321{
322 mod_gnutls_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
323
324 dc->client_verify_mode = -1;
325
326 return dc;
327}
328
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c
index 681411b..fbcbc52 100644
--- a/src/mod_gnutls.c
+++ b/src/mod_gnutls.c
@@ -292,11 +292,6 @@ static apr_port_t mod_gnutls_hook_default_port(const request_rec * r)
292 return 443; 292 return 443;
293} 293}
294 294
295static void mod_gnutls_changed_servers(mod_gnutls_handle_t *ctxt)
296{
297 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
298}
299
300#define MAX_HOST_LEN 255 295#define MAX_HOST_LEN 255
301 296
302#if USING_2_1_RECENT 297#if USING_2_1_RECENT
@@ -334,7 +329,11 @@ int vhost_cb (void* baton, conn_rec* conn, server_rec* s)
334 * things like ClientVerify. 329 * things like ClientVerify.
335 */ 330 */
336 x->ctxt->sc = tsc; 331 x->ctxt->sc = tsc;
337 mod_gnutls_changed_servers(x->ctxt); 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);
338 return 1; 337 return 1;
339 } 338 }
340 return 0; 339 return 0;
@@ -425,7 +424,7 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret)
425 "'%s' == '%s'", tsc->cert_cn, sni_name); 424 "'%s' == '%s'", tsc->cert_cn, sni_name);
426#endif 425#endif
427 ctxt->sc = tsc; 426 ctxt->sc = tsc;
428 mod_gnutls_changed_servers(ctxt); 427 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
429 return 0; 428 return 0;
430 } 429 }
431 } 430 }
@@ -482,8 +481,7 @@ static mod_gnutls_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c)
482 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs); 481 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
483 482
484 gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); 483 gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn);
485 484 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
486 mod_gnutls_changed_servers(ctxt);
487 return ctxt; 485 return ctxt;
488} 486}
489 487
@@ -560,273 +558,6 @@ static int mod_gnutls_hook_fixups(request_rec *r)
560 return OK; 558 return OK;
561} 559}
562 560
563static int load_datum_from_file(apr_pool_t* pool,
564 const char* file,
565 gnutls_datum_t* data)
566{
567 apr_file_t* fp;
568 apr_finfo_t finfo;
569 apr_status_t rv;
570 apr_size_t br = 0;
571
572 rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT,
573 pool);
574 if (rv != APR_SUCCESS) {
575 return rv;
576 }
577
578 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
579
580 if (rv != APR_SUCCESS) {
581 return rv;
582 }
583
584 data->data = apr_palloc(pool, finfo.size+1);
585 rv = apr_file_read_full(fp, data->data, finfo.size, &br);
586
587 if (rv != APR_SUCCESS) {
588 return rv;
589 }
590 apr_file_close(fp);
591
592 data->data[br] = '\0';
593 data->size = br;
594
595 return 0;
596}
597
598static const char *gnutls_set_cert_file(cmd_parms * parms, void *dummy,
599 const char *arg)
600{
601 int ret;
602 gnutls_datum_t data;
603 const char* file;
604 apr_pool_t* spool;
605 mod_gnutls_srvconf_rec *sc =
606 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
607 module_config,
608 &gnutls_module);
609 apr_pool_create(&spool, parms->pool);
610
611 file = ap_server_root_relative(spool, arg);
612
613 if (load_datum_from_file(spool, file, &data) != 0) {
614 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
615 "Certificate '%s'", file);
616 }
617
618 gnutls_x509_crt_init(&sc->cert_x509);
619 ret = gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
620 if (ret != 0) {
621 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
622 "Certificate'%s': (%d) %s", file, ret,
623 gnutls_strerror(ret));
624 }
625
626 apr_pool_destroy(spool);
627 return NULL;
628}
629
630static const char *gnutls_set_key_file(cmd_parms * parms, void *dummy,
631 const char *arg)
632{
633 int ret;
634 gnutls_datum_t data;
635 const char* file;
636 apr_pool_t* spool;
637 mod_gnutls_srvconf_rec *sc =
638 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
639 module_config,
640 &gnutls_module);
641 apr_pool_create(&spool, parms->pool);
642
643 file = ap_server_root_relative(spool, arg);
644
645 if (load_datum_from_file(spool, file, &data) != 0) {
646 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
647 "Private Key '%s'", file);
648 }
649
650 gnutls_x509_privkey_init(&sc->privkey_x509);
651 ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
652 if (ret != 0) {
653 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
654 "Private Key '%s': (%d) %s", file, ret,
655 gnutls_strerror(ret));
656 }
657 apr_pool_destroy(spool);
658 return NULL;
659}
660
661static const char *gnutls_set_cache(cmd_parms * parms, void *dummy,
662 const char *type, const char* arg)
663{
664 const char* err;
665 mod_gnutls_srvconf_rec *sc = ap_get_module_config(parms->server->
666 module_config,
667 &gnutls_module);
668 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
669 return err;
670 }
671
672 if (strcasecmp("none", type) == 0) {
673 sc->cache_type = mod_gnutls_cache_none;
674 }
675 else if (strcasecmp("dbm", type) == 0) {
676 sc->cache_type = mod_gnutls_cache_dbm;
677 }
678#if HAVE_APR_MEMCACHE
679 else if (strcasecmp("memcache", type) == 0) {
680 sc->cache_type = mod_gnutls_cache_memcache;
681 }
682#endif
683 else {
684 return "Invalid Type for GnuTLSCache!";
685 }
686
687 if (sc->cache_type == mod_gnutls_cache_dbm) {
688 sc->cache_config = ap_server_root_relative(parms->pool, arg);
689 }
690 else {
691 sc->cache_config = apr_pstrdup(parms->pool, arg);
692 }
693
694 return NULL;
695}
696
697static const char *gnutls_set_cache_timeout(cmd_parms * parms, void *dummy,
698 const char *arg)
699{
700 int argint;
701 mod_gnutls_srvconf_rec *sc =
702 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
703 module_config,
704 &gnutls_module);
705
706 argint = atoi(arg);
707
708 if (argint < 0) {
709 return "GnuTLSCacheTimeout: Invalid argument";
710 }
711 else if (argint == 0) {
712 sc->cache_timeout = 0;
713 }
714 else {
715 sc->cache_timeout = apr_time_from_sec(argint);
716 }
717
718 return NULL;
719}
720
721
722static const char *gnutls_set_client_verify(cmd_parms * parms, void *dummy,
723 const char *arg)
724{
725 int mode;
726
727 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
728 mode = GNUTLS_CERT_IGNORE;
729 }
730 else if (strcasecmp("optional", arg) == 0 || strcasecmp("request", arg) == 0) {
731 mode = GNUTLS_CERT_REQUEST;
732 }
733 else if (strcasecmp("require", arg) == 0) {
734 mode = GNUTLS_CERT_REQUIRE;
735 }
736 else {
737 return "GnuTLSClientVerify: Invalid argument";
738 }
739
740 /* This was set from a directory context */
741 if (parms->path) {
742 mod_gnutls_dirconf_rec *dc = (mod_gnutls_dirconf_rec *)dummy;
743 dc->client_verify_mode = mode;
744 }
745 else {
746 mod_gnutls_srvconf_rec *sc =
747 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
748 module_config,
749 &gnutls_module);
750 sc->client_verify_mode = mode;
751 }
752
753 return NULL;
754}
755
756static const char *gnutls_set_client_ca_file(cmd_parms * parms, void *dummy,
757 const char *arg)
758{
759 int rv;
760 const char* file;
761 mod_gnutls_srvconf_rec *sc =
762 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
763 module_config,
764 &gnutls_module);
765 file = ap_server_root_relative(parms->pool, arg);
766 rv = gnutls_certificate_set_x509_trust_file(sc->certs,
767 file, GNUTLS_X509_FMT_PEM);
768
769 if (rv < 0) {
770 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
771 "Client CA File '%s': (%d) %s", file, rv,
772 gnutls_strerror(rv));
773 }
774 return NULL;
775}
776
777
778static const char *gnutls_set_enabled(cmd_parms * parms, void *dummy,
779 const char *arg)
780{
781 mod_gnutls_srvconf_rec *sc =
782 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server->
783 module_config,
784 &gnutls_module);
785 if (!strcasecmp(arg, "On")) {
786 sc->enabled = GNUTLS_ENABLED_TRUE;
787 }
788 else if (!strcasecmp(arg, "Off")) {
789 sc->enabled = GNUTLS_ENABLED_FALSE;
790 }
791 else {
792 return "GnuTLSEnable must be set to 'On' or 'Off'";
793 }
794
795 return NULL;
796}
797
798static const command_rec gnutls_cmds[] = {
799 AP_INIT_TAKE1("GnuTLSClientVerify", gnutls_set_client_verify,
800 NULL,
801 RSRC_CONF|OR_AUTHCFG,
802 "Set Verification Requirements of the Client Certificate"),
803 AP_INIT_TAKE1("GnuTLSClientCAFile", gnutls_set_client_ca_file,
804 NULL,
805 RSRC_CONF,
806 "Set the CA File for Client Certificates"),
807 AP_INIT_TAKE1("GnuTLSCertificateFile", gnutls_set_cert_file,
808 NULL,
809 RSRC_CONF,
810 "SSL Server Key file"),
811 AP_INIT_TAKE1("GnuTLSKeyFile", gnutls_set_key_file,
812 NULL,
813 RSRC_CONF,
814 "SSL Server Certificate file"),
815 AP_INIT_TAKE1("GnuTLSCacheTimeout", gnutls_set_cache_timeout,
816 NULL,
817 RSRC_CONF,
818 "Cache Timeout"),
819 AP_INIT_TAKE2("GnuTLSCache", gnutls_set_cache,
820 NULL,
821 RSRC_CONF,
822 "Cache Configuration"),
823 AP_INIT_TAKE1("GnuTLSEnable", gnutls_set_enabled,
824 NULL, RSRC_CONF,
825 "Whether this server has GnuTLS Enabled. Default: Off"),
826
827 {NULL}
828};
829
830int mod_gnutls_hook_authz(request_rec *r) 561int mod_gnutls_hook_authz(request_rec *r)
831{ 562{
832 int rv; 563 int rv;
@@ -836,6 +567,14 @@ int mod_gnutls_hook_authz(request_rec *r)
836 &gnutls_module); 567 &gnutls_module);
837 568
838 ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module); 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 }
839 578
840 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { 579 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
841 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 580 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
@@ -947,89 +686,44 @@ static void gnutls_hooks(apr_pool_t * p)
947 AP_FTYPE_CONNECTION + 5); 686 AP_FTYPE_CONNECTION + 5);
948} 687}
949 688
950static void *gnutls_config_server_create(apr_pool_t * p, server_rec * s) 689static const command_rec mgs_config_cmds[] = {
951{ 690 AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify,
952 int i; 691 NULL,
953 mod_gnutls_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); 692 RSRC_CONF|OR_AUTHCFG,
954 693 "Set Verification Requirements of the Client Certificate"),
955 sc->enabled = GNUTLS_ENABLED_FALSE; 694 AP_INIT_TAKE1("GnuTLSClientCAFile", mgs_set_client_ca_file,
956 695 NULL,
957 gnutls_certificate_allocate_credentials(&sc->certs); 696 RSRC_CONF,
958 sc->privkey_x509 = NULL; 697 "Set the CA File for Client Certificates"),
959 sc->cert_x509 = NULL; 698 AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file,
960 sc->cache_timeout = apr_time_from_sec(300); 699 NULL,
961 sc->cache_type = mod_gnutls_cache_dbm; 700 RSRC_CONF,
962 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); 701 "SSL Server Key file"),
963 702 AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file,
964 /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */ 703 NULL,
965 sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile"); 704 RSRC_CONF,
966 sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile"); 705 "SSL Server Certificate file"),
967 706 AP_INIT_TAKE1("GnuTLSCacheTimeout", mgs_set_cache_timeout,
968 /* Finish SSL Client Certificate Support */ 707 NULL,
969 sc->client_verify_mode = GNUTLS_CERT_IGNORE; 708 RSRC_CONF,
970 709 "Cache Timeout"),
971 /* TODO: Make this Configurable ! */ 710 AP_INIT_TAKE2("GnuTLSCache", mgs_set_cache,
972 /* mod_ssl uses a flex based parser for this part.. sigh */ 711 NULL,
973 i = 0; 712 RSRC_CONF,
974 sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC; 713 "Cache Configuration"),
975 sc->ciphers[i++] = GNUTLS_CIPHER_AES_128_CBC; 714 AP_INIT_TAKE1("GnuTLSEnable", mgs_set_enabled,
976 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128; 715 NULL, RSRC_CONF,
977 sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC; 716 "Whether this server has GnuTLS Enabled. Default: Off"),
978 sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
979 sc->ciphers[i] = 0;
980
981 i = 0;
982 sc->key_exchange[i++] = GNUTLS_KX_RSA;
983 sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
984 sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
985 sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
986 sc->key_exchange[i++] = GNUTLS_KX_ANON_DH;
987 sc->key_exchange[i++] = GNUTLS_KX_SRP;
988 sc->key_exchange[i++] = GNUTLS_KX_SRP_RSA;
989 sc->key_exchange[i++] = GNUTLS_KX_SRP_DSS;
990 sc->key_exchange[i] = 0;
991
992 i = 0;
993 sc->macs[i++] = GNUTLS_MAC_SHA;
994 sc->macs[i++] = GNUTLS_MAC_MD5;
995 sc->macs[i++] = GNUTLS_MAC_RMD160;
996 sc->macs[i] = 0;
997
998 i = 0;
999 sc->protocol[i++] = GNUTLS_TLS1_1;
1000 sc->protocol[i++] = GNUTLS_TLS1;
1001 sc->protocol[i++] = GNUTLS_SSL3;
1002 sc->protocol[i] = 0;
1003
1004 i = 0;
1005 sc->compression[i++] = GNUTLS_COMP_NULL;
1006 sc->compression[i++] = GNUTLS_COMP_ZLIB;
1007 sc->compression[i++] = GNUTLS_COMP_LZO;
1008 sc->compression[i] = 0;
1009
1010 i = 0;
1011 sc->cert_types[i++] = GNUTLS_CRT_X509;
1012 sc->cert_types[i] = 0;
1013
1014 return sc;
1015}
1016
1017void *gnutls_config_dir_create(apr_pool_t *p, char *dir)
1018{
1019 mod_gnutls_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
1020
1021 dc->client_verify_mode = -1;
1022 717
1023 return dc; 718 {NULL}
1024} 719};
1025 720
1026module AP_MODULE_DECLARE_DATA gnutls_module = { 721module AP_MODULE_DECLARE_DATA gnutls_module = {
1027 STANDARD20_MODULE_STUFF, 722 STANDARD20_MODULE_STUFF,
1028 gnutls_config_dir_create, 723 mgs_config_dir_create,
1029 NULL, 724 NULL,
1030 gnutls_config_server_create, 725 mgs_config_server_create,
1031 NULL, 726 NULL,
1032/* gnutls_config_server_merge, */ 727 mgs_config_cmds,
1033 gnutls_cmds,
1034 gnutls_hooks 728 gnutls_hooks
1035}; 729};