Skip to content

Commit f2e6407

Browse files
author
Bradley Nicholes
committed
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@104273 13f79535-47bb-0310-9956-ffa450edef68
1 parent e328507 commit f2e6407

2 files changed

Lines changed: 31 additions & 13 deletions

File tree

modules/ssl/ssl_engine_io.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,14 +1170,17 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
11701170

11711171
{
11721172
#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
1173-
#define UPGRADE_HEADER "Upgrade: TLS/1.0 HTTP/1.1"
1173+
#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
11741174
#define CONNECTION_HEADER "Connection: Upgrade"
11751175
const char *upgrade;
11761176
const char *connection;
11771177
apr_bucket_brigade *upgradebb;
11781178
request_rec *r = f->r;
11791179
SSLConnRec *sslconn;
11801180
SSL *ssl;
1181+
char *token_string;
1182+
char *token;
1183+
char *token_state;
11811184

11821185
/* Just remove the filter, if it doesn't work the first time, it won't
11831186
* work at all for this request.
@@ -1192,19 +1195,30 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
11921195
if (upgrade == NULL) {
11931196
return ap_pass_brigade(f->next, bb);
11941197
}
1195-
connection = apr_table_get(r->headers_in, "Connection");
1198+
token_string = apr_pstrdup(r->pool,upgrade);
1199+
token = apr_strtok(token_string,", ",&token_state);
1200+
while (token && strcmp(token,"TLS/1.0")) {
1201+
apr_strtok(NULL,", ",&token_state);
1202+
}
1203+
/* "Upgrade: TLS/1.0" header not found, don't do Upgrade */
1204+
if (!token) {
1205+
return ap_pass_brigade(f->next, bb);
1206+
}
11961207

1197-
apr_table_unset(r->headers_out, "Upgrade");
1208+
connection = apr_table_get(r->headers_in, "Connection");
11981209

1199-
/* XXX: I don't think the requirement that the client sends exactly
1200-
* "Connection: Upgrade" is correct; the only requirement here is
1201-
* on the client to send a Connection header including the "upgrade"
1202-
* token.
1203-
*/
1204-
if (strcmp(connection, "Upgrade") || strcmp(upgrade, "TLS/1.0")) {
1210+
token_string = apr_pstrdup(r->pool,connection);
1211+
token = apr_strtok(token_string,",",&token_state);
1212+
while (token && strcmp(token,"Upgrade")) {
1213+
apr_strtok(NULL,",",&token_state);
1214+
}
1215+
/* "Connection: Upgrade" header not found, don't do Upgrade */
1216+
if (!token) {
12051217
return ap_pass_brigade(f->next, bb);
12061218
}
12071219

1220+
apr_table_unset(r->headers_out, "Upgrade");
1221+
12081222
if (r->method_number == M_OPTIONS) {
12091223
apr_bucket *b = NULL;
12101224
/* This is a mandatory SSL upgrade. */
@@ -1238,18 +1252,22 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
12381252
* However, this causes failures in perl-framework currently,
12391253
* perhaps pre-test if we have already negotiated?
12401254
*/
1241-
SSL_set_state(ssl, SSL_ST_ACCEPT);
1255+
SSL_set_accept_state(ssl);
12421256
SSL_do_handshake(ssl);
12431257

12441258
if (SSL_get_state(ssl) != SSL_ST_OK) {
12451259
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
1246-
"Re-negotiation handshake failed: "
1260+
"TLS Upgrade handshake failed: "
12471261
"Not accepted by client!?");
12481262

12491263
return AP_FILTER_ERROR;
12501264
}
12511265

1252-
return OK;
1266+
/* Now that we have initialized the ssl connection which added the ssl_io_filter,
1267+
pass the brigade off to the connection based output filters so that the
1268+
request can complete encrypted */
1269+
return ap_pass_brigade(f->c->output_filters, bb);
1270+
12531271
}
12541272

12551273
static apr_status_t ssl_io_filter_input(ap_filter_t *f,

modules/ssl/ssl_engine_kernel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ int ssl_hook_Fixup(request_rec *r)
10131013
SSL *ssl;
10141014
int i;
10151015

1016-
if (sc->enabled == SSL_ENABLED_OPTIONAL) {
1016+
if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)) {
10171017
apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
10181018
}
10191019

0 commit comments

Comments
 (0)