diff options
Diffstat (limited to 'src/gnutls_io.c')
-rw-r--r-- | src/gnutls_io.c | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/src/gnutls_io.c b/src/gnutls_io.c index e92646b..a44ba9c 100644 --- a/src/gnutls_io.c +++ b/src/gnutls_io.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* ==================================================================== | 1 | /** |
2 | * Copyright 2004 Paul Querna | 2 | * Copyright 2004-2005 Paul Querna |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
@@ -342,33 +342,46 @@ static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) | |||
342 | { | 342 | { |
343 | int ret; | 343 | int ret; |
344 | 344 | ||
345 | if (ctxt->status != 0) | 345 | if (ctxt->status != 0) { |
346 | return; | 346 | return; |
347 | ret = gnutls_handshake(ctxt->session); | 347 | } |
348 | if (ret < 0) { | 348 | |
349 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED | 349 | tryagain: |
350 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { | 350 | |
351 | ret = gnutls_alert_get(ctxt->session); | 351 | ret = gnutls_handshake(ctxt->session); |
352 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, | 352 | if (ret < 0) { |
353 | "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, | 353 | if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED |
354 | gnutls_alert_get_name(ret)); | 354 | || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { |
355 | } | 355 | ret = gnutls_alert_get(ctxt->session); |
356 | |||
357 | gnutls_deinit(ctxt->session); | ||
358 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, | 356 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, |
359 | "GnuTLS: Handshake Failed (%d) '%s'", ret, | 357 | "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, |
360 | gnutls_strerror(ret)); | 358 | gnutls_alert_get_name(ret)); |
361 | ctxt->status = -1; | ||
362 | return; | ||
363 | } | 359 | } |
364 | else { | 360 | |
365 | ctxt->status = 1; | 361 | if (!gnutls_error_is_fatal(ret)) { |
366 | return; /* all done with the handshake */ | 362 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, ctxt->c->base_server, |
363 | "GnuTLS: Non-Fatal Handshake Error: (%d) '%s'", ret, | ||
364 | gnutls_strerror(ret)); | ||
365 | goto tryagain; | ||
367 | } | 366 | } |
367 | |||
368 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, | ||
369 | "GnuTLS: Handshake Failed (%d) '%s'", ret, | ||
370 | gnutls_strerror(ret)); | ||
371 | ctxt->status = -1; | ||
372 | gnutls_alert_send(ctxt->session, GNUTLS_AL_FATAL, | ||
373 | gnutls_error_to_alert(ret, NULL)); | ||
374 | gnutls_deinit(ctxt->session); | ||
375 | return; | ||
376 | } | ||
377 | else { | ||
378 | ctxt->status = 1; | ||
379 | return; /* all done with the handshake */ | ||
380 | } | ||
368 | } | 381 | } |
369 | 382 | ||
370 | 383 | ||
371 | apr_status_t mod_gnutls_filter_input(ap_filter_t * f, | 384 | apr_status_t mod_gnutls_filter_input(ap_filter_t* f, |
372 | apr_bucket_brigade * bb, | 385 | apr_bucket_brigade * bb, |
373 | ap_input_mode_t mode, | 386 | ap_input_mode_t mode, |
374 | apr_read_type_e block, | 387 | apr_read_type_e block, |
@@ -455,7 +468,7 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
455 | 468 | ||
456 | while (!APR_BRIGADE_EMPTY(bb)) { | 469 | while (!APR_BRIGADE_EMPTY(bb)) { |
457 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); | 470 | apr_bucket *bucket = APR_BRIGADE_FIRST(bb); |
458 | if (APR_BUCKET_IS_EOS(bucket) || AP_BUCKET_IS_EOC(bucket)) { | 471 | if (AP_BUCKET_IS_EOC(bucket)) { |
459 | 472 | ||
460 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); | 473 | gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); |
461 | gnutls_deinit(ctxt->session); | 474 | gnutls_deinit(ctxt->session); |
@@ -465,7 +478,7 @@ apr_status_t mod_gnutls_filter_output(ap_filter_t * f, | |||
465 | } | 478 | } |
466 | break; | 479 | break; |
467 | 480 | ||
468 | } else if (APR_BUCKET_IS_FLUSH(bucket)) { | 481 | } else if (APR_BUCKET_IS_FLUSH(bucket) || APR_BUCKET_IS_EOS(bucket)) { |
469 | 482 | ||
470 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { | 483 | if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { |
471 | return status; | 484 | return status; |