Annotation of embedaddon/nginx/src/mail/ngx_mail_handler.c, revision 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>