Merged with the default branch.

This commit is contained in:
Sergey Kandaurov 2021-05-28 13:33:08 +03:00
commit a3e072bf8b
34 changed files with 812 additions and 298 deletions

View File

@ -51,6 +51,7 @@ types {
application/vnd.openxmlformats-officedocument.wordprocessingml.document
docx;
application/vnd.wap.wmlc wmlc;
application/wasm wasm;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;

View File

@ -5,6 +5,100 @@
<change_log title="nginx">
<changes ver="1.21.0" date="2021-05-25">
<change type="security">
<para lang="ru">
при использовании директивы resolver
во время обработки ответа DNS-сервера
могла происходить перезапись одного байта памяти,
что позволяло атакующему,
имеющему возможность подделывать UDP-пакеты от DNS-сервера,
вызвать падение рабочего процесса
или, потенциально, выполнение произвольного кода (CVE-2021-23017).
</para>
<para lang="en">
1-byte memory overwrite might occur
during DNS server response processing
if the "resolver" directive was used,
allowing an attacker
who is able to forge UDP packets from the DNS server
to cause worker process crash
or, potentially, arbitrary code execution (CVE-2021-23017).
</para>
</change>
<change type="feature">
<para lang="ru">
директивы proxy_ssl_certificate, proxy_ssl_certificate_key,
grpc_ssl_certificate, grpc_ssl_certificate_key,
uwsgi_ssl_certificate и uwsgi_ssl_certificate_key
поддерживают переменные.
</para>
<para lang="en">
variables support
in the "proxy_ssl_certificate", "proxy_ssl_certificate_key"
"grpc_ssl_certificate", "grpc_ssl_certificate_key",
"uwsgi_ssl_certificate", and "uwsgi_ssl_certificate_key" directives.
</para>
</change>
<change type="feature">
<para lang="ru">
директива max_errors в почтовом прокси-сервере.
</para>
<para lang="en">
the "max_errors" directive in the mail proxy module.
</para>
</change>
<change type="feature">
<para lang="ru">
почтовый прокси-сервер поддерживает POP3 и IMAP pipelining.
</para>
<para lang="en">
the mail proxy module supports POP3 and IMAP pipelining.
</para>
</change>
<change type="feature">
<para lang="ru">
параметр fastopen директивы listen в модуле stream.<br/>
Спасибо Anbang Wen.
</para>
<para lang="en">
the "fastopen" parameter of the "listen" directive in the stream module.<br/>
Thanks to Anbang Wen.
</para>
</change>
<change type="bugfix">
<para lang="ru">
специальные символы не экранировались
при автоматическом перенаправлении с добавлением завершающего слэша.
</para>
<para lang="en">
special characters were not escaped
during automatic redirect with appended trailing slash.
</para>
</change>
<change type="bugfix">
<para lang="ru">
при использовании SMTP pipelining
соединения с клиентами в почтовом прокси-сервере
могли неожиданно закрываться.
</para>
<para lang="en">
connections with clients in the mail proxy module
might be closed unexpectedly
when using SMTP pipelining.
</para>
</change>
</changes>
<changes ver="1.19.10" date="2021-04-13">
<change type="change">

View File

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1019010
#define NGINX_VERSION "1.19.10"
#define nginx_version 1021000
#define NGINX_VERSION "1.21.0"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD

View File

@ -1798,6 +1798,12 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n,
i = sizeof(ngx_resolver_hdr_t);
while (i < (ngx_uint_t) n) {
if (buf[i] & 0xc0) {
err = "unexpected compression pointer in DNS response";
goto done;
}
if (buf[i] == '\0') {
goto found;
}
@ -3939,11 +3945,11 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
{
char *err;
u_char *p, *dst;
ssize_t len;
size_t len;
ngx_uint_t i, n;
p = src;
len = -1;
len = 0;
/*
* compression pointers allow to create endless loop, so we set limit;
@ -3958,6 +3964,16 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
}
if (n & 0xc0) {
if ((n & 0xc0) != 0xc0) {
err = "invalid label type in DNS response";
goto invalid;
}
if (p >= last) {
err = "name is out of DNS response";
goto invalid;
}
n = ((n & 0x3f) << 8) + *p;
p = &buf[n];
@ -3986,7 +4002,7 @@ done:
return NGX_OK;
}
if (len == -1) {
if (len == 0) {
ngx_str_null(name);
return NGX_OK;
}
@ -3998,30 +4014,23 @@ done:
name->data = dst;
n = *src++;
for ( ;; ) {
n = *src++;
if (n == 0) {
name->len = dst - name->data - 1;
return NGX_OK;
}
if (n & 0xc0) {
n = ((n & 0x3f) << 8) + *src;
src = &buf[n];
n = *src++;
} else {
ngx_strlow(dst, src, n);
dst += n;
src += n;
n = *src++;
if (n != 0) {
*dst++ = '.';
}
}
if (n == 0) {
name->len = dst - name->data;
return NGX_OK;
*dst++ = '.';
}
}
}

View File

@ -1573,7 +1573,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
/* " ", """, "%", "'", %00-%1F, %7F-%FF */
/* " ", """, "'", %00-%1F, %7F-%FF */
static uint32_t refresh[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */

View File

@ -16,7 +16,7 @@
typedef struct {
ngx_http_complex_value_t *realm;
ngx_http_complex_value_t user_file;
ngx_http_complex_value_t *user_file;
} ngx_http_auth_basic_loc_conf_t;
@ -107,7 +107,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
if (alcf->realm == NULL || alcf->user_file.value.data == NULL) {
if (alcf->realm == NULL || alcf->user_file == NULL) {
return NGX_DECLINED;
}
@ -133,7 +133,7 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (ngx_http_complex_value(r, &alcf->user_file, &user_file) != NGX_OK) {
if (ngx_http_complex_value(r, alcf->user_file, &user_file) != NGX_OK) {
return NGX_ERROR;
}
@ -357,6 +357,9 @@ ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf)
return NULL;
}
conf->realm = NGX_CONF_UNSET_PTR;
conf->user_file = NGX_CONF_UNSET_PTR;
return conf;
}
@ -367,13 +370,8 @@ ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_auth_basic_loc_conf_t *prev = parent;
ngx_http_auth_basic_loc_conf_t *conf = child;
if (conf->realm == NULL) {
conf->realm = prev->realm;
}
if (conf->user_file.value.data == NULL) {
conf->user_file = prev->user_file;
}
ngx_conf_merge_ptr_value(conf->realm, prev->realm, NULL);
ngx_conf_merge_ptr_value(conf->user_file, prev->user_file, NULL);
return NGX_CONF_OK;
}
@ -406,17 +404,22 @@ ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
ngx_http_compile_complex_value_t ccv;
if (alcf->user_file.value.data) {
if (alcf->user_file != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
alcf->user_file = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
if (alcf->user_file == NULL) {
return NGX_CONF_ERROR;
}
value = cf->args->elts;
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = &alcf->user_file;
ccv.complex_value = alcf->user_file;
ccv.zero = 1;
ccv.conf_prefix = 1;

View File

@ -1072,6 +1072,10 @@ ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, ngx_int_t not_found,
static ngx_int_t
ngx_http_dav_location(ngx_http_request_t *r)
{
u_char *p;
size_t len;
uintptr_t escape;
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
return NGX_ERROR;
@ -1079,7 +1083,26 @@ ngx_http_dav_location(ngx_http_request_t *r)
r->headers_out.location->hash = 1;
ngx_str_set(&r->headers_out.location->key, "Location");
r->headers_out.location->value = r->uri;
escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI);
if (escape) {
len = r->uri.len + escape;
p = ngx_pnalloc(r->pool, len);
if (p == NULL) {
ngx_http_clear_location(r);
return NGX_ERROR;
}
r->headers_out.location->value.len = len;
r->headers_out.location->value.data = p;
ngx_escape_uri(p, r->uri.data, r->uri.len, NGX_ESCAPE_URI);
} else {
r->headers_out.location->value = r->uri;
}
return NGX_OK;
}

View File

@ -37,9 +37,6 @@ typedef struct {
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_str_t ssl_certificate;
ngx_str_t ssl_certificate_key;
ngx_array_t *ssl_passwords;
ngx_array_t *ssl_conf_commands;
#endif
} ngx_http_grpc_loc_conf_t;
@ -425,16 +422,16 @@ static ngx_command_t ngx_http_grpc_commands[] = {
{ ngx_string("grpc_ssl_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_grpc_loc_conf_t, ssl_certificate),
offsetof(ngx_http_grpc_loc_conf_t, upstream.ssl_certificate),
NULL },
{ ngx_string("grpc_ssl_certificate_key"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_grpc_loc_conf_t, ssl_certificate_key),
offsetof(ngx_http_grpc_loc_conf_t, upstream.ssl_certificate_key),
NULL },
{ ngx_string("grpc_ssl_password_file"),
@ -4331,7 +4328,6 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.ignore_headers = 0;
* conf->upstream.next_upstream = 0;
* conf->upstream.hide_headers_hash = { NULL, 0 };
* conf->upstream.ssl_name = NULL;
*
* conf->headers.lengths = NULL;
* conf->headers.values = NULL;
@ -4343,8 +4339,6 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
* conf->ssl_ciphers = { 0, NULL };
* conf->ssl_trusted_certificate = { 0, NULL };
* conf->ssl_crl = { 0, NULL };
* conf->ssl_certificate = { 0, NULL };
* conf->ssl_certificate_key = { 0, NULL };
*/
conf->upstream.local = NGX_CONF_UNSET_PTR;
@ -4364,10 +4358,13 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_SSL)
conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
conf->upstream.ssl_name = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_server_name = NGX_CONF_UNSET;
conf->upstream.ssl_verify = NGX_CONF_UNSET;
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
@ -4459,10 +4456,8 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");
if (conf->upstream.ssl_name == NULL) {
conf->upstream.ssl_name = prev->upstream.ssl_name;
}
ngx_conf_merge_ptr_value(conf->upstream.ssl_name,
prev->upstream.ssl_name, NULL);
ngx_conf_merge_value(conf->upstream.ssl_server_name,
prev->upstream.ssl_server_name, 0);
ngx_conf_merge_value(conf->upstream.ssl_verify,
@ -4473,11 +4468,12 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->ssl_trusted_certificate, "");
ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
ngx_conf_merge_str_value(conf->ssl_certificate,
prev->ssl_certificate, "");
ngx_conf_merge_str_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, "");
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate,
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
@ -4833,15 +4829,15 @@ ngx_http_grpc_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
if (glcf->ssl_passwords != NGX_CONF_UNSET_PTR) {
if (glcf->upstream.ssl_passwords != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
value = cf->args->elts;
glcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
glcf->upstream.ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
if (glcf->ssl_passwords == NULL) {
if (glcf->upstream.ssl_passwords == NULL) {
return NGX_CONF_ERROR;
}
@ -4887,20 +4883,34 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
cln->handler = ngx_ssl_cleanup_ctx;
cln->data = glcf->upstream.ssl;
if (glcf->ssl_certificate.len) {
if (glcf->upstream.ssl_certificate) {
if (glcf->ssl_certificate_key.len == 0) {
if (glcf->upstream.ssl_certificate_key == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"grpc_ssl_certificate_key\" is defined "
"for certificate \"%V\"", &glcf->ssl_certificate);
"for certificate \"%V\"",
&glcf->upstream.ssl_certificate->value);
return NGX_ERROR;
}
if (ngx_ssl_certificate(cf, glcf->upstream.ssl, &glcf->ssl_certificate,
&glcf->ssl_certificate_key, glcf->ssl_passwords)
!= NGX_OK)
if (glcf->upstream.ssl_certificate->lengths
|| glcf->upstream.ssl_certificate_key->lengths)
{
return NGX_ERROR;
glcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, glcf->upstream.ssl_passwords);
if (glcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, glcf->upstream.ssl,
&glcf->upstream.ssl_certificate->value,
&glcf->upstream.ssl_certificate_key->value,
glcf->upstream.ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
}
}

View File

@ -124,9 +124,6 @@ typedef struct {
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_str_t ssl_certificate;
ngx_str_t ssl_certificate_key;
ngx_array_t *ssl_passwords;
ngx_array_t *ssl_conf_commands;
#endif
} ngx_http_proxy_loc_conf_t;
@ -753,16 +750,16 @@ static ngx_command_t ngx_http_proxy_commands[] = {
{ ngx_string("proxy_ssl_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate),
offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_certificate),
NULL },
{ ngx_string("proxy_ssl_certificate_key"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key),
offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_certificate_key),
NULL },
{ ngx_string("proxy_ssl_password_file"),
@ -3327,9 +3324,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.hide_headers_hash = { NULL, 0 };
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
* conf->upstream.ssl_name = NULL;
*
* conf->method = NULL;
* conf->location = NULL;
* conf->url = { 0, NULL };
* conf->headers.lengths = NULL;
@ -3347,8 +3342,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->ssl_ciphers = { 0, NULL };
* conf->ssl_trusted_certificate = { 0, NULL };
* conf->ssl_crl = { 0, NULL };
* conf->ssl_certificate = { 0, NULL };
* conf->ssl_certificate_key = { 0, NULL };
*/
conf->upstream.store = NGX_CONF_UNSET;
@ -3400,20 +3393,26 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_SSL)
conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
conf->upstream.ssl_name = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_server_name = NGX_CONF_UNSET;
conf->upstream.ssl_verify = NGX_CONF_UNSET;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
/* "proxy_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
conf->upstream.change_buffering = 1;
conf->headers_source = NGX_CONF_UNSET_PTR;
conf->method = NGX_CONF_UNSET_PTR;
conf->redirect = NGX_CONF_UNSET;
conf->upstream.change_buffering = 1;
conf->cookie_domains = NGX_CONF_UNSET_PTR;
conf->cookie_paths = NGX_CONF_UNSET_PTR;
@ -3708,10 +3707,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#endif
if (conf->method == NULL) {
conf->method = prev->method;
}
ngx_conf_merge_value(conf->upstream.pass_request_headers,
prev->upstream.pass_request_headers, 1);
ngx_conf_merge_value(conf->upstream.pass_request_body,
@ -3732,10 +3727,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");
if (conf->upstream.ssl_name == NULL) {
conf->upstream.ssl_name = prev->upstream.ssl_name;
}
ngx_conf_merge_ptr_value(conf->upstream.ssl_name,
prev->upstream.ssl_name, NULL);
ngx_conf_merge_value(conf->upstream.ssl_server_name,
prev->upstream.ssl_server_name, 0);
ngx_conf_merge_value(conf->upstream.ssl_verify,
@ -3746,11 +3739,12 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->ssl_trusted_certificate, "");
ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
ngx_conf_merge_str_value(conf->ssl_certificate,
prev->ssl_certificate, "");
ngx_conf_merge_str_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, "");
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate,
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
@ -3761,6 +3755,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#endif
ngx_conf_merge_ptr_value(conf->method, prev->method, NULL);
ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
if (conf->redirect) {
@ -4859,15 +4855,15 @@ ngx_http_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
if (plcf->ssl_passwords != NGX_CONF_UNSET_PTR) {
if (plcf->upstream.ssl_passwords != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
value = cf->args->elts;
plcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
plcf->upstream.ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
if (plcf->ssl_passwords == NULL) {
if (plcf->upstream.ssl_passwords == NULL) {
return NGX_CONF_ERROR;
}
@ -4946,20 +4942,34 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
cln->handler = ngx_ssl_cleanup_ctx;
cln->data = plcf->upstream.ssl;
if (plcf->ssl_certificate.len) {
if (plcf->upstream.ssl_certificate) {
if (plcf->ssl_certificate_key.len == 0) {
if (plcf->upstream.ssl_certificate_key == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"proxy_ssl_certificate_key\" is defined "
"for certificate \"%V\"", &plcf->ssl_certificate);
"for certificate \"%V\"",
&plcf->upstream.ssl_certificate->value);
return NGX_ERROR;
}
if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate,
&plcf->ssl_certificate_key, plcf->ssl_passwords)
!= NGX_OK)
if (plcf->upstream.ssl_certificate->lengths
|| plcf->upstream.ssl_certificate_key->lengths)
{
return NGX_ERROR;
plcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, plcf->upstream.ssl_passwords);
if (plcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, plcf->upstream.ssl,
&plcf->upstream.ssl_certificate->value,
&plcf->upstream.ssl_certificate_key->value,
plcf->upstream.ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
}
}

View File

@ -302,11 +302,12 @@ ngx_http_secure_link_create_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
* conf->variable = NULL;
* conf->md5 = NULL;
* conf->secret = { 0, NULL };
*/
conf->variable = NGX_CONF_UNSET_PTR;
conf->md5 = NGX_CONF_UNSET_PTR;
return conf;
}
@ -318,6 +319,9 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_secure_link_conf_t *conf = child;
if (conf->secret.data) {
ngx_conf_init_ptr_value(conf->variable, NULL);
ngx_conf_init_ptr_value(conf->md5, NULL);
if (conf->variable || conf->md5) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"secure_link_secret\" cannot be mixed with "
@ -328,13 +332,8 @@ ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
if (conf->variable == NULL) {
conf->variable = prev->variable;
}
if (conf->md5 == NULL) {
conf->md5 = prev->md5;
}
ngx_conf_merge_ptr_value(conf->variable, prev->variable, NULL);
ngx_conf_merge_ptr_value(conf->md5, prev->md5, NULL);
if (conf->variable == NULL && conf->md5 == NULL) {
conf->secret = prev->secret;

View File

@ -50,6 +50,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
{
u_char *last, *location;
size_t root, len;
uintptr_t escape;
ngx_str_t path;
ngx_int_t rc;
ngx_uint_t level;
@ -155,14 +156,18 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
len = r->uri.len + 1;
escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
NGX_ESCAPE_URI);
if (!clcf->alias && r->args.len == 0) {
if (!clcf->alias && r->args.len == 0 && escape == 0) {
len = r->uri.len + 1;
location = path.data + root;
*last = '/';
} else {
len = r->uri.len + escape + 1;
if (r->args.len) {
len += r->args.len + 1;
}
@ -173,7 +178,13 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
last = ngx_copy(location, r->uri.data, r->uri.len);
if (escape) {
last = (u_char *) ngx_escape_uri(location, r->uri.data,
r->uri.len, NGX_ESCAPE_URI);
} else {
last = ngx_copy(location, r->uri.data, r->uri.len);
}
*last = '/';

View File

@ -54,9 +54,6 @@ typedef struct {
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_str_t ssl_certificate;
ngx_str_t ssl_certificate_key;
ngx_array_t *ssl_passwords;
ngx_array_t *ssl_conf_commands;
#endif
} ngx_http_uwsgi_loc_conf_t;
@ -548,16 +545,16 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
{ ngx_string("uwsgi_ssl_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate),
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_certificate),
NULL },
{ ngx_string("uwsgi_ssl_certificate_key"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_http_set_complex_value_zero_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key),
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_certificate_key),
NULL },
{ ngx_string("uwsgi_ssl_password_file"),
@ -1509,10 +1506,13 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_SSL)
conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
conf->upstream.ssl_name = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_server_name = NGX_CONF_UNSET;
conf->upstream.ssl_verify = NGX_CONF_UNSET;
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
@ -1824,10 +1824,8 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");
if (conf->upstream.ssl_name == NULL) {
conf->upstream.ssl_name = prev->upstream.ssl_name;
}
ngx_conf_merge_ptr_value(conf->upstream.ssl_name,
prev->upstream.ssl_name, NULL);
ngx_conf_merge_value(conf->upstream.ssl_server_name,
prev->upstream.ssl_server_name, 0);
ngx_conf_merge_value(conf->upstream.ssl_verify,
@ -1838,11 +1836,12 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
prev->ssl_trusted_certificate, "");
ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
ngx_conf_merge_str_value(conf->ssl_certificate,
prev->ssl_certificate, "");
ngx_conf_merge_str_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, "");
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate,
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
@ -2377,15 +2376,15 @@ ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
if (uwcf->ssl_passwords != NGX_CONF_UNSET_PTR) {
if (uwcf->upstream.ssl_passwords != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
value = cf->args->elts;
uwcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
uwcf->upstream.ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
if (uwcf->ssl_passwords == NULL) {
if (uwcf->upstream.ssl_passwords == NULL) {
return NGX_CONF_ERROR;
}
@ -2431,20 +2430,34 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
cln->handler = ngx_ssl_cleanup_ctx;
cln->data = uwcf->upstream.ssl;
if (uwcf->ssl_certificate.len) {
if (uwcf->upstream.ssl_certificate) {
if (uwcf->ssl_certificate_key.len == 0) {
if (uwcf->upstream.ssl_certificate_key == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"uwsgi_ssl_certificate_key\" is defined "
"for certificate \"%V\"", &uwcf->ssl_certificate);
"for certificate \"%V\"",
&uwcf->upstream.ssl_certificate->value);
return NGX_ERROR;
}
if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate,
&uwcf->ssl_certificate_key, uwcf->ssl_passwords)
!= NGX_OK)
if (uwcf->upstream.ssl_certificate->lengths
|| uwcf->upstream.ssl_certificate_key->lengths)
{
return NGX_ERROR;
uwcf->upstream.ssl_passwords =
ngx_ssl_preserve_passwords(cf, uwcf->upstream.ssl_passwords);
if (uwcf->upstream.ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, uwcf->upstream.ssl,
&uwcf->upstream.ssl_certificate->value,
&uwcf->upstream.ssl_certificate_key->value,
uwcf->upstream.ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
}
}

View File

@ -37,6 +37,8 @@ static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
ngx_http_core_loc_conf_t *pclcf);
static ngx_int_t ngx_http_escape_location_name(ngx_conf_t *cf,
ngx_http_core_loc_conf_t *clcf);
static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
const ngx_queue_t *two);
static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
@ -882,6 +884,41 @@ ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
ngx_queue_insert_tail(*locations, &lq->queue);
if (ngx_http_escape_location_name(cf, clcf) != NGX_OK) {
return NGX_ERROR;
}
return NGX_OK;
}
static ngx_int_t
ngx_http_escape_location_name(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf)
{
u_char *p;
size_t len;
uintptr_t escape;
escape = 2 * ngx_escape_uri(NULL, clcf->name.data, clcf->name.len,
NGX_ESCAPE_URI);
if (escape) {
len = clcf->name.len + escape;
p = ngx_pnalloc(cf->pool, len);
if (p == NULL) {
return NGX_ERROR;
}
clcf->escaped_name.len = len;
clcf->escaped_name.data = p;
ngx_escape_uri(p, clcf->name.data, clcf->name.len, NGX_ESCAPE_URI);
} else {
clcf->escaped_name = clcf->name;
}
return NGX_OK;
}

View File

@ -1010,10 +1010,10 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
ngx_str_set(&r->headers_out.location->key, "Location");
if (r->args.len == 0) {
r->headers_out.location->value = clcf->name;
r->headers_out.location->value = clcf->escaped_name;
} else {
len = clcf->name.len + 1 + r->args.len;
len = clcf->escaped_name.len + 1 + r->args.len;
p = ngx_pnalloc(r->pool, len);
if (p == NULL) {
@ -1025,7 +1025,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
r->headers_out.location->value.len = len;
r->headers_out.location->value.data = p;
p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
p = ngx_cpymem(p, clcf->escaped_name.data, clcf->escaped_name.len);
*p++ = '?';
ngx_memcpy(p, r->args.data, r->args.len);
}
@ -3467,6 +3467,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
* clcf->escaped_name = { 0, NULL };
* clcf->root = { 0, NULL };
* clcf->limit_except = 0;
* clcf->post_action = { 0, NULL };
@ -3479,8 +3480,6 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
* clcf->exact_match = 0;
* clcf->auto_redirect = 0;
* clcf->alias = 0;
* clcf->limit_rate = NULL;
* clcf->limit_rate_after = NULL;
* clcf->gzip_proxied = 0;
* clcf->keepalive_disable = 0;
*/
@ -3512,6 +3511,8 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
clcf->send_lowat = NGX_CONF_UNSET_SIZE;
clcf->postpone_output = NGX_CONF_UNSET_SIZE;
clcf->limit_rate = NGX_CONF_UNSET_PTR;
clcf->limit_rate_after = NGX_CONF_UNSET_PTR;
clcf->keepalive_time = NGX_CONF_UNSET_MSEC;
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
@ -3743,13 +3744,9 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
if (conf->limit_rate == NULL) {
conf->limit_rate = prev->limit_rate;
}
if (conf->limit_rate_after == NULL) {
conf->limit_rate_after = prev->limit_rate_after;
}
ngx_conf_merge_ptr_value(conf->limit_rate, prev->limit_rate, NULL);
ngx_conf_merge_ptr_value(conf->limit_rate_after,
prev->limit_rate_after, NULL);
ngx_conf_merge_msec_value(conf->keepalive_time,
prev->keepalive_time, 3600000);

View File

@ -305,6 +305,7 @@ typedef struct {
struct ngx_http_core_loc_conf_s {
ngx_str_t name; /* location name */
ngx_str_t escaped_name;
#if (NGX_PCRE)
ngx_http_regex_t *regex;

View File

@ -1052,12 +1052,14 @@ ngx_http_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
}
ngx_http_free_request(r, 0);
c->log->action = "SSL handshaking";
c->destroyed = 0;
return 1;
failed:
ngx_http_free_request(r, 0);
c->log->action = "SSL handshaking";
c->destroyed = 0;
return 0;
}

View File

@ -250,7 +250,7 @@ ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cv = (ngx_http_complex_value_t **) (p + cmd->offset);
if (*cv != NULL) {
if (*cv != NGX_CONF_UNSET_PTR && *cv != NULL) {
return "is duplicate";
}
@ -275,6 +275,44 @@ ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
char *
ngx_http_set_complex_value_zero_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
char *p = conf;
ngx_str_t *value;
ngx_http_complex_value_t **cv;
ngx_http_compile_complex_value_t ccv;
cv = (ngx_http_complex_value_t **) (p + cmd->offset);
if (*cv != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
*cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
if (*cv == NULL) {
return NGX_CONF_ERROR;
}
value = cf->args->elts;
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = *cv;
ccv.zero = 1;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
char *
ngx_http_set_complex_value_size_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)

View File

@ -216,6 +216,8 @@ size_t ngx_http_complex_value_size(ngx_http_request_t *r,
ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_http_set_complex_value_zero_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_http_set_complex_value_size_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);

View File

@ -187,6 +187,8 @@ static void ngx_http_upstream_ssl_handshake(ngx_http_request_t *,
static void ngx_http_upstream_ssl_save_session(ngx_connection_t *c);
static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c);
static ngx_int_t ngx_http_upstream_ssl_certificate(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c);
#endif
@ -1712,6 +1714,16 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
}
}
if (u->conf->ssl_certificate && (u->conf->ssl_certificate->lengths
|| u->conf->ssl_certificate_key->lengths))
{
if (ngx_http_upstream_ssl_certificate(r, u, c) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
if (u->conf->ssl_session_reuse) {
c->ssl->save_session = ngx_http_upstream_ssl_save_session;
@ -1932,6 +1944,45 @@ done:
return NGX_OK;
}
static ngx_int_t
ngx_http_upstream_ssl_certificate(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_connection_t *c)
{
ngx_str_t cert, key;
if (ngx_http_complex_value(r, u->conf->ssl_certificate, &cert)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl cert: \"%s\"", cert.data);
if (*cert.data == '\0') {
return NGX_OK;
}
if (ngx_http_complex_value(r, u->conf->ssl_certificate_key, &key)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl key: \"%s\"", key.data);
if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
u->conf->ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
return NGX_OK;
}
#endif

View File

@ -234,6 +234,10 @@ typedef struct {
ngx_http_complex_value_t *ssl_name;
ngx_flag_t ssl_server_name;
ngx_flag_t ssl_verify;
ngx_http_complex_value_t *ssl_certificate;
ngx_http_complex_value_t *ssl_certificate_key;
ngx_array_t *ssl_passwords;
#endif
ngx_str_t module;

View File

@ -115,6 +115,8 @@ typedef struct {
ngx_msec_t timeout;
ngx_msec_t resolver_timeout;
ngx_uint_t max_errors;
ngx_str_t server_name;
u_char *file_name;
@ -231,14 +233,15 @@ typedef struct {
ngx_uint_t command;
ngx_array_t args;
ngx_uint_t errors;
ngx_uint_t login_attempt;
/* used to parse POP3/IMAP/SMTP command */
ngx_uint_t state;
u_char *tag_start;
u_char *cmd_start;
u_char *arg_start;
u_char *arg_end;
ngx_uint_t literal_len;
} ngx_mail_session_t;

View File

@ -85,6 +85,13 @@ static ngx_command_t ngx_mail_core_commands[] = {
offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
NULL },
{ ngx_string("max_errors"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, max_errors),
NULL },
ngx_null_command
};
@ -163,6 +170,8 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
cscf->timeout = NGX_CONF_UNSET_MSEC;
cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
cscf->max_errors = NGX_CONF_UNSET_UINT;
cscf->resolver = NGX_CONF_UNSET_PTR;
cscf->file_name = cf->conf_file->file.name.data;
@ -182,6 +191,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
30000);
ngx_conf_merge_uint_value(conf->max_errors, prev->max_errors, 5);
ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");

View File

@ -833,20 +833,23 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
ngx_str_t l;
ngx_mail_core_srv_conf_t *cscf;
n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
if (s->buffer->last < s->buffer->end) {
if (n == NGX_ERROR || n == 0) {
ngx_mail_close_connection(c);
return NGX_ERROR;
}
n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
if (n > 0) {
s->buffer->last += n;
}
if (n == NGX_ERROR || n == 0) {
ngx_mail_close_connection(c);
return NGX_ERROR;
}
if (n == NGX_AGAIN) {
if (s->buffer->pos == s->buffer->last) {
return NGX_AGAIN;
if (n > 0) {
s->buffer->last += n;
}
if (n == NGX_AGAIN) {
if (s->buffer->pos == s->buffer->last) {
return NGX_AGAIN;
}
}
}
@ -871,7 +874,20 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
s->errors++;
if (s->errors >= cscf->max_errors) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too many invalid commands");
s->quit = 1;
}
return rc;
}
if (rc == NGX_IMAP_NEXT) {
return rc;
}

View File

@ -101,10 +101,9 @@ ngx_mail_imap_init_protocol(ngx_event_t *rev)
void
ngx_mail_imap_auth_state(ngx_event_t *rev)
{
u_char *p, *dst, *src, *end;
ngx_str_t *arg;
u_char *p;
ngx_int_t rc;
ngx_uint_t tag, i;
ngx_uint_t tag;
ngx_connection_t *c;
ngx_mail_session_t *s;
@ -158,27 +157,6 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth command: %i",
s->command);
if (s->backslash) {
arg = s->args.elts;
for (i = 0; i < s->args.nelts; i++) {
dst = arg[i].data;
end = dst + arg[i].len;
for (src = dst; src < end; dst++) {
*dst = *src;
if (*src++ == '\\') {
*dst = *src++;
}
}
arg[i].len = dst - arg[i].data;
}
s->backslash = 0;
}
switch (s->mail_state) {
case ngx_imap_start:
@ -248,6 +226,10 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
ngx_str_set(&s->out, imap_next);
}
if (s->buffer->pos < s->buffer->last) {
s->blocked = 1;
}
switch (rc) {
case NGX_DONE:
@ -297,13 +279,14 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
if (s->state) {
/* preserve tag */
s->arg_start = s->buffer->start + s->tag.len;
s->buffer->pos = s->arg_start;
s->buffer->last = s->arg_start;
s->arg_start = s->buffer->pos;
} else {
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
if (s->buffer->pos == s->buffer->last) {
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
}
s->tag.len = 0;
}
}
@ -481,6 +464,8 @@ ngx_mail_imap_starttls(ngx_mail_session_t *s, ngx_connection_t *c)
if (c->ssl == NULL) {
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
if (sslcf->starttls) {
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
c->read->handler = ngx_mail_starttls_handler;
return NGX_OK;
}

View File

@ -21,6 +21,8 @@ ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
ngx_str_t *arg;
enum {
sw_start = 0,
sw_command,
sw_invalid,
sw_spaces_before_argument,
sw_argument,
sw_almost_done
@ -35,8 +37,14 @@ ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
/* POP3 command */
case sw_start:
s->cmd_start = p;
state = sw_command;
/* fall through */
case sw_command:
if (ch == ' ' || ch == CR || ch == LF) {
c = s->buffer->start;
c = s->cmd_start;
if (p - c == 4) {
@ -85,6 +93,9 @@ ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
goto invalid;
}
s->cmd.data = s->cmd_start;
s->cmd.len = p - s->cmd_start;
switch (ch) {
case ' ':
state = sw_spaces_before_argument;
@ -104,16 +115,17 @@ ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
break;
case sw_invalid:
goto invalid;
case sw_spaces_before_argument:
switch (ch) {
case ' ':
break;
case CR:
state = sw_almost_done;
s->arg_end = p;
break;
case LF:
s->arg_end = p;
goto done;
default:
if (s->args.nelts <= 2) {
@ -188,37 +200,39 @@ ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
done:
s->buffer->pos = p + 1;
if (s->arg_start) {
arg = ngx_array_push(&s->args);
if (arg == NULL) {
return NGX_ERROR;
}
arg->len = s->arg_end - s->arg_start;
arg->data = s->arg_start;
s->arg_start = NULL;
}
s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
return NGX_OK;
invalid:
s->state = sw_start;
s->arg_start = NULL;
s->state = sw_invalid;
return NGX_MAIL_PARSE_INVALID_COMMAND;
/* skip invalid command till LF */
for ( /* void */ ; p < s->buffer->last; p++) {
if (*p == LF) {
s->state = sw_start;
s->buffer->pos = p + 1;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
}
s->buffer->pos = p;
return NGX_AGAIN;
}
ngx_int_t
ngx_mail_imap_parse_command(ngx_mail_session_t *s)
{
u_char ch, *p, *c;
u_char ch, *p, *c, *dst, *src, *end;
ngx_str_t *arg;
enum {
sw_start = 0,
sw_tag,
sw_invalid,
sw_spaces_before_command,
sw_command,
sw_spaces_before_argument,
@ -241,31 +255,45 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
/* IMAP tag */
case sw_start:
s->tag_start = p;
state = sw_tag;
/* fall through */
case sw_tag:
switch (ch) {
case ' ':
s->tag.len = p - s->buffer->start + 1;
s->tag.data = s->buffer->start;
s->tag.len = p - s->tag_start + 1;
s->tag.data = s->tag_start;
state = sw_spaces_before_command;
break;
case CR:
s->state = sw_start;
return NGX_MAIL_PARSE_INVALID_COMMAND;
case LF:
s->state = sw_start;
return NGX_MAIL_PARSE_INVALID_COMMAND;
goto invalid;
default:
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')
&& (ch < '0' || ch > '9') && ch != '-' && ch != '.'
&& ch != '_')
{
goto invalid;
}
if (p - s->tag_start > 31) {
goto invalid;
}
break;
}
break;
case sw_invalid:
goto invalid;
case sw_spaces_before_command:
switch (ch) {
case ' ':
break;
case CR:
s->state = sw_start;
return NGX_MAIL_PARSE_INVALID_COMMAND;
case LF:
s->state = sw_start;
return NGX_MAIL_PARSE_INVALID_COMMAND;
goto invalid;
default:
s->cmd_start = p;
state = sw_command;
@ -385,6 +413,9 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
goto invalid;
}
s->cmd.data = s->cmd_start;
s->cmd.len = p - s->cmd_start;
switch (ch) {
case ' ':
state = sw_spaces_before_argument;
@ -410,10 +441,8 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
break;
case CR:
state = sw_almost_done;
s->arg_end = p;
break;
case LF:
s->arg_end = p;
goto done;
case '"':
if (s->args.nelts <= 2) {
@ -460,6 +489,22 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
}
arg->len = p - s->arg_start;
arg->data = s->arg_start;
if (s->backslash) {
dst = s->arg_start;
end = p;
for (src = dst; src < end; dst++) {
*dst = *src;
if (*src++ == '\\') {
*dst = *src++;
}
}
arg->len = dst - s->arg_start;
s->backslash = 0;
}
s->arg_start = NULL;
switch (ch) {
@ -588,34 +633,46 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
done:
s->buffer->pos = p + 1;
if (s->arg_start) {
arg = ngx_array_push(&s->args);
if (arg == NULL) {
return NGX_ERROR;
}
arg->len = s->arg_end - s->arg_start;
arg->data = s->arg_start;
s->arg_start = NULL;
s->cmd_start = NULL;
s->quoted = 0;
s->no_sync_literal = 0;
s->literal_len = 0;
}
s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument;
return NGX_OK;
invalid:
s->state = sw_start;
s->state = sw_invalid;
s->quoted = 0;
s->backslash = 0;
s->no_sync_literal = 0;
s->literal_len = 0;
return NGX_MAIL_PARSE_INVALID_COMMAND;
/* skip invalid command till LF */
for ( /* void */ ; p < s->buffer->last; p++) {
if (*p == LF) {
s->state = sw_start;
s->buffer->pos = p + 1;
/* detect non-synchronizing literals */
if ((size_t) (p - s->buffer->start) > sizeof("{1+}") - 1) {
p--;
if (*p == CR) {
p--;
}
if (*p == '}' && *(p - 1) == '+') {
s->quit = 1;
}
}
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
}
s->buffer->pos = p;
return NGX_AGAIN;
}
@ -758,10 +815,8 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
break;
case CR:
state = sw_almost_done;
s->arg_end = p;
break;
case LF:
s->arg_end = p;
goto done;
default:
if (s->args.nelts <= 10) {
@ -821,17 +876,6 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
done:
s->buffer->pos = p + 1;
if (s->arg_start) {
arg = ngx_array_push(&s->args);
if (arg == NULL) {
return NGX_ERROR;
}
arg->len = s->arg_end - s->arg_start;
arg->data = s->arg_start;
s->arg_start = NULL;
}
s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument;
return NGX_OK;
@ -839,21 +883,20 @@ done:
invalid:
s->state = sw_invalid;
s->arg_start = NULL;
/* skip invalid command till LF */
for (p = s->buffer->pos; p < s->buffer->last; p++) {
for ( /* void */ ; p < s->buffer->last; p++) {
if (*p == LF) {
s->state = sw_start;
p++;
break;
s->buffer->pos = p + 1;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
}
s->buffer->pos = p;
return NGX_MAIL_PARSE_INVALID_COMMAND;
return NGX_AGAIN;
}

View File

@ -262,6 +262,10 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
}
}
if (s->buffer->pos < s->buffer->last) {
s->blocked = 1;
}
switch (rc) {
case NGX_DONE:
@ -283,11 +287,14 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
case NGX_OK:
s->args.nelts = 0;
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
if (s->buffer->pos == s->buffer->last) {
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
}
if (s->state) {
s->arg_start = s->buffer->start;
s->arg_start = s->buffer->pos;
}
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
@ -400,6 +407,8 @@ ngx_mail_pop3_stls(ngx_mail_session_t *s, ngx_connection_t *c)
if (c->ssl == NULL) {
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
if (sslcf->starttls) {
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
c->read->handler = ngx_mail_starttls_handler;
return NGX_OK;
}

View File

@ -327,6 +327,10 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos < s->buffer->last) {
ngx_post_event(c->write, &ngx_posted_events);
}
ngx_mail_proxy_handler(s->connection->write);
return;
@ -482,6 +486,10 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos < s->buffer->last) {
ngx_post_event(c->write, &ngx_posted_events);
}
ngx_mail_proxy_handler(s->connection->write);
return;
@ -813,13 +821,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
c->log->action = NULL;
ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
if (s->buffer->pos == s->buffer->last) {
ngx_mail_proxy_handler(s->connection->write);
} else {
ngx_mail_proxy_handler(c->write);
if (s->buffer->pos < s->buffer->last) {
ngx_post_event(c->write, &ngx_posted_events);
}
ngx_mail_proxy_handler(s->connection->write);
return;
default:

View File

@ -398,6 +398,8 @@ ngx_pass_open_channel(ngx_cycle_t *cycle)
ngx_int_t i;
ngx_channel_t ch;
ngx_memzero(&ch, sizeof(ngx_channel_t));
ch.command = NGX_CMD_OPEN_CHANNEL;
ch.pid = ngx_processes[ngx_process_slot].pid;
ch.slot = ngx_process_slot;

View File

@ -510,6 +510,10 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
ls->ipv6only = addr[i].opt.ipv6only;
#endif
#if (NGX_HAVE_TCP_FASTOPEN)
ls->fastopen = addr[i].opt.fastopen;
#endif
#if (NGX_HAVE_REUSEPORT)
ls->reuseport = addr[i].opt.reuseport;
#endif

View File

@ -70,6 +70,9 @@ typedef struct {
int backlog;
int rcvbuf;
int sndbuf;
#if (NGX_HAVE_TCP_FASTOPEN)
int fastopen;
#endif
int type;
} ngx_stream_listen_t;

View File

@ -618,6 +618,10 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->type = SOCK_STREAM;
ls->ctx = cf->ctx;
#if (NGX_HAVE_TCP_FASTOPEN)
ls->fastopen = -1;
#endif
#if (NGX_HAVE_INET6)
ls->ipv6only = 1;
#endif
@ -638,6 +642,21 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
#if (NGX_HAVE_TCP_FASTOPEN)
if (ngx_strncmp(value[i].data, "fastopen=", 9) == 0) {
ls->fastopen = ngx_atoi(value[i].data + 9, value[i].len - 9);
ls->bind = 1;
if (ls->fastopen == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid fastopen \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
continue;
}
#endif
if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) {
ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8);
ls->bind = 1;
@ -891,6 +910,12 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ls->proxy_protocol) {
return "\"proxy_protocol\" parameter is incompatible with \"udp\"";
}
#if (NGX_HAVE_TCP_FASTOPEN)
if (ls->fastopen != -1) {
return "\"fastopen\" parameter is incompatible with \"udp\"";
}
#endif
}
als = cmcf->listen.elts;

View File

@ -46,8 +46,8 @@ typedef struct {
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_str_t ssl_certificate;
ngx_str_t ssl_certificate_key;
ngx_stream_complex_value_t *ssl_certificate;
ngx_stream_complex_value_t *ssl_certificate_key;
ngx_array_t *ssl_passwords;
ngx_array_t *ssl_conf_commands;
@ -101,6 +101,7 @@ static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s);
static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc);
static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
ngx_stream_proxy_srv_conf_t *pscf);
@ -318,14 +319,14 @@ static ngx_command_t ngx_stream_proxy_commands[] = {
{ ngx_string("proxy_ssl_certificate"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_stream_set_complex_value_zero_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate),
NULL },
{ ngx_string("proxy_ssl_certificate_key"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_stream_set_complex_value_zero_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
NULL },
@ -1060,6 +1061,15 @@ ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
}
}
if (pscf->ssl_certificate && (pscf->ssl_certificate->lengths
|| pscf->ssl_certificate_key->lengths))
{
if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) {
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
if (pscf->ssl_session_reuse) {
pc->ssl->save_session = ngx_stream_proxy_ssl_save_session;
@ -1247,6 +1257,50 @@ done:
return NGX_OK;
}
static ngx_int_t
ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s)
{
ngx_str_t cert, key;
ngx_connection_t *c;
ngx_stream_proxy_srv_conf_t *pscf;
c = s->upstream->peer.connection;
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
if (ngx_stream_complex_value(s, pscf->ssl_certificate, &cert)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
"stream upstream ssl cert: \"%s\"", cert.data);
if (*cert.data == '\0') {
return NGX_OK;
}
if (ngx_stream_complex_value(s, pscf->ssl_certificate_key, &key)
!= NGX_OK)
{
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
"stream upstream ssl key: \"%s\"", key.data);
if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
pscf->ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
return NGX_OK;
}
#endif
@ -1977,14 +2031,9 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
*
* conf->ssl_protocols = 0;
* conf->ssl_ciphers = { 0, NULL };
* conf->ssl_name = NULL;
* conf->ssl_trusted_certificate = { 0, NULL };
* conf->ssl_crl = { 0, NULL };
* conf->ssl_certificate = { 0, NULL };
* conf->ssl_certificate_key = { 0, NULL };
*
* conf->upload_rate = NULL;
* conf->download_rate = NULL;
* conf->ssl = NULL;
* conf->upstream = NULL;
* conf->upstream_value = NULL;
@ -1994,6 +2043,8 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
conf->timeout = NGX_CONF_UNSET_MSEC;
conf->next_upstream_timeout = NGX_CONF_UNSET_MSEC;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
conf->upload_rate = NGX_CONF_UNSET_PTR;
conf->download_rate = NGX_CONF_UNSET_PTR;
conf->requests = NGX_CONF_UNSET_UINT;
conf->responses = NGX_CONF_UNSET_UINT;
conf->next_upstream_tries = NGX_CONF_UNSET_UINT;
@ -2005,9 +2056,12 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
#if (NGX_STREAM_SSL)
conf->ssl_enable = NGX_CONF_UNSET;
conf->ssl_session_reuse = NGX_CONF_UNSET;
conf->ssl_name = NGX_CONF_UNSET_PTR;
conf->ssl_server_name = NGX_CONF_UNSET;
conf->ssl_verify = NGX_CONF_UNSET;
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_certificate = NGX_CONF_UNSET_PTR;
conf->ssl_certificate_key = NGX_CONF_UNSET_PTR;
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
@ -2034,13 +2088,9 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->buffer_size,
prev->buffer_size, 16384);
if (conf->upload_rate == NULL) {
conf->upload_rate = prev->upload_rate;
}
ngx_conf_merge_ptr_value(conf->upload_rate, prev->upload_rate, NULL);
if (conf->download_rate == NULL) {
conf->download_rate = prev->download_rate;
}
ngx_conf_merge_ptr_value(conf->download_rate, prev->download_rate, NULL);
ngx_conf_merge_uint_value(conf->requests,
prev->requests, 0);
@ -2073,9 +2123,7 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, "DEFAULT");
if (conf->ssl_name == NULL) {
conf->ssl_name = prev->ssl_name;
}
ngx_conf_merge_ptr_value(conf->ssl_name, prev->ssl_name, NULL);
ngx_conf_merge_value(conf->ssl_server_name, prev->ssl_server_name, 0);
@ -2089,11 +2137,11 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
ngx_conf_merge_str_value(conf->ssl_certificate,
prev->ssl_certificate, "");
ngx_conf_merge_ptr_value(conf->ssl_certificate,
prev->ssl_certificate, NULL);
ngx_conf_merge_str_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, "");
ngx_conf_merge_ptr_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, NULL);
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
@ -2137,20 +2185,34 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
cln->handler = ngx_ssl_cleanup_ctx;
cln->data = pscf->ssl;
if (pscf->ssl_certificate.len) {
if (pscf->ssl_certificate) {
if (pscf->ssl_certificate_key.len == 0) {
if (pscf->ssl_certificate_key == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"proxy_ssl_certificate_key\" is defined "
"for certificate \"%V\"", &pscf->ssl_certificate);
"for certificate \"%V\"",
&pscf->ssl_certificate->value);
return NGX_ERROR;
}
if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate,
&pscf->ssl_certificate_key, pscf->ssl_passwords)
!= NGX_OK)
if (pscf->ssl_certificate->lengths
|| pscf->ssl_certificate_key->lengths)
{
return NGX_ERROR;
pscf->ssl_passwords =
ngx_ssl_preserve_passwords(cf, pscf->ssl_passwords);
if (pscf->ssl_passwords == NULL) {
return NGX_ERROR;
}
} else {
if (ngx_ssl_certificate(cf, pscf->ssl,
&pscf->ssl_certificate->value,
&pscf->ssl_certificate_key->value,
pscf->ssl_passwords)
!= NGX_OK)
{
return NGX_ERROR;
}
}
}

View File

@ -252,7 +252,7 @@ ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
if (*cv != NULL) {
if (*cv != NGX_CONF_UNSET_PTR && *cv != NULL) {
return "is duplicate";
}
@ -277,6 +277,44 @@ ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
}
char *
ngx_stream_set_complex_value_zero_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
char *p = conf;
ngx_str_t *value;
ngx_stream_complex_value_t **cv;
ngx_stream_compile_complex_value_t ccv;
cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
if (*cv != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
*cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
if (*cv == NULL) {
return NGX_CONF_ERROR;
}
value = cf->args->elts;
ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = *cv;
ccv.zero = 1;
if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
char *
ngx_stream_set_complex_value_size_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)

View File

@ -112,6 +112,8 @@ ngx_int_t ngx_stream_compile_complex_value(
ngx_stream_compile_complex_value_t *ccv);
char *ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_stream_set_complex_value_zero_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_stream_set_complex_value_size_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);