Hey, OpenSSL doesn't do anything to verify that "negotiated" protocol was actually advertised to the client, so we have to do it ourselves.
Note: I dislike the way NGX_HTTP_NPN_NEGOTIATED is defined here, but it kind of matches the way NGX_HTTP_NPN_ADVERTISE is defined and I didn't see a better place to add it. Feel free to move it elsewhere. Best regards, Piotr Sikora diff -r 4bcd35e7a0f0 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Fri Mar 29 08:47:37 2013 +0000 +++ b/src/http/ngx_http_request.c Tue Apr 02 17:54:05 2013 -0700 @@ -712,6 +712,10 @@ } +#ifdef TLSEXT_TYPE_next_proto_neg +#define NGX_HTTP_NPN_NEGOTIATED "http/1.1" +#endif + static void ngx_http_ssl_handshake_handler(ngx_connection_t *c) { @@ -727,17 +731,34 @@ c->ssl->no_wait_shutdown = 1; -#if (NGX_HTTP_SPDY && defined TLSEXT_TYPE_next_proto_neg) +#ifdef TLSEXT_TYPE_next_proto_neg { unsigned int len; const unsigned char *data; + static const ngx_str_t http = ngx_string(NGX_HTTP_NPN_NEGOTIATED); +#if (NGX_HTTP_SPDY) static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED); +#endif SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len); - if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) { - ngx_http_spdy_init(c->read); - return; + if (len) { +#if (NGX_HTTP_SPDY) + if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) + { + ngx_http_spdy_init(c->read); + return; + } +#endif + + if (len != http.len || ngx_strncmp(data, http.data, http.len)) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "client negotiated unsupported protocol \"%*s\"", + len, data); + + ngx_http_close_connection(c); + return; + } } } #endif _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel