aboutsummaryrefslogtreecommitdiff
path: root/src/imap/ngx_imap_handler.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2005-12-05 13:18:09 +0000
committerIgor Sysoev <igor@sysoev.ru>2005-12-05 13:18:09 +0000
commitd3283ff9224a41a1a24c2d89f671811c0747480a (patch)
treee122c436f72f587622e8ec0e75632434045e330d /src/imap/ngx_imap_handler.c
parent0624ed3d7eaa1995d9e5ec4292bd1eccda09cafc (diff)
downloadnginx-d3283ff9224a41a1a24c2d89f671811c0747480a.tar.gz
nginx-d3283ff9224a41a1a24c2d89f671811c0747480a.zip
nginx-0.3.13-RELEASE importrelease-0.3.13
*) Feature: the IMAP/POP3 proxy supports STARTTLS and STLS. *) Bugfix: the IMAP/POP3 proxy did not work with the select, poll, and /dev/poll methods. *) Bugfix: in SSI handling. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket. *) Bugfix: the "auth_basic" directive did not disable the authorization; the bug had appeared in 0.3.11.
Diffstat (limited to 'src/imap/ngx_imap_handler.c')
-rw-r--r--src/imap/ngx_imap_handler.c196
1 files changed, 161 insertions, 35 deletions
diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c
index ddff96a29..f90b96880 100644
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -16,6 +16,7 @@ static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s);
static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len);
#if (NGX_IMAP_SSL)
+static void ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
static void ngx_imap_ssl_handshake_handler(ngx_connection_t *c);
#endif
@@ -43,11 +44,10 @@ static u_char imap_invalid_command[] = "BAD invalid command" CRLF;
void
ngx_imap_init_connection(ngx_connection_t *c)
{
- ngx_imap_log_ctx_t *lctx;
+ ngx_imap_log_ctx_t *lctx;
#if (NGX_IMAP_SSL)
- ngx_imap_conf_ctx_t *ctx;
- ngx_imap_ssl_conf_t *sslcf;
- ngx_imap_core_srv_conf_t *cscf;
+ ngx_imap_conf_ctx_t *ctx;
+ ngx_imap_ssl_conf_t *sslcf;
#endif
ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V",
@@ -75,44 +75,82 @@ ngx_imap_init_connection(ngx_connection_t *c)
sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module);
if (sslcf->enable) {
- if (ngx_ssl_create_connection(&sslcf->ssl, c, 0) == NGX_ERROR) {
- ngx_imap_close_connection(c);
- return;
- }
+ ngx_imap_ssl_init_connection(&sslcf->ssl, c);
+ return;
+ }
- if (ngx_ssl_handshake(c) == NGX_AGAIN) {
+#endif
- cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
+ ngx_imap_init_session(c);
+}
- ngx_add_timer(c->read, cscf->timeout);
- c->ssl->handler = ngx_imap_ssl_handshake_handler;
+#if (NGX_IMAP_SSL)
- return;
- }
+static void
+ngx_imap_starttls_handler(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+ ngx_imap_session_t *s;
+ ngx_imap_ssl_conf_t *sslcf;
+
+ c = rev->data;
+ s = c->data;
+
+ c->log->action = "in starttls state";
- ngx_imap_ssl_handshake_handler(c);
+ sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
+
+ ngx_imap_ssl_init_connection(&sslcf->ssl, c);
+}
+
+
+static void
+ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
+{
+ ngx_imap_conf_ctx_t *ctx;
+ ngx_imap_core_srv_conf_t *cscf;
+
+ if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
+ ngx_imap_close_connection(c);
return;
}
-#endif
+ if (ngx_ssl_handshake(c) == NGX_AGAIN) {
- ngx_imap_init_session(c);
-}
+ ctx = c->ctx;
+ cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
+ ngx_add_timer(c->read, cscf->timeout);
+
+ c->ssl->handler = ngx_imap_ssl_handshake_handler;
+
+ return;
+ }
+
+ ngx_imap_ssl_handshake_handler(c);
+}
-#if (NGX_IMAP_SSL)
static void
ngx_imap_ssl_handshake_handler(ngx_connection_t *c)
{
if (c->ssl->handshaked) {
+
+ if (c->data) {
+ c->read->handler = ngx_imap_init_protocol;
+ c->write->handler = ngx_imap_send;
+
+ ngx_imap_init_protocol(c->read);
+
+ return;
+ }
+
ngx_imap_init_session(c);
return;
}
ngx_imap_close_connection(c);
- return;
}
#endif
@@ -253,11 +291,6 @@ ngx_imap_init_protocol(ngx_event_t *rev)
s = c->data;
- if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {
- ngx_imap_session_internal_server_error(s);
- return;
- }
-
if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
size = 128;
s->imap_state = ngx_pop3_start;
@@ -270,10 +303,19 @@ ngx_imap_init_protocol(ngx_event_t *rev)
c->read->handler = ngx_imap_auth_state;
}
- s->buffer = ngx_create_temp_buf(c->pool, size);
if (s->buffer == NULL) {
- ngx_imap_session_internal_server_error(s);
- return;
+ if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t))
+ == NGX_ERROR)
+ {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ s->buffer = ngx_create_temp_buf(c->pool, size);
+ if (s->buffer == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
}
c->read->handler(rev);
@@ -291,6 +333,9 @@ ngx_imap_auth_state(ngx_event_t *rev)
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_core_srv_conf_t *cscf;
+#if (NGX_IMAP_SSL)
+ ngx_imap_ssl_conf_t *sslcf;
+#endif
c = rev->data;
s = c->data;
@@ -357,6 +402,19 @@ ngx_imap_auth_state(ngx_event_t *rev)
switch (s->command) {
case NGX_IMAP_LOGIN:
+
+#if (NGX_IMAP_SSL)
+
+ if (c->ssl == NULL) {
+ sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
+
+ if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) {
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+ }
+ }
+#endif
+
arg = s->args.elts;
if (s->args.nelts == 2 && arg[0].len) {
@@ -410,8 +468,28 @@ ngx_imap_auth_state(ngx_event_t *rev)
case NGX_IMAP_CAPABILITY:
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
- text = cscf->imap_capability->pos;
- text_len = cscf->imap_capability->last - cscf->imap_capability->pos;
+
+#if (NGX_IMAP_SSL)
+
+ if (c->ssl == NULL) {
+ sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
+
+ if (sslcf->starttls == NGX_IMAP_STARTTLS_ON) {
+ text_len = cscf->imap_starttls_capability.len;
+ text = cscf->imap_starttls_capability.data;
+ break;
+ }
+
+ if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) {
+ text_len = cscf->imap_starttls_only_capability.len;
+ text = cscf->imap_starttls_only_capability.data;
+ break;
+ }
+ }
+#endif
+
+ text_len = cscf->imap_capability.len;
+ text = cscf->imap_capability.data;
break;
case NGX_IMAP_LOGOUT:
@@ -423,6 +501,21 @@ ngx_imap_auth_state(ngx_event_t *rev)
case NGX_IMAP_NOOP:
break;
+#if (NGX_IMAP_SSL)
+
+ case NGX_IMAP_STARTTLS:
+ if (c->ssl == NULL) {
+ sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module);
+ if (sslcf->starttls) {
+ c->read->handler = ngx_imap_starttls_handler;
+ break;
+ }
+ }
+
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+#endif
+
default:
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
break;
@@ -492,6 +585,9 @@ ngx_pop3_auth_state(ngx_event_t *rev)
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_core_srv_conf_t *cscf;
+#if (NGX_IMAP_SSL)
+ ngx_imap_ssl_conf_t *sslcf;
+#endif
c = rev->data;
s = c->data;
@@ -554,8 +650,22 @@ ngx_pop3_auth_state(ngx_event_t *rev)
case NGX_POP3_CAPA:
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
- text = cscf->pop3_capability->pos;
- size = cscf->pop3_capability->last - cscf->pop3_capability->pos;
+
+#if (NGX_IMAP_SSL)
+
+ if (c->ssl == NULL) {
+ sslcf = ngx_imap_get_module_srv_conf(s,
+ ngx_imap_ssl_module);
+ if (sslcf->starttls) {
+ size = cscf->pop3_starttls_capability.len;
+ text = cscf->pop3_starttls_capability.data;
+ break;
+ }
+ }
+#endif
+
+ size = cscf->pop3_capability.len;
+ text = cscf->pop3_capability.data;
break;
case NGX_POP3_QUIT:
@@ -565,6 +675,22 @@ ngx_pop3_auth_state(ngx_event_t *rev)
case NGX_POP3_NOOP:
break;
+#if (NGX_IMAP_SSL)
+
+ case NGX_POP3_STLS:
+ if (c->ssl == NULL) {
+ sslcf = ngx_imap_get_module_srv_conf(s,
+ ngx_imap_ssl_module);
+ if (sslcf->starttls) {
+ c->read->handler = ngx_imap_starttls_handler;
+ break;
+ }
+ }
+
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ break;
+#endif
+
default:
s->imap_state = ngx_pop3_start;
rc = NGX_IMAP_PARSE_INVALID_COMMAND;
@@ -616,8 +742,8 @@ ngx_pop3_auth_state(ngx_event_t *rev)
case NGX_POP3_CAPA:
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
- text = cscf->pop3_capability->pos;
- size = cscf->pop3_capability->last - cscf->pop3_capability->pos;
+ size = cscf->pop3_capability.len;
+ text = cscf->pop3_capability.data;
break;
case NGX_POP3_QUIT:
@@ -735,7 +861,7 @@ ngx_imap_close_connection(ngx_connection_t *c)
#endif
- c->closed = 1;
+ c->destroyed = 1;
pool = c->pool;