diff src/imap/ngx_imap_auth_http_module.c @ 633:f971949ffb58 release-0.3.38

nginx-0.3.38-RELEASE import *) Feature: the ngx_http_dav_module. *) Change: the ngx_http_perl_module optimizations. Thanks to Sergey Skvortsov. *) Feature: the ngx_http_perl_module supports the $r->request_body_file method. *) Feature: the "client_body_in_file_only" directive. *) Workaround: now on disk overflow nginx tries to write access logs once a second only. Thanks to Anton Yuzhaninov and Maxim Dounin. *) Bugfix: now the "limit_rate" directive more precisely limits rate if rate is more than 100 Kbyte/s. Thanks to ForJest. *) Bugfix: now the IMAP/POP3 proxy escapes the "\r" and "\n" symbols in login and password to pass authorization server. Thanks to Maxim Dounin.
author Igor Sysoev <igor@sysoev.ru>
date Fri, 14 Apr 2006 09:53:38 +0000
parents 4e296b7d25bf
children 9737d6fb1ac6
line wrap: on
line diff
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -68,6 +68,8 @@ static void ngx_imap_auth_http_block_rea
 static void ngx_imap_auth_http_dummy_handler(ngx_event_t *ev);
 static ngx_buf_t *ngx_imap_auth_http_create_request(ngx_imap_session_t *s,
     ngx_pool_t *pool, ngx_imap_auth_http_conf_t *ahcf);
+static ngx_int_t ngx_imap_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text,
+    ngx_str_t *escaped);
 
 static void *ngx_imap_auth_http_create_conf(ngx_conf_t *cf);
 static char *ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
@@ -984,12 +986,21 @@ ngx_imap_auth_http_create_request(ngx_im
 {
     size_t      len;
     ngx_buf_t  *b;
+    ngx_str_t   login, passwd;
+
+    if (ngx_imap_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
+        return NULL;
+    }
+
+    if (ngx_imap_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
+        return NULL;
+    }
 
     len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1
           + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1
           + sizeof("Auth-Method: plain" CRLF) - 1
-          + sizeof("Auth-User: ") - 1 + s->login.len + sizeof(CRLF) - 1
-          + sizeof("Auth-Pass: ") - 1 + s->passwd.len + sizeof(CRLF) - 1
+          + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
+          + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
           + sizeof("Auth-Protocol: imap" CRLF) - 1
           + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN
                 + sizeof(CRLF) - 1
@@ -1016,11 +1027,11 @@ ngx_imap_auth_http_create_request(ngx_im
                          sizeof("Auth-Method: plain" CRLF) - 1);
 
     b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
-    b->last = ngx_copy(b->last, s->login.data, s->login.len);
+    b->last = ngx_copy(b->last, login.data, login.len);
     *b->last++ = CR; *b->last++ = LF;
 
     b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1);
-    b->last = ngx_copy(b->last, s->passwd.data, s->passwd.len);
+    b->last = ngx_copy(b->last, passwd.data, passwd.len);
     *b->last++ = CR; *b->last++ = LF;
 
     b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
@@ -1059,6 +1070,60 @@ ngx_imap_auth_http_create_request(ngx_im
 }
 
 
+static ngx_int_t
+ngx_imap_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
+{
+    u_char      ch, *p;
+    ngx_uint_t  i, n;
+
+    n = 0;
+
+    for (i = 0; i < text->len; i++) {
+        ch = text->data[i];
+
+        if (ch == CR || ch == LF) {
+            n++;
+        }
+    }
+
+    if (n == 0) {
+        *escaped = *text;
+        return NGX_OK;
+    }
+
+    escaped->len = text->len + n * 2;
+
+    p = ngx_palloc(pool, escaped->len);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    escaped->data = p;
+
+    for (i = 0; i < text->len; i++) {
+        ch = text->data[i];
+
+        if (ch == CR) {
+            *p++ = '%';
+            *p++ = '0';
+            *p++ = 'D';
+            continue;
+        }
+
+        if (ch == LF) {
+            *p++ = '%';
+            *p++ = '0';
+            *p++ = 'A';
+            continue;
+        }
+
+        *p++ = ch;
+    }
+
+    return NGX_OK;
+}
+
+
 static void *
 ngx_imap_auth_http_create_conf(ngx_conf_t *cf)
 {