diff options
| author | 2005-04-06 04:52:25 +0000 | |
|---|---|---|
| committer | 2005-04-06 04:52:25 +0000 | |
| commit | 42307a9120b12fa5eb6fe1b316ef521ae46dbeb9 (patch) | |
| tree | 3f3da6cbf06c91cbca72f9f6f552a0a26afe62f2 /src/gnutls_io.c | |
| parent | fcb122d264414b86ca89dddffba5f839963fc7fa (diff) | |
- remove anno creds
- initial attempt at Server Name Extension
- change to adding 'mod_gnutls' to the server sig instead of GnuTLS/
- fix for EOF/EOC/EOS buckets
- 'general' code cleanups
Diffstat (limited to 'src/gnutls_io.c')
| -rw-r--r-- | src/gnutls_io.c | 99 |
1 files changed, 73 insertions, 26 deletions
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 | } |
