source: mod_gnutls/src/mod_gnutls.c @ 7e2b223

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since 7e2b223 was 7e2b223, checked in by Paul Querna <chip@…>, 15 years ago

break up the IO functions into their own file

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/* ====================================================================
2 *  Copyright 2004 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
20#if APR_HAS_THREADS
21GCRY_THREAD_OPTION_PTHREAD_IMPL;
22#endif
23
24static apr_status_t gnutls_cleanup_pre_config(void *data)
25{
26    gnutls_global_deinit();
27    return APR_SUCCESS;
28}
29
30static int gnutls_hook_pre_config(apr_pool_t * pconf,
31                                  apr_pool_t * plog, apr_pool_t * ptemp)
32{
33
34#if APR_HAS_THREADS
35    gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
36#endif
37
38    gnutls_global_init();
39
40    apr_pool_cleanup_register(pconf, NULL, gnutls_cleanup_pre_config,
41                              apr_pool_cleanup_null);
42
43    return OK;
44}
45
46#define DH_BITS 1024
47#define RSA_BITS 512
48
49static int gnutls_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
50                                   apr_pool_t * ptemp,
51                                   server_rec * base_server)
52{
53    gnutls_srvconf_rec *sc;
54    server_rec *s;
55    gnutls_dh_params_t dh_params;
56    gnutls_rsa_params_t rsa_params;
57
58
59    /* TODO: Should we regenerate these after X requests / X time ? */
60//    gnutls_dh_params_init(&dh_params);
61//    gnutls_dh_params_generate2(dh_params, DH_BITS);
62//    gnutls_rsa_params_init(&rsa_params);
63//    gnutls_rsa_params_generate2(rsa_params, RSA_BITS);
64
65    for (s = base_server; s; s = s->next) {
66        sc = (gnutls_srvconf_rec *) ap_get_module_config(s->module_config,
67                                                         &gnutls_module);
68        if (sc->cert_file != NULL && sc->key_file != NULL) {
69            gnutls_certificate_set_x509_key_file(sc->certs, sc->cert_file,
70                                                 sc->key_file,
71                                                 GNUTLS_X509_FMT_PEM);
72//          gnutls_certificate_set_rsa_export_params(sc->certs, rsa_params);
73//          gnutls_certificate_set_dh_params(sc->certs, dh_params);
74        }
75        else if (sc->enabled == GNUTLS_ENABLED_TRUE) {
76            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
77                         "[GnuTLS] - Host '%s:%d' is missing a Cert and Key File!",
78                         s->server_hostname, s->port);
79        }
80    }
81
82
83    ap_add_version_component(p, "GnuTLS/" LIBGNUTLS_VERSION);
84    return OK;
85}
86
87static const char *gnutls_hook_http_method(const request_rec * r)
88{
89    gnutls_srvconf_rec *sc =
90        (gnutls_srvconf_rec *) ap_get_module_config(r->server->module_config,
91                                                    &gnutls_module);
92
93    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
94        return NULL;
95    }
96
97    return "https";
98}
99
100static apr_port_t gnutls_hook_default_port(const request_rec * r)
101{
102    gnutls_srvconf_rec *sc =
103        (gnutls_srvconf_rec *) ap_get_module_config(r->server->module_config,
104                                                    &gnutls_module);
105
106    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
107        return 0;
108    }
109
110    return 443;
111}
112
113static int gnutls_hook_pre_connection(conn_rec * c, void *csd)
114{
115    gnutls_handle_t *ctxt;
116    gnutls_srvconf_rec *sc =
117        (gnutls_srvconf_rec *) ap_get_module_config(c->base_server->
118                                                    module_config,
119                                                    &gnutls_module);
120
121    if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
122        return DECLINED;
123    }
124
125    ctxt = apr_pcalloc(c->pool, sizeof(*ctxt));
126
127    ctxt->sc = sc;
128    ctxt->status = 0;
129    gnutls_init(&ctxt->session, GNUTLS_SERVER);
130
131    gnutls_cipher_set_priority(ctxt->session, sc->ciphers);
132    gnutls_compression_set_priority(ctxt->session, sc->compression);
133    gnutls_kx_set_priority(ctxt->session, sc->key_exchange);
134    gnutls_protocol_set_priority(ctxt->session, sc->protocol);
135    gnutls_mac_set_priority(ctxt->session, sc->macs);
136
137    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs);
138//  if(anon) {
139//    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred);
140//  }
141
142    gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE);
143
144//    gnutls_dh_set_prime_bits(ctxt->session, DH_BITS);
145
146
147    ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
148
149    gnutls_transport_set_pull_function(ctxt->session,
150                                       mod_gnutls_transport_read);
151    gnutls_transport_set_push_function(ctxt->session,
152                                       mod_gnutls_transport_write);
153    gnutls_transport_set_ptr(ctxt->session, ctxt);
154    ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
155    ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
156
157    return OK;
158}
159
160static const char *gnutls_set_cert_file(cmd_parms * parms, void *dummy,
161                                        const char *arg)
162{
163    gnutls_srvconf_rec *sc =
164        (gnutls_srvconf_rec *) ap_get_module_config(parms->server->
165                                                    module_config,
166                                                    &gnutls_module);
167    sc->cert_file = apr_pstrdup(parms->pool, arg);
168    return NULL;
169}
170
171static const char *gnutls_set_key_file(cmd_parms * parms, void *dummy,
172                                       const char *arg)
173{
174    gnutls_srvconf_rec *sc =
175        (gnutls_srvconf_rec *) ap_get_module_config(parms->server->
176                                                    module_config,
177                                                    &gnutls_module);
178    sc->key_file = apr_pstrdup(parms->pool, arg);
179    return NULL;
180}
181
182static const char *gnutls_set_enabled(cmd_parms * parms, void *dummy,
183                                      const char *arg)
184{
185    gnutls_srvconf_rec *sc =
186        (gnutls_srvconf_rec *) ap_get_module_config(parms->server->
187                                                    module_config,
188                                                    &gnutls_module);
189    if (!strcasecmp(arg, "On")) {
190        sc->enabled = GNUTLS_ENABLED_TRUE;
191    }
192    else if (!strcasecmp(arg, "Off")) {
193        sc->enabled = GNUTLS_ENABLED_FALSE;
194    }
195    else {
196        return "GnuTLSEnable must be set to 'On' or 'Off'";
197    }
198
199    return NULL;
200}
201
202static const command_rec gnutls_cmds[] = {
203    AP_INIT_TAKE1("GnuTLSCertificateFile", gnutls_set_cert_file,
204                  NULL,
205                  RSRC_CONF,
206                  "SSL Server Key file"),
207    AP_INIT_TAKE1("GnuTLSKeyFile", gnutls_set_key_file,
208                  NULL,
209                  RSRC_CONF,
210                  "SSL Server Certificate file"),
211    AP_INIT_TAKE1("GnuTLSEnable", gnutls_set_enabled,
212                  NULL, RSRC_CONF,
213                  "Whether this server has GnuTLS Enabled. Default: Off"),
214
215    {NULL}
216};
217
218/* TODO: CACertificateFile & Client Authentication
219 *    AP_INIT_TAKE1("GnuTLSCACertificateFile", ap_set_server_string_slot,
220 *                 (void *) APR_OFFSETOF(gnutls_srvconf_rec, key_file), NULL,
221 *                 RSRC_CONF,
222 *                 "CA"),
223 */
224
225static void gnutls_hooks(apr_pool_t * p)
226{
227    ap_hook_pre_connection(gnutls_hook_pre_connection, NULL, NULL,
228                           APR_HOOK_MIDDLE);
229    ap_hook_post_config(gnutls_hook_post_config, NULL, NULL, APR_HOOK_MIDDLE);
230    ap_hook_http_method(gnutls_hook_http_method, NULL, NULL, APR_HOOK_MIDDLE);
231    ap_hook_default_port(gnutls_hook_default_port, NULL, NULL,
232                         APR_HOOK_MIDDLE);
233    ap_hook_pre_config(gnutls_hook_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
234
235    /* TODO: HTTP Upgrade Filter */
236    /* ap_register_output_filter ("UPGRADE_FILTER",
237     *          ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5);
238     */
239    ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME,
240                             mod_gnutls_filter_input, NULL,
241                             AP_FTYPE_CONNECTION + 5);
242    ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME,
243                              mod_gnutls_filter_output, NULL,
244                              AP_FTYPE_CONNECTION + 5);
245}
246
247static void *gnutls_config_server_create(apr_pool_t * p, server_rec * s)
248{
249    int i;
250    gnutls_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
251
252    sc->enabled = GNUTLS_ENABLED_FALSE;
253
254    gnutls_certificate_allocate_credentials(&sc->certs);
255    gnutls_anon_allocate_server_credentials(&sc->anoncred);
256    sc->key_file = NULL;
257    sc->cert_file = NULL;
258
259    i = 0;
260    sc->ciphers[i++] = GNUTLS_CIPHER_RIJNDAEL_128_CBC;
261    sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128;
262    sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC;
263    sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
264    sc->ciphers[i] = 0;
265
266    i = 0;
267    sc->key_exchange[i++] = GNUTLS_KX_RSA;
268    sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
269    sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
270    sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
271    sc->key_exchange[i] = 0;
272
273    i = 0;
274    sc->macs[i++] = GNUTLS_MAC_MD5;
275    sc->macs[i++] = GNUTLS_MAC_SHA;
276    sc->macs[i++] = GNUTLS_MAC_RMD160;
277    sc->macs[i] = 0;
278
279    i = 0;
280    sc->protocol[i++] = GNUTLS_TLS1_1;
281    sc->protocol[i++] = GNUTLS_TLS1;
282    sc->protocol[i++] = GNUTLS_SSL3;
283    sc->protocol[i] = 0;
284
285    i = 0;
286    sc->compression[i++] = GNUTLS_COMP_NULL;
287    sc->compression[i++] = GNUTLS_COMP_ZLIB;
288    sc->compression[i++] = GNUTLS_COMP_LZO;
289    sc->compression[i] = 0;
290
291    return sc;
292}
293
294
295
296module AP_MODULE_DECLARE_DATA gnutls_module = {
297    STANDARD20_MODULE_STUFF,
298    NULL,
299    NULL,
300    gnutls_config_server_create,
301    NULL,
302/*    gnutls_config_server_merge, */
303    gnutls_cmds,
304    gnutls_hooks
305};
Note: See TracBrowser for help on using the repository browser.