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 @@ static int vhost_cb (void* baton, conn_rec* conn, server_rec* s) | |||
330 | /* 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 | } |