source: mod_gnutls/src/gnutls_config.c @ fd73a08

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since fd73a08 was fd73a08, checked in by Nokis Mavrogiannopoulos <nmav@…>, 12 years ago

Added support for subject alternative names. (untested)

  • Property mode set to 100644
File size: 10.4 KB
Line 
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, gnutls_datum_t * data)
22{
23    apr_file_t *fp;
24    apr_finfo_t finfo;
25    apr_status_t rv;
26    apr_size_t br = 0;
27
28    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,
29                       pool);
30    if (rv != APR_SUCCESS) {
31        return rv;
32    }
33
34    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
35
36    if (rv != APR_SUCCESS) {
37        return rv;
38    }
39
40    data->data = apr_palloc(pool, finfo.size + 1);
41    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
42
43    if (rv != APR_SUCCESS) {
44        return rv;
45    }
46    apr_file_close(fp);
47
48    data->data[br] = '\0';
49    data->size = br;
50
51    return 0;
52}
53
54const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
55                            const char *arg)
56{
57    mgs_srvconf_rec *sc =
58        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
59                                                 module_config,
60                                                 &gnutls_module);
61
62    sc->dh_params_file = ap_server_root_relative(parms->pool, arg);
63
64    return NULL;
65}
66
67const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
68                                    const char *arg)
69{
70    mgs_srvconf_rec *sc =
71        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
72                                                 module_config,
73                                                 &gnutls_module);
74
75    sc->rsa_params_file = ap_server_root_relative(parms->pool, arg);
76
77    return NULL;
78}
79
80
81const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
82                              const char *arg)
83{
84    int ret;
85    gnutls_datum_t data;
86    const char *file;
87    apr_pool_t *spool;
88    mgs_srvconf_rec *sc =
89        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
90                                                 module_config,
91                                                 &gnutls_module);
92    apr_pool_create(&spool, parms->pool);
93
94    file = ap_server_root_relative(spool, arg);
95
96    if (load_datum_from_file(spool, file, &data) != 0) {
97        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
98                            "Certificate '%s'", file);
99    }
100
101    gnutls_x509_crt_init(&sc->cert_x509);
102    ret =
103        gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
104    if (ret != 0) {
105        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
106                            "Certificate'%s': (%d) %s", file, ret,
107                            gnutls_strerror(ret));
108    }
109
110    apr_pool_destroy(spool);
111    return NULL;
112}
113
114const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
115                             const char *arg)
116{
117    int ret;
118    gnutls_datum_t data;
119    const char *file;
120    apr_pool_t *spool;
121    mgs_srvconf_rec *sc =
122        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
123                                                 module_config,
124                                                 &gnutls_module);
125    apr_pool_create(&spool, parms->pool);
126
127    file = ap_server_root_relative(spool, arg);
128
129    if (load_datum_from_file(spool, file, &data) != 0) {
130        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
131                            "Private Key '%s'", file);
132    }
133
134    gnutls_x509_privkey_init(&sc->privkey_x509);
135    ret =
136        gnutls_x509_privkey_import(sc->privkey_x509, &data,
137                                   GNUTLS_X509_FMT_PEM);
138    if (ret != 0) {
139        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
140                            "Private Key '%s': (%d) %s", file, ret,
141                            gnutls_strerror(ret));
142    }
143    apr_pool_destroy(spool);
144    return NULL;
145}
146
147const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
148                                     const char *arg)
149{
150    mgs_srvconf_rec *sc =
151        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
152                                                 module_config,
153                                                 &gnutls_module);
154
155    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
156
157    return NULL;
158}
159
160const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
161                                          const char *arg)
162{
163    mgs_srvconf_rec *sc =
164        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
165                                                 module_config,
166                                                 &gnutls_module);
167
168    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
169
170    return NULL;
171}
172
173const char *mgs_set_cache(cmd_parms * parms, void *dummy,
174                          const char *type, const char *arg)
175{
176    const char *err;
177    mgs_srvconf_rec *sc = ap_get_module_config(parms->server->
178                                               module_config,
179                                               &gnutls_module);
180    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
181        return err;
182    }
183
184    if (strcasecmp("none", type) == 0) {
185        sc->cache_type = mgs_cache_none;
186    } else if (strcasecmp("dbm", type) == 0) {
187        sc->cache_type = mgs_cache_dbm;
188    }
189#if HAVE_APR_MEMCACHE
190    else if (strcasecmp("memcache", type) == 0) {
191        sc->cache_type = mgs_cache_memcache;
192    }
193#endif
194    else {
195        return "Invalid Type for GnuTLSCache!";
196    }
197
198    if (sc->cache_type == mgs_cache_dbm) {
199        sc->cache_config = ap_server_root_relative(parms->pool, arg);
200    } else {
201        sc->cache_config = apr_pstrdup(parms->pool, arg);
202    }
203
204    return NULL;
205}
206
207const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
208                                  const char *arg)
209{
210    int argint;
211    mgs_srvconf_rec *sc =
212        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
213                                                 module_config,
214                                                 &gnutls_module);
215
216    argint = atoi(arg);
217
218    if (argint < 0) {
219        return "GnuTLSCacheTimeout: Invalid argument";
220    } else if (argint == 0) {
221        sc->cache_timeout = 0;
222    } else {
223        sc->cache_timeout = apr_time_from_sec(argint);
224    }
225
226    return NULL;
227}
228
229const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
230                                  const char *arg)
231{
232    int mode;
233
234    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
235        mode = GNUTLS_CERT_IGNORE;
236    } else if (strcasecmp("optional", arg) == 0
237               || strcasecmp("request", arg) == 0) {
238        mode = GNUTLS_CERT_REQUEST;
239    } else if (strcasecmp("require", arg) == 0) {
240        mode = GNUTLS_CERT_REQUIRE;
241    } else {
242        return "GnuTLSClientVerify: Invalid argument";
243    }
244
245    /* This was set from a directory context */
246    if (parms->path) {
247        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
248        dc->client_verify_mode = mode;
249    } else {
250        mgs_srvconf_rec *sc =
251            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
252                                                     module_config,
253                                                     &gnutls_module);
254        sc->client_verify_mode = mode;
255    }
256
257    return NULL;
258}
259
260const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
261                                   const char *arg)
262{
263    int rv;
264    const char *file;
265    apr_pool_t *spool;
266    gnutls_datum_t data;
267
268    mgs_srvconf_rec *sc =
269        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
270                                                 module_config,
271                                                 &gnutls_module);
272    apr_pool_create(&spool, parms->pool);
273
274    file = ap_server_root_relative(spool, arg);
275
276    if (load_datum_from_file(spool, file, &data) != 0) {
277        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
278                            "Client CA File '%s'", file);
279    }
280
281    sc->ca_list_size = MAX_CA_CRTS;
282    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
283                                     &data, GNUTLS_X509_FMT_PEM,
284                                     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
285    if (rv < 0) {
286        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
287                            "Client CA File '%s': (%d) %s", file, rv,
288                            gnutls_strerror(rv));
289    }
290
291    apr_pool_destroy(spool);
292    return NULL;
293}
294
295const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
296                            const char *arg)
297{
298    mgs_srvconf_rec *sc =
299        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
300                                                 module_config,
301                                                 &gnutls_module);
302    if (!strcasecmp(arg, "On")) {
303        sc->enabled = GNUTLS_ENABLED_TRUE;
304    } else if (!strcasecmp(arg, "Off")) {
305        sc->enabled = GNUTLS_ENABLED_FALSE;
306    } else {
307        return "GnuTLSEnable must be set to 'On' or 'Off'";
308    }
309
310    return NULL;
311}
312
313const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
314                            const char *arg)
315{
316    mgs_srvconf_rec *sc =
317        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
318                                                 module_config,
319                                                 &gnutls_module);
320    if (!strcasecmp(arg, "On")) {
321        sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;
322    } else if (!strcasecmp(arg, "Off")) {
323        sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;
324    } else {
325        return "GnuTLSExportCertificates must be set to 'On' or 'Off'";
326    }
327
328    return NULL;
329}
330
331
332const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg)
333{
334    int ret;
335    const char *err;
336    mgs_srvconf_rec *sc =
337        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
338                                                 module_config,
339                                                 &gnutls_module);
340
341
342    ret = gnutls_priority_init( &sc->priorities, arg, &err);
343    if (ret < 0) {
344      if (ret == GNUTLS_E_INVALID_REQUEST)
345        return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err);
346      return "Error setting priorities";
347    }
348
349    return NULL;
350}
351
352void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
353{
354    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
355
356    sc->enabled = GNUTLS_ENABLED_FALSE;
357
358    gnutls_certificate_allocate_credentials(&sc->certs);
359    gnutls_anon_allocate_server_credentials(&sc->anon_creds);
360    gnutls_srp_allocate_server_credentials(&sc->srp_creds);
361
362    sc->srp_tpasswd_conf_file = NULL;
363    sc->srp_tpasswd_file = NULL;
364    sc->privkey_x509 = NULL;
365    sc->cert_x509 = NULL;
366    sc->cache_timeout = apr_time_from_sec(300);
367    sc->cache_type = mgs_cache_dbm;
368    sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
369
370    sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile");
371    sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile");
372
373    sc->client_verify_mode = GNUTLS_CERT_IGNORE;
374
375    return sc;
376}
377
378void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
379{
380    mgs_dirconf_rec *new;
381/*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
382    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
383
384    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
385    new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
386                                       add->lua_bytecode_len);
387    new->lua_bytecode_len = add->lua_bytecode_len;
388    new->client_verify_mode = add->client_verify_mode;
389    return new;
390}
391
392void *mgs_config_dir_create(apr_pool_t * p, char *dir)
393{
394    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
395
396    dc->client_verify_mode = -1;
397    dc->lua_bytecode = NULL;
398    dc->lua_bytecode_len = 0;
399    return dc;
400}
Note: See TracBrowser for help on using the repository browser.