- Timestamp:
- Sep 27, 2004, 3:21:52 PM (18 years ago)
- Branches:
- asyncio, debian/master, debian/stretch-backports, jessie-backports, main, master, msva, proxy-ticket, upstream
- Children:
- 7e2b223
- Parents:
- 6a8a839
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mod_gnutls.c
r6a8a839 raa99b13 50 50 char *cert_file; 51 51 int enabled; 52 int non_https;53 52 int ciphers[16]; 54 53 int key_exchange[16]; … … 63 62 gnutls_srvconf_rec *sc; 64 63 gnutls_session_t session; 65 #ifdef GNUTLS_AS_FILTER66 64 ap_filter_t *input_filter; 67 65 apr_bucket_brigade *input_bb; 68 66 apr_read_type_e input_block; 69 #endif 67 int status; 68 int non_https; 70 69 }; 71 70 72 #ifdef GNUTLS_AS_FILTER73 71 static apr_status_t gnutls_filter_input(ap_filter_t * f, 74 72 apr_bucket_brigade * bb, … … 86 84 } 87 85 86 87 for (b = APR_BRIGADE_FIRST(bb); 88 b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { 89 if (APR_BUCKET_IS_EOS(b)) { 90 /* end of connection */ 91 } 92 else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) 93 == APR_SUCCESS) { 94 /* more data */ 95 } 96 } 97 88 98 return status; 89 99 } 100 101 #define HANDSHAKE_ATTEMPTS 10 90 102 91 103 static apr_status_t gnutls_filter_output(ap_filter_t * f, 92 104 apr_bucket_brigade * bb) 93 105 { 94 apr_bucket *b;106 int ret, i; 95 107 const char *buf = 0; 96 108 apr_size_t bytes = 0; 97 109 gnutls_handle_t *ctxt = (gnutls_handle_t *) f->ctx; 98 110 apr_status_t status = APR_SUCCESS; 99 100 if (!ctxt) { 101 /* first run. */ 102 } 103 104 for (b = APR_BRIGADE_FIRST(bb); 105 b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { 106 if (APR_BUCKET_IS_EOS(b)) { 107 /* end of connection */ 108 } 109 else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) 110 == APR_SUCCESS) { 111 /* more data */ 111 apr_read_type_e rblock = APR_NONBLOCK_READ; 112 113 if (f->c->aborted) { 114 apr_brigade_cleanup(bb); 115 return APR_ECONNABORTED; 116 } 117 118 if(ctxt->status == 0) { 119 for (i=HANDSHAKE_ATTEMPTS; i>0; i--){ 120 ret = gnutls_handshake(ctxt->session); 121 122 if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN){ 123 continue; 124 } 125 126 if (ret < 0) { 127 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { 128 ret = gnutls_alert_get(ctxt->session); 129 ap_log_error(APLOG_MARK, APLOG_ERR, 0, f->c->base_server, 130 "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, gnutls_alert_get_name(ret)); 131 } 132 133 if (gnutls_error_is_fatal(ret) != 0) { 134 gnutls_deinit(ctxt->session); 135 ap_log_error(APLOG_MARK, APLOG_ERR, 0, f->c->base_server, 136 "GnuTLS: Handshake Failed (%d) '%s'",ret, gnutls_strerror(ret)); 137 ctxt->status = -1; 138 break; 139 } 140 } 141 else { 142 ctxt->status = 1; 143 break; /* all done with the handshake */ 144 } 145 } 146 } 147 148 if (ctxt->status < 0) { 149 return ap_pass_brigade(f->next, bb); 150 } 151 152 while (!APR_BRIGADE_EMPTY(bb)) { 153 apr_bucket *bucket = APR_BRIGADE_FIRST(bb); 154 if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) { 155 /** TODO: GnuTLS doesn't have a special flush method? **/ 156 if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { 157 return status; 158 } 159 break; 160 } 161 else if(AP_BUCKET_IS_EOC(bucket)) { 162 gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); 163 164 if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) { 165 return status; 166 } 167 break; 168 } 169 else { 170 /* filter output */ 171 const char *data; 172 apr_size_t len; 173 174 status = apr_bucket_read(bucket, &data, &len, rblock); 175 176 if (APR_STATUS_IS_EAGAIN(status)) { 177 rblock = APR_BLOCK_READ; 178 continue; /* and try again with a blocking read. */ 179 } 180 181 rblock = APR_NONBLOCK_READ; 182 183 if (!APR_STATUS_IS_EOF(status) && (status != APR_SUCCESS)) { 184 break; 185 } 186 187 ret = gnutls_record_send(ctxt->session, data, len); 188 status = ssl_filter_write(f, data, len); 189 if(ret < 0) { 190 /* error sending output */ 191 } 192 else if ((apr_size_t)res != len) { 193 /* not all of the data was sent. */ 194 /* mod_ssl basicly errors out here.. this doesn't seem right? */ 195 } 196 else { 197 /* send complete */ 198 199 } 200 201 apr_bucket_delete(bucket); 202 203 if (status != APR_SUCCESS) { 204 break; 205 } 206 112 207 } 113 208 } … … 115 210 return status; 116 211 } 117 118 #endif /* GNUTLS_AS_FILTER */119 212 120 213 static apr_status_t gnutls_cleanup_pre_config(void *data) … … 207 300 } 208 301 209 #ifdef GNUTLS_AS_FILTER210 302 /** 211 303 * From mod_ssl / ssl_engine_io.c … … 346 438 return 0; 347 439 } 348 #endif /* GNUTLS_AS_FILTER */349 440 350 441 static int gnutls_hook_pre_connection(conn_rec * c, void *csd) 351 442 { 352 #ifndef GNUTLS_AS_FILTER353 int cfd;354 int ret;355 #endif356 443 gnutls_handle_t *ctxt; 357 444 gnutls_srvconf_rec *sc = … … 367 454 368 455 ctxt->sc = sc; 456 ctxt->status = 0; 369 457 gnutls_init(&ctxt->session, GNUTLS_SERVER); 370 458 … … 376 464 377 465 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs); 466 // if(anon) { 467 // gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred); 468 // } 469 378 470 gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE); 379 471 … … 383 475 ap_set_module_config(c->conn_config, &gnutls_module, ctxt); 384 476 385 #ifdef GNUTLS_AS_FILTER386 477 gnutls_transport_set_pull_function(ctxt->session, gnutls_transport_read); 387 478 gnutls_transport_set_push_function(ctxt->session, gnutls_transport_write); 388 479 gnutls_transport_set_ptr(ctxt->session, ctxt); 389 390 480 ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c); 391 481 ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c); 392 #else 393 apr_os_sock_get(&cfd, csd); 394 gnutls_transport_set_ptr(ctxt->session, (gnutls_transport_ptr)cfd); 395 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred); 396 397 do{ 398 ret = gnutls_handshake(ctxt->session); 399 400 if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN){ 401 continue; 402 } 403 404 if (ret < 0) { 405 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { 406 ret = gnutls_alert_get(ctxt->session); 407 ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, 408 "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, gnutls_alert_get_name(ret)); 409 } 410 411 if (gnutls_error_is_fatal(ret) != 0) { 412 gnutls_deinit(ctxt->session); 413 ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, 414 "GnuTLS: Handshake Failed (%d) '%s'",ret, gnutls_strerror(ret)); 415 sc->non_https = 1; 416 break; 417 } 418 } 419 break; /* all done with the handshake */ 420 } while(1); 421 #endif 482 422 483 return OK; 423 484 } … … 502 563 * ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); 503 564 */ 504 #ifdef GNUTLS_AS_FILTER505 565 ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, gnutls_filter_input, 506 566 NULL, AP_FTYPE_CONNECTION + 5); 507 567 ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, gnutls_filter_output, 508 568 NULL, AP_FTYPE_CONNECTION + 5); 509 #endif510 569 } 511 570
Note: See TracChangeset
for help on using the changeset viewer.