# HG changeset patch # User Maxim Dounin # Date 1185230718 0 # Node ID d4cac61d8e95766d44c26a485c033a4e502cc92d # Parent 29cf4046a9a5c3aafecfad97d1041a5b4b199df6# Parent d16d691432c9044f8b26ffccbd6ae68c11d0cde9 Merge with nginx 0.6.5. diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -158,6 +158,7 @@ 429900ca25ee0bb45391c0c0aec4a2c2b945c5d1 d5ec0be9c835834844c6d1661b36313413231a06 NGINX_0_6_1 a6d84efa510670a5401fbd31ddd28f6931a88869 NGINX_0_6_2 fc223117327fbb2e852840dcb533ba5ff998d9ee NGINX_0_6_3 +95183808f549b2d1c8d8004b704287025b4bf76b NGINX_0_6_4 e2d916d7e50f07f94fa4bf0d0e99ba85225ea2fa PATCH_NGINX_MAIL_0_1 f9e6413396d47def780cf9600bbe35b35ce09e6e PATCH_NGINX_MAIL_0_2 98c752b41cbc0f0ecaafced85d906effa27e8fc9 PATCH_NGINX_MAIL_0_3 diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,29 @@ +Changes with nginx 0.6.5 23 Jul 2007 + + *) Feature: $nginx_version variable. + Thanks to Nick S. Grechukh. + + *) Feature: the mail proxy supports AUTHENTICATE in IMAP mode. + Thanks to Maxim Dounin. + + *) Feature: the mail proxy supports STARTTLS in SMTP mode. + Thanks to Maxim Dounin. + + *) Bugfix: now nginx escapes space in $memcached_key variable. + + *) Bugfix: nginx was incorrectly built by Sun Studio on + Solaris/amd64. + Thanks to Jiang Hong. + + *) Bugfix: of minor potential bugs. + Thanks to Coverity's Scan. + + Changes with nginx 0.6.4 17 Jul 2007 *) Security: the "msie_refresh" directive allowed XSS. + Thanks to Maxim Boguk. *) Change: the "proxy_store" and "fastcgi_store" directives were changed. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,8 +1,33 @@ +Изменения в nginx 0.6.5 23.07.2007 + + *) Добавление: переменная $nginx_version. + Спасибо Николаю Гречуху. + + *) Добавление: почтовый прокси-сервер поддерживает AUTHENTICATE в + режиме IMAP. + Спасибо Максиму Дунину. + + *) Добавление: почтовый прокси-сервер поддерживает STARTTLS в режиме + SMTP. + Спасибо Максиму Дунину. + + *) Исправление: теперь nginx экранирует пробел в переменной + $memcached_key. + + *) Исправление: nginx неправильно собирался Sun Studio на + Solaris/amd64. + Спасибо Jiang Hong. + + *) Исправление: незначительных потенциальных ошибок. + Спасибо Coverity's Scan. + + Изменения в nginx 0.6.4 17.07.2007 *) Безопасность: при использовании директивы msie_refresh был возможен XSS. + Спасибо Максиму Богуку. *) Изменение: директивы proxy_store и fastcgi_store изменены. diff --git a/auto/cc/sunc b/auto/cc/sunc --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -74,6 +74,7 @@ esac IPO=-xipo CFLAGS="$CFLAGS -fast $IPO" +CORE_LINK="$CORE_LINK -fast $IPO" case $CPU in @@ -128,7 +129,7 @@ case $CPU in # build 64-bit amd64 binary CPU_OPT="$ngx_amd64" CORE_LINK="$CORE_LINK $ngx_amd64" - CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_amd4" + CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_amd64" NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il" NGX_CPU_CACHE_LINE=64 ;; diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf --- a/auto/lib/pcre/conf +++ b/auto/lib/pcre/conf @@ -29,7 +29,7 @@ if [ $PCRE != NONE ]; then ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \ | sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'` - else if [ -f $PCRE/configure.in.h ]; then + else if [ -f $PCRE/configure.in ]; then ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \ | sed -e 's/^.*=\(.*\)$/\1/'` diff --git a/conf/fastcgi_params b/conf/fastcgi_params --- a/conf/fastcgi_params +++ b/conf/fastcgi_params @@ -11,7 +11,7 @@ fastcgi_param DOCUMENT_ROOT $docum fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; -fastcgi_param SERVER_SOFTWARE nginx; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -438,6 +438,9 @@ ngx_set_environment(ngx_cycle_t *cycle, } var = ngx_array_push(&ccf->env); + if (var == NULL) { + return NULL; + } var->len = 2; var->data = (u_char *) "TZ"; diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VERSION "0.6.4" +#define NGINX_VERSION "0.6.5" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -518,6 +518,9 @@ ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_s } ctx->data = data; + + } else { + data = NULL; } for ( ;; ) { @@ -643,8 +646,8 @@ done: ngx_free(buf.data); } - if (ctx->alloc) { - ngx_free(ctx->data); + if (data) { + ngx_free(data); ctx->data = prev; } diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c --- a/src/core/ngx_palloc.c +++ b/src/core/ngx_palloc.c @@ -163,6 +163,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); if (large == NULL) { + ngx_free(p); return NULL; } diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -1059,7 +1059,27 @@ ngx_escape_uri(u_char *dst, u_char *src, 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ }; - static uint32_t *map[] = { uri, args, html, refresh }; + /* " ", %00-%1F */ + + static uint32_t memcached[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0x00000001, /* 0000 0000 0000 0000 0000 0000 0000 0001 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + }; + + static uint32_t *map[] = { uri, args, html, refresh, memcached }; escape = map[type]; diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -150,12 +150,13 @@ size_t ngx_utf_length(u_char *p, size_t u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n); -#define NGX_ESCAPE_URI 0 -#define NGX_ESCAPE_ARGS 1 -#define NGX_ESCAPE_HTML 2 -#define NGX_ESCAPE_REFRESH 3 +#define NGX_ESCAPE_URI 0 +#define NGX_ESCAPE_ARGS 1 +#define NGX_ESCAPE_HTML 2 +#define NGX_ESCAPE_REFRESH 3 +#define NGX_ESCAPE_MEMCACHED 4 -#define NGX_UNESCAPE_URI 1 +#define NGX_UNESCAPE_URI 1 uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type); @@ -164,11 +165,11 @@ void ngx_unescape_uri(u_char **dst, u_ch void ngx_sort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)); -#define ngx_qsort qsort +#define ngx_qsort qsort -#define ngx_value_helper(n) #n -#define ngx_value(n) ngx_value_helper(n) +#define ngx_value_helper(n) #n +#define ngx_value(n) ngx_value_helper(n) #endif /* _NGX_STRING_H_INCLUDED_ */ diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -226,6 +226,7 @@ static ngx_int_t ngx_http_memcached_create_request(ngx_http_request_t *r) { size_t len; + uintptr_t escape; ngx_buf_t *b; ngx_chain_t *cl; ngx_http_memcached_ctx_t *ctx; @@ -242,10 +243,9 @@ ngx_http_memcached_create_request(ngx_ht return NGX_ERROR; } - len = sizeof("get ") - 1 + vv->len + sizeof(CRLF) - 1; - if (vv->len) { - len += 1 + vv->len; - } + escape = 2 * ngx_escape_uri(NULL, vv->data, vv->len, NGX_ESCAPE_MEMCACHED); + + len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1; b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { @@ -268,7 +268,13 @@ ngx_http_memcached_create_request(ngx_ht ctx->key.data = b->last; - b->last = ngx_copy(b->last, vv->data, vv->len); + if (escape == 0) { + b->last = ngx_copy(b->last, vv->data, vv->len); + + } else { + b->last = (u_char *) ngx_escape_uri(b->last, vv->data, vv->len, + NGX_ESCAPE_MEMCACHED); + } ctx->key.len = b->last - ctx->key.data; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -439,6 +439,8 @@ ngx_http_ssi_body_filter(ngx_http_reques if (rc == NGX_ERROR || rc == NGX_AGAIN) { return rc; } + + break; } } diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.6.4'; +our $VERSION = '0.6.5'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -8,6 +8,7 @@ #include #include #include +#include static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, @@ -66,6 +67,8 @@ static ngx_int_t ngx_http_variable_sent_ static ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); /* * TODO: @@ -205,6 +208,9 @@ static ngx_http_variable_t ngx_http_cor offsetof(ngx_http_request_t, limit_rate), NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOCACHABLE, 0 }, + { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version, + 0, 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -1205,6 +1211,20 @@ ngx_http_variable_request_body_file(ngx_ } +static ngx_int_t +ngx_http_variable_nginx_version(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + v->len = sizeof(NGINX_VERSION) - 1; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = (u_char *) NGINX_VERSION; + + return NGX_OK; +} + + ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf) { diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -68,7 +68,6 @@ typedef struct { ngx_array_t listen; /* ngx_mail_listen_t */ } ngx_mail_core_main_conf_t; -typedef void (*ngx_mail_handler_pt)(ngx_connection_t *c); #define NGX_MAIL_POP3_PROTOCOL 0 #define NGX_MAIL_IMAP_PROTOCOL 1 @@ -108,34 +107,6 @@ typedef struct { ngx_array_t imap_capabilities; ngx_array_t smtp_capabilities; - /* - * Handlers: - * - * - handler_init_session - * - * Init new session after client connects. Protocol greetings printed - * from here, so you need to define this if you need custom greeting - * (or pause before greeting printed). - * - * - handler_init_protocol - * - * Initialize protocol-specific data after client sent first command. - * Notably, this is re-called after STARTTLS negotiation. - * - * - handler_read - * - * Read client command. Could be the only handler used by simple - * modules. - * - * NB: handler_read is re-used after auth_http module work (if it was - * called throgh ngx_mail_auth_http_init()) in case of error returned - * by auth server, so you should set this if you use auth_http. - */ - - ngx_mail_handler_pt handler_init_session; - ngx_event_handler_pt handler_init_protocol; - ngx_event_handler_pt handler_read; - /* server ctx */ ngx_mail_conf_ctx_t *ctx; } ngx_mail_core_srv_conf_t; @@ -181,12 +152,8 @@ typedef enum { ngx_smtp_auth_plain, ngx_smtp_auth_cram_md5, ngx_smtp_helo, - ngx_smtp_helo_xclient, - ngx_smtp_helo_from, - ngx_smtp_xclient, - ngx_smtp_xclient_from, - ngx_smtp_from, - ngx_smtp_to + ngx_smtp_noxclient, + ngx_smtp_xclient } ngx_smtp_state_e; @@ -220,7 +187,7 @@ typedef struct { unsigned no_sync_literal:1; unsigned starttls:1; unsigned esmtp:1; - unsigned auth_method:3; + unsigned auth_method:2; unsigned auth_wait:1; ngx_str_t login; @@ -232,8 +199,6 @@ typedef struct { ngx_str_t *addr_text; ngx_str_t smtp_helo; - ngx_str_t smtp_from; - ngx_str_t smtp_to; ngx_uint_t command; ngx_array_t args; @@ -303,14 +268,12 @@ typedef struct { #define NGX_MAIL_AUTH_LOGIN 1 #define NGX_MAIL_AUTH_APOP 2 #define NGX_MAIL_AUTH_CRAM_MD5 3 -#define NGX_MAIL_AUTH_UNAUTH 4 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 #define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004 #define NGX_MAIL_AUTH_APOP_ENABLED 0x0008 #define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010 -#define NGX_MAIL_AUTH_UNAUTH_ENABLED 0x0020 #define NGX_MAIL_PARSE_INVALID_COMMAND 20 @@ -349,15 +312,10 @@ void ngx_smtp_auth_state(ngx_event_t *re void ngx_mail_close_connection(ngx_connection_t *c); void ngx_mail_session_internal_server_error(ngx_mail_session_t *s); -ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s); - ngx_int_t ngx_pop3_parse_command(ngx_mail_session_t *s); ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s); ngx_int_t ngx_smtp_parse_command(ngx_mail_session_t *s); -#if (NGX_MAIL_SSL) -void ngx_mail_starttls_handler(ngx_event_t *rev); -#endif /* STUB */ void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_peer_addr_t *peer); diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -304,7 +304,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t ngx_mail_core_srv_conf_t *prev = parent; ngx_mail_core_srv_conf_t *conf = child; - u_char *p, *auth_p, *last_p; + u_char *p, *auth, *last; size_t size, stls_only_size; ngx_str_t *c, *d; ngx_uint_t i, m, smtp_auth_enabled; @@ -518,7 +518,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t p = ngx_cpymem(p, c[i].data, c[i].len); } - auth_p = p; + auth = p; for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; @@ -550,8 +550,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *p++ = CR; *p = LF; - size = (auth_p - conf->imap_capability.data) + sizeof(CRLF) - 1 - + sizeof(" STARTTLS LOGINDISABLED") - 1; + size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 + + sizeof(" STARTTLS LOGINDISABLED") - 1; p = ngx_palloc(cf->pool, size); if (p == NULL) { @@ -562,7 +562,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t conf->imap_starttls_only_capability.data = p; p = ngx_cpymem(p, conf->imap_capability.data, - auth_p - conf->imap_capability.data); + auth - conf->imap_capability.data); p = ngx_cpymem(p, " STARTTLS LOGINDISABLED", sizeof(" STARTTLS LOGINDISABLED") - 1); *p++ = CR; *p = LF; @@ -632,22 +632,22 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t conf->smtp_capability.len = size; conf->smtp_capability.data = p; - last_p = p; + last = p; *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len); *p++ = CR; *p++ = LF; for (i = 0; i < conf->smtp_capabilities.nelts; i++) { - last_p = p; + last = p; *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; p = ngx_cpymem(p, c[i].data, c[i].len); *p++ = CR; *p++ = LF; } - auth_p = p; + auth = p; if (smtp_auth_enabled) { - last_p = p; + last = p; *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' '; *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H'; @@ -666,7 +666,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *p++ = CR; *p = LF; } else { - last_p[3] = ' '; + last[3] = ' '; } size += sizeof("250 STARTTLS" CRLF) - 1; @@ -686,10 +686,10 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *p++ = CR; *p = LF; p = conf->smtp_starttls_capability.data - + (last_p - conf->smtp_capability.data) + 3; + + (last - conf->smtp_capability.data) + 3; *p = '-'; - size = (auth_p - conf->smtp_capability.data) + size = (auth - conf->smtp_capability.data) + sizeof("250 STARTTLS" CRLF) - 1; p = ngx_palloc(cf->pool, size); @@ -701,13 +701,13 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t conf->smtp_starttls_only_capability.data = p; p = ngx_cpymem(p, conf->smtp_capability.data, - auth_p - conf->smtp_capability.data); + auth - conf->smtp_capability.data); p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - if (last_p < auth_p) { + if (last < auth) { p = conf->smtp_starttls_only_capability.data - + (last_p - conf->smtp_capability.data) + 3; + + (last - conf->smtp_capability.data) + 3; *p = '-'; } diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -1408,7 +1408,6 @@ ngx_imap_auth_state(ngx_event_t *rev) ngx_mail_do_auth(s); return; - } } else if (rc == NGX_IMAP_NEXT) { @@ -1464,6 +1463,7 @@ ngx_imap_auth_state(ngx_event_t *rev) s->arg_start = s->buffer->start + s->tag.len; s->buffer->pos = s->arg_start; s->buffer->last = s->arg_start; + } else { s->buffer->pos = s->buffer->start; s->buffer->last = s->buffer->start; @@ -1851,8 +1851,8 @@ ngx_smtp_auth_state(ngx_event_t *rev) c->read->handler = ngx_mail_starttls_handler; /* - * RFC3207 requires us to discard any knowledge obtained - * from client before STARTTLS. + * RFC3207 requires us to discard any knowledge + * obtained from client before STARTTLS. */ s->smtp_helo.len = 0; diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -686,7 +686,6 @@ ngx_int_t ngx_smtp_parse_command(ngx_mai } else { goto invalid; } - #if (NGX_MAIL_SSL) } else if (p - c == 8) { @@ -705,7 +704,6 @@ ngx_int_t ngx_smtp_parse_command(ngx_mai goto invalid; } #endif - } else { goto invalid; }