diff options
| -rw-r--r-- | include/mod_gnutls.h.in | 1 | ||||
| -rw-r--r-- | src/gnutls_hooks.c | 71 | ||||
| -rw-r--r-- | src/gnutls_io.c | 10 |
3 files changed, 46 insertions, 36 deletions
diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in index b5a84c0..e787beb 100644 --- a/include/mod_gnutls.h.in +++ b/include/mod_gnutls.h.in | ||||||
| @@ -240,6 +240,7 @@ void *mgs_config_server_create(apr_pool_t * p, server_rec * s); | ||||||
| 240 | 240 | |||||
| 241 | void *mgs_config_dir_create(apr_pool_t *p, char *dir); | 241 | void *mgs_config_dir_create(apr_pool_t *p, char *dir); | |||
| 242 | 242 | |||||
| 243 | mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session); | |||||
| 243 | 244 | |||||
| 244 | /* mod_gnutls Hooks. */ | 245 | /* mod_gnutls Hooks. */ | |||
| 245 | 246 | |||||
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 7c14f07..2d12b51 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | ||||||
| @@ -300,7 +300,7 @@ apr_port_t mgs_hook_default_port(const request_rec * r) | ||||||
| 300 | typedef struct | 300 | typedef struct | |||
| 301 | { | 301 | { | |||
| 302 | mgs_handle_t *ctxt; | 302 | mgs_handle_t *ctxt; | |||
| 303 | gnutls_retr_st* ret; | 303 | mgs_srvconf_rec *sc; | |||
| 304 | const char* sni_name; | 304 | const char* sni_name; | |||
| 305 | } vhost_cb_rec; | 305 | } vhost_cb_rec; | |||
| 306 | 306 | |||||
| @@ -319,8 +319,6 @@ static int vhost_cb (void* baton, conn_rec* conn, server_rec* s) | ||||||
| 319 | /* The CN can contain a * -- this will match those too. */ | 319 | /* The CN can contain a * -- this will match those too. */ | |||
| 320 | if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { | 320 | if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { | |||
| 321 | /* found a match */ | 321 | /* found a match */ | |||
| 322 | x->ret->cert.x509 = &tsc->cert_x509; | |||||
| 323 | x->ret->key.x509 = tsc->privkey_x509; | |||||
| 324 | #if MOD_GNUTLS_DEBUG | 322 | #if MOD_GNUTLS_DEBUG | |||
| 325 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 323 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | |||
| 326 | x->ctxt->c->base_server, | 324 | x->ctxt->c->base_server, | |||
| @@ -330,19 +328,18 @@ stati | /* Because we actually change the server used here, we need to reset | 328 | /* Because we actually change the server used here, we need to reset | |||
| 331 | * things like ClientVerify. | 329 | * things like ClientVerify. | |||
| 332 | */ | 330 | */ | |||
| 333 | x->ctxt->sc = tsc; | 331 | x->sc = tsc; | |||
| 334 | /* Shit. Crap. Dammit. We *really* should rehandshake here, as our | 332 | /* Shit. Crap. Dammit. We *really* should rehandshake here, as our | |||
| 335 | * certificate structure *should* change when the server changes. | 333 | * certificate structure *should* change when the server changes. | |||
| 336 | * acccckkkkkk. | 334 | * acccckkkkkk. | |||
| 337 | */ | 335 | */ | |||
| 338 | gnutls_certificate_server_set_request(x->ctxt->session, x->ctxt->sc->client_verify_mode); | |||||
| 339 | return 1; | 336 | return 1; | |||
| 340 | } | 337 | } | |||
| 341 | return 0; | 338 | return 0; | |||
| 342 | } | 339 | } | |||
| 343 | #endif | 340 | #endif | |||
| 344 | 341 | |||||
| 345 | static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | 342 | mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session) | |||
| 346 | { | 343 | { | |||
| 347 | int rv; | 344 | int rv; | |||
| 348 | int sni_type; | 345 | int sni_type; | |||
| @@ -364,26 +361,22 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | ||||||
| 364 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, | 361 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, | |||
| 365 | ctxt->c->base_server, | 362 | ctxt->c->base_server, | |||
| 366 | "GnuTLS: Only x509 Certificates are currently supported."); | 363 | "GnuTLS: Only x509 Certificates are currently supported."); | |||
| 367 | return -1; | 364 | return NULL; | |||
| 368 | } | 365 | } | |||
| 369 | ||||||
| 370 | ret->type = GNUTLS_CRT_X509; | |||||
| 371 | ret->ncerts = 1; | |||||
| 372 | ret->deinit_all = 0; | |||||
| 373 | 366 | |||||
| 374 | rv = gnutls_server_name_get(ctxt->session, sni_name, | 367 | rv = gnutls_server_name_get(ctxt->session, sni_name, | |||
| 375 | &data_len, &sni_type, 0); | 368 | &data_len, &sni_type, 0); | |||
| 376 | 369 | |||||
| 377 | if (rv != 0) { | 370 | if (rv != 0) { | |||
| 378 | goto use_default_crt; | 371 | return NULL; | |||
| 379 | } | 372 | } | |||
| 380 | 373 | |||||
| 381 | if (sni_type != GNUTLS_NAME_DNS) { | 374 | if (sni_type != GNUTLS_NAME_DNS) { | |||
| 382 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, | 375 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, | |||
| 383 | ctxt->c->base_server, | 376 | ctxt->c->base_server, | |||
| 384 | "GnuTLS: Unknown type '%d' for SNI: " | 377 | "GnuTLS: Unknown type '%d' for SNI: " | |||
| 385 | "'%s'", sni_type, sni_name); | 378 | "'%s'", sni_type, sni_name); | |||
| 386 | goto use_default_crt; | 379 | return NULL; | |||
| 387 | } | 380 | } | |||
| 388 | 381 | |||||
| 389 | /** | 382 | /** | |||
| @@ -392,18 +385,18 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | ||||||
| 392 | */ | 385 | */ | |||
| 393 | #if USING_2_1_RECENT | 386 | #if USING_2_1_RECENT | |||
| 394 | cbx.ctxt = ctxt; | 387 | cbx.ctxt = ctxt; | |||
| 395 | cbx.ret = ret; | 388 | cbx.sc = NULL; | |||
| 396 | cbx.sni_name = sni_name; | 389 | cbx.sni_name = sni_name; | |||
| 397 | 390 | |||||
| 398 | rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); | 391 | rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); | |||
| 399 | if (rv == 1) { | 392 | if (rv == 1) { | |||
| 400 | return 0; | 393 | return cbx.sc; | |||
| 401 | } | 394 | } | |||
| 402 | #else | 395 | #else | |||
| 403 | for (s = ap_server_conf; s; s = s->next) { | 396 | for (s = ap_server_conf; s; s = s->next) { | |||
| 404 | 397 | |||||
| 405 | tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | 398 | tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | |||
| 406 | &gnutls_module); | 399 | &gnutls_module); | |||
| 407 | if (tsc->enabled != GNUTLS_ENABLED_TRUE) { | 400 | if (tsc->enabled != GNUTLS_ENABLED_TRUE) { | |||
| 408 | continue; | 401 | continue; | |||
| 409 | } | 402 | } | |||
| @@ -416,34 +409,40 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | ||||||
| 416 | #endif | 409 | #endif | |||
| 417 | /* The CN can contain a * -- this will match those too. */ | 410 | /* The CN can contain a * -- this will match those too. */ | |||
| 418 | if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { | 411 | if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { | |||
| 419 | /* found a match */ | |||||
| 420 | ret->cert.x509 = &tsc->cert_x509; | |||||
| 421 | ret->key.x509 = tsc->privkey_x509; | |||||
| 422 | #if MOD_GNUTLS_DEBUG | 412 | #if MOD_GNUTLS_DEBUG | |||
| 423 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 413 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | |||
| 424 | ctxt->c->base_server, | 414 | ctxt->c->base_server, | |||
| 425 | "GnuTLS: Virtual Host: " | 415 | "GnuTLS: Virtual Host: " | |||
| 426 | "'%s' == '%s'", tsc->cert_cn, sni_name); | 416 | "'%s' == '%s'", tsc->cert_cn, sni_name); | |||
| 427 | #endif | 417 | #endif | |||
| 428 | ctxt->sc = tsc; | 418 | return tsc; | |||
| 429 | gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode); | |||||
| 430 | return 0; | |||||
| 431 | } | 419 | } | |||
| 432 | } | 420 | } | |||
| 433 | #endif | 421 | #endif | |||
| 422 | return NULL; | |||||
| 423 | } | |||||
| 424 | ||||||
| 425 | ||||||
| 426 | static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) | |||||
| 427 | { | |||||
| 428 | mgs_handle_t *ctxt; | |||||
| 429 | mgs_srvconf_rec *tsc; | |||||
| 430 | ||||||
| 431 | ctxt = gnutls_transport_get_ptr(session); | |||||
| 432 | ||||||
| 433 | ret->type = GNUTLS_CRT_X509; | |||||
| 434 | ret->ncerts = 1; | |||||
| 435 | ret->deinit_all = 0; | |||||
| 436 | ||||||
| 437 | tsc = mgs_find_sni_server(session); | |||||
| 438 | ||||||
| 439 | if (tsc != NULL) { | |||||
| 440 | ctxt->sc = tsc; | |||||
| 441 | gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode); | |||||
| 442 | } | |||||
| 434 | 443 | |||||
| 435 | /** | |||||
| 436 | * If the client does not support the Server Name Indication, give the default | |||||
| 437 | * certificate for this server. | |||||
| 438 | */ | |||||
| 439 | use_default_crt: | |||||
| 440 | ret->cert.x509 = &ctxt->sc->cert_x509; | 444 | ret->cert.x509 = &ctxt->sc->cert_x509; | |||
| 441 | ret->key.x509 = ctxt->sc->privkey_x509; | 445 | ret->key.x509 = ctxt->sc->privkey_x509; | |||
| 442 | #if MOD_GNUTLS_DEBUG | |||||
| 443 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | |||||
| 444 | ctxt->c->base_server, | |||||
| 445 | "GnuTLS: Using Default Certificate."); | |||||
| 446 | #endif | |||||
| 447 | return 0; | 446 | return 0; | |||
| 448 | } | 447 | } | |||
| 449 | 448 | |||||
diff --git a/src/gnutls_io.c b/src/gnutls_io.c index acb6095..925517b 100644 --- a/src/gnutls_io.c +++ b/src/gnutls_io.c | ||||||
| @@ -399,6 +399,16 @@ tryagain: | ||||||
| 399 | else { | 399 | else { | |||
| 400 | /* all done with the handshake */ | 400 | /* all done with the handshake */ | |||
| 401 | ctxt->status = 1; | 401 | ctxt->status = 1; | |||
| 402 | /* If the session was resumed, we did not set the correct | |||||
| 403 | * server_rec in ctxt->sc. Go Find it. (ick!) | |||||
| 404 | */ | |||||
| 405 | if (gnutls_session_is_resumed(ctxt->session)) { | |||||
| 406 | mgs_srvconf_rec* sc; | |||||
| 407 | sc = mgs_find_sni_server(ctxt->session); | |||||
| 408 | if (sc) { | |||||
| 409 | ctxt->sc = sc; | |||||
| 410 | } | |||||
| 411 | } | |||||
| 402 | return 0; | 412 | return 0; | |||
| 403 | } | 413 | } | |||
| 404 | } | 414 | } | |||
