summaryrefslogtreecommitdiffstatsabout
path: root/src/gnutls_io.c
diff options
context:
space:
mode:
authorPaul Querna <chip@outoforder.cc>2005-04-06 04:52:25 (GMT)
committer Paul Querna <chip@outoforder.cc>2005-04-06 04:52:25 (GMT)
commit42307a9120b12fa5eb6fe1b316ef521ae46dbeb9 (patch)
tree3f3da6cbf06c91cbca72f9f6f552a0a26afe62f2 /src/gnutls_io.c
parentfcb122d264414b86ca89dddffba5f839963fc7fa (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.c99
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,
341static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) 357static 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}