diff options
| -rw-r--r-- | configure.ac | 8 | ||||
| -rw-r--r-- | include/mod_gnutls.h.in | 16 | ||||
| -rw-r--r-- | mod_gnutls.xcode/project.pbxproj | 20 | ||||
| -rw-r--r-- | src/gnutls_cache.c | 153 | ||||
| -rw-r--r-- | src/gnutls_io.c | 99 | ||||
| -rw-r--r-- | src/mod_gnutls.c | 52 |
6 files changed, 277 insertions, 71 deletions
diff --git a/configure.ac b/configure.ac index 086b9f5..772177c 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | |||
| 2 | AC_INIT(mod_gnutls, 0.1.0) | 1 | AC_INIT(mod_gnutls, 0.1.0) |
| 3 | OOO_CONFIG_NICE(config.nice) | 2 | OOO_CONFIG_NICE(config.nice) |
| 3 | MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION | ||
| 4 | AC_PREREQ(2.53) | 4 | AC_PREREQ(2.53) |
| 5 | AC_CONFIG_SRCDIR([src/mod_gnutls.c]) | 5 | AC_CONFIG_SRCDIR([src/mod_gnutls.c]) |
| 6 | AC_CONFIG_AUX_DIR(config) | 6 | AC_CONFIG_AUX_DIR(config) |
| @@ -9,6 +9,7 @@ AC_CANONICAL_TARGET | |||
| 9 | AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) | 9 | AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) |
| 10 | AM_CONFIG_HEADER(include/mod_gnutls_config.h:config.in) | 10 | AM_CONFIG_HEADER(include/mod_gnutls_config.h:config.in) |
| 11 | 11 | ||
| 12 | AC_SUBST(MOD_GNUTLS_VERSION) | ||
| 12 | 13 | ||
| 13 | AC_PROG_CC | 14 | AC_PROG_CC |
| 14 | AC_PROG_LD | 15 | AC_PROG_LD |
| @@ -41,9 +42,10 @@ AC_CONFIG_FILES([Makefile src/Makefile include/mod_gnutls.h]) | |||
| 41 | AC_OUTPUT | 42 | AC_OUTPUT |
| 42 | 43 | ||
| 43 | echo "---" | 44 | echo "---" |
| 44 | echo "Configuration summary for mod_gnutls" | 45 | echo "Configuration summary for mod_gnutls:" |
| 45 | echo "" | 46 | echo "" |
| 47 | echo " * mod_gnutls version: ${MOD_GNUTLS_VERSION}" | ||
| 46 | echo " * Apache Modules directory: ${AP_LIBEXECDIR}" | 48 | echo " * Apache Modules directory: ${AP_LIBEXECDIR}" |
| 47 | echo " * GnuTLS Library Version: ${LIBGNUTLS_VERSION}" | 49 | echo " * GnuTLS Library version: ${LIBGNUTLS_VERSION}" |
| 48 | echo "" | 50 | echo "" |
| 49 | echo "---" | 51 | echo "---" |
diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in index f9ff32b..58fc928 100644 --- a/include/mod_gnutls.h.in +++ b/include/mod_gnutls.h.in | |||
| @@ -42,6 +42,8 @@ module AP_MODULE_DECLARE_DATA gnutls_module; | |||
| 42 | #define GNUTLS_ENABLED_FALSE 0 | 42 | #define GNUTLS_ENABLED_FALSE 0 |
| 43 | #define GNUTLS_ENABLED_TRUE 1 | 43 | #define GNUTLS_ENABLED_TRUE 1 |
| 44 | 44 | ||
| 45 | #define MOD_GNUTLS_VERSION "@MOD_GNUTLS_VERSION@" | ||
| 46 | |||
| 45 | typedef enum | 47 | typedef enum |
| 46 | { | 48 | { |
| 47 | mod_gnutls_cache_none, | 49 | mod_gnutls_cache_none, |
| @@ -54,7 +56,6 @@ typedef enum | |||
| 54 | typedef struct | 56 | typedef struct |
| 55 | { | 57 | { |
| 56 | gnutls_certificate_credentials_t certs; | 58 | gnutls_certificate_credentials_t certs; |
| 57 | gnutls_anon_server_credentials_t anoncred; | ||
| 58 | char *key_file; | 59 | char *key_file; |
| 59 | char *cert_file; | 60 | char *cert_file; |
| 60 | int enabled; | 61 | int enabled; |
| @@ -171,4 +172,17 @@ int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s, | |||
| 171 | */ | 172 | */ |
| 172 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt); | 173 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt); |
| 173 | 174 | ||
| 175 | #define GNUTLS_SESSION_ID_STRING_LEN \ | ||
| 176 | ((GNUTLS_MAX_SESSION_ID + 1) * 2) | ||
| 177 | |||
| 178 | /** | ||
| 179 | * Convert a SSL Session ID into a Null Terminated Hex Encoded String | ||
| 180 | * @param id raw SSL Session ID | ||
| 181 | * @param idlen Length of the raw Session ID | ||
| 182 | * @param str Location to store the Hex Encoded String | ||
| 183 | * @param strsize The Maximum Length that can be stored in str | ||
| 184 | */ | ||
| 185 | char *mod_gnutls_session_id2sz(unsigned char *id, int idlen, | ||
| 186 | char *str, int strsize); | ||
| 187 | |||
| 174 | #endif /* __mod_gnutls_h_inc */ | 188 | #endif /* __mod_gnutls_h_inc */ |
diff --git a/mod_gnutls.xcode/project.pbxproj b/mod_gnutls.xcode/project.pbxproj index 6d79e40..7b9c1e0 100644 --- a/mod_gnutls.xcode/project.pbxproj +++ b/mod_gnutls.xcode/project.pbxproj | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | 45B624630802F1E200CBFD9A = { | 8 | 45B624630802F1E200CBFD9A = { |
| 9 | children = ( | 9 | children = ( |
| 10 | 45B6246D0802F20D00CBFD9A, | 10 | 45B6246D0802F20D00CBFD9A, |
| 11 | 45B6247D0802F85B00CBFD9A, | ||
| 12 | 45B6247A0802F84500CBFD9A, | ||
| 11 | 45B6246E0802F20D00CBFD9A, | 13 | 45B6246E0802F20D00CBFD9A, |
| 12 | 45B6246F0802F20D00CBFD9A, | 14 | 45B6246F0802F20D00CBFD9A, |
| 13 | ); | 15 | ); |
| @@ -70,6 +72,24 @@ | |||
| 70 | refType = 2; | 72 | refType = 2; |
| 71 | sourceTree = SOURCE_ROOT; | 73 | sourceTree = SOURCE_ROOT; |
| 72 | }; | 74 | }; |
| 75 | 45B6247A0802F84500CBFD9A = { | ||
| 76 | fileEncoding = 4; | ||
| 77 | isa = PBXFileReference; | ||
| 78 | lastKnownFileType = sourcecode.c.h; | ||
| 79 | name = mod_gnutls.h; | ||
| 80 | path = include/mod_gnutls.h; | ||
| 81 | refType = 2; | ||
| 82 | sourceTree = SOURCE_ROOT; | ||
| 83 | }; | ||
| 84 | 45B6247D0802F85B00CBFD9A = { | ||
| 85 | fileEncoding = 4; | ||
| 86 | isa = PBXFileReference; | ||
| 87 | lastKnownFileType = text; | ||
| 88 | name = mod_gnutls.h.in; | ||
| 89 | path = include/mod_gnutls.h.in; | ||
| 90 | refType = 2; | ||
| 91 | sourceTree = SOURCE_ROOT; | ||
| 92 | }; | ||
| 73 | }; | 93 | }; |
| 74 | rootObject = 45B624670802F1E200CBFD9A; | 94 | rootObject = 45B624670802F1E200CBFD9A; |
| 75 | } | 95 | } |
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c index 868568b..91e6ec9 100644 --- a/src/gnutls_cache.c +++ b/src/gnutls_cache.c | |||
| @@ -32,15 +32,14 @@ | |||
| 32 | #include "unixd.h" | 32 | #include "unixd.h" |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | #define GNUTLS_SESSION_ID_STRING_LEN \ | 35 | |
| 36 | ((GNUTLS_MAX_SESSION_ID + 1) * 2) | ||
| 37 | #define MC_TAG "mod_gnutls:" | 36 | #define MC_TAG "mod_gnutls:" |
| 38 | #define MC_TAG_LEN \ | 37 | #define MC_TAG_LEN \ |
| 39 | (sizeof(MC_TAG)) | 38 | (sizeof(MC_TAG)) |
| 40 | #define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN) | 39 | #define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN) |
| 41 | 40 | ||
| 42 | static char *gnutls_session_id2sz(unsigned char *id, int idlen, | 41 | static char *gnutls_session_id2sz(unsigned char *id, int idlen, |
| 43 | char *str, int strsize) | 42 | char *str, int strsize) |
| 44 | { | 43 | { |
| 45 | char *cp; | 44 | char *cp; |
| 46 | int n; | 45 | int n; |
| @@ -54,6 +53,21 @@ static char *gnutls_session_id2sz(unsigned char *id, int idlen, | |||
| 54 | return str; | 53 | return str; |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 56 | char *mod_gnutls_session_id2sz(unsigned char *id, int idlen, | ||
| 57 | char *str, int strsize) | ||
| 58 | { | ||
| 59 | char *cp; | ||
| 60 | int n; | ||
| 61 | |||
| 62 | cp = str; | ||
| 63 | for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) { | ||
| 64 | apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]); | ||
| 65 | cp += 2; | ||
| 66 | } | ||
| 67 | *cp = '\0'; | ||
| 68 | return str; | ||
| 69 | } | ||
| 70 | |||
| 57 | 71 | ||
| 58 | #if HAVE_APR_MEMCACHE | 72 | #if HAVE_APR_MEMCACHE |
| 59 | 73 | ||
| @@ -103,13 +117,13 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s, | |||
| 103 | apr_port_t port; | 117 | apr_port_t port; |
| 104 | 118 | ||
| 105 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p); | 119 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p); |
| 106 | if(rv != APR_SUCCESS) { | 120 | if (rv != APR_SUCCESS) { |
| 107 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 121 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
| 108 | "[gnutls_cache] Failed to Parse Server: '%s'", split); | 122 | "[gnutls_cache] Failed to Parse Server: '%s'", split); |
| 109 | return rv; | 123 | return rv; |
| 110 | } | 124 | } |
| 111 | 125 | ||
| 112 | if(host_str == NULL) { | 126 | if (host_str == NULL) { |
| 113 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 127 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
| 114 | "[gnutls_cache] Failed to Parse Server, " | 128 | "[gnutls_cache] Failed to Parse Server, " |
| 115 | "no hostname specified: '%s'", split); | 129 | "no hostname specified: '%s'", split); |
| @@ -128,7 +142,7 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s, | |||
| 128 | thread_limit, | 142 | thread_limit, |
| 129 | 600, | 143 | 600, |
| 130 | &st); | 144 | &st); |
| 131 | if(rv != APR_SUCCESS) { | 145 | if (rv != APR_SUCCESS) { |
| 132 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 146 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
| 133 | "[gnutls_cache] Failed to Create Server: %s:%d", | 147 | "[gnutls_cache] Failed to Create Server: %s:%d", |
| 134 | host_str, port); | 148 | host_str, port); |
| @@ -136,7 +150,7 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s, | |||
| 136 | } | 150 | } |
| 137 | 151 | ||
| 138 | rv = apr_memcache_add_server(mc, st); | 152 | rv = apr_memcache_add_server(mc, st); |
| 139 | if(rv != APR_SUCCESS) { | 153 | if (rv != APR_SUCCESS) { |
| 140 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 154 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
| 141 | "[gnutls_cache] Failed to Add Server: %s:%d", | 155 | "[gnutls_cache] Failed to Add Server: %s:%d", |
| 142 | host_str, port); | 156 | host_str, port); |
| @@ -161,11 +175,11 @@ static int mc_cache_store(void* baton, gnutls_datum_t key, | |||
| 161 | if(!strkey) | 175 | if(!strkey) |
| 162 | return -1; | 176 | return -1; |
| 163 | 177 | ||
| 164 | timeout = ctxt->sc->cache_timeout; | 178 | timeout = apr_time_sec(ctxt->sc->cache_timeout); |
| 165 | 179 | ||
| 166 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); | 180 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); |
| 167 | 181 | ||
| 168 | if(rv != APR_SUCCESS) { | 182 | if (rv != APR_SUCCESS) { |
| 169 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, | 183 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, |
| 170 | ctxt->c->base_server, | 184 | ctxt->c->base_server, |
| 171 | "[gnutls_cache] error setting key '%s' " | 185 | "[gnutls_cache] error setting key '%s' " |
| @@ -187,14 +201,14 @@ static gnutls_datum_t mc_cache_fetch(void* baton, gnutls_datum_t key) | |||
| 187 | gnutls_datum_t data = { NULL, 0 }; | 201 | gnutls_datum_t data = { NULL, 0 }; |
| 188 | 202 | ||
| 189 | strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf)); | 203 | strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf)); |
| 190 | if(!strkey) { | 204 | if (!strkey) { |
| 191 | return data; | 205 | return data; |
| 192 | } | 206 | } |
| 193 | 207 | ||
| 194 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, | 208 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, |
| 195 | &value, &value_len, NULL); | 209 | &value, &value_len, NULL); |
| 196 | 210 | ||
| 197 | if(rv != APR_SUCCESS) { | 211 | if (rv != APR_SUCCESS) { |
| 198 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 212 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
| 199 | ctxt->c->base_server, | 213 | ctxt->c->base_server, |
| 200 | "[gnutls_cache] error fetching key '%s' ", | 214 | "[gnutls_cache] error fetching key '%s' ", |
| @@ -229,7 +243,7 @@ static int mc_cache_delete(void* baton, gnutls_datum_t key) | |||
| 229 | 243 | ||
| 230 | rv = apr_memcache_delete(mc, strkey, 0); | 244 | rv = apr_memcache_delete(mc, strkey, 0); |
| 231 | 245 | ||
| 232 | if(rv != APR_SUCCESS) { | 246 | if (rv != APR_SUCCESS) { |
| 233 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 247 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
| 234 | ctxt->c->base_server, | 248 | ctxt->c->base_server, |
| 235 | "[gnutls_cache] error deleting key '%s' ", | 249 | "[gnutls_cache] error deleting key '%s' ", |
| @@ -248,18 +262,80 @@ static int dbm_cache_expire(mod_gnutls_handle_t *ctxt) | |||
| 248 | { | 262 | { |
| 249 | apr_status_t rv; | 263 | apr_status_t rv; |
| 250 | apr_dbm_t *dbm; | 264 | apr_dbm_t *dbm; |
| 251 | 265 | apr_datum_t *keylist; | |
| 252 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 266 | apr_datum_t dbmkey; |
| 253 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 267 | apr_datum_t dbmval; |
| 268 | apr_time_t ex; | ||
| 269 | apr_time_t dtime; | ||
| 270 | apr_pool_t* spool; | ||
| 271 | int i = 0; | ||
| 272 | int keyidx = 0; | ||
| 273 | int should_delete = 0; | ||
| 274 | |||
| 275 | apr_pool_create(&spool, ctxt->c->pool); | ||
| 276 | ex = apr_time_now(); | ||
| 277 | |||
| 278 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, APR_DBM_READONLY, | ||
| 279 | SSL_DBM_FILE_MODE, spool); | ||
| 254 | if (rv != APR_SUCCESS) { | 280 | if (rv != APR_SUCCESS) { |
| 255 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 281 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
| 256 | ctxt->c->base_server, | 282 | ctxt->c->base_server, |
| 257 | "[gnutls_cache] error opening cache '%s'", | 283 | "[gnutls_cache] error opening cache searcher '%s'", |
| 258 | ctxt->sc->cache_config); | 284 | ctxt->sc->cache_config); |
| 259 | return -1; | 285 | return -1; |
| 260 | } | 286 | } |
| 287 | |||
| 288 | #define KEYMAX 128 | ||
| 289 | |||
| 290 | keylist = apr_palloc(spool, sizeof(dbmkey)*KEYMAX); | ||
| 291 | |||
| 292 | apr_dbm_firstkey(dbm, &dbmkey); | ||
| 293 | while (dbmkey.dptr != NULL) { | ||
| 294 | apr_dbm_fetch(dbm, dbmkey, &dbmval); | ||
| 295 | if (dbmval.dptr != NULL) { | ||
| 296 | if (dbmval.dsize >= sizeof(apr_time_t)) { | ||
| 297 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); | ||
| 298 | if (dtime < ex) { | ||
| 299 | should_delete = 1; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | else { | ||
| 303 | should_delete = 1; | ||
| 304 | } | ||
| 305 | |||
| 306 | if (should_delete == 1) { | ||
| 307 | should_delete = 0; | ||
| 308 | keylist[keyidx].dptr = apr_palloc(spool, dbmkey.dsize) ; | ||
| 309 | memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize); | ||
| 310 | keylist[keyidx].dsize = dbmkey.dsize; | ||
| 311 | keyidx++; | ||
| 312 | if (keyidx == KEYMAX) { | ||
| 313 | break; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | } | ||
| 318 | apr_dbm_nextkey(dbm, &dbmkey); | ||
| 319 | } | ||
| 261 | apr_dbm_close(dbm); | 320 | apr_dbm_close(dbm); |
| 262 | 321 | ||
| 322 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
| 323 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, spool); | ||
| 324 | if (rv != APR_SUCCESS) { | ||
| 325 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
| 326 | ctxt->c->base_server, | ||
| 327 | "[gnutls_cache] error opening cache writer '%s'", | ||
| 328 | ctxt->sc->cache_config); | ||
| 329 | return -1; | ||
| 330 | } | ||
| 331 | |||
| 332 | for (i = 0; i < keyidx; i++) { | ||
| 333 | apr_dbm_delete(dbm, keylist[i]); | ||
| 334 | } | ||
| 335 | |||
| 336 | apr_dbm_close(dbm); | ||
| 337 | apr_pool_destroy(spool); | ||
| 338 | |||
| 263 | return 0; | 339 | return 0; |
| 264 | } | 340 | } |
| 265 | 341 | ||
| @@ -275,6 +351,8 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | |||
| 275 | dbmkey.dptr = key.data; | 351 | dbmkey.dptr = key.data; |
| 276 | dbmkey.dsize = key.size; | 352 | dbmkey.dsize = key.size; |
| 277 | 353 | ||
| 354 | dbm_cache_expire(ctxt); | ||
| 355 | |||
| 278 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 356 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, |
| 279 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 357 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); |
| 280 | if (rv != APR_SUCCESS) { | 358 | if (rv != APR_SUCCESS) { |
| @@ -286,7 +364,7 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | |||
| 286 | } | 364 | } |
| 287 | 365 | ||
| 288 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | 366 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); |
| 289 | 367 | ||
| 290 | if (rv != APR_SUCCESS) { | 368 | if (rv != APR_SUCCESS) { |
| 291 | apr_dbm_close(dbm); | 369 | apr_dbm_close(dbm); |
| 292 | return data; | 370 | return data; |
| @@ -296,15 +374,17 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | |||
| 296 | apr_dbm_close(dbm); | 374 | apr_dbm_close(dbm); |
| 297 | return data; | 375 | return data; |
| 298 | } | 376 | } |
| 299 | 377 | apr_dbm_close(dbm); | |
| 300 | data.data = gnutls_malloc(dbmval.dsize - sizeof(apr_time_t)); | ||
| 301 | if (data.data == NULL) | ||
| 302 | return data; | ||
| 303 | 378 | ||
| 304 | data.size = dbmval.dsize - sizeof(apr_time_t); | 379 | data.size = dbmval.dsize - sizeof(apr_time_t); |
| 380 | |||
| 381 | data.data = gnutls_malloc(data.size); | ||
| 382 | if (data.data == NULL) { | ||
| 383 | return data; | ||
| 384 | } | ||
| 385 | |||
| 305 | memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); | 386 | memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); |
| 306 | 387 | ||
| 307 | apr_dbm_close(dbm); | ||
| 308 | return data; | 388 | return data; |
| 309 | } | 389 | } |
| 310 | 390 | ||
| @@ -316,18 +396,23 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key, | |||
| 316 | apr_datum_t dbmval; | 396 | apr_datum_t dbmval; |
| 317 | mod_gnutls_handle_t *ctxt = baton; | 397 | mod_gnutls_handle_t *ctxt = baton; |
| 318 | apr_status_t rv; | 398 | apr_status_t rv; |
| 319 | apr_time_t timeout; | 399 | apr_time_t expiry; |
| 320 | 400 | ||
| 321 | dbmkey.dptr = (char *)key.data; | 401 | dbmkey.dptr = (char *)key.data; |
| 322 | dbmkey.dsize = key.size; | 402 | dbmkey.dsize = key.size; |
| 323 | 403 | ||
| 324 | /* create DBM value */ | 404 | /* create DBM value */ |
| 325 | dbmval.dsize = data.size; | 405 | dbmval.dsize = data.size + sizeof(apr_time_t); |
| 326 | dbmval.dptr = (char *)malloc(dbmval.dsize+sizeof(apr_time_t)); | 406 | dbmval.dptr = (char *)malloc(dbmval.dsize); |
| 407 | |||
| 408 | expiry = apr_time_now() + ctxt->sc->cache_timeout; | ||
| 327 | 409 | ||
| 410 | memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t)); | ||
| 328 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), | 411 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), |
| 329 | data.data, data.size); | 412 | data.data, data.size); |
| 330 | 413 | ||
| 414 | dbm_cache_expire(ctxt); | ||
| 415 | |||
| 331 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 416 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, |
| 332 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 417 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); |
| 333 | if (rv != APR_SUCCESS) { | 418 | if (rv != APR_SUCCESS) { |
| @@ -340,7 +425,7 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key, | |||
| 340 | } | 425 | } |
| 341 | 426 | ||
| 342 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | 427 | rv = apr_dbm_store(dbm, dbmkey, dbmval); |
| 343 | 428 | ||
| 344 | if (rv != APR_SUCCESS) { | 429 | if (rv != APR_SUCCESS) { |
| 345 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 430 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
| 346 | ctxt->c->base_server, | 431 | ctxt->c->base_server, |
| @@ -368,6 +453,8 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key) | |||
| 368 | dbmkey.dptr = (char *)key.data; | 453 | dbmkey.dptr = (char *)key.data; |
| 369 | dbmkey.dsize = key.size; | 454 | dbmkey.dsize = key.size; |
| 370 | 455 | ||
| 456 | dbm_cache_expire(ctxt); | ||
| 457 | |||
| 371 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 458 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, |
| 372 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 459 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); |
| 373 | if (rv != APR_SUCCESS) { | 460 | if (rv != APR_SUCCESS) { |
| @@ -383,7 +470,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key) | |||
| 383 | if (rv != APR_SUCCESS) { | 470 | if (rv != APR_SUCCESS) { |
| 384 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 471 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
| 385 | ctxt->c->base_server, | 472 | ctxt->c->base_server, |
| 386 | "[gnutls_cache] error storing in cache '%s'", | 473 | "[gnutls_cache] error deleting from cache '%s'", |
| 387 | ctxt->sc->cache_config); | 474 | ctxt->sc->cache_config); |
| 388 | apr_dbm_close(dbm); | 475 | apr_dbm_close(dbm); |
| 389 | return -1; | 476 | return -1; |
| @@ -394,7 +481,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key) | |||
| 394 | return 0; | 481 | return 0; |
| 395 | } | 482 | } |
| 396 | 483 | ||
| 397 | static int dbm_cache_child_init(apr_pool_t *p, server_rec *s, | 484 | static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, |
| 398 | mod_gnutls_srvconf_rec *sc) | 485 | mod_gnutls_srvconf_rec *sc) |
| 399 | { | 486 | { |
| 400 | apr_status_t rv; | 487 | apr_status_t rv; |
| @@ -434,7 +521,7 @@ int mod_gnutls_cache_post_config(apr_pool_t *p, server_rec *s, | |||
| 434 | mod_gnutls_srvconf_rec *sc) | 521 | mod_gnutls_srvconf_rec *sc) |
| 435 | { | 522 | { |
| 436 | if (sc->cache_type == mod_gnutls_cache_dbm) { | 523 | if (sc->cache_type == mod_gnutls_cache_dbm) { |
| 437 | return dbm_cache_child_init(p, s, sc); | 524 | return dbm_cache_post_config(p, s, sc); |
| 438 | } | 525 | } |
| 439 | return 0; | 526 | return 0; |
| 440 | } | 527 | } |
| @@ -457,7 +544,6 @@ int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s, | |||
| 457 | 544 | ||
| 458 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) | 545 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) |
| 459 | { | 546 | { |
| 460 | printf("Type: %d Params: %s\n",ctxt->sc->cache_type, ctxt->sc->cache_config); | ||
| 461 | if (ctxt->sc->cache_type == mod_gnutls_cache_dbm) { | 547 | if (ctxt->sc->cache_type == mod_gnutls_cache_dbm) { |
| 462 | gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); | 548 | gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); |
| 463 | gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); | 549 | gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); |
| @@ -472,9 +558,6 @@ int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) | |||
| 472 | gnutls_db_set_ptr(ctxt->session, ctxt); | 558 | gnutls_db_set_ptr(ctxt->session, ctxt); |
| 473 | } | 559 | } |
| 474 | #endif | 560 | #endif |
| 475 | else { | 561 | |
| 476 | assert(1); | ||
| 477 | /* No Session Cache is Available. Opps. */ | ||
| 478 | } | ||
| 479 | return 0; | 562 | return 0; |
| 480 | } | 563 | } |
diff --git a/src/gnutls_io.c b/src/gnutls_io.c index a44ba9c..f761f96 100644 --- a/src/gnutls_io.c +++ b/src/gnutls_io.c | |||
| @@ -271,6 +271,22 @@ static apr_status_t gnutls_io_input_read(mod_gnutls_handle_t * ctxt, | |||
| 271 | "GnuTLS: Error reading data. Client Requested a New Handshake." | 271 | "GnuTLS: Error reading data. Client Requested a New Handshake." |
| 272 | " (%d) '%s'", rc, gnutls_strerror(rc)); | 272 | " (%d) '%s'", rc, gnutls_strerror(rc)); |
| 273 | } | 273 | } |
| 274 | else if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { | ||
| 275 | rc = gnutls_alert_get(ctxt->session); | ||
| 276 | ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc, | ||
| 277 | ctxt->c->base_server, | ||
| 278 | "GnuTLS: Warning Alert From Client: " | ||
| 279 | " (%d) '%s'", rc, gnutls_alert_get_name(rc)); | ||
| 280 | } | ||
| 281 | else if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { | ||
| 282 | rc = gnutls_alert_get(ctxt->session); | ||
| 283 | ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc, | ||
| 284 | ctxt->c->base_server, | ||
| 285 | "GnuTLS: Fatal Alert From Client: " | ||
| 286 | "(%d) '%s'", rc, gnutls_alert_get_name(rc)); | ||
| 287 | ctxt->input_rc = APR_EGENERAL; | ||
| 288 | break; | ||
| 289 | } | ||
| 274 | else { | 290 | else { |
| 275 | /* Some Other Error. Report it. Die. */ | 291 | /* Some Other Error. Report it. Die. */ |
| 276 | if(gnutls_error_is_fatal(rc)) { | 292 | if(gnutls_error_is_fatal(rc)) { |
| @@ -341,7 +357,7 @@ static apr_status_t gnutls_io_input_getline(mod_gnutls_handle_t * ctxt, | |||
| 341 | static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) | 357 | static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) |
| 342 | { | 358 | { |
| 343 | int ret; | 359 | int ret; |
| 344 | 360 | int errcode; | |
| 345 | if (ctxt->status != 0) { | 361 | if (ctxt->status != 0) { |
| 346 | return; | 362 | return; |
| 347 | } | 363 | } |
| @@ -352,10 +368,10 @@ tryagain: | |||
| 352 | if (ret < 0) { | 368 | if (ret < 0) { |
| 353 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED | 369 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED |
| 354 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { | 370 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { |
| 355 | ret = gnutls_alert_get(ctxt->session); | 371 | errcode = gnutls_alert_get(ctxt->session); |
| 356 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, | 372 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, |
| 357 | "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, | 373 | "GnuTLS: Hanshake Alert (%d) '%s'.", errcode, |
| 358 | gnutls_alert_get_name(ret)); | 374 | gnutls_alert_get_name(errcode)); |
| 359 | } | 375 | } |
| 360 | 376 | ||
| 361 | if (!gnutls_error_is_fatal(ret)) { | 377 | if (!gnutls_error_is_fatal(ret)) { |
| @@ -398,7 +414,26 @@ apr_status_t mod_gnutls_filter_input(ap_filter_t* f, | |||
| 398 | } | 414 | } |
| 399 | 415 | ||
| 400 | if (ctxt->status == 0) { | 416 | if (ctxt->status == 0) { |
| 417 | char* server_name; | ||
| 418 | int server_type; | ||
| 419 | int data_len = 256; | ||
| 420 | |||
| 401 | gnutls_do_handshake(ctxt); | 421 | gnutls_do_handshake(ctxt); |
| 422 | |||
| 423 | /** | ||
| 424 | * Due to issues inside the GnuTLS API, we cannot currently do TLS 1.1 | ||
| 425 | * Server Name Indication. | ||
| 426 | */ | ||
| 427 | server_name = apr_palloc(ctxt->c->pool, data_len); | ||
| 428 | if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) { | ||
| 429 | if (server_type == GNUTLS_NAME_DNS) { | ||
| 430 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | ||
| 431 | ctxt->c->base_server, | ||
| 432 | "GnuTLS: TLS 1.1 Server Name: " | ||
| 433 | "%s", server_name); | ||
| 434 | |||
| 435 | } | ||
| 436 | } | ||
| 402 | } | 437 | } |
| 403 | 438 | ||
| 404 | if (ctxt->status < 0) { | 439 | if (ctxt->status < 0) { |
| @@ -449,6 +484,7 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
| 449 | apr_bucket_brigade * bb) | 484 | apr_bucket_brigade * bb) |
| 450 | { | 485 | { |
| 451 | apr_size_t ret; | 486 | apr_size_t ret; |
| 487 | apr_bucket* e; | ||
| 452 | mod_gnutls_handle_t *ctxt = (mod_gnutls_handle_t *) f->ctx; | 488 | mod_gnutls_handle_t *ctxt = (mod_gnutls_handle_t *) f->ctx; |
| 453 | apr_status_t status = APR_SUCCESS; | 489 | apr_status_t status = APR_SUCCESS; |
| 454 | apr_read_type_e rblock = APR_NONBLOCK_READ; | 490 | apr_read_type_e rblock = APR_NONBLOCK_READ; |
| @@ -469,21 +505,34 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
| 469 | while (!APR_BRIGADE_EMPTY(bb)) { | 505 | while (!APR_BRIGADE_EMPTY(bb)) { |
| 470 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); | 506 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); |
| 471 | if (AP_BUCKET_IS_EOC(bucket)) { | 507 | if (AP_BUCKET_IS_EOC(bucket)) { |
| 508 | do { | ||
| 509 | ret = gnutls_alert_send(ctxt->session, GNUTLS_AL_FATAL, | ||
| 510 | GNUTLS_A_CLOSE_NOTIFY); | ||
| 511 | } while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); | ||
| 512 | |||
| 513 | apr_bucket_copy(bucket, &e); | ||
| 514 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e); | ||
| 515 | |||
| 516 | if ((status = ap_pass_brigade(f->next, ctxt->output_bb)) != APR_SUCCESS) { | ||
| 517 | apr_brigade_cleanup(ctxt->output_bb); | ||
| 518 | return status; | ||
| 519 | } | ||
| 472 | 520 | ||
| 521 | apr_brigade_cleanup(ctxt->output_bb); | ||
| 473 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); | 522 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); |
| 474 | gnutls_deinit(ctxt->session); | 523 | gnutls_deinit(ctxt->session); |
| 475 | 524 | continue; | |
| 476 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | ||
| 477 | return status; | ||
| 478 | } | ||
| 479 | break; | ||
| 480 | 525 | ||
| 481 | } else if (APR_BUCKET_IS_FLUSH(bucket) || APR_BUCKET_IS_EOS(bucket)) { | 526 | } else if (APR_BUCKET_IS_FLUSH(bucket) || APR_BUCKET_IS_EOS(bucket)) { |
| 482 | 527 | ||
| 528 | apr_bucket_copy(bucket, &e); | ||
| 529 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e); | ||
| 483 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | 530 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { |
| 531 | apr_brigade_cleanup(ctxt->output_bb); | ||
| 484 | return status; | 532 | return status; |
| 485 | } | 533 | } |
| 486 | break; | 534 | apr_brigade_cleanup(ctxt->output_bb); |
| 535 | continue; | ||
| 487 | } | 536 | } |
| 488 | else { | 537 | else { |
| 489 | /* filter output */ | 538 | /* filter output */ |
| @@ -628,9 +677,9 @@ static ssize_t write_flush(mod_gnutls_handle_t * ctxt) | |||
| 628 | 677 | ||
| 629 | ctxt->output_rc = ap_pass_brigade(ctxt->output_filter->next, | 678 | ctxt->output_rc = ap_pass_brigade(ctxt->output_filter->next, |
| 630 | ctxt->output_bb); | 679 | ctxt->output_bb); |
| 631 | /* create new brigade ready for next time through */ | 680 | /* clear the brigade to be ready for next time */ |
| 632 | ctxt->output_bb = | 681 | apr_brigade_cleanup(ctxt->output_bb); |
| 633 | apr_brigade_create(ctxt->c->pool, ctxt->c->bucket_alloc); | 682 | |
| 634 | return (ctxt->output_rc == APR_SUCCESS) ? 1 : -1; | 683 | return (ctxt->output_rc == APR_SUCCESS) ? 1 : -1; |
| 635 | } | 684 | } |
| 636 | 685 | ||
| @@ -639,19 +688,17 @@ ssize_t mod_gnutls_transport_write(gnutls_transport_ptr_t ptr, | |||
| 639 | { | 688 | { |
| 640 | mod_gnutls_handle_t *ctxt = ptr; | 689 | mod_gnutls_handle_t *ctxt = ptr; |
| 641 | 690 | ||
| 642 | /* pass along the encrypted data | 691 | /* pass along the encrypted data |
| 643 | * need to flush since we're using SSL's malloc-ed buffer | 692 | * need to flush since we're using SSL's malloc-ed buffer |
| 644 | * which will be overwritten once we leave here | 693 | * which will be overwritten once we leave here |
| 645 | */ | 694 | */ |
| 646 | apr_bucket *bucket = apr_bucket_transient_create(buffer, len, | 695 | apr_bucket *bucket = apr_bucket_transient_create(buffer, len, |
| 647 | ctxt->output_bb-> | 696 | ctxt->output_bb->bucket_alloc); |
| 648 | bucket_alloc); | 697 | ctxt->output_length += len; |
| 649 | 698 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, bucket); | |
| 650 | ctxt->output_length += len; | ||
| 651 | APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, bucket); | ||
| 652 | 699 | ||
| 653 | if (write_flush(ctxt) < 0) { | 700 | if (write_flush(ctxt) < 0) { |
| 654 | return -1; | 701 | return -1; |
| 655 | } | 702 | } |
| 656 | return len; | 703 | return len; |
| 657 | } | 704 | } |
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c index edf7068..b803ce7 100644 --- a/src/mod_gnutls.c +++ b/src/mod_gnutls.c | |||
| @@ -189,6 +189,7 @@ static int mod_gnutls_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
| 189 | sc->cache_config = sc_base->cache_config; | 189 | sc->cache_config = sc_base->cache_config; |
| 190 | 190 | ||
| 191 | if (sc->cert_file != NULL && sc->key_file != NULL) { | 191 | if (sc->cert_file != NULL && sc->key_file != NULL) { |
| 192 | |||
| 192 | rv = gnutls_certificate_set_x509_key_file(sc->certs, sc->cert_file, | 193 | rv = gnutls_certificate_set_x509_key_file(sc->certs, sc->cert_file, |
| 193 | sc->key_file, | 194 | sc->key_file, |
| 194 | GNUTLS_X509_FMT_PEM); | 195 | GNUTLS_X509_FMT_PEM); |
| @@ -214,7 +215,7 @@ static int mod_gnutls_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
| 214 | } | 215 | } |
| 215 | } /* first_run */ | 216 | } /* first_run */ |
| 216 | 217 | ||
| 217 | ap_add_version_component(p, "GnuTLS/" LIBGNUTLS_VERSION); | 218 | ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION); |
| 218 | 219 | ||
| 219 | return OK; | 220 | return OK; |
| 220 | } | 221 | } |
| @@ -266,6 +267,30 @@ static apr_port_t mod_gnutls_hook_default_port(const request_rec * r) | |||
| 266 | return 443; | 267 | return 443; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 270 | /* TODO: Complete support for Server Name Indication */ | ||
| 271 | static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | ||
| 272 | { | ||
| 273 | char* server_name; | ||
| 274 | int server_type; | ||
| 275 | int data_len = 256; | ||
| 276 | mod_gnutls_handle_t *ctxt; | ||
| 277 | ctxt = gnutls_transport_get_ptr(session); | ||
| 278 | |||
| 279 | ret->type = GNUTLS_CRT_X509; | ||
| 280 | ret->ncerts = 1; | ||
| 281 | server_name = apr_palloc(ctxt->c->pool, data_len); | ||
| 282 | if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) { | ||
| 283 | if (server_type == GNUTLS_NAME_DNS) { | ||
| 284 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, | ||
| 285 | ctxt->c->base_server, | ||
| 286 | "GnuTLS: Virtual Host: " | ||
| 287 | "%s", server_name); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | |||
| 269 | static mod_gnutls_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c) | 294 | static mod_gnutls_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c) |
| 270 | { | 295 | { |
| 271 | mod_gnutls_handle_t *ctxt; | 296 | mod_gnutls_handle_t *ctxt; |
| @@ -299,13 +324,12 @@ static mod_gnutls_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c) | |||
| 299 | 324 | ||
| 300 | gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs); | 325 | gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs); |
| 301 | 326 | ||
| 302 | // if(anon) { | ||
| 303 | // gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred); | ||
| 304 | // } | ||
| 305 | |||
| 306 | gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE); | 327 | gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE); |
| 307 | 328 | ||
| 308 | mod_gnutls_cache_session_init(ctxt); | 329 | mod_gnutls_cache_session_init(ctxt); |
| 330 | |||
| 331 | /* TODO: Finish Support for Server Name Indication */ | ||
| 332 | /* gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); */ | ||
| 309 | return ctxt; | 333 | return ctxt; |
| 310 | } | 334 | } |
| 311 | 335 | ||
| @@ -341,7 +365,10 @@ static int mod_gnutls_hook_pre_connection(conn_rec * c, void *csd) | |||
| 341 | 365 | ||
| 342 | static int mod_gnutls_hook_fixups(request_rec *r) | 366 | static int mod_gnutls_hook_fixups(request_rec *r) |
| 343 | { | 367 | { |
| 368 | unsigned char sbuf[GNUTLS_MAX_SESSION_ID]; | ||
| 369 | char buf[GNUTLS_SESSION_ID_STRING_LEN]; | ||
| 344 | const char* tmp; | 370 | const char* tmp; |
| 371 | int len; | ||
| 345 | mod_gnutls_handle_t *ctxt; | 372 | mod_gnutls_handle_t *ctxt; |
| 346 | apr_table_t *env = r->subprocess_env; | 373 | apr_table_t *env = r->subprocess_env; |
| 347 | 374 | ||
| @@ -352,17 +379,30 @@ static int mod_gnutls_hook_fixups(request_rec *r) | |||
| 352 | } | 379 | } |
| 353 | 380 | ||
| 354 | apr_table_setn(env, "HTTPS", "on"); | 381 | apr_table_setn(env, "HTTPS", "on"); |
| 382 | |||
| 383 | apr_table_setn(env, "GNUTLS_VERSION_INTERFACE", MOD_GNUTLS_VERSION); | ||
| 384 | apr_table_setn(env, "GNUTLS_VERSION_LIBRARY", LIBGNUTLS_VERSION); | ||
| 385 | |||
| 355 | apr_table_setn(env, "SSL_PROTOCOL", | 386 | apr_table_setn(env, "SSL_PROTOCOL", |
| 356 | gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session))); | 387 | gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session))); |
| 388 | |||
| 357 | apr_table_setn(env, "SSL_CIPHER", | 389 | apr_table_setn(env, "SSL_CIPHER", |
| 358 | gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session))); | 390 | gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session))); |
| 359 | 391 | ||
| 392 | apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE"); | ||
| 393 | |||
| 360 | tmp = apr_psprintf(r->pool, "%d", | 394 | tmp = apr_psprintf(r->pool, "%d", |
| 361 | 8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session))); | 395 | 8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session))); |
| 362 | 396 | ||
| 363 | apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp); | 397 | apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp); |
| 398 | |||
| 364 | apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp); | 399 | apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp); |
| 365 | 400 | ||
| 401 | len = sizeof(sbuf); | ||
| 402 | gnutls_session_get_id(ctxt->session, sbuf, &len); | ||
| 403 | tmp = mod_gnutls_session_id2sz(sbuf, len, buf, sizeof(buf)); | ||
| 404 | apr_table_setn(env, "SSL_SESSION_ID", tmp); | ||
| 405 | |||
| 366 | return OK; | 406 | return OK; |
| 367 | } | 407 | } |
| 368 | 408 | ||
| @@ -384,6 +424,7 @@ static const char *gnutls_set_key_file(cmd_parms * parms, void *dummy, | |||
| 384 | (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> | 424 | (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> |
| 385 | module_config, | 425 | module_config, |
| 386 | &gnutls_module); | 426 | &gnutls_module); |
| 427 | |||
| 387 | sc->key_file = ap_server_root_relative(parms->pool, arg); | 428 | sc->key_file = ap_server_root_relative(parms->pool, arg); |
| 388 | return NULL; | 429 | return NULL; |
| 389 | } | 430 | } |
| @@ -508,7 +549,6 @@ static void *gnutls_config_server_create(apr_pool_t * p, server_rec * s) | |||
| 508 | sc->enabled = GNUTLS_ENABLED_FALSE; | 549 | sc->enabled = GNUTLS_ENABLED_FALSE; |
| 509 | 550 | ||
| 510 | gnutls_certificate_allocate_credentials(&sc->certs); | 551 | gnutls_certificate_allocate_credentials(&sc->certs); |
| 511 | gnutls_anon_allocate_server_credentials(&sc->anoncred); | ||
| 512 | sc->key_file = NULL; | 552 | sc->key_file = NULL; |
| 513 | sc->cert_file = NULL; | 553 | sc->cert_file = NULL; |
| 514 | sc->cache_timeout = apr_time_from_sec(3600); | 554 | sc->cache_timeout = apr_time_from_sec(3600); |
