source: mod_gnutls/src/gnutls_config.c @ b077bdd

asynciodebian/masterdebian/stretch-backportsjessie-backportsmsvaproxy-ticketupstream
Last change on this file since b077bdd was b077bdd, checked in by Nokis Mavrogiannopoulos <nmav@…>, 14 years ago

added more error checks.

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