nghttpx: Don't allow application protocol not listed in --npn-list option
This commit is contained in:
parent
78e5149495
commit
20877b1107
|
@ -602,7 +602,7 @@ void print_help(std::ostream& out)
|
|||
<< " Path to file that contains DH parameters in\n"
|
||||
<< " PEM format. Without this option, DHE cipher\n"
|
||||
<< " suites are not available.\n"
|
||||
<< " --npn-list=<LIST> Comma delimited list of NPN protocol sorted\n"
|
||||
<< " --npn-list=<LIST> Comma delimited list of NPN/ALPN protocol sorted\n"
|
||||
<< " in the order of preference. That means\n"
|
||||
<< " most desirable protocol comes first.\n"
|
||||
<< " The parameter must be delimited by a single\n"
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "shrpx_http_downstream_connection.h"
|
||||
#include "shrpx_http2_downstream_connection.h"
|
||||
#include "shrpx_accesslog.h"
|
||||
#include "shrpx_ssl.h"
|
||||
#ifdef HAVE_SPDYLAY
|
||||
#include "shrpx_spdy_upstream.h"
|
||||
#endif // HAVE_SPDYLAY
|
||||
|
@ -108,7 +109,10 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg)
|
|||
if(LOG_ENABLED(INFO)) {
|
||||
CLOG(INFO, handler) << "SSL/TLS handleshake completed";
|
||||
}
|
||||
handler->validate_next_proto();
|
||||
if(handler->validate_next_proto() != 0) {
|
||||
delete handler;
|
||||
return;
|
||||
}
|
||||
if(LOG_ENABLED(INFO)) {
|
||||
if(SSL_session_reused(handler->get_ssl())) {
|
||||
CLOG(INFO, handler) << "SSL/TLS session reused";
|
||||
|
@ -305,6 +309,11 @@ int ClientHandler::validate_next_proto()
|
|||
std::string proto(next_proto, next_proto+next_proto_len);
|
||||
CLOG(INFO, this) << "The negotiated next protocol: " << proto;
|
||||
}
|
||||
if(!ssl::in_proto_list(get_config()->npn_list,
|
||||
get_config()->npn_list_len,
|
||||
next_proto, next_proto_len)) {
|
||||
break;
|
||||
}
|
||||
if(next_proto_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
|
||||
memcmp(NGHTTP2_PROTO_VERSION_ID, next_proto,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN) == 0) {
|
||||
|
@ -320,6 +329,10 @@ int ClientHandler::validate_next_proto()
|
|||
return 0;
|
||||
}
|
||||
#endif // HAVE_SPDYLAY
|
||||
if(next_proto_len == 8 && memcmp("http/1.1", next_proto, 8) == 0) {
|
||||
upstream_ = util::make_unique<HttpsUpstream>(this);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -331,14 +344,15 @@ int ClientHandler::validate_next_proto()
|
|||
}
|
||||
if(!next_proto) {
|
||||
if(LOG_ENABLED(INFO)) {
|
||||
CLOG(INFO, this) << "No proto negotiated.";
|
||||
CLOG(INFO, this) << "No protocol negotiated. Fallback to HTTP/1.1";
|
||||
}
|
||||
upstream_ = util::make_unique<HttpsUpstream>(this);
|
||||
return 0;
|
||||
}
|
||||
if(LOG_ENABLED(INFO)) {
|
||||
CLOG(INFO, this) << "Use HTTP/1.1";
|
||||
CLOG(INFO, this) << "The negotiated protocol is not supported";
|
||||
}
|
||||
upstream_ = util::make_unique<HttpsUpstream>(this);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ClientHandler::on_read()
|
||||
|
|
|
@ -147,8 +147,9 @@ struct Config {
|
|||
char *downstream_http_proxy_host;
|
||||
// Rate limit configuration
|
||||
ev_token_bucket_cfg *rate_limit_cfg;
|
||||
// Comma delimited list of NPN protocol strings in the order of
|
||||
// preference.
|
||||
// list of supported NPN/ALPN protocol strings in the order of
|
||||
// preference. The each element of this list is a NULL-terminated
|
||||
// string.
|
||||
char **npn_list;
|
||||
// Path to file containing CA certificate solely used for client
|
||||
// certificate validation
|
||||
|
|
|
@ -831,6 +831,18 @@ int cert_lookup_tree_add_cert_from_file(CertLookupTree *lt, SSL_CTX *ssl_ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool in_proto_list(char **protos, size_t len,
|
||||
const unsigned char *proto, size_t protolen)
|
||||
{
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
if(strlen(protos[i]) == protolen &&
|
||||
memcmp(protos[i], proto, protolen) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ssl
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
|
@ -126,6 +126,12 @@ SSL_CTX* cert_lookup_tree_lookup(CertLookupTree *lt, const char *hostname,
|
|||
int cert_lookup_tree_add_cert_from_file(CertLookupTree *lt, SSL_CTX *ssl_ctx,
|
||||
const char *certfile);
|
||||
|
||||
// Returns true if |proto| which has |protolen| bytes is included in
|
||||
// the protocol list |protos|, which has |len| elements. The format of
|
||||
// the |protos| is the one used in Config::npn_list.
|
||||
bool in_proto_list(char **protos, size_t len,
|
||||
const unsigned char *proto, size_t protolen);
|
||||
|
||||
} // namespace ssl
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
Loading…
Reference in New Issue