summaryrefslogtreecommitdiffhomepage
path: root/src/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_grpc_module.c25
-rw-r--r--src/http/modules/ngx_http_ssl_module.c156
-rw-r--r--src/http/modules/ngx_http_ssl_module.h4
-rw-r--r--src/http/ngx_http_request.c12
-rw-r--r--src/http/ngx_http_upstream.c2
-rw-r--r--src/http/ngx_http_variables.c2
-rw-r--r--src/http/v2/ngx_http_v2.c10
7 files changed, 194 insertions, 17 deletions
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
index d4af66dbf..992211e73 100644
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -120,6 +120,7 @@ typedef struct {
unsigned end_stream:1;
unsigned done:1;
unsigned status:1;
+ unsigned rst:1;
ngx_http_request_t *request;
@@ -1205,6 +1206,7 @@ ngx_http_grpc_reinit_request(ngx_http_request_t *r)
ctx->end_stream = 0;
ctx->done = 0;
ctx->status = 0;
+ ctx->rst = 0;
ctx->connection = NULL;
return NGX_OK;
@@ -2088,7 +2090,10 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
return NGX_ERROR;
}
- if (ctx->stream_id && ctx->done) {
+ if (ctx->stream_id && ctx->done
+ && ctx->type != NGX_HTTP_V2_RST_STREAM_FRAME
+ && ctx->type != NGX_HTTP_V2_WINDOW_UPDATE_FRAME)
+ {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent frame for closed stream %ui",
ctx->stream_id);
@@ -2131,11 +2136,21 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
return NGX_ERROR;
}
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream rejected request with error %ui",
- ctx->error);
+ if (ctx->error || !ctx->done) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream rejected request with error %ui",
+ ctx->error);
+ return NGX_ERROR;
+ }
- return NGX_ERROR;
+ if (ctx->rst) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent frame for closed stream %ui",
+ ctx->stream_id);
+ return NGX_ERROR;
+ }
+
+ ctx->rst = 1;
}
if (ctx->type == NGX_HTTP_V2_GOAWAY_FRAME) {
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index a48d3b924..7daa4daf2 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -50,6 +50,8 @@ static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
@@ -74,6 +76,14 @@ static ngx_conf_enum_t ngx_http_ssl_verify[] = {
};
+static ngx_conf_enum_t ngx_http_ssl_ocsp[] = {
+ { ngx_string("off"), 0 },
+ { ngx_string("on"), 1 },
+ { ngx_string("leaf"), 2 },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_conf_deprecated_t ngx_http_ssl_deprecated = {
ngx_conf_deprecated, "ssl", "listen ... ssl"
};
@@ -214,6 +224,27 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, crl),
NULL },
+ { ngx_string("ssl_ocsp"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, ocsp),
+ &ngx_http_ssl_ocsp },
+
+ { ngx_string("ssl_ocsp_responder"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, ocsp_responder),
+ NULL },
+
+ { ngx_string("ssl_ocsp_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_http_ssl_ocsp_cache,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("ssl_stapling"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -569,6 +600,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->crl = { 0, NULL };
* sscf->ciphers = { 0, NULL };
* sscf->shm_zone = NULL;
+ * sscf->ocsp_responder = { 0, NULL };
* sscf->stapling_file = { 0, NULL };
* sscf->stapling_responder = { 0, NULL };
*/
@@ -586,6 +618,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->session_timeout = NGX_CONF_UNSET;
sscf->session_tickets = NGX_CONF_UNSET;
sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
+ sscf->ocsp = NGX_CONF_UNSET_UINT;
+ sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
sscf->stapling = NGX_CONF_UNSET;
sscf->stapling_verify = NGX_CONF_UNSET;
@@ -649,6 +683,11 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
+ ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
+ ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
+ ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
+ prev->ocsp_cache_zone, NULL);
+
ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
@@ -810,6 +849,23 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
+ if (conf->ocsp) {
+
+ if (conf->verify == 3) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "\"ssl_ocsp\" is incompatible with "
+ "\"ssl_verify_client optional_no_ca\"");
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
+ conf->ocsp_cache_zone)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+
if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -1108,6 +1164,85 @@ invalid:
}
+static char *
+ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_ssl_srv_conf_t *sscf = conf;
+
+ size_t len;
+ ngx_int_t n;
+ ngx_str_t *value, name, size;
+ ngx_uint_t j;
+
+ if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ sscf->ocsp_cache_zone = NULL;
+ return NGX_CONF_OK;
+ }
+
+ if (value[1].len <= sizeof("shared:") - 1
+ || ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
+ {
+ goto invalid;
+ }
+
+ len = 0;
+
+ for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
+ if (value[1].data[j] == ':') {
+ break;
+ }
+
+ len++;
+ }
+
+ if (len == 0) {
+ goto invalid;
+ }
+
+ name.len = len;
+ name.data = value[1].data + sizeof("shared:") - 1;
+
+ size.len = value[1].len - j - 1;
+ size.data = name.data + len + 1;
+
+ n = ngx_parse_size(&size);
+
+ if (n == NGX_ERROR) {
+ goto invalid;
+ }
+
+ if (n < (ngx_int_t) (8 * ngx_pagesize)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "OCSP cache \"%V\" is too small", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
+ &ngx_http_ssl_module_ctx);
+ if (sscf->ocsp_cache_zone == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ sscf->ocsp_cache_zone->init = ngx_ssl_ocsp_cache_init;
+
+ return NGX_CONF_OK;
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid OCSP cache \"%V\"", &value[1]);
+
+ return NGX_CONF_ERROR;
+}
+
+
static ngx_int_t
ngx_http_ssl_init(ngx_conf_t *cf)
{
@@ -1126,17 +1261,28 @@ ngx_http_ssl_init(ngx_conf_t *cf)
sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
- if (sscf->ssl.ctx == NULL || !sscf->stapling) {
+ if (sscf->ssl.ctx == NULL) {
continue;
}
clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
- if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
+ if (sscf->stapling) {
+ if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
+ clcf->resolver_timeout)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ if (sscf->ocsp) {
+ if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, clcf->resolver,
clcf->resolver_timeout)
- != NGX_OK)
- {
- return NGX_ERROR;
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
}
}
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
index 26fdccfe4..98aa1be40 100644
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -54,6 +54,10 @@ typedef struct {
ngx_flag_t session_tickets;
ngx_array_t *session_ticket_keys;
+ ngx_uint_t ocsp;
+ ngx_str_t ocsp_responder;
+ ngx_shm_zone_t *ocsp_cache_zone;
+
ngx_flag_t stapling;
ngx_flag_t stapling_verify;
ngx_str_t stapling_file;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 1b3573598..3e6fce676 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2127,6 +2127,7 @@ ngx_http_process_request(ngx_http_request_t *r)
if (r->http_connection->ssl) {
long rc;
X509 *cert;
+ const char *s;
ngx_http_ssl_srv_conf_t *sscf;
if (c->ssl == NULL) {
@@ -2171,6 +2172,17 @@ ngx_http_process_request(ngx_http_request_t *r)
X509_free(cert);
}
+
+ if (ngx_ssl_ocsp_get_status(c, &s) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client SSL certificate verify error: %s", s);
+
+ ngx_ssl_remove_cached_session(c->ssl->session_ctx,
+ (SSL_get0_session(c->ssl->connection)));
+
+ ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
+ return;
+ }
}
}
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 89e1319f9..be96be47a 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2502,6 +2502,8 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
#endif
+
+ break;
}
#if (NGX_HTTP_CACHE)
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index e067cf0c2..c2113c843 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1075,7 +1075,7 @@ ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
len = name->len - (sizeof("arg_") - 1);
arg = name->data + sizeof("arg_") - 1;
- if (ngx_http_arg(r, arg, len, &value) != NGX_OK) {
+ if (len == 0 || ngx_http_arg(r, arg, len, &value) != NGX_OK) {
v->not_found = 1;
return NGX_OK;
}
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 8b0fc53b0..08d66c97b 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -731,9 +731,8 @@ ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
}
if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
- "invalid http2 connection preface \"%*s\"",
- sizeof(preface) - 1, pos);
+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+ "invalid connection preface");
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
}
@@ -754,9 +753,8 @@ ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
}
if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
- "invalid http2 connection preface \"%*s\"",
- sizeof(preface) - 1, pos);
+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+ "invalid connection preface");
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
}