summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-10-25 16:29:03 +0000
committerJonathan Kolb <jon@b0g.us>2006-10-25 16:29:03 +0000
commitf93a68b72b7aecd45263df647c742e36399a145e (patch)
tree2656b720c8f7742320a3c7d1f1f70bdf08219f30
parent4b3695ff841d6e09a302cfd58887e62b4aed557d (diff)
downloadnginx-f93a68b72b7aecd45263df647c742e36399a145e.tar.gz
Changes with nginx 0.4.11 25 Oct 2006v0.4.11
*) Feature: the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5. *) Feature: the ngx_http_perl_module supports the $r->allow_ranges method. *) Bugfix: if the APOP was enabledi in the POP3 proxy, then the USER/PASS commands might not work; bug appeared in 0.4.10.
-rw-r--r--CHANGES11
-rw-r--r--CHANGES.ru11
-rw-r--r--auto/sources2
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_core.h3
-rw-r--r--src/core/ngx_inet.c316
-rw-r--r--src/core/ngx_inet.h68
-rw-r--r--src/core/ngx_unix_domain.c79
-rw-r--r--src/core/ngx_unix_domain.h29
-rw-r--r--src/http/modules/ngx_http_index_module.c10
-rw-r--r--src/http/modules/ngx_http_memcached_module.c17
-rw-r--r--src/http/modules/ngx_http_proxy_module.c26
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs13
-rw-r--r--src/http/ngx_http_core_module.c59
-rw-r--r--src/imap/ngx_imap.h35
-rw-r--r--src/imap/ngx_imap_auth_http_module.c68
-rw-r--r--src/imap/ngx_imap_core_module.c99
-rw-r--r--src/imap/ngx_imap_handler.c290
-rw-r--r--src/imap/ngx_imap_parse.c8
20 files changed, 519 insertions, 629 deletions
diff --git a/CHANGES b/CHANGES
index 997aad537..1cd55cc2b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,15 @@
+Changes with nginx 0.4.11 25 Oct 2006
+
+ *) Feature: the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5.
+
+ *) Feature: the ngx_http_perl_module supports the $r->allow_ranges
+ method.
+
+ *) Bugfix: if the APOP was enabledi in the POP3 proxy, then the
+ USER/PASS commands might not work; bug appeared in 0.4.10.
+
+
Changes with nginx 0.4.10 23 Oct 2006
*) Feature: the IMAP/POP3 proxy supports the APOP command.
diff --git a/CHANGES.ru b/CHANGES.ru
index 598db7a78..4a79103d0 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,15 @@
+Изменения в nginx 0.4.11 25.10.2006
+
+ *) Добавление: POP3 прокси поддерживает AUTH LOIGN PLAIN и CRAM-MD5.
+
+ *) Добавление: модуль ngx_http_perl_module поддерживает метод
+ $r->allow_ranges.
+
+ *) Исправление: при включённой поддержке команды APOP в POP3 прокси
+ могли не работать команды USER/PASS; ошибка появилась в 0.4.10.
+
+
Изменения в nginx 0.4.10 23.10.2006
*) Добавление: IMAP/POP3 прокси поддерживает APOP.
diff --git a/auto/sources b/auto/sources
index c031ef8e1..253d947c5 100644
--- a/auto/sources
+++ b/auto/sources
@@ -120,7 +120,6 @@ AIO_SRCS="src/event/modules/ngx_aio_module.c \
UNIX_INCS="$CORE_INCS $EVENT_INCS src/os/unix"
UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
- src/core/ngx_unix_domain.h \
src/os/unix/ngx_time.h \
src/os/unix/ngx_types.h \
src/os/unix/ngx_errno.h \
@@ -149,7 +148,6 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
- src/core/ngx_unix_domain.c \
src/os/unix/ngx_time.c \
src/os/unix/ngx_errno.c \
src/os/unix/ngx_alloc.c \
diff --git a/src/core/nginx.h b/src/core/nginx.h
index e8d79cb87..c151098a4 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.4.10"
+#define NGINX_VERSION "0.4.11"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 0a82d8b2a..7c1fbbdff 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -68,9 +68,6 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#include <ngx_event_openssl.h>
#endif
#include <ngx_inet.h>
-#if (NGX_HAVE_UNIX_DOMAIN)
-#include <ngx_unix_domain.h>
-#endif
#include <ngx_cycle.h>
#include <ngx_process_cycle.h>
#include <ngx_conf_file.h>
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index cf4b8f699..6b2c2721f 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -223,10 +223,11 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
ngx_int_t
ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
{
- u_char *p;
+ u_char *p, *host;
size_t len;
ngx_int_t port;
ngx_uint_t i;
+ struct hostent *h;
#if (NGX_HAVE_UNIX_DOMAIN)
struct sockaddr_un *saun;
#endif
@@ -390,6 +391,47 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
port:
if (u->listen) {
+ if (u->portn == 0) {
+ if (u->default_portn == 0) {
+ u->err = "no port";
+ return NGX_ERROR;
+ }
+
+ u->portn = u->default_portn;
+ }
+
+ if (u->host.len == 1 && u->host.data[0] == '*') {
+ u->host.len = 0;
+ }
+
+ /* AF_INET only */
+
+ if (u->host.len) {
+
+ host = ngx_palloc(cf->temp_pool, u->host.len + 1);
+ if (host == NULL) {
+ return NGX_ERROR;
+ }
+
+ (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
+
+ u->addr.in_addr = inet_addr((const char *) host);
+
+ if (u->addr.in_addr == INADDR_NONE) {
+ h = gethostbyname((const char *) host);
+
+ if (h == NULL || h->h_addr_list[0] == NULL) {
+ u->err = "host not found";
+ return NGX_ERROR;
+ }
+
+ u->addr.in_addr = *(in_addr_t *)(h->h_addr_list[0]);
+ }
+
+ } else {
+ u->addr.in_addr = INADDR_ANY;
+ }
+
return NGX_OK;
}
@@ -558,275 +600,3 @@ ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port)
return peers;
}
-
-
-ngx_peers_t *
-ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
-{
- char *err;
- u_char *host;
- size_t len;
- in_addr_t in_addr;
- ngx_uint_t i;
- ngx_peers_t *peers;
- struct hostent *h;
- struct sockaddr_in *sin;
-
- err = ngx_inet_parse_host_port(u);
-
- if (err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in upstream \"%V\"", err, &u->name);
- return NULL;
- }
-
- if (u->default_port) {
-
- if (u->default_port_value == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no port in upstream \"%V\"", &u->name);
- return NULL;
- }
-
- u->port = u->default_port_value;
-
- u->port_text.data = ngx_palloc(cf->pool, sizeof("65536") - 1);
- if (u->port_text.data == NULL) {
- return NULL;
- }
-
- u->port_text.len = ngx_sprintf(u->port_text.data, "%d",
- u->default_port_value)
- - u->port_text.data;
-
- } else if (u->port) {
- if (u->port == u->default_port_value) {
- u->default_port = 1;
- }
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no port in upstream \"%V\"", &u->name);
- return NULL;
- }
-
- if (u->host.len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no host in upstream \"%V\"", &u->name);
- return NULL;
- }
-
- u->port = htons(u->port);
-
- host = ngx_palloc(cf->temp_pool, u->host.len + 1);
- if (host == NULL) {
- return NULL;
- }
-
- (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
-
- /* AF_INET only */
-
- in_addr = inet_addr((char *) host);
-
- if (in_addr == INADDR_NONE) {
- h = gethostbyname((char *) host);
-
- if (h == NULL || h->h_addr_list[0] == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "host %s is not found in upstream \"%V\"",
- host, &u->name);
- return NULL;
- }
-
- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
-
- /* MP: ngx_shared_palloc() */
-
- peers = ngx_pcalloc(cf->pool,
- sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
- if (peers == NULL) {
- return NULL;
- }
-
- peers->number = i;
-
- for (i = 0; h->h_addr_list[i] != NULL; i++) {
-
- sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NULL;
- }
-
- sin->sin_family = AF_INET;
- sin->sin_port = u->port;
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
-
- peers->peer[i].sockaddr = (struct sockaddr *) sin;
- peers->peer[i].socklen = sizeof(struct sockaddr_in);
-
- len = INET_ADDRSTRLEN - 1 + 1 + u->port_text.len;
-
- peers->peer[i].name.data = ngx_palloc(cf->pool, len);
- if (peers->peer[i].name.data == NULL) {
- return NULL;
- }
-
- len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
- peers->peer[i].name.data, len);
-
- peers->peer[i].name.data[len++] = ':';
-
- ngx_memcpy(peers->peer[i].name.data + len,
- u->port_text.data, u->port_text.len);
-
- peers->peer[i].name.len = len + u->port_text.len;
-
- peers->peer[i].uri_separator = "";
-
- peers->peer[i].weight = NGX_CONF_UNSET_UINT;
- peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
- peers->peer[i].fail_timeout = NGX_CONF_UNSET;
- }
-
- } else {
-
- /* MP: ngx_shared_palloc() */
-
- peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
- if (peers == NULL) {
- return NULL;
- }
-
- sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NULL;
- }
-
- peers->number = 1;
-
- sin->sin_family = AF_INET;
- sin->sin_port = u->port;
- sin->sin_addr.s_addr = in_addr;
-
- peers->peer[0].sockaddr = (struct sockaddr *) sin;
- peers->peer[0].socklen = sizeof(struct sockaddr_in);
-
- len = u->host.len + 1 + u->port_text.len;
-
- peers->peer[0].name.len = len;
-
- peers->peer[0].name.data = ngx_palloc(cf->pool, len);
- if (peers->peer[0].name.data == NULL) {
- return NULL;
- }
-
- len = u->host.len;
-
- ngx_memcpy(peers->peer[0].name.data, u->host.data, len);
-
- peers->peer[0].name.data[len++] = ':';
-
- ngx_memcpy(peers->peer[0].name.data + len,
- u->port_text.data, u->port_text.len);
-
- peers->peer[0].uri_separator = "";
- }
-
- return peers;
-}
-
-
-char *
-ngx_inet_parse_host_port(ngx_inet_upstream_t *u)
-{
- size_t i;
- ngx_int_t port;
- ngx_str_t *url;
-
- url = &u->url;
-
- if (u->port_only) {
- i = 0;
-
- } else {
- if (url->data[0] == ':' || url->data[0] == '/') {
- return "invalid host";
- }
-
- i = 1;
- }
-
- u->host.data = url->data;
- u->host_header = *url;
-
- for ( /* void */ ; i < url->len; i++) {
-
- if (url->data[i] == ':') {
- u->port_text.data = &url->data[i] + 1;
- u->host.len = i;
-
- if (!u->uri_part) {
- u->port_text.len = &url->data[url->len] - u->port_text.data;
- break;
- }
- }
-
- if (url->data[i] == '/') {
- u->uri.data = &url->data[i];
- u->uri.len = url->len - i;
- u->host_header.len = i;
-
- if (u->host.len == 0) {
- u->host.len = i;
- }
-
- if (u->port_text.data == NULL) {
- u->default_port = 1;
- return NULL;
- }
-
- u->port_text.len = &url->data[i] - u->port_text.data;
-
- if (u->port_text.len == 0) {
- return "invalid port";
- }
-
- break;
- }
- }
-
- if (u->port_text.data) {
-
- if (u->port_text.len == 0) {
- u->port_text.len = &url->data[i] - u->port_text.data;
-
- if (u->port_text.len == 0) {
- return "invalid port";
- }
- }
-
- port = ngx_atoi(u->port_text.data, u->port_text.len);
-
- if (port == NGX_ERROR || port < 1 || port > 65536) {
- return "invalid port";
- }
-
- } else {
- port = ngx_atoi(url->data, url->len);
-
- if (port == NGX_ERROR) {
- u->default_port = 1;
- u->host.len = url->len;
-
- return NULL;
- }
-
- u->port_text = *url;
- u->wildcard = 1;
- }
-
- u->port = (in_port_t) port;
-
- return NULL;
-}
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
index 301402382..1cec748c0 100644
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -17,8 +17,8 @@
typedef struct {
- in_addr_t addr;
- in_addr_t mask;
+ in_addr_t addr;
+ in_addr_t mask;
} ngx_inet_cidr_t;
@@ -57,62 +57,44 @@ struct ngx_peers_s {
};
-typedef struct {
- ngx_int_t type;
-
- ngx_peers_t *peers;
-
- ngx_str_t url;
- ngx_str_t host;
- ngx_str_t host_header;
- ngx_str_t port;
- ngx_str_t uri;
+typedef union {
+ in_addr_t in_addr;
+} ngx_url_addr_t;
- in_port_t portn;
- in_port_t default_portn;
- unsigned listen:1;
- unsigned uri_part:1;
- unsigned upstream:1;
-
- unsigned default_port:1;
- unsigned wildcard:1;
+typedef struct {
+ ngx_int_t type;
- char *err;
-} ngx_url_t;
+ ngx_peers_t *peers;
+ ngx_str_t url;
+ ngx_str_t host;
+ ngx_str_t host_header;
+ ngx_str_t port;
+ ngx_str_t uri;
-typedef struct {
- ngx_str_t name; /* "schema:host:port/uri" */
- ngx_str_t url; /* "host:port/uri" */
- ngx_str_t host;
- ngx_str_t uri;
- ngx_str_t host_header; /* "host:port" */
- ngx_str_t port_text; /* "port" */
+ in_port_t portn;
+ in_port_t default_portn;
- in_port_t port;
+ unsigned listen:1;
+ unsigned uri_part:1;
+ unsigned upstream:1;
- in_port_t default_port_value;
+ unsigned default_port:1;
+ unsigned wildcard:1;
- unsigned default_port:1;
- unsigned wildcard:1;
+ ngx_url_addr_t addr;
- unsigned uri_part:1;
- unsigned port_only:1;
-} ngx_inet_upstream_t;
+ char *err;
+} ngx_url_t;
-size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text,
- size_t len);
+size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
-
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
-
-ngx_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u);
+ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name,
in_port_t port);
-char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u);
-ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
#endif /* _NGX_INET_H_INCLUDED_ */
diff --git a/src/core/ngx_unix_domain.c b/src/core/ngx_unix_domain.c
deleted file mode 100644
index 12ffaecdb..000000000
--- a/src/core/ngx_unix_domain.c
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-
-
-/* Solaris has predefined "#define sun 1" */
-#undef sun
-
-
-ngx_peers_t *
-ngx_unix_upstream_parse(ngx_conf_t *cf, ngx_unix_domain_upstream_t *u)
-{
- size_t len;
- ngx_uint_t i;
- ngx_peers_t *peers;
- struct sockaddr_un *sun;
-
- len = u->url.len - 5;
-
- if (u->uri_part) {
- for (i = 5; i < u->url.len; i++) {
- if (u->url.data[i] == ':') {
- len = i - 5;
- u->uri.len = u->url.len - 5 - len - 1;
- u->uri.data = u->url.data + 5 + len + 1;
-
- break;
- }
- }
- }
-
- if (len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the unix domain socket \"%V\" has no path",
- &u->name);
- return NULL;
- }
-
- if (len + 1 > sizeof(sun->sun_path)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the unix domain socket path \"%V\" is too long",
- &u->name);
- return NULL;
- }
-
- /* MP: ngx_shared_palloc() */
-
- peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
- if (peers == NULL) {
- return NULL;
- }
-
- sun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un));
- if (sun == NULL) {
- return NULL;
- }
-
- peers->number = 1;
-
- sun->sun_family = AF_UNIX;
- (void) ngx_cpystrn((u_char *) sun->sun_path, u->url.data + 5, len + 1);
-
- peers->peer[0].sockaddr = (struct sockaddr *) sun;
- peers->peer[0].socklen = sizeof(struct sockaddr_un);
-
- peers->peer[0].name.len = 5 + len;
- peers->peer[0].name.data = u->url.data;
-
- peers->peer[0].uri_separator = ":";
-
- return peers;
-}
diff --git a/src/core/ngx_unix_domain.h b/src/core/ngx_unix_domain.h
deleted file mode 100644
index 2c1de83b0..000000000
--- a/src/core/ngx_unix_domain.h
+++ /dev/null
@@ -1,29 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#ifndef _NGX_UNIX_DOMAIN_H_INCLUDED_
-#define _NGX_UNIX_DOMAIN_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- ngx_str_t name; /* "schema:unix:path:/uri" */
- ngx_str_t url; /* "unix:path:/uri" */
- ngx_str_t uri;
-
- ngx_uint_t uri_part; /* unsigned uri_part:1; */
-} ngx_unix_domain_upstream_t;
-
-
-ngx_peers_t *ngx_unix_upstream_parse(ngx_conf_t *cf,
- ngx_unix_domain_upstream_t *u);
-
-
-#endif /* _NGX_UNIX_DOMAIN_H_INCLUDED_ */
-
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 3af802663..4df57f9ce 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -315,10 +315,14 @@ ngx_http_index_handler(ngx_http_request_t *r)
static ngx_int_t
ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
{
+ u_char c;
+ ngx_uint_t i;
ngx_err_t err;
ngx_file_info_t fi;
- *(ctx->index.data - 1) = '\0';
+ c = *(ctx->index.data - 1);
+ i = (c == '/') ? 1 : 0;
+ *(ctx->index.data - i) = '\0';
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http index check dir: \"%s\"", ctx->path.data);
@@ -328,7 +332,7 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
err = ngx_errno;
if (err == NGX_ENOENT) {
- *(ctx->index.data - 1) = '/';
+ *(ctx->index.data - i) = c;
return ngx_http_index_error(r, ctx, err);
}
@@ -338,7 +342,7 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- *(ctx->index.data - 1) = '/';
+ *(ctx->index.data - i) = c;
if (ngx_is_dir(&fi)) {
return NGX_OK;
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index bb5ab5d0a..63bda6498 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -590,7 +590,7 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_memcached_loc_conf_t *lcf = conf;
ngx_str_t *value;
- ngx_inet_upstream_t inet_upstream;
+ ngx_url_t u;
ngx_http_core_loc_conf_t *clcf;
if (lcf->upstream.schema.len) {
@@ -599,16 +599,19 @@ ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
+ ngx_memzero(&u, sizeof(ngx_url_t));
- inet_upstream.name = value[1];
- inet_upstream.url = value[1];
+ u.url = value[1];
+ u.uri_part = 1;
- lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
- if (lcf->peers == NULL) {
- return NGX_CONF_ERROR;
+ if (ngx_parse_url(cf, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in \"%V\"", u.err, &u.url);
+ }
}
+ lcf->peers = u.peers;
lcf->upstream.schema.len = sizeof("memcached://") - 1;
lcf->upstream.schema.data = (u_char *) "memcached://";
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index f85454968..a9df3d735 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2105,32 +2105,6 @@ peers:
return NGX_CONF_ERROR;
}
-
-#if 0
- conf->headers_set_hash = ngx_pcalloc(cf->pool, sizeof(ngx_hash0_t));
- if (conf->headers_set_hash == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->headers_set_hash->max_size = 100;
- conf->headers_set_hash->bucket_limit = 1;
- conf->headers_set_hash->bucket_size = sizeof(ngx_str_t);
- conf->headers_set_hash->name = "proxy_headers";
-
- if (ngx_hash0_init(conf->headers_set_hash, cf->pool,
- conf->headers_names->elts, conf->headers_names->nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "proxy_headers hash size: %ui, "
- "max buckets per entry: %ui",
- conf->headers_set_hash->hash_size,
- conf->headers_set_hash->min_buckets);
-#endif
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index b6189c6eb..5f329493b 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -17,7 +17,7 @@ our @EXPORT = qw(
HTTP_SERVER_ERROR
);
-our $VERSION = '0.4.10';
+our $VERSION = '0.4.11';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index f65bbf093..d337edbd8 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -719,6 +719,19 @@ internal_redirect(r, uri)
void
+allow_ranges(r)
+ CODE:
+
+ ngx_http_request_t *r;
+
+ ngx_http_perl_set_request(r);
+
+ r->allow_ranges = 1;
+
+ XSRETURN_EMPTY;
+
+
+void
unescape(r, text, type = 0)
CODE:
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index f70c98879..adc751ee6 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2371,12 +2371,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_srv_conf_t *scf = conf;
- char *err;
- ngx_str_t *value, size;
- ngx_uint_t n;
- struct hostent *h;
- ngx_http_listen_t *ls;
- ngx_inet_upstream_t inet_upstream;
+ ngx_str_t *value, size;
+ ngx_url_t u;
+ ngx_uint_t n;
+ ngx_http_listen_t *ls;
/*
* TODO: check duplicate 'listen' directives,
@@ -2385,17 +2383,19 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
+ ngx_memzero(&u, sizeof(ngx_url_t));
- inet_upstream.url = value[1];
- inet_upstream.port_only = 1;
+ u.url = value[1];
+ u.listen = 1;
+ u.default_portn = 80;
- err = ngx_inet_parse_host_port(&inet_upstream);
+ if (ngx_parse_url(cf, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in \"%V\" of the \"listen\" directive",
+ u.err, &u.url);
+ }
- if (err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in \"%V\" of the \"listen\" directive",
- err, &inet_upstream.url);
return NGX_CONF_ERROR;
}
@@ -2407,41 +2407,14 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(ls, sizeof(ngx_http_listen_t));
ls->family = AF_INET;
- ls->port = (in_port_t) (inet_upstream.default_port ?
- 80 : inet_upstream.port);
+ ls->addr = u.addr.in_addr;
+ ls->port = u.portn;
ls->file_name = cf->conf_file->file.name;
ls->line = cf->conf_file->line;
ls->conf.backlog = -1;
ls->conf.rcvbuf = -1;
ls->conf.sndbuf = -1;
- if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') {
- inet_upstream.host.len = 0;
- }
-
- if (inet_upstream.host.len) {
- inet_upstream.host.data[inet_upstream.host.len] = '\0';
-
- ls->addr = inet_addr((const char *) inet_upstream.host.data);
-
- if (ls->addr == INADDR_NONE) {
- h = gethostbyname((const char *) inet_upstream.host.data);
-
- if (h == NULL || h->h_addr_list[0] == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "can not resolve host \"%s\" "
- "in the \"listen\" directive",
- inet_upstream.host.data);
- return NGX_CONF_ERROR;
- }
-
- ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
- }
-
- } else {
- ls->addr = INADDR_ANY;
- }
-
n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, INET_ADDRSTRLEN + 6);
ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
diff --git a/src/imap/ngx_imap.h b/src/imap/ngx_imap.h
index 2c24b5cf0..b7b62a5cb 100644
--- a/src/imap/ngx_imap.h
+++ b/src/imap/ngx_imap.h
@@ -83,6 +83,8 @@ typedef struct {
ngx_str_t pop3_capability;
ngx_str_t pop3_starttls_capability;
+ ngx_str_t pop3_auth_capability;
+
ngx_str_t imap_capability;
ngx_str_t imap_starttls_capability;
ngx_str_t imap_starttls_only_capability;
@@ -120,7 +122,11 @@ typedef enum {
typedef enum {
ngx_pop3_start = 0,
ngx_pop3_user,
- ngx_pop3_passwd
+ ngx_pop3_passwd,
+ ngx_pop3_auth_login_username,
+ ngx_pop3_auth_login_password,
+ ngx_pop3_auth_plain,
+ ngx_pop3_auth_cram_md5
} ngx_po3_state_e;
@@ -153,7 +159,7 @@ typedef struct {
unsigned backslash:1;
unsigned no_sync_literal:1;
unsigned starttls:1;
- unsigned auth_method:1;
+ unsigned auth_method:2;
ngx_str_t login;
ngx_str_t passwd;
@@ -192,13 +198,14 @@ typedef struct {
#define NGX_POP3_NOOP 5
#define NGX_POP3_STLS 6
#define NGX_POP3_APOP 7
-#define NGX_POP3_STAT 8
-#define NGX_POP3_LIST 9
-#define NGX_POP3_RETR 10
-#define NGX_POP3_DELE 11
-#define NGX_POP3_RSET 12
-#define NGX_POP3_TOP 13
-#define NGX_POP3_UIDL 14
+#define NGX_POP3_AUTH 8
+#define NGX_POP3_STAT 9
+#define NGX_POP3_LIST 10
+#define NGX_POP3_RETR 11
+#define NGX_POP3_DELE 12
+#define NGX_POP3_RSET 13
+#define NGX_POP3_TOP 14
+#define NGX_POP3_UIDL 15
#define NGX_IMAP_LOGIN 1
@@ -210,12 +217,14 @@ typedef struct {
#define NGX_IMAP_NEXT 6
-#define NGX_IMAP_AUTH_PLAIN 0
-#define NGX_IMAP_AUTH_APOP 1
+#define NGX_IMAP_AUTH_PLAIN 0
+#define NGX_IMAP_AUTH_APOP 1
+#define NGX_IMAP_AUTH_CRAM_MD5 2
-#define NGX_IMAP_AUTH_PLAIN_ENABLED 0x0002
-#define NGX_IMAP_AUTH_APOP_ENABLED 0x0004
+#define NGX_IMAP_AUTH_PLAIN_ENABLED 0x0002
+#define NGX_IMAP_AUTH_APOP_ENABLED 0x0004
+#define NGX_IMAP_AUTH_CRAM_MD5_ENABLED 0x0008
#define NGX_IMAP_PARSE_INVALID_COMMAND 20
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c
index fd9bb5352..85728f46a 100644
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -133,7 +133,9 @@ ngx_module_t ngx_imap_auth_http_module = {
static char *ngx_imap_auth_http_protocol[] = { "pop3", "imap" };
static ngx_str_t ngx_imap_auth_http_method[] = {
- ngx_string("plain"), ngx_string("apop")
+ ngx_string("plain"),
+ ngx_string("apop"),
+ ngx_string("cram-md5")
};
@@ -1078,7 +1080,7 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
b->last = ngx_copy(b->last, passwd.data, passwd.len);
*b->last++ = CR; *b->last++ = LF;
- if (s->salt.len) {
+ if (s->auth_method != NGX_IMAP_AUTH_PLAIN && s->salt.len) {
b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
@@ -1247,61 +1249,29 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_imap_auth_http_conf_t *ahcf = conf;
- ngx_str_t *value, *url;
- ngx_inet_upstream_t inet_upstream;
-#if (NGX_HAVE_UNIX_DOMAIN)
- ngx_unix_domain_upstream_t unix_upstream;
-#endif
+ ngx_str_t *value;
+ ngx_url_t u;
value = cf->args->elts;
- url = &value[1];
-
- if (ngx_strncasecmp(url->data, "unix:", 5) == 0) {
-
-#if (NGX_HAVE_UNIX_DOMAIN)
+ ngx_memzero(&u, sizeof(ngx_url_t));
- ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t));
+ u.url = value[1];
+ u.default_portn = 80;
+ u.uri_part = 1;
- unix_upstream.name = *url;
- unix_upstream.url = *url;
- unix_upstream.uri_part = 1;
-
- ahcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream);
- if (ahcf->peers == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ahcf->host_header.len = sizeof("localhost") - 1;
- ahcf->host_header.data = (u_char *) "localhost";
- ahcf->uri = unix_upstream.uri;
-
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the unix domain sockets are not supported "
- "on this platform");
- return NGX_CONF_ERROR;
-
-#endif
-
- } else {
- ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
-
- inet_upstream.name = *url;
- inet_upstream.url = *url;
- inet_upstream.default_port_value = 80;
- inet_upstream.uri_part = 1;
-
- ahcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream);
- if (ahcf->peers == NULL) {
- return NGX_CONF_ERROR;
+ if (ngx_parse_url(cf, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in auth_http \"%V\"", u.err, &u.url);
}
+ }
- ahcf->peers->number = 1;
+ ahcf->peers = u.peers;
+ ahcf->peers->number = 1;
- ahcf->host_header = inet_upstream.host_header;
- ahcf->uri = inet_upstream.uri;
- }
+ ahcf->host_header = u.host_header;
+ ahcf->uri = u.uri;
if (ahcf->uri.len == 0) {
ahcf->uri.len = sizeof("/") - 1;
diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c
index 3ae370a5d..3cd3991ba 100644
--- a/src/imap/ngx_imap_core_module.c
+++ b/src/imap/ngx_imap_core_module.c
@@ -48,10 +48,27 @@ static ngx_str_t ngx_imap_default_capabilities[] = {
static ngx_conf_bitmask_t ngx_imap_auth_methods[] = {
{ ngx_string("plain"), NGX_IMAP_AUTH_PLAIN_ENABLED },
{ ngx_string("apop"), NGX_IMAP_AUTH_APOP_ENABLED },
+ { ngx_string("cram-md5"), NGX_IMAP_AUTH_CRAM_MD5_ENABLED },
{ ngx_null_string, 0 }
};
+static ngx_str_t ngx_pop3_auth_plain_capability =
+ ngx_string("+OK methods supported:" CRLF
+ "LOGIN" CRLF
+ "PLAIN" CRLF
+ "." CRLF);
+
+
+static ngx_str_t ngx_pop3_auth_cram_md5_capability =
+ ngx_string("+OK methods supported:" CRLF
+ "LOGIN" CRLF
+ "PLAIN" CRLF
+ "CRAM-MD5" CRLF
+ "." CRLF);
+
+
+
static ngx_command_t ngx_imap_core_commands[] = {
{ ngx_string("server"),
@@ -279,6 +296,13 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
size += c[i].len + sizeof(CRLF) - 1;
}
+ if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
+ size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
+
+ } else {
+ size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
+ }
+
p = ngx_palloc(cf->pool, size);
if (p == NULL) {
return NGX_CONF_ERROR;
@@ -295,6 +319,15 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
*p++ = CR; *p++ = LF;
}
+ if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
+ p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
+ sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
+
+ } else {
+ p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
+ sizeof("SASL LOGIN PLAIN" CRLF) - 1);
+ }
+
*p++ = '.'; *p++ = CR; *p = LF;
@@ -315,6 +348,14 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
*p++ = '.'; *p++ = CR; *p = LF;
+ if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
+ conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability;
+
+ } else {
+ conf->pop3_auth_capability = ngx_pop3_auth_plain_capability;
+ }
+
+
if (conf->imap_capabilities.nelts == 0) {
conf->imap_capabilities = prev->imap_capabilities;
}
@@ -471,56 +512,27 @@ ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- char *err;
ngx_str_t *value;
- in_addr_t in_addr;
+ ngx_url_t u;
ngx_uint_t i;
- struct hostent *h;
ngx_imap_listen_t *imls;
- ngx_inet_upstream_t inet_upstream;
ngx_imap_core_main_conf_t *cmcf;
value = cf->args->elts;
- ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
-
- inet_upstream.url = value[1];
- inet_upstream.port_only = 1;
-
- err = ngx_inet_parse_host_port(&inet_upstream);
-
- if (err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in \"%V\" of the \"listen\" directive",
- err, &inet_upstream.url);
- return NGX_CONF_ERROR;
- }
-
- if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') {
- inet_upstream.host.len = 0;
- }
-
- if (inet_upstream.host.len) {
- inet_upstream.host.data[inet_upstream.host.len] = '\0';
-
- in_addr = inet_addr((const char *) inet_upstream.host.data);
-
- if (in_addr == INADDR_NONE) {
- h = gethostbyname((const char *) inet_upstream.host.data);
+ ngx_memzero(&u, sizeof(ngx_url_t));
- if (h == NULL || h->h_addr_list[0] == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "can not resolve host \"%s\" "
- "in the \"listen\" directive",
- inet_upstream.host.data);
- return NGX_CONF_ERROR;
- }
+ u.url = value[1];
+ u.listen = 1;
- in_addr = *(in_addr_t *)(h->h_addr_list[0]);
+ if (ngx_parse_url(cf, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in \"%V\" of the \"listen\" directive",
+ u.err, &u.url);
}
- } else {
- in_addr = INADDR_ANY;
+ return NGX_CONF_ERROR;
}
cmcf = ngx_imap_conf_get_module_main_conf(cf, ngx_imap_core_module);
@@ -529,13 +541,12 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (i = 0; i < cmcf->listen.nelts; i++) {
- if (imls[i].addr != in_addr || imls[i].port != inet_upstream.port) {
+ if (imls[i].addr != u.addr.in_addr || imls[i].port != u.portn) {
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"%V\" address and port pair",
- &inet_upstream.url);
+ "duplicate \"%V\" address and port pair", &u.url);
return NGX_CONF_ERROR;
}
@@ -546,8 +557,8 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_memzero(imls, sizeof(ngx_imap_listen_t));
- imls->addr = in_addr;
- imls->port = inet_upstream.port;
+ imls->addr = u.addr.in_addr;
+ imls->port = u.portn;
imls->family = AF_INET;
imls->ctx = cf->ctx;
diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c
index bb92b36df..26513940b 100644
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -32,6 +32,9 @@ static ngx_str_t internal_server_errors[] = {
};
static u_char pop3_ok[] = "+OK" CRLF;
+static u_char pop3_next[] = "+ " CRLF;
+static u_char pop3_username[] = "+ VXNlcm5hbWU6" CRLF;
+static u_char pop3_password[] = "+ UGFzc3dvcmQ6" CRLF;
static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF;
static u_char imap_star[] = "* ";
@@ -547,11 +550,9 @@ ngx_imap_auth_state(ngx_event_t *rev)
ngx_imap_auth_http_init(s);
return;
-
- } else {
- rc = NGX_IMAP_PARSE_INVALID_COMMAND;
}
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
break;
case NGX_IMAP_CAPABILITY:
@@ -666,10 +667,10 @@ ngx_imap_auth_state(ngx_event_t *rev)
void
ngx_pop3_auth_state(ngx_event_t *rev)
{
- u_char *text;
+ u_char *text, *p, *last;
ssize_t size;
ngx_int_t rc;
- ngx_str_t *arg;
+ ngx_str_t *arg, salt, plain;
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_core_srv_conf_t *cscf;
@@ -730,10 +731,10 @@ ngx_pop3_auth_state(ngx_event_t *rev)
ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
"pop3 login: \"%V\"", &s->login);
- } else {
- rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
}
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
break;
case NGX_POP3_CAPA:
@@ -799,11 +800,74 @@ ngx_pop3_auth_state(ngx_event_t *rev)
ngx_imap_auth_http_init(s);
return;
+ }
+
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
- } else {
+ case NGX_POP3_AUTH:
+ cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
+
+ if (s->args.nelts == 0) {
+ size = cscf->pop3_auth_capability.len;
+ text = cscf->pop3_auth_capability.data;
+ s->state = 0;
+ break;
+ }
+
+ if (s->args.nelts != 1) {
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ arg = s->args.elts;
+
+ if (arg[0].len == 5) {
+
+ if (ngx_strncasecmp(arg[0].data, "LOGIN", 5) == 0) {
+ s->imap_state = ngx_pop3_auth_login_username;
+
+ size = sizeof(pop3_username) - 1;
+ text = pop3_username;
+
+ break;
+
+ } else if (ngx_strncasecmp(arg[0].data, "PLAIN", 5) == 0) {
+ s->imap_state = ngx_pop3_auth_plain;
+
+ size = sizeof(pop3_next) - 1;
+ text = pop3_next;
+
+ break;
+ }
+
+ } else if (arg[0].len == 8
+ && ngx_strncasecmp(arg[0].data, "CRAM-MD5", 8) == 0)
+ {
+ s->imap_state = ngx_pop3_auth_cram_md5;
+
+ text = ngx_palloc(c->pool,
+ sizeof("+ " CRLF) - 1
+ + ngx_base64_encoded_length(s->salt.len));
+ if (text == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ text[0] = '+'; text[1]= ' ';
+ salt.data = &text[2];
+ s->salt.len -= 2;
+
+ ngx_encode_base64(&salt, &s->salt);
+
+ s->salt.len += 2;
+ size = 2 + salt.len;
+ text[size++] = CR; text[size++] = LF;
+
+ break;
}
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
break;
case NGX_POP3_QUIT:
@@ -869,11 +933,9 @@ ngx_pop3_auth_state(ngx_event_t *rev)
ngx_imap_auth_http_init(s);
return;
-
- } else {
- rc = NGX_IMAP_PARSE_INVALID_COMMAND;
}
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
break;
case NGX_POP3_CAPA:
@@ -900,10 +962,212 @@ ngx_pop3_auth_state(ngx_event_t *rev)
/* suppress warinings */
case ngx_pop3_passwd:
break;
+
+ case ngx_pop3_auth_login_username:
+ arg = s->args.elts;
+ s->imap_state = ngx_pop3_auth_login_password;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth login username: \"%V\"", &arg[0]);
+
+ s->login.data = ngx_palloc(c->pool,
+ ngx_base64_decoded_length(arg[0].len));
+ if (s->login.data == NULL){
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid base64 encoding "
+ "in AUTH LOGIN command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth login username: \"%V\"", &s->login);
+
+ size = sizeof(pop3_password) - 1;
+ text = pop3_password;
+
+ break;
+
+ case ngx_pop3_auth_login_password:
+ arg = s->args.elts;
+
+#if (NGX_DEBUG_IMAP_PASSWD)
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth login password: \"%V\"", &arg[0]);
+#endif
+
+ s->passwd.data = ngx_palloc(c->pool,
+ ngx_base64_decoded_length(arg[0].len));
+ if (s->passwd.data == NULL){
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid base64 encoding "
+ "in AUTH LOGIN command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+#if (NGX_DEBUG_IMAP_PASSWD)
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth login password: \"%V\"", &s->passwd);
+#endif
+
+ s->args.nelts = 0;
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ }
+
+ ngx_imap_auth_http_init(s);
+
+ return;
+
+ case ngx_pop3_auth_plain:
+ arg = s->args.elts;
+
+#if (NGX_DEBUG_IMAP_PASSWD)
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth plain: \"%V\"", &arg[0]);
+#endif
+
+ plain.data = ngx_palloc(c->pool,
+ ngx_base64_decoded_length(arg[0].len));
+ if (plain.data == NULL){
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ if (ngx_decode_base64(&plain, &arg[0]) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid base64 encoding "
+ "in AUTH PLAIN command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ p = plain.data;
+ last = p + plain.len;
+
+ while (p < last && *p++) { /* void */ }
+
+ if (p == last) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid login "
+ "in AUTH PLAIN command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ s->login.data = p;
+
+ while (p < last && *p) { p++; }
+
+ if (p == last) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid password "
+ "in AUTH PLAIN command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ s->login.len = p++ - s->login.data;
+
+ s->passwd.len = last - p;
+ s->passwd.data = p;
+
+#if (NGX_DEBUG_IMAP_PASSWD)
+ ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth plain: \"%V\" \"%V\"",
+ &s->login, &s->passwd);
+#endif
+
+ s->args.nelts = 0;
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ }
+
+ ngx_imap_auth_http_init(s);
+
+ return;
+
+ case ngx_pop3_auth_cram_md5:
+ arg = s->args.elts;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth cram-md5: \"%V\"", &arg[0]);
+
+ s->login.data = ngx_palloc(c->pool,
+ ngx_base64_decoded_length(arg[0].len));
+ if (s->login.data == NULL){
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid base64 encoding "
+ "in AUTH CRAM-MD5 command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ p = s->login.data;
+ last = p + s->login.len;
+
+ while (p < last) {
+ if (*p++ == ' ') {
+ s->login.len = p - s->login.data - 1;
+ s->passwd.len = last - p;
+ s->passwd.data = p;
+ break;
+ }
+ }
+
+ if (s->passwd.len != 32) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid CRAM-MD5 hash "
+ "in AUTH CRAM-MD5 command");
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 auth cram-md5: \"%V\" \"%V\"",
+ &s->login, &s->passwd);
+
+ s->auth_method = NGX_IMAP_AUTH_CRAM_MD5;
+
+ s->args.nelts = 0;
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ }
+
+ ngx_imap_auth_http_init(s);
+
+ return;
}
}
if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) {
+ s->imap_state = ngx_pop3_start;
+ s->state = 0;
text = pop3_invalid_command;
size = sizeof(pop3_invalid_command) - 1;
}
@@ -912,6 +1176,10 @@ ngx_pop3_auth_state(ngx_event_t *rev)
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
+ if (s->state) {
+ s->arg_start = s->buffer->start;
+ }
+
s->out.data = text;
s->out.len = size;
diff --git a/src/imap/ngx_imap_parse.c b/src/imap/ngx_imap_parse.c
index 6256cc863..fabba26af 100644
--- a/src/imap/ngx_imap_parse.c
+++ b/src/imap/ngx_imap_parse.c
@@ -441,6 +441,10 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
{
s->command = NGX_POP3_CAPA;
+ } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
+ {
+ s->command = NGX_POP3_AUTH;
+
} else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
{
s->command = NGX_POP3_NOOP;
@@ -571,13 +575,13 @@ done:
s->arg_start = NULL;
}
- s->state = sw_start;
-
+ s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
return NGX_OK;
invalid:
s->state = sw_start;
+ s->arg_start = NULL;
return NGX_IMAP_PARSE_INVALID_COMMAND;
}