You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by bn...@apache.org on 2004/07/13 20:11:22 UTC
cvs commit: httpd-2.0/modules/ssl ssl_engine_io.c ssl_engine_kernel.c
bnicholes 2004/07/13 11:11:22
Modified: modules/ssl ssl_engine_io.c ssl_engine_kernel.c
Log:
Tokenize the header while parsing it for the upgrade tokens and once the protocol has been upgraded, allow the request to complete encrypted.
Revision Changes Path
1.124 +30 -12 httpd-2.0/modules/ssl/ssl_engine_io.c
Index: ssl_engine_io.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_io.c,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -r1.123 -r1.124
--- ssl_engine_io.c 15 Jun 2004 21:00:22 -0000 1.123
+++ ssl_engine_io.c 13 Jul 2004 18:11:22 -0000 1.124
@@ -1170,7 +1170,7 @@
{
#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 @@
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 @@
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 @@
* 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,
1.108 +1 -1 httpd-2.0/modules/ssl/ssl_engine_kernel.c
Index: ssl_engine_kernel.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_kernel.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -r1.107 -r1.108
--- ssl_engine_kernel.c 3 Jun 2004 15:00:15 -0000 1.107
+++ ssl_engine_kernel.c 13 Jul 2004 18:11:22 -0000 1.108
@@ -1013,7 +1013,7 @@
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");
}