Annotation of embedaddon/nginx/src/mail/ngx_mail_handler.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_event.h>
                     11: #include <ngx_mail.h>
                     12: 
                     13: 
                     14: static void ngx_mail_init_session(ngx_connection_t *c);
                     15: 
                     16: #if (NGX_MAIL_SSL)
                     17: static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
                     18: static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c);
                     19: #endif
                     20: 
                     21: 
                     22: void
                     23: ngx_mail_init_connection(ngx_connection_t *c)
                     24: {
                     25:     ngx_uint_t             i;
                     26:     ngx_mail_port_t       *port;
                     27:     struct sockaddr       *sa;
                     28:     struct sockaddr_in    *sin;
                     29:     ngx_mail_log_ctx_t    *ctx;
                     30:     ngx_mail_in_addr_t    *addr;
                     31:     ngx_mail_session_t    *s;
                     32:     ngx_mail_addr_conf_t  *addr_conf;
                     33: #if (NGX_HAVE_INET6)
                     34:     struct sockaddr_in6   *sin6;
                     35:     ngx_mail_in6_addr_t   *addr6;
                     36: #endif
                     37: 
                     38: 
                     39:     /* find the server configuration for the address:port */
                     40: 
                     41:     port = c->listening->servers;
                     42: 
                     43:     if (port->naddrs > 1) {
                     44: 
                     45:         /*
                     46:          * There are several addresses on this port and one of them
                     47:          * is the "*:port" wildcard so getsockname() is needed to determine
                     48:          * the server address.
                     49:          *
                     50:          * AcceptEx() already gave this address.
                     51:          */
                     52: 
                     53:         if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
                     54:             ngx_mail_close_connection(c);
                     55:             return;
                     56:         }
                     57: 
                     58:         sa = c->local_sockaddr;
                     59: 
                     60:         switch (sa->sa_family) {
                     61: 
                     62: #if (NGX_HAVE_INET6)
                     63:         case AF_INET6:
                     64:             sin6 = (struct sockaddr_in6 *) sa;
                     65: 
                     66:             addr6 = port->addrs;
                     67: 
                     68:             /* the last address is "*" */
                     69: 
                     70:             for (i = 0; i < port->naddrs - 1; i++) {
                     71:                 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
                     72:                     break;
                     73:                 }
                     74:             }
                     75: 
                     76:             addr_conf = &addr6[i].conf;
                     77: 
                     78:             break;
                     79: #endif
                     80: 
                     81:         default: /* AF_INET */
                     82:             sin = (struct sockaddr_in *) sa;
                     83: 
                     84:             addr = port->addrs;
                     85: 
                     86:             /* the last address is "*" */
                     87: 
                     88:             for (i = 0; i < port->naddrs - 1; i++) {
                     89:                 if (addr[i].addr == sin->sin_addr.s_addr) {
                     90:                     break;
                     91:                 }
                     92:             }
                     93: 
                     94:             addr_conf = &addr[i].conf;
                     95: 
                     96:             break;
                     97:         }
                     98: 
                     99:     } else {
                    100:         switch (c->local_sockaddr->sa_family) {
                    101: 
                    102: #if (NGX_HAVE_INET6)
                    103:         case AF_INET6:
                    104:             addr6 = port->addrs;
                    105:             addr_conf = &addr6[0].conf;
                    106:             break;
                    107: #endif
                    108: 
                    109:         default: /* AF_INET */
                    110:             addr = port->addrs;
                    111:             addr_conf = &addr[0].conf;
                    112:             break;
                    113:         }
                    114:     }
                    115: 
                    116:     s = ngx_pcalloc(c->pool, sizeof(ngx_mail_session_t));
                    117:     if (s == NULL) {
                    118:         ngx_mail_close_connection(c);
                    119:         return;
                    120:     }
                    121: 
                    122:     s->main_conf = addr_conf->ctx->main_conf;
                    123:     s->srv_conf = addr_conf->ctx->srv_conf;
                    124: 
                    125:     s->addr_text = &addr_conf->addr_text;
                    126: 
                    127:     c->data = s;
                    128:     s->connection = c;
                    129: 
                    130:     ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V",
                    131:                   c->number, &c->addr_text, s->addr_text);
                    132: 
                    133:     ctx = ngx_palloc(c->pool, sizeof(ngx_mail_log_ctx_t));
                    134:     if (ctx == NULL) {
                    135:         ngx_mail_close_connection(c);
                    136:         return;
                    137:     }
                    138: 
                    139:     ctx->client = &c->addr_text;
                    140:     ctx->session = s;
                    141: 
                    142:     c->log->connection = c->number;
                    143:     c->log->handler = ngx_mail_log_error;
                    144:     c->log->data = ctx;
                    145:     c->log->action = "sending client greeting line";
                    146: 
                    147:     c->log_error = NGX_ERROR_INFO;
                    148: 
                    149: #if (NGX_MAIL_SSL)
                    150:     {
                    151:     ngx_mail_ssl_conf_t  *sslcf;
                    152: 
                    153:     sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
                    154: 
                    155:     if (sslcf->enable) {
                    156:         c->log->action = "SSL handshaking";
                    157: 
                    158:         ngx_mail_ssl_init_connection(&sslcf->ssl, c);
                    159:         return;
                    160:     }
                    161: 
                    162:     if (addr_conf->ssl) {
                    163: 
                    164:         c->log->action = "SSL handshaking";
                    165: 
                    166:         if (sslcf->ssl.ctx == NULL) {
                    167:             ngx_log_error(NGX_LOG_ERR, c->log, 0,
                    168:                           "no \"ssl_certificate\" is defined "
                    169:                           "in server listening on SSL port");
                    170:             ngx_mail_close_connection(c);
                    171:             return;
                    172:         }
                    173: 
                    174:         ngx_mail_ssl_init_connection(&sslcf->ssl, c);
                    175:         return;
                    176:     }
                    177: 
                    178:     }
                    179: #endif
                    180: 
                    181:     ngx_mail_init_session(c);
                    182: }
                    183: 
                    184: 
                    185: #if (NGX_MAIL_SSL)
                    186: 
                    187: void
                    188: ngx_mail_starttls_handler(ngx_event_t *rev)
                    189: {
                    190:     ngx_connection_t     *c;
                    191:     ngx_mail_session_t   *s;
                    192:     ngx_mail_ssl_conf_t  *sslcf;
                    193: 
                    194:     c = rev->data;
                    195:     s = c->data;
                    196:     s->starttls = 1;
                    197: 
                    198:     c->log->action = "in starttls state";
                    199: 
                    200:     sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
                    201: 
                    202:     ngx_mail_ssl_init_connection(&sslcf->ssl, c);
                    203: }
                    204: 
                    205: 
                    206: static void
                    207: ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
                    208: {
                    209:     ngx_mail_session_t        *s;
                    210:     ngx_mail_core_srv_conf_t  *cscf;
                    211: 
                    212:     if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
                    213:         ngx_mail_close_connection(c);
                    214:         return;
                    215:     }
                    216: 
                    217:     if (ngx_ssl_handshake(c) == NGX_AGAIN) {
                    218: 
                    219:         s = c->data;
                    220: 
                    221:         cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    222: 
                    223:         ngx_add_timer(c->read, cscf->timeout);
                    224: 
                    225:         c->ssl->handler = ngx_mail_ssl_handshake_handler;
                    226: 
                    227:         return;
                    228:     }
                    229: 
                    230:     ngx_mail_ssl_handshake_handler(c);
                    231: }
                    232: 
                    233: 
                    234: static void
                    235: ngx_mail_ssl_handshake_handler(ngx_connection_t *c)
                    236: {
                    237:     ngx_mail_session_t        *s;
                    238:     ngx_mail_core_srv_conf_t  *cscf;
                    239: 
                    240:     if (c->ssl->handshaked) {
                    241: 
                    242:         s = c->data;
                    243: 
                    244:         if (s->starttls) {
                    245:             cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    246: 
                    247:             c->read->handler = cscf->protocol->init_protocol;
                    248:             c->write->handler = ngx_mail_send;
                    249: 
                    250:             cscf->protocol->init_protocol(c->read);
                    251: 
                    252:             return;
                    253:         }
                    254: 
                    255:         c->read->ready = 0;
                    256: 
                    257:         ngx_mail_init_session(c);
                    258:         return;
                    259:     }
                    260: 
                    261:     ngx_mail_close_connection(c);
                    262: }
                    263: 
                    264: #endif
                    265: 
                    266: 
                    267: static void
                    268: ngx_mail_init_session(ngx_connection_t *c)
                    269: {
                    270:     ngx_mail_session_t        *s;
                    271:     ngx_mail_core_srv_conf_t  *cscf;
                    272: 
                    273:     s = c->data;
                    274: 
                    275:     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    276: 
                    277:     s->protocol = cscf->protocol->type;
                    278: 
                    279:     s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_mail_max_module);
                    280:     if (s->ctx == NULL) {
                    281:         ngx_mail_session_internal_server_error(s);
                    282:         return;
                    283:     }
                    284: 
                    285:     c->write->handler = ngx_mail_send;
                    286: 
                    287:     cscf->protocol->init_session(s, c);
                    288: }
                    289: 
                    290: 
                    291: ngx_int_t
                    292: ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
                    293:     ngx_mail_core_srv_conf_t *cscf)
                    294: {
                    295:     s->salt.data = ngx_pnalloc(c->pool,
                    296:                                sizeof(" <18446744073709551616.@>" CRLF) - 1
                    297:                                + NGX_TIME_T_LEN
                    298:                                + cscf->server_name.len);
                    299:     if (s->salt.data == NULL) {
                    300:         return NGX_ERROR;
                    301:     }
                    302: 
                    303:     s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF,
                    304:                               ngx_random(), ngx_time(), &cscf->server_name)
                    305:                   - s->salt.data;
                    306: 
                    307:     return NGX_OK;
                    308: }
                    309: 
                    310: 
                    311: #if (NGX_MAIL_SSL)
                    312: 
                    313: ngx_int_t
                    314: ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
                    315: {
                    316:     ngx_mail_ssl_conf_t  *sslcf;
                    317: 
                    318:     if (c->ssl) {
                    319:         return 0;
                    320:     }
                    321: 
                    322:     sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
                    323: 
                    324:     if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
                    325:         return 1;
                    326:     }
                    327: 
                    328:     return 0;
                    329: }
                    330: 
                    331: #endif
                    332: 
                    333: 
                    334: ngx_int_t
                    335: ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
                    336: {
                    337:     u_char     *p, *last;
                    338:     ngx_str_t  *arg, plain;
                    339: 
                    340:     arg = s->args.elts;
                    341: 
                    342: #if (NGX_DEBUG_MAIL_PASSWD)
                    343:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    344:                    "mail auth plain: \"%V\"", &arg[n]);
                    345: #endif
                    346: 
                    347:     plain.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
                    348:     if (plain.data == NULL) {
                    349:         return NGX_ERROR;
                    350:     }
                    351: 
                    352:     if (ngx_decode_base64(&plain, &arg[n]) != NGX_OK) {
                    353:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    354:             "client sent invalid base64 encoding in AUTH PLAIN command");
                    355:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    356:     }
                    357: 
                    358:     p = plain.data;
                    359:     last = p + plain.len;
                    360: 
                    361:     while (p < last && *p++) { /* void */ }
                    362: 
                    363:     if (p == last) {
                    364:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    365:                       "client sent invalid login in AUTH PLAIN command");
                    366:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    367:     }
                    368: 
                    369:     s->login.data = p;
                    370: 
                    371:     while (p < last && *p) { p++; }
                    372: 
                    373:     if (p == last) {
                    374:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    375:                       "client sent invalid password in AUTH PLAIN command");
                    376:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    377:     }
                    378: 
                    379:     s->login.len = p++ - s->login.data;
                    380: 
                    381:     s->passwd.len = last - p;
                    382:     s->passwd.data = p;
                    383: 
                    384: #if (NGX_DEBUG_MAIL_PASSWD)
                    385:     ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    386:                    "mail auth plain: \"%V\" \"%V\"", &s->login, &s->passwd);
                    387: #endif
                    388: 
                    389:     return NGX_DONE;
                    390: }
                    391: 
                    392: 
                    393: ngx_int_t
                    394: ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
                    395:     ngx_uint_t n)
                    396: {
                    397:     ngx_str_t  *arg;
                    398: 
                    399:     arg = s->args.elts;
                    400: 
                    401:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    402:                    "mail auth login username: \"%V\"", &arg[n]);
                    403: 
                    404:     s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
                    405:     if (s->login.data == NULL) {
                    406:         return NGX_ERROR;
                    407:     }
                    408: 
                    409:     if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) {
                    410:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    411:             "client sent invalid base64 encoding in AUTH LOGIN command");
                    412:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    413:     }
                    414: 
                    415:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    416:                    "mail auth login username: \"%V\"", &s->login);
                    417: 
                    418:     return NGX_OK;
                    419: }
                    420: 
                    421: 
                    422: ngx_int_t
                    423: ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
                    424: {
                    425:     ngx_str_t  *arg;
                    426: 
                    427:     arg = s->args.elts;
                    428: 
                    429: #if (NGX_DEBUG_MAIL_PASSWD)
                    430:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    431:                    "mail auth login password: \"%V\"", &arg[0]);
                    432: #endif
                    433: 
                    434:     s->passwd.data = ngx_pnalloc(c->pool,
                    435:                                  ngx_base64_decoded_length(arg[0].len));
                    436:     if (s->passwd.data == NULL) {
                    437:         return NGX_ERROR;
                    438:     }
                    439: 
                    440:     if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
                    441:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    442:             "client sent invalid base64 encoding in AUTH LOGIN command");
                    443:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    444:     }
                    445: 
                    446: #if (NGX_DEBUG_MAIL_PASSWD)
                    447:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    448:                    "mail auth login password: \"%V\"", &s->passwd);
                    449: #endif
                    450: 
                    451:     return NGX_DONE;
                    452: }
                    453: 
                    454: 
                    455: ngx_int_t
                    456: ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c,
                    457:     char *prefix, size_t len)
                    458: {
                    459:     u_char      *p;
                    460:     ngx_str_t    salt;
                    461:     ngx_uint_t   n;
                    462: 
                    463:     p = ngx_pnalloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
                    464:     if (p == NULL) {
                    465:         return NGX_ERROR;
                    466:     }
                    467: 
                    468:     salt.data = ngx_cpymem(p, prefix, len);
                    469:     s->salt.len -= 2;
                    470: 
                    471:     ngx_encode_base64(&salt, &s->salt);
                    472: 
                    473:     s->salt.len += 2;
                    474:     n = len + salt.len;
                    475:     p[n++] = CR; p[n++] = LF;
                    476: 
                    477:     s->out.len = n;
                    478:     s->out.data = p;
                    479: 
                    480:     return NGX_OK;
                    481: }
                    482: 
                    483: 
                    484: ngx_int_t
                    485: ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
                    486: {
                    487:     u_char     *p, *last;
                    488:     ngx_str_t  *arg;
                    489: 
                    490:     arg = s->args.elts;
                    491: 
                    492:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    493:                    "mail auth cram-md5: \"%V\"", &arg[0]);
                    494: 
                    495:     s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
                    496:     if (s->login.data == NULL) {
                    497:         return NGX_ERROR;
                    498:     }
                    499: 
                    500:     if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
                    501:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    502:             "client sent invalid base64 encoding in AUTH CRAM-MD5 command");
                    503:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    504:     }
                    505: 
                    506:     p = s->login.data;
                    507:     last = p + s->login.len;
                    508: 
                    509:     while (p < last) {
                    510:         if (*p++ == ' ') {
                    511:             s->login.len = p - s->login.data - 1;
                    512:             s->passwd.len = last - p;
                    513:             s->passwd.data = p;
                    514:             break;
                    515:         }
                    516:     }
                    517: 
                    518:     if (s->passwd.len != 32) {
                    519:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    520:             "client sent invalid CRAM-MD5 hash in AUTH CRAM-MD5 command");
                    521:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    522:     }
                    523: 
                    524:     ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    525:                    "mail auth cram-md5: \"%V\" \"%V\"", &s->login, &s->passwd);
                    526: 
                    527:     s->auth_method = NGX_MAIL_AUTH_CRAM_MD5;
                    528: 
                    529:     return NGX_DONE;
                    530: }
                    531: 
                    532: 
                    533: void
                    534: ngx_mail_send(ngx_event_t *wev)
                    535: {
                    536:     ngx_int_t                  n;
                    537:     ngx_connection_t          *c;
                    538:     ngx_mail_session_t        *s;
                    539:     ngx_mail_core_srv_conf_t  *cscf;
                    540: 
                    541:     c = wev->data;
                    542:     s = c->data;
                    543: 
                    544:     if (wev->timedout) {
                    545:         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
                    546:         c->timedout = 1;
                    547:         ngx_mail_close_connection(c);
                    548:         return;
                    549:     }
                    550: 
                    551:     if (s->out.len == 0) {
                    552:         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
                    553:             ngx_mail_close_connection(c);
                    554:         }
                    555: 
                    556:         return;
                    557:     }
                    558: 
                    559:     n = c->send(c, s->out.data, s->out.len);
                    560: 
                    561:     if (n > 0) {
                    562:         s->out.len -= n;
                    563: 
                    564:         if (wev->timer_set) {
                    565:             ngx_del_timer(wev);
                    566:         }
                    567: 
                    568:         if (s->quit) {
                    569:             ngx_mail_close_connection(c);
                    570:             return;
                    571:         }
                    572: 
                    573:         if (s->blocked) {
                    574:             c->read->handler(c->read);
                    575:         }
                    576: 
                    577:         return;
                    578:     }
                    579: 
                    580:     if (n == NGX_ERROR) {
                    581:         ngx_mail_close_connection(c);
                    582:         return;
                    583:     }
                    584: 
                    585:     /* n == NGX_AGAIN */
                    586: 
                    587:     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    588: 
                    589:     ngx_add_timer(c->write, cscf->timeout);
                    590: 
                    591:     if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
                    592:         ngx_mail_close_connection(c);
                    593:         return;
                    594:     }
                    595: }
                    596: 
                    597: 
                    598: ngx_int_t
                    599: ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
                    600: {
                    601:     ssize_t                    n;
                    602:     ngx_int_t                  rc;
                    603:     ngx_str_t                  l;
                    604:     ngx_mail_core_srv_conf_t  *cscf;
                    605: 
                    606:     n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
                    607: 
                    608:     if (n == NGX_ERROR || n == 0) {
                    609:         ngx_mail_close_connection(c);
                    610:         return NGX_ERROR;
                    611:     }
                    612: 
                    613:     if (n > 0) {
                    614:         s->buffer->last += n;
                    615:     }
                    616: 
                    617:     if (n == NGX_AGAIN) {
                    618:         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
                    619:             ngx_mail_session_internal_server_error(s);
                    620:             return NGX_ERROR;
                    621:         }
                    622: 
                    623:         return NGX_AGAIN;
                    624:     }
                    625: 
                    626:     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    627: 
                    628:     rc = cscf->protocol->parse_command(s);
                    629: 
                    630:     if (rc == NGX_AGAIN) {
                    631: 
                    632:         if (s->buffer->last < s->buffer->end) {
                    633:             return rc;
                    634:         }
                    635: 
                    636:         l.len = s->buffer->last - s->buffer->start;
                    637:         l.data = s->buffer->start;
                    638: 
                    639:         ngx_log_error(NGX_LOG_INFO, c->log, 0,
                    640:                       "client sent too long command \"%V\"", &l);
                    641: 
                    642:         s->quit = 1;
                    643: 
                    644:         return NGX_MAIL_PARSE_INVALID_COMMAND;
                    645:     }
                    646: 
                    647:     if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
                    648:         return rc;
                    649:     }
                    650: 
                    651:     if (rc == NGX_ERROR) {
                    652:         ngx_mail_close_connection(c);
                    653:         return NGX_ERROR;
                    654:     }
                    655: 
                    656:     return NGX_OK;
                    657: }
                    658: 
                    659: 
                    660: void
                    661: ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c)
                    662: {
                    663:     s->args.nelts = 0;
                    664:     s->buffer->pos = s->buffer->start;
                    665:     s->buffer->last = s->buffer->start;
                    666:     s->state = 0;
                    667: 
                    668:     if (c->read->timer_set) {
                    669:         ngx_del_timer(c->read);
                    670:     }
                    671: 
                    672:     s->login_attempt++;
                    673: 
                    674:     ngx_mail_auth_http_init(s);
                    675: }
                    676: 
                    677: 
                    678: void
                    679: ngx_mail_session_internal_server_error(ngx_mail_session_t *s)
                    680: {
                    681:     ngx_mail_core_srv_conf_t  *cscf;
                    682: 
                    683:     cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
                    684: 
                    685:     s->out = cscf->protocol->internal_server_error;
                    686:     s->quit = 1;
                    687: 
                    688:     ngx_mail_send(s->connection->write);
                    689: }
                    690: 
                    691: 
                    692: void
                    693: ngx_mail_close_connection(ngx_connection_t *c)
                    694: {
                    695:     ngx_pool_t  *pool;
                    696: 
                    697:     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    698:                    "close mail connection: %d", c->fd);
                    699: 
                    700: #if (NGX_MAIL_SSL)
                    701: 
                    702:     if (c->ssl) {
                    703:         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
                    704:             c->ssl->handler = ngx_mail_close_connection;
                    705:             return;
                    706:         }
                    707:     }
                    708: 
                    709: #endif
                    710: 
                    711: #if (NGX_STAT_STUB)
                    712:     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
                    713: #endif
                    714: 
                    715:     c->destroyed = 1;
                    716: 
                    717:     pool = c->pool;
                    718: 
                    719:     ngx_close_connection(c);
                    720: 
                    721:     ngx_destroy_pool(pool);
                    722: }
                    723: 
                    724: 
                    725: u_char *
                    726: ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len)
                    727: {
                    728:     u_char              *p;
                    729:     ngx_mail_session_t  *s;
                    730:     ngx_mail_log_ctx_t  *ctx;
                    731: 
                    732:     if (log->action) {
                    733:         p = ngx_snprintf(buf, len, " while %s", log->action);
                    734:         len -= p - buf;
                    735:         buf = p;
                    736:     }
                    737: 
                    738:     ctx = log->data;
                    739: 
                    740:     p = ngx_snprintf(buf, len, ", client: %V", ctx->client);
                    741:     len -= p - buf;
                    742:     buf = p;
                    743: 
                    744:     s = ctx->session;
                    745: 
                    746:     if (s == NULL) {
                    747:         return p;
                    748:     }
                    749: 
                    750:     p = ngx_snprintf(buf, len, "%s, server: %V",
                    751:                      s->starttls ? " using starttls" : "",
                    752:                      s->addr_text);
                    753:     len -= p - buf;
                    754:     buf = p;
                    755: 
                    756:     if (s->login.len == 0) {
                    757:         return p;
                    758:     }
                    759: 
                    760:     p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
                    761:     len -= p - buf;
                    762:     buf = p;
                    763: 
                    764:     if (s->proxy == NULL) {
                    765:         return p;
                    766:     }
                    767: 
                    768:     p = ngx_snprintf(buf, len, ", upstream: %V", s->proxy->upstream.name);
                    769: 
                    770:     return p;
                    771: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>