mirror of
https://github.com/nginx/nginx.git
synced 2024-11-21 16:28:40 +00:00
Merged with the default branch.
This commit is contained in:
commit
3123fac3e7
1
.hgtags
1
.hgtags
@ -469,3 +469,4 @@ d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5
|
||||
714eb4b2c09e712fb2572a2164ce2bf67638ccac release-1.21.6
|
||||
5da2c0902e8e2aa4534008a582a60c61c135960e release-1.23.0
|
||||
a63d0a70afea96813ba6667997bc7d68b5863f0d release-1.23.1
|
||||
aa901551a7ebad1e8b0f8c11cb44e3424ba29707 release-1.23.2
|
||||
|
@ -6,7 +6,7 @@
|
||||
all:
|
||||
cd $(OPENSSL)
|
||||
|
||||
perl Configure VC-WIN32 no-shared \
|
||||
perl Configure VC-WIN32 no-shared no-threads \
|
||||
--prefix="%cd%/openssl" \
|
||||
--openssldir="%cd%/openssl/ssl" \
|
||||
$(OPENSSL_OPT)
|
||||
|
@ -5,6 +5,120 @@
|
||||
<change_log title="nginx">
|
||||
|
||||
|
||||
<changes ver="1.23.2" date="2022-10-19">
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
обработка специально созданного mp4-файла модулем ngx_http_mp4_module
|
||||
могла приводить к падению рабочего процесса,
|
||||
отправке клиенту части содержимого памяти рабочего процесса,
|
||||
а также потенциально могла иметь другие последствия
|
||||
(CVE-2022-41741, CVE-2022-41742).
|
||||
</para>
|
||||
<para lang="en">
|
||||
processing of a specially crafted mp4 file by the ngx_http_mp4_module
|
||||
might cause a worker process crash,
|
||||
worker process memory disclosure,
|
||||
or might have potential other impact
|
||||
(CVE-2022-41741, CVE-2022-41742).
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
переменные "$proxy_protocol_tlv_...".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "$proxy_protocol_tlv_..." variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ключи шифрования TLS session tickets теперь автоматически меняются
|
||||
при использовании разделяемой памяти в ssl_session_cache.
|
||||
</para>
|
||||
<para lang="en">
|
||||
TLS session tickets encryption keys are now automatically rotated
|
||||
when using shared memory in the "ssl_session_cache" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
уровень логгирования ошибок SSL "bad record type"
|
||||
понижен с уровня crit до info.<br/>
|
||||
Спасибо Murilo Andrade.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the logging level of the "bad record type" SSL errors
|
||||
has been lowered from "crit" to "info".<br/>
|
||||
Thanks to Murilo Andrade.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
теперь при использовании разделяемой памяти в ssl_session_cache
|
||||
сообщения "could not allocate new session"
|
||||
логгируются на уровне warn вместо alert
|
||||
и не чаще одного раза в секунду.
|
||||
</para>
|
||||
<para lang="en">
|
||||
now when using shared memory in the "ssl_session_cache" directive
|
||||
the "could not allocate new session" errors
|
||||
are logged at the "warn" level instead of "alert"
|
||||
and not more often than once per second.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx/Windows не собирался с OpenSSL 3.0.x.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx/Windows could not be built with OpenSSL 3.0.x.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в логгировании ошибок протокола PROXY.<br/>
|
||||
Спасибо Сергею Брестеру.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in logging of the PROXY protocol errors.<br/>
|
||||
Thanks to Sergey Brester.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="workaround">
|
||||
<para lang="ru">
|
||||
при использовании TLSv1.3 с OpenSSL
|
||||
разделяемая память из ssl_session_cache расходовалась
|
||||
в том числе на сессии, использующие TLS session tickets.
|
||||
</para>
|
||||
<para lang="en">
|
||||
shared memory from the "ssl_session_cache" directive
|
||||
was spent on sessions using TLS session tickets
|
||||
when using TLSv1.3 with OpenSSL.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="workaround">
|
||||
<para lang="ru">
|
||||
таймаут, заданный с помощью директивы ssl_session_timeout,
|
||||
не работал при использовании TLSv1.3 с OpenSSL или BoringSSL.
|
||||
</para>
|
||||
<para lang="en">
|
||||
timeout specified with the "ssl_session_timeout" directive
|
||||
did not work when using TLSv1.3 with OpenSSL or BoringSSL.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.23.1" date="2022-07-19">
|
||||
|
||||
<change type="feature">
|
||||
|
@ -9,8 +9,8 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1023001
|
||||
#define NGINX_VERSION "1.23.1"
|
||||
#define nginx_version 1023002
|
||||
#define NGINX_VERSION "1.23.2"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
@ -13,7 +13,15 @@
|
||||
#define NGX_PROXY_PROTOCOL_AF_INET6 2
|
||||
|
||||
|
||||
#define ngx_proxy_protocol_parse_uint16(p) ((p)[0] << 8 | (p)[1])
|
||||
#define ngx_proxy_protocol_parse_uint16(p) \
|
||||
( ((uint16_t) (p)[0] << 8) \
|
||||
+ ( (p)[1]) )
|
||||
|
||||
#define ngx_proxy_protocol_parse_uint32(p) \
|
||||
( ((uint32_t) (p)[0] << 24) \
|
||||
+ ( (p)[1] << 16) \
|
||||
+ ( (p)[2] << 8) \
|
||||
+ ( (p)[3]) )
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -40,12 +48,52 @@ typedef struct {
|
||||
} ngx_proxy_protocol_inet6_addrs_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char type;
|
||||
u_char len[2];
|
||||
} ngx_proxy_protocol_tlv_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char client;
|
||||
u_char verify[4];
|
||||
} ngx_proxy_protocol_tlv_ssl_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t type;
|
||||
} ngx_proxy_protocol_tlv_entry_t;
|
||||
|
||||
|
||||
static u_char *ngx_proxy_protocol_read_addr(ngx_connection_t *c, u_char *p,
|
||||
u_char *last, ngx_str_t *addr);
|
||||
static u_char *ngx_proxy_protocol_read_port(u_char *p, u_char *last,
|
||||
in_port_t *port, u_char sep);
|
||||
static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf,
|
||||
u_char *last);
|
||||
static ngx_int_t ngx_proxy_protocol_lookup_tlv(ngx_connection_t *c,
|
||||
ngx_str_t *tlvs, ngx_uint_t type, ngx_str_t *value);
|
||||
|
||||
|
||||
static ngx_proxy_protocol_tlv_entry_t ngx_proxy_protocol_tlv_entries[] = {
|
||||
{ ngx_string("alpn"), 0x01 },
|
||||
{ ngx_string("authority"), 0x02 },
|
||||
{ ngx_string("unique_id"), 0x05 },
|
||||
{ ngx_string("ssl"), 0x20 },
|
||||
{ ngx_string("netns"), 0x30 },
|
||||
{ ngx_null_string, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_proxy_protocol_tlv_entry_t ngx_proxy_protocol_tlv_ssl_entries[] = {
|
||||
{ ngx_string("version"), 0x21 },
|
||||
{ ngx_string("cn"), 0x22 },
|
||||
{ ngx_string("cipher"), 0x23 },
|
||||
{ ngx_string("sig_alg"), 0x24 },
|
||||
{ ngx_string("key_alg"), 0x25 },
|
||||
{ ngx_null_string, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
u_char *
|
||||
@ -139,8 +187,14 @@ skip:
|
||||
|
||||
invalid:
|
||||
|
||||
for (p = buf; p < last; p++) {
|
||||
if (*p == CR || *p == LF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"broken header: \"%*s\"", (size_t) (last - buf), buf);
|
||||
"broken header: \"%*s\"", (size_t) (p - buf), buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -412,11 +466,147 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last)
|
||||
&pp->src_addr, pp->src_port, &pp->dst_addr, pp->dst_port);
|
||||
|
||||
if (buf < end) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
|
||||
"PROXY protocol v2 %z bytes of tlv ignored", end - buf);
|
||||
pp->tlvs.data = ngx_pnalloc(c->pool, end - buf);
|
||||
if (pp->tlvs.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_memcpy(pp->tlvs.data, buf, end - buf);
|
||||
pp->tlvs.len = end - buf;
|
||||
}
|
||||
|
||||
c->proxy_protocol = pp;
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_proxy_protocol_get_tlv(ngx_connection_t *c, ngx_str_t *name,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
u_char *p;
|
||||
size_t n;
|
||||
uint32_t verify;
|
||||
ngx_str_t ssl, *tlvs;
|
||||
ngx_int_t rc, type;
|
||||
ngx_proxy_protocol_tlv_ssl_t *tlv_ssl;
|
||||
ngx_proxy_protocol_tlv_entry_t *te;
|
||||
|
||||
if (c->proxy_protocol == NULL) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
|
||||
"PROXY protocol v2 get tlv \"%V\"", name);
|
||||
|
||||
te = ngx_proxy_protocol_tlv_entries;
|
||||
tlvs = &c->proxy_protocol->tlvs;
|
||||
|
||||
p = name->data;
|
||||
n = name->len;
|
||||
|
||||
if (n >= 4 && p[0] == 's' && p[1] == 's' && p[2] == 'l' && p[3] == '_') {
|
||||
|
||||
rc = ngx_proxy_protocol_lookup_tlv(c, tlvs, 0x20, &ssl);
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ssl.len < sizeof(ngx_proxy_protocol_tlv_ssl_t)) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p += 4;
|
||||
n -= 4;
|
||||
|
||||
if (n == 6 && ngx_strncmp(p, "verify", 6) == 0) {
|
||||
|
||||
tlv_ssl = (ngx_proxy_protocol_tlv_ssl_t *) ssl.data;
|
||||
verify = ngx_proxy_protocol_parse_uint32(tlv_ssl->verify);
|
||||
|
||||
value->data = ngx_pnalloc(c->pool, NGX_INT32_LEN);
|
||||
if (value->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
value->len = ngx_sprintf(value->data, "%uD", verify)
|
||||
- value->data;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ssl.data += sizeof(ngx_proxy_protocol_tlv_ssl_t);
|
||||
ssl.len -= sizeof(ngx_proxy_protocol_tlv_ssl_t);
|
||||
|
||||
te = ngx_proxy_protocol_tlv_ssl_entries;
|
||||
tlvs = &ssl;
|
||||
}
|
||||
|
||||
if (n >= 2 && p[0] == '0' && p[1] == 'x') {
|
||||
|
||||
type = ngx_hextoi(p + 2, n - 2);
|
||||
if (type == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"invalid PROXY protocol TLV \"%V\"", name);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ngx_proxy_protocol_lookup_tlv(c, tlvs, type, value);
|
||||
}
|
||||
|
||||
for ( /* void */ ; te->type; te++) {
|
||||
if (te->name.len == n && ngx_strncmp(te->name.data, p, n) == 0) {
|
||||
return ngx_proxy_protocol_lookup_tlv(c, tlvs, te->type, value);
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"unknown PROXY protocol TLV \"%V\"", name);
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_proxy_protocol_lookup_tlv(ngx_connection_t *c, ngx_str_t *tlvs,
|
||||
ngx_uint_t type, ngx_str_t *value)
|
||||
{
|
||||
u_char *p;
|
||||
size_t n, len;
|
||||
ngx_proxy_protocol_tlv_t *tlv;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
|
||||
"PROXY protocol v2 lookup tlv:%02xi", type);
|
||||
|
||||
p = tlvs->data;
|
||||
n = tlvs->len;
|
||||
|
||||
while (n) {
|
||||
if (n < sizeof(ngx_proxy_protocol_tlv_t)) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0, "broken PROXY protocol TLV");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
tlv = (ngx_proxy_protocol_tlv_t *) p;
|
||||
len = ngx_proxy_protocol_parse_uint16(tlv->len);
|
||||
|
||||
p += sizeof(ngx_proxy_protocol_tlv_t);
|
||||
n -= sizeof(ngx_proxy_protocol_tlv_t);
|
||||
|
||||
if (n < len) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0, "broken PROXY protocol TLV");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (tlv->type == type) {
|
||||
value->data = p;
|
||||
value->len = len;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
p += len;
|
||||
n -= len;
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ struct ngx_proxy_protocol_s {
|
||||
ngx_str_t dst_addr;
|
||||
in_port_t src_port;
|
||||
in_port_t dst_port;
|
||||
ngx_str_t tlvs;
|
||||
};
|
||||
|
||||
|
||||
@ -28,6 +29,8 @@ u_char *ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf,
|
||||
u_char *last);
|
||||
u_char *ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf,
|
||||
u_char *last);
|
||||
ngx_int_t ngx_proxy_protocol_get_tlv(ngx_connection_t *c, ngx_str_t *name,
|
||||
ngx_str_t *value);
|
||||
|
||||
|
||||
#endif /* _NGX_PROXY_PROTOCOL_H_INCLUDED_ */
|
||||
|
@ -231,9 +231,8 @@ ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags)
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags)
|
||||
static ngx_int_t
|
||||
ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
||||
{
|
||||
int rc;
|
||||
u_int key;
|
||||
@ -356,7 +355,7 @@ ngx_iocp_create_conf(ngx_cycle_t *cycle)
|
||||
|
||||
cf = ngx_palloc(cycle->pool, sizeof(ngx_iocp_conf_t));
|
||||
if (cf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cf->threads = NGX_CONF_UNSET;
|
||||
|
@ -71,10 +71,11 @@ static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
|
||||
static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
static int ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
|
||||
HMAC_CTX *hctx, int enc);
|
||||
static void ngx_ssl_session_ticket_keys_cleanup(void *data);
|
||||
static ngx_int_t ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log);
|
||||
static void ngx_ssl_ticket_keys_cleanup(void *data);
|
||||
#endif
|
||||
|
||||
#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT
|
||||
@ -131,7 +132,7 @@ ngx_module_t ngx_openssl_module = {
|
||||
int ngx_ssl_connection_index;
|
||||
int ngx_ssl_server_conf_index;
|
||||
int ngx_ssl_session_cache_index;
|
||||
int ngx_ssl_session_ticket_keys_index;
|
||||
int ngx_ssl_ticket_keys_index;
|
||||
int ngx_ssl_ocsp_index;
|
||||
int ngx_ssl_certificate_index;
|
||||
int ngx_ssl_next_certificate_index;
|
||||
@ -208,9 +209,9 @@ ngx_ssl_init(ngx_log_t *log)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
|
||||
NULL, NULL);
|
||||
if (ngx_ssl_session_ticket_keys_index == -1) {
|
||||
ngx_ssl_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (ngx_ssl_ticket_keys_index == -1) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0,
|
||||
"SSL_CTX_get_ex_new_index() failed");
|
||||
return NGX_ERROR;
|
||||
@ -1083,6 +1084,53 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TLS1_3_VERSION
|
||||
|
||||
if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP
|
||||
&& SSL_version(ssl_conn) == TLS1_3_VERSION)
|
||||
{
|
||||
time_t now, time, timeout, conf_timeout;
|
||||
SSL_SESSION *sess;
|
||||
|
||||
/*
|
||||
* OpenSSL with TLSv1.3 updates the session creation time on
|
||||
* session resumption and keeps the session timeout unmodified,
|
||||
* making it possible to maintain the session forever, bypassing
|
||||
* client certificate expiration and revocation. To make sure
|
||||
* session timeouts are actually used, we now update the session
|
||||
* creation time and reduce the session timeout accordingly.
|
||||
*
|
||||
* BoringSSL with TLSv1.3 ignores configured session timeouts
|
||||
* and uses a hardcoded timeout instead, 7 days. So we update
|
||||
* session timeout to the configured value as soon as a session
|
||||
* is created.
|
||||
*/
|
||||
|
||||
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
|
||||
sess = SSL_get0_session(ssl_conn);
|
||||
|
||||
if (!c->ssl->session_timeout_set && sess) {
|
||||
c->ssl->session_timeout_set = 1;
|
||||
|
||||
now = ngx_time();
|
||||
time = SSL_SESSION_get_time(sess);
|
||||
timeout = SSL_SESSION_get_timeout(sess);
|
||||
conf_timeout = SSL_CTX_get_timeout(c->ssl->session_ctx);
|
||||
|
||||
timeout = ngx_min(timeout, conf_timeout);
|
||||
|
||||
if (now - time >= timeout) {
|
||||
SSL_SESSION_set1_id_context(sess, (unsigned char *) "", 0);
|
||||
|
||||
} else {
|
||||
SSL_SESSION_set_time(sess, now);
|
||||
SSL_SESSION_set_timeout(sess, timeout - (now - time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
|
||||
@ -1426,9 +1474,9 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
|
||||
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
|
||||
|
||||
#if SSL_CTRL_SET_ECDH_AUTO
|
||||
#ifdef SSL_CTRL_SET_ECDH_AUTO
|
||||
/* not needed in OpenSSL 1.1.0+ */
|
||||
SSL_CTX_set_ecdh_auto(ssl->ctx, 1);
|
||||
(void) SSL_CTX_set_ecdh_auto(ssl->ctx, 1);
|
||||
#endif
|
||||
|
||||
if (ngx_strcmp(name->data, "auto") == 0) {
|
||||
@ -1769,7 +1817,7 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BIO_get_ktls_send
|
||||
#if (defined BIO_get_ktls_send && !NGX_WIN32)
|
||||
|
||||
if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
@ -1914,7 +1962,7 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
|
||||
c->read->ready = 1;
|
||||
c->write->ready = 1;
|
||||
|
||||
#ifdef BIO_get_ktls_send
|
||||
#if (defined BIO_get_ktls_send && !NGX_WIN32)
|
||||
|
||||
if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
@ -2943,7 +2991,7 @@ ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)
|
||||
static ssize_t
|
||||
ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||
{
|
||||
#ifdef BIO_get_ktls_send
|
||||
#if (defined BIO_get_ktls_send && !NGX_WIN32)
|
||||
|
||||
int sslerr, flags;
|
||||
ssize_t n;
|
||||
@ -3429,6 +3477,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
||||
#endif
|
||||
#ifdef SSL_R_VERSION_TOO_LOW
|
||||
|| n == SSL_R_VERSION_TOO_LOW /* 396 */
|
||||
#endif
|
||||
#ifdef SSL_R_BAD_RECORD_TYPE
|
||||
|| n == SSL_R_BAD_RECORD_TYPE /* 443 */
|
||||
#endif
|
||||
|| n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
|
||||
#ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE
|
||||
@ -3774,6 +3825,12 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
|
||||
|
||||
ngx_queue_init(&cache->expire_queue);
|
||||
|
||||
cache->ticket_keys[0].expire = 0;
|
||||
cache->ticket_keys[1].expire = 0;
|
||||
cache->ticket_keys[2].expire = 0;
|
||||
|
||||
cache->fail_time = 0;
|
||||
|
||||
len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len;
|
||||
|
||||
shpool->log_ctx = ngx_slab_alloc(shpool, len);
|
||||
@ -3792,16 +3849,16 @@ ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
|
||||
|
||||
/*
|
||||
* The length of the session id is 16 bytes for SSLv2 sessions and
|
||||
* between 1 and 32 bytes for SSLv3/TLSv1, typically 32 bytes.
|
||||
* It seems that the typical length of the external ASN1 representation
|
||||
* of a session is 118 or 119 bytes for SSLv3/TSLv1.
|
||||
* between 1 and 32 bytes for SSLv3 and TLS, typically 32 bytes.
|
||||
* Typical length of the external ASN1 representation of a session
|
||||
* is about 150 bytes plus SNI server name.
|
||||
*
|
||||
* Thus on 32-bit platforms we allocate separately an rbtree node,
|
||||
* a session id, and an ASN1 representation, they take accordingly
|
||||
* 64, 32, and 128 bytes.
|
||||
* On 32-bit platforms we allocate an rbtree node, a session id, and
|
||||
* an ASN1 representation in a single allocation, it typically takes
|
||||
* 256 bytes.
|
||||
*
|
||||
* On 64-bit platforms we allocate separately an rbtree node + session_id,
|
||||
* and an ASN1 representation, they take accordingly 128 and 128 bytes.
|
||||
* and an ASN1 representation, they take accordingly 128 and 256 bytes.
|
||||
*
|
||||
* OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
|
||||
* so they are outside the code locked by shared pool mutex
|
||||
@ -3811,7 +3868,8 @@ static int
|
||||
ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
{
|
||||
int len;
|
||||
u_char *p, *id, *cached_sess, *session_id;
|
||||
u_char *p, *session_id;
|
||||
size_t n;
|
||||
uint32_t hash;
|
||||
SSL_CTX *ssl_ctx;
|
||||
unsigned int session_id_length;
|
||||
@ -3822,17 +3880,42 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
ngx_ssl_session_cache_t *cache;
|
||||
u_char buf[NGX_SSL_MAX_SESSION_SIZE];
|
||||
|
||||
#ifdef TLS1_3_VERSION
|
||||
|
||||
/*
|
||||
* OpenSSL tries to save TLSv1.3 sessions into session cache
|
||||
* even when using tickets for stateless session resumption,
|
||||
* "because some applications just want to know about the creation
|
||||
* of a session"; do not cache such sessions
|
||||
*/
|
||||
|
||||
if (SSL_version(ssl_conn) == TLS1_3_VERSION
|
||||
&& (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
len = i2d_SSL_SESSION(sess, NULL);
|
||||
|
||||
/* do not cache too big session */
|
||||
|
||||
if (len > (int) NGX_SSL_MAX_SESSION_SIZE) {
|
||||
if (len > NGX_SSL_MAX_SESSION_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
i2d_SSL_SESSION(sess, &p);
|
||||
|
||||
session_id = (u_char *) SSL_SESSION_get_id(sess, &session_id_length);
|
||||
|
||||
/* do not cache sessions with too long session id */
|
||||
|
||||
if (session_id_length > 32) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
|
||||
ssl_ctx = c->ssl->session_ctx;
|
||||
@ -3846,23 +3929,13 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
/* drop one or two expired sessions */
|
||||
ngx_ssl_expire_sessions(cache, shpool, 1);
|
||||
|
||||
cached_sess = ngx_slab_alloc_locked(shpool, len);
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
n = sizeof(ngx_ssl_sess_id_t);
|
||||
#else
|
||||
n = offsetof(ngx_ssl_sess_id_t, session) + len;
|
||||
#endif
|
||||
|
||||
if (cached_sess == NULL) {
|
||||
|
||||
/* drop the oldest non-expired session and try once more */
|
||||
|
||||
ngx_ssl_expire_sessions(cache, shpool, 0);
|
||||
|
||||
cached_sess = ngx_slab_alloc_locked(shpool, len);
|
||||
|
||||
if (cached_sess == NULL) {
|
||||
sess_id = NULL;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
|
||||
sess_id = ngx_slab_alloc_locked(shpool, n);
|
||||
|
||||
if (sess_id == NULL) {
|
||||
|
||||
@ -3870,41 +3943,34 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
|
||||
ngx_ssl_expire_sessions(cache, shpool, 0);
|
||||
|
||||
sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
|
||||
sess_id = ngx_slab_alloc_locked(shpool, n);
|
||||
|
||||
if (sess_id == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
session_id = (u_char *) SSL_SESSION_get_id(sess, &session_id_length);
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
|
||||
id = sess_id->sess_id;
|
||||
sess_id->session = ngx_slab_alloc_locked(shpool, len);
|
||||
|
||||
#else
|
||||
|
||||
id = ngx_slab_alloc_locked(shpool, session_id_length);
|
||||
|
||||
if (id == NULL) {
|
||||
if (sess_id->session == NULL) {
|
||||
|
||||
/* drop the oldest non-expired session and try once more */
|
||||
|
||||
ngx_ssl_expire_sessions(cache, shpool, 0);
|
||||
|
||||
id = ngx_slab_alloc_locked(shpool, session_id_length);
|
||||
sess_id->session = ngx_slab_alloc_locked(shpool, len);
|
||||
|
||||
if (id == NULL) {
|
||||
if (sess_id->session == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ngx_memcpy(cached_sess, buf, len);
|
||||
|
||||
ngx_memcpy(id, session_id, session_id_length);
|
||||
ngx_memcpy(sess_id->session, buf, len);
|
||||
ngx_memcpy(sess_id->id, session_id, session_id_length);
|
||||
|
||||
hash = ngx_crc32_short(session_id, session_id_length);
|
||||
|
||||
@ -3914,9 +3980,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
|
||||
sess_id->node.key = hash;
|
||||
sess_id->node.data = (u_char) session_id_length;
|
||||
sess_id->id = id;
|
||||
sess_id->len = len;
|
||||
sess_id->session = cached_sess;
|
||||
|
||||
sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx);
|
||||
|
||||
@ -3930,18 +3994,17 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
|
||||
|
||||
failed:
|
||||
|
||||
if (cached_sess) {
|
||||
ngx_slab_free_locked(shpool, cached_sess);
|
||||
}
|
||||
|
||||
if (sess_id) {
|
||||
ngx_slab_free_locked(shpool, sess_id);
|
||||
}
|
||||
|
||||
ngx_shmtx_unlock(&shpool->mutex);
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
||||
if (cache->fail_time != ngx_time()) {
|
||||
cache->fail_time = ngx_time();
|
||||
ngx_log_error(NGX_LOG_WARN, c->log, 0,
|
||||
"could not allocate new session%s", shpool->log_ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4027,9 +4090,10 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
|
||||
|
||||
ngx_rbtree_delete(&cache->session_rbtree, node);
|
||||
|
||||
ngx_explicit_memzero(sess_id->session, sess_id->len);
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
ngx_slab_free_locked(shpool, sess_id->session);
|
||||
#if (NGX_PTR_SIZE == 4)
|
||||
ngx_slab_free_locked(shpool, sess_id->id);
|
||||
#endif
|
||||
ngx_slab_free_locked(shpool, sess_id);
|
||||
|
||||
@ -4117,9 +4181,10 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
|
||||
|
||||
ngx_rbtree_delete(&cache->session_rbtree, node);
|
||||
|
||||
ngx_explicit_memzero(sess_id->session, sess_id->len);
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
ngx_slab_free_locked(shpool, sess_id->session);
|
||||
#if (NGX_PTR_SIZE == 4)
|
||||
ngx_slab_free_locked(shpool, sess_id->id);
|
||||
#endif
|
||||
ngx_slab_free_locked(shpool, sess_id);
|
||||
|
||||
@ -4166,9 +4231,10 @@ ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
|
||||
|
||||
ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);
|
||||
|
||||
ngx_explicit_memzero(sess_id->session, sess_id->len);
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
ngx_slab_free_locked(shpool, sess_id->session);
|
||||
#if (NGX_PTR_SIZE == 4)
|
||||
ngx_slab_free_locked(shpool, sess_id->id);
|
||||
#endif
|
||||
ngx_slab_free_locked(shpool, sess_id);
|
||||
}
|
||||
@ -4231,14 +4297,16 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
|
||||
ngx_array_t *keys;
|
||||
ngx_file_info_t fi;
|
||||
ngx_pool_cleanup_t *cln;
|
||||
ngx_ssl_session_ticket_key_t *key;
|
||||
ngx_ssl_ticket_key_t *key;
|
||||
|
||||
if (paths == NULL) {
|
||||
if (paths == NULL
|
||||
&& SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_session_cache_index) == NULL)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
keys = ngx_array_create(cf->pool, paths->nelts,
|
||||
sizeof(ngx_ssl_session_ticket_key_t));
|
||||
keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
|
||||
sizeof(ngx_ssl_ticket_key_t));
|
||||
if (keys == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -4248,9 +4316,41 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cln->handler = ngx_ssl_session_ticket_keys_cleanup;
|
||||
cln->handler = ngx_ssl_ticket_keys_cleanup;
|
||||
cln->data = keys;
|
||||
|
||||
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ticket_keys_index, keys) == 0) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CTX_set_ex_data() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, ngx_ssl_ticket_key_callback)
|
||||
== 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"nginx was built with Session Tickets support, however, "
|
||||
"now it is linked dynamically to an OpenSSL library "
|
||||
"which has no tlsext support, therefore Session Tickets "
|
||||
"are not available");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (paths == NULL) {
|
||||
|
||||
/* placeholder for keys in shared memory */
|
||||
|
||||
key = ngx_array_push_n(keys, 3);
|
||||
key[0].shared = 1;
|
||||
key[0].expire = 0;
|
||||
key[1].shared = 1;
|
||||
key[1].expire = 0;
|
||||
key[2].shared = 1;
|
||||
key[2].expire = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
path = paths->elts;
|
||||
for (i = 0; i < paths->nelts; i++) {
|
||||
|
||||
@ -4305,6 +4405,9 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
key->shared = 0;
|
||||
key->expire = 1;
|
||||
|
||||
if (size == 48) {
|
||||
key->size = 48;
|
||||
ngx_memcpy(key->name, buf, 16);
|
||||
@ -4326,25 +4429,6 @@ ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
|
||||
ngx_explicit_memzero(&buf, 80);
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_ticket_keys_index, keys)
|
||||
== 0)
|
||||
{
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||
"SSL_CTX_set_ex_data() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx,
|
||||
ngx_ssl_session_ticket_key_callback)
|
||||
== 0)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||
"nginx was built with Session Tickets support, however, "
|
||||
"now it is linked dynamically to an OpenSSL library "
|
||||
"which has no tlsext support, therefore Session Tickets "
|
||||
"are not available");
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
failed:
|
||||
@ -4361,7 +4445,7 @@ failed:
|
||||
|
||||
|
||||
static int
|
||||
ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
|
||||
HMAC_CTX *hctx, int enc)
|
||||
{
|
||||
@ -4370,20 +4454,24 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
ngx_uint_t i;
|
||||
ngx_array_t *keys;
|
||||
ngx_connection_t *c;
|
||||
ngx_ssl_session_ticket_key_t *key;
|
||||
ngx_ssl_ticket_key_t *key;
|
||||
const EVP_MD *digest;
|
||||
const EVP_CIPHER *cipher;
|
||||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
ssl_ctx = c->ssl->session_ctx;
|
||||
|
||||
if (ngx_ssl_rotate_ticket_keys(ssl_ctx, c->log) != NGX_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_NO_SHA256
|
||||
digest = EVP_sha1();
|
||||
#else
|
||||
digest = EVP_sha256();
|
||||
#endif
|
||||
|
||||
keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index);
|
||||
keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
|
||||
if (keys == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -4394,7 +4482,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
/* encrypt session ticket */
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket encrypt, key: \"%*xs\" (%s session)",
|
||||
"ssl ticket encrypt, key: \"%*xs\" (%s session)",
|
||||
(size_t) 16, key[0].name,
|
||||
SSL_session_reused(ssl_conn) ? "reused" : "new");
|
||||
|
||||
@ -4441,7 +4529,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket decrypt, key: \"%*xs\" not found",
|
||||
"ssl ticket decrypt, key: \"%*xs\" not found",
|
||||
(size_t) 16, name);
|
||||
|
||||
return 0;
|
||||
@ -4449,7 +4537,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
found:
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl session ticket decrypt, key: \"%*xs\"%s",
|
||||
"ssl ticket decrypt, key: \"%*xs\"%s",
|
||||
(size_t) 16, key[i].name, (i == 0) ? " (default)" : "");
|
||||
|
||||
if (key[i].size == 48) {
|
||||
@ -4486,7 +4574,7 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
|
||||
/* renew if non-default key */
|
||||
|
||||
if (i != 0) {
|
||||
if (i != 0 && key[i].expire) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -4495,13 +4583,142 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
|
||||
{
|
||||
time_t now, expire;
|
||||
ngx_array_t *keys;
|
||||
ngx_shm_zone_t *shm_zone;
|
||||
ngx_slab_pool_t *shpool;
|
||||
ngx_ssl_ticket_key_t *key;
|
||||
ngx_ssl_session_cache_t *cache;
|
||||
u_char buf[80];
|
||||
|
||||
keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
|
||||
if (keys == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
key = keys->elts;
|
||||
|
||||
if (!key[0].shared) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we don't need to update expiration of the current key
|
||||
* and the previous key is still needed, don't sync with shared
|
||||
* memory to save some work; in the worst case other worker process
|
||||
* will switch to the next key, but this process will still be able
|
||||
* to decrypt tickets encrypted with it
|
||||
*/
|
||||
|
||||
now = ngx_time();
|
||||
expire = now + SSL_CTX_get_timeout(ssl_ctx);
|
||||
|
||||
if (key[0].expire >= expire && key[1].expire >= now) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);
|
||||
|
||||
cache = shm_zone->data;
|
||||
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
|
||||
|
||||
ngx_shmtx_lock(&shpool->mutex);
|
||||
|
||||
key = cache->ticket_keys;
|
||||
|
||||
if (key[0].expire == 0) {
|
||||
|
||||
/* initialize the current key */
|
||||
|
||||
if (RAND_bytes(buf, 80) != 1) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
|
||||
ngx_shmtx_unlock(&shpool->mutex);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
key[0].shared = 1;
|
||||
key[0].expire = expire;
|
||||
key[0].size = 80;
|
||||
ngx_memcpy(key[0].name, buf, 16);
|
||||
ngx_memcpy(key[0].hmac_key, buf + 16, 32);
|
||||
ngx_memcpy(key[0].aes_key, buf + 48, 32);
|
||||
|
||||
ngx_explicit_memzero(&buf, 80);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
|
||||
"ssl ticket key: \"%*xs\"",
|
||||
(size_t) 16, key[0].name);
|
||||
|
||||
/*
|
||||
* copy the current key to the next key, as initialization of
|
||||
* the previous key will replace the current key with the next
|
||||
* key
|
||||
*/
|
||||
|
||||
key[2] = key[0];
|
||||
}
|
||||
|
||||
if (key[1].expire < now) {
|
||||
|
||||
/*
|
||||
* if the previous key is no longer needed (or not initialized),
|
||||
* replace it with the current key, replace the current key with
|
||||
* the next key, and generate new next key
|
||||
*/
|
||||
|
||||
key[1] = key[0];
|
||||
key[0] = key[2];
|
||||
|
||||
if (RAND_bytes(buf, 80) != 1) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
|
||||
ngx_shmtx_unlock(&shpool->mutex);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
key[2].shared = 1;
|
||||
key[2].expire = 0;
|
||||
key[2].size = 80;
|
||||
ngx_memcpy(key[2].name, buf, 16);
|
||||
ngx_memcpy(key[2].hmac_key, buf + 16, 32);
|
||||
ngx_memcpy(key[2].aes_key, buf + 48, 32);
|
||||
|
||||
ngx_explicit_memzero(&buf, 80);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
|
||||
"ssl ticket key: \"%*xs\"",
|
||||
(size_t) 16, key[2].name);
|
||||
}
|
||||
|
||||
/*
|
||||
* update expiration of the current key: it is going to be needed
|
||||
* at least till the session being created expires
|
||||
*/
|
||||
|
||||
if (expire > key[0].expire) {
|
||||
key[0].expire = expire;
|
||||
}
|
||||
|
||||
/* sync keys to the worker process memory */
|
||||
|
||||
ngx_memcpy(keys->elts, cache->ticket_keys,
|
||||
2 * sizeof(ngx_ssl_ticket_key_t));
|
||||
|
||||
ngx_shmtx_unlock(&shpool->mutex);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_ssl_session_ticket_keys_cleanup(void *data)
|
||||
ngx_ssl_ticket_keys_cleanup(void *data)
|
||||
{
|
||||
ngx_array_t *keys = data;
|
||||
|
||||
ngx_explicit_memzero(keys->elts,
|
||||
keys->nelts * sizeof(ngx_ssl_session_ticket_key_t));
|
||||
keys->nelts * sizeof(ngx_ssl_ticket_key_t));
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -122,6 +122,7 @@ struct ngx_ssl_connection_s {
|
||||
unsigned no_send_shutdown:1;
|
||||
unsigned shutdown_without_free:1;
|
||||
unsigned handshake_buffer_set:1;
|
||||
unsigned session_timeout_set:1;
|
||||
unsigned try_early_data:1;
|
||||
unsigned in_early:1;
|
||||
unsigned in_ocsp:1;
|
||||
@ -142,37 +143,37 @@ typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
|
||||
|
||||
struct ngx_ssl_sess_id_s {
|
||||
ngx_rbtree_node_t node;
|
||||
u_char *id;
|
||||
size_t len;
|
||||
u_char *session;
|
||||
ngx_queue_t queue;
|
||||
time_t expire;
|
||||
u_char id[32];
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
void *stub;
|
||||
u_char sess_id[32];
|
||||
u_char *session;
|
||||
#else
|
||||
u_char session[1];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char name[16];
|
||||
u_char hmac_key[32];
|
||||
u_char aes_key[32];
|
||||
time_t expire;
|
||||
unsigned size:8;
|
||||
unsigned shared:1;
|
||||
} ngx_ssl_ticket_key_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_rbtree_t session_rbtree;
|
||||
ngx_rbtree_node_t sentinel;
|
||||
ngx_queue_t expire_queue;
|
||||
ngx_ssl_ticket_key_t ticket_keys[3];
|
||||
time_t fail_time;
|
||||
} ngx_ssl_session_cache_t;
|
||||
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
u_char name[16];
|
||||
u_char hmac_key[32];
|
||||
u_char aes_key[32];
|
||||
} ngx_ssl_session_ticket_key_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define NGX_SSL_SSLv2 0x0002
|
||||
#define NGX_SSL_SSLv3 0x0004
|
||||
#define NGX_SSL_TLSv1 0x0008
|
||||
@ -212,10 +213,12 @@ ngx_int_t ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
|
||||
ngx_uint_t depth, ngx_shm_zone_t *shm_zone);
|
||||
ngx_int_t ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
|
||||
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
|
||||
|
||||
ngx_int_t ngx_ssl_ocsp_validate(ngx_connection_t *c);
|
||||
ngx_int_t ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s);
|
||||
void ngx_ssl_ocsp_cleanup(ngx_connection_t *c);
|
||||
ngx_int_t ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data);
|
||||
|
||||
ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
|
||||
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
|
||||
ngx_array_t *passwords);
|
||||
@ -322,7 +325,7 @@ void ngx_ssl_cleanup_ctx(void *data);
|
||||
extern int ngx_ssl_connection_index;
|
||||
extern int ngx_ssl_server_conf_index;
|
||||
extern int ngx_ssl_session_cache_index;
|
||||
extern int ngx_ssl_session_ticket_keys_index;
|
||||
extern int ngx_ssl_ticket_keys_index;
|
||||
extern int ngx_ssl_ocsp_index;
|
||||
extern int ngx_ssl_certificate_index;
|
||||
extern int ngx_ssl_next_certificate_index;
|
||||
|
@ -1121,6 +1121,12 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (mp4->ftyp_atom.buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 ftyp atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
|
||||
|
||||
ftyp_atom = ngx_palloc(mp4->request->pool, atom_size);
|
||||
@ -1179,6 +1185,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (mp4->moov_atom.buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 moov atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
|
||||
|
||||
if (atom_data_size > mp4->buffer_size) {
|
||||
@ -1246,6 +1258,12 @@ ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom");
|
||||
|
||||
if (mp4->mdat_atom.buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 mdat atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
data = &mp4->mdat_data_buf;
|
||||
data->file = &mp4->file;
|
||||
data->in_file = 1;
|
||||
@ -1372,6 +1390,12 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom");
|
||||
|
||||
if (mp4->mvhd_atom.buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 mvhd atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom_header = ngx_mp4_atom_header(mp4);
|
||||
mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header;
|
||||
mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header;
|
||||
@ -1637,6 +1661,13 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 tkhd atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->tkhd_size = atom_size;
|
||||
trak->movie_duration = duration;
|
||||
|
||||
@ -1676,6 +1707,12 @@ ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 mdia atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->mdia_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -1799,6 +1836,13 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 mdhd atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->mdhd_size = atom_size;
|
||||
trak->timescale = timescale;
|
||||
trak->duration = duration;
|
||||
@ -1862,6 +1906,12 @@ ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 hdlr atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->hdlr_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -1890,6 +1940,12 @@ ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_MINF_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 minf atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->minf_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -1933,6 +1989,15 @@ ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
|
||||
|| trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 vmhd/smhd atom in \"%s\"",
|
||||
mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->vmhd_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -1964,6 +2029,15 @@ ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf
|
||||
|| trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 vmhd/smhd atom in \"%s\"",
|
||||
mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->smhd_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -1995,6 +2069,12 @@ ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_DINF_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 dinf atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->dinf_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -2023,6 +2103,12 @@ ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STBL_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stbl atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->stbl_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -2144,6 +2230,12 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STSD_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stsd atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
atom = &trak->stsd_atom_buf;
|
||||
atom->temporary = 1;
|
||||
atom->pos = atom_header;
|
||||
@ -2212,6 +2304,13 @@ ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STTS_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stts atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->time_to_sample_entries = entries;
|
||||
|
||||
atom = &trak->stts_atom_buf;
|
||||
@ -2480,6 +2579,13 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
"sync sample entries:%uD", entries);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STSS_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stss atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->sync_samples_entries = entries;
|
||||
|
||||
atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t);
|
||||
@ -2678,6 +2784,13 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
"composition offset entries:%uD", entries);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 ctts atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->composition_offset_entries = entries;
|
||||
|
||||
atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t);
|
||||
@ -2881,6 +2994,13 @@ ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STSC_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stsc atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->sample_to_chunk_entries = entries;
|
||||
|
||||
atom = &trak->stsc_atom_buf;
|
||||
@ -3213,6 +3333,13 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
"sample uniform size:%uD, entries:%uD", size, entries);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf) {
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stsz atom in \"%s\"", mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->sample_sizes_entries = entries;
|
||||
|
||||
atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t);
|
||||
@ -3396,6 +3523,16 @@ ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_end = atom_table + entries * sizeof(uint32_t);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
|
||||
|| trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stco/co64 atom in \"%s\"",
|
||||
mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->chunks = entries;
|
||||
|
||||
atom = &trak->stco_atom_buf;
|
||||
@ -3602,6 +3739,16 @@ ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
|
||||
atom_end = atom_table + entries * sizeof(uint64_t);
|
||||
|
||||
trak = ngx_mp4_last_trak(mp4);
|
||||
|
||||
if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf
|
||||
|| trak->out[NGX_HTTP_MP4_CO64_ATOM].buf)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
|
||||
"duplicate mp4 stco/co64 atom in \"%s\"",
|
||||
mp4->file.name.data);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
trak->chunks = entries;
|
||||
|
||||
atom = &trak->co64_atom_buf;
|
||||
|
@ -1116,7 +1116,7 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0 || j == value[i].len) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
@ -1206,7 +1206,7 @@ ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0 || j == value[1].len) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,8 @@ static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_proxy_protocol_tlv(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
|
||||
@ -214,6 +216,10 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
ngx_http_variable_proxy_protocol_port,
|
||||
offsetof(ngx_proxy_protocol_t, dst_port), 0, 0 },
|
||||
|
||||
{ ngx_string("proxy_protocol_tlv_"), NULL,
|
||||
ngx_http_variable_proxy_protocol_tlv,
|
||||
0, NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },
|
||||
@ -1386,6 +1392,39 @@ ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_proxy_protocol_tlv(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_str_t *name = (ngx_str_t *) data;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t tlv, value;
|
||||
|
||||
tlv.len = name->len - (sizeof("proxy_protocol_tlv_") - 1);
|
||||
tlv.data = name->data + sizeof("proxy_protocol_tlv_") - 1;
|
||||
|
||||
rc = ngx_proxy_protocol_get_tlv(r->connection, &tlv, &value);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->len = value.len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_server_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
|
@ -682,7 +682,7 @@ ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0 || j == value[i].len) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,6 @@ typedef long time_t;
|
||||
|
||||
#pragma warning(default:4201)
|
||||
|
||||
/* disable some "-W4" level warnings */
|
||||
|
||||
/* 'type cast': from function pointer to data pointer */
|
||||
#pragma warning(disable:4054)
|
||||
|
||||
@ -106,6 +104,9 @@ typedef long time_t;
|
||||
/* array is too small to include a terminating null character */
|
||||
#pragma warning(disable:4295)
|
||||
|
||||
/* conversion from 'type1' to 'type2' of greater size */
|
||||
#pragma warning(disable:4306)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1073,7 +1073,7 @@ ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0 || j == value[i].len) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ static ngx_int_t ngx_stream_variable_proxy_protocol_addr(
|
||||
ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_variable_proxy_protocol_port(
|
||||
ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_variable_proxy_protocol_tlv(
|
||||
ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_variable_server_addr(ngx_stream_session_t *s,
|
||||
ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_variable_server_port(ngx_stream_session_t *s,
|
||||
@ -79,6 +81,10 @@ static ngx_stream_variable_t ngx_stream_core_variables[] = {
|
||||
ngx_stream_variable_proxy_protocol_port,
|
||||
offsetof(ngx_proxy_protocol_t, dst_port), 0, 0 },
|
||||
|
||||
{ ngx_string("proxy_protocol_tlv_"), NULL,
|
||||
ngx_stream_variable_proxy_protocol_tlv,
|
||||
0, NGX_STREAM_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("server_addr"), NULL,
|
||||
ngx_stream_variable_server_addr, 0, 0, 0 },
|
||||
|
||||
@ -621,6 +627,39 @@ ngx_stream_variable_proxy_protocol_port(ngx_stream_session_t *s,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_variable_proxy_protocol_tlv(ngx_stream_session_t *s,
|
||||
ngx_stream_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_str_t *name = (ngx_str_t *) data;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t tlv, value;
|
||||
|
||||
tlv.len = name->len - (sizeof("proxy_protocol_tlv_") - 1);
|
||||
tlv.data = name->data + sizeof("proxy_protocol_tlv_") - 1;
|
||||
|
||||
rc = ngx_proxy_protocol_get_tlv(s->connection, &tlv, &value);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->len = value.len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_variable_server_addr(ngx_stream_session_t *s,
|
||||
ngx_stream_variable_value_t *v, uintptr_t data)
|
||||
|
Loading…
Reference in New Issue
Block a user