diff options
author | Bradley Nicholes <bnicholes@apache.org> | 2004-07-13 18:11:22 +0000 |
---|---|---|
committer | Bradley Nicholes <bnicholes@apache.org> | 2004-07-13 18:11:22 +0000 |
commit | 2922d23daf30ad61061c544c9e0e66950d42283e (patch) | |
tree | 22289d3c68f12f2bfae381a8efe8347a8380fd82 | |
parent | ea6637bfe64ee7464704bd58af2a8dbec6b8555a (diff) | |
download | httpd-2922d23daf30ad61061c544c9e0e66950d42283e.tar.gz |
Tokenize the header while parsing it for the upgrade tokens and once the protocol has been upgraded, allow the request to complete encrypted.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/ssl@104273 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | ssl_engine_io.c | 42 | ||||
-rw-r--r-- | ssl_engine_kernel.c | 2 |
2 files changed, 31 insertions, 13 deletions
diff --git a/ssl_engine_io.c b/ssl_engine_io.c index 0d97797555..d48292c50e 100644 --- a/ssl_engine_io.c +++ b/ssl_engine_io.c @@ -1170,7 +1170,7 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, { #define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols" -#define UPGRADE_HEADER "Upgrade: TLS/1.0 HTTP/1.1" +#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1" #define CONNECTION_HEADER "Connection: Upgrade" const char *upgrade; const char *connection; @@ -1178,6 +1178,9 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, request_rec *r = f->r; SSLConnRec *sslconn; SSL *ssl; + char *token_string; + char *token; + char *token_state; /* Just remove the filter, if it doesn't work the first time, it won't * work at all for this request. @@ -1192,19 +1195,30 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, if (upgrade == NULL) { return ap_pass_brigade(f->next, bb); } - connection = apr_table_get(r->headers_in, "Connection"); + token_string = apr_pstrdup(r->pool,upgrade); + token = apr_strtok(token_string,", ",&token_state); + while (token && strcmp(token,"TLS/1.0")) { + apr_strtok(NULL,", ",&token_state); + } + /* "Upgrade: TLS/1.0" header not found, don't do Upgrade */ + if (!token) { + return ap_pass_brigade(f->next, bb); + } - apr_table_unset(r->headers_out, "Upgrade"); + connection = apr_table_get(r->headers_in, "Connection"); - /* XXX: I don't think the requirement that the client sends exactly - * "Connection: Upgrade" is correct; the only requirement here is - * on the client to send a Connection header including the "upgrade" - * token. - */ - if (strcmp(connection, "Upgrade") || strcmp(upgrade, "TLS/1.0")) { + token_string = apr_pstrdup(r->pool,connection); + token = apr_strtok(token_string,",",&token_state); + while (token && strcmp(token,"Upgrade")) { + apr_strtok(NULL,",",&token_state); + } + /* "Connection: Upgrade" header not found, don't do Upgrade */ + if (!token) { return ap_pass_brigade(f->next, bb); } + apr_table_unset(r->headers_out, "Upgrade"); + if (r->method_number == M_OPTIONS) { apr_bucket *b = NULL; /* This is a mandatory SSL upgrade. */ @@ -1238,18 +1252,22 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, * However, this causes failures in perl-framework currently, * perhaps pre-test if we have already negotiated? */ - SSL_set_state(ssl, SSL_ST_ACCEPT); + SSL_set_accept_state(ssl); SSL_do_handshake(ssl); if (SSL_get_state(ssl) != SSL_ST_OK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "Re-negotiation handshake failed: " + "TLS Upgrade handshake failed: " "Not accepted by client!?"); return AP_FILTER_ERROR; } - return OK; + /* Now that we have initialized the ssl connection which added the ssl_io_filter, + pass the brigade off to the connection based output filters so that the + request can complete encrypted */ + return ap_pass_brigade(f->c->output_filters, bb); + } static apr_status_t ssl_io_filter_input(ap_filter_t *f, diff --git a/ssl_engine_kernel.c b/ssl_engine_kernel.c index ccd84deed7..6022ef9262 100644 --- a/ssl_engine_kernel.c +++ b/ssl_engine_kernel.c @@ -1013,7 +1013,7 @@ int ssl_hook_Fixup(request_rec *r) SSL *ssl; int i; - if (sc->enabled == SSL_ENABLED_OPTIONAL) { + if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)) { apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1"); } |