⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_mail_smtp_handler.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_event.h>#include <ngx_mail.h>#include <ngx_mail_smtp_module.h>static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);static void ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c);static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s,    ngx_connection_t *c);static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c);static ngx_int_t ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c);static ngx_int_t ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c);static ngx_int_t ngx_mail_smtp_starttls(ngx_mail_session_t *s,    ngx_connection_t *c);static ngx_int_t ngx_mail_smtp_discard_command(ngx_mail_session_t *s,    ngx_connection_t *c, char *err);static void ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s,    ngx_connection_t *c, char *err);static u_char  smtp_ok[] = "250 2.0.0 OK" CRLF;static u_char  smtp_bye[] = "221 2.0.0 Bye" CRLF;static u_char  smtp_starttls[] = "220 2.0.0 Start TLS" CRLF;static u_char  smtp_next[] = "334 " CRLF;static u_char  smtp_username[] = "334 VXNlcm5hbWU6" CRLF;static u_char  smtp_password[] = "334 UGFzc3dvcmQ6" CRLF;static u_char  smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF;static u_char  smtp_invalid_pipelining[] =   "503 5.5.0 Improper use of SMTP command pipelining" CRLF;static u_char  smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF;static u_char  smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF;static ngx_str_t  smtp_unavailable = ngx_string("[UNAVAILABLE]");static ngx_str_t  smtp_tempunavail = ngx_string("[TEMPUNAVAIL]");voidngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c){    struct sockaddr_in        *sin;    ngx_resolver_ctx_t        *ctx;    ngx_mail_core_srv_conf_t  *cscf;    cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);    if (cscf->resolver == NULL) {        s->host = smtp_unavailable;        ngx_mail_smtp_greeting(s, c);        return;    }    c->log->action = "in resolving client address";    ctx = ngx_resolve_start(cscf->resolver, NULL);    if (ctx == NULL) {        ngx_mail_close_connection(c);        return;    }    /* AF_INET only */    sin = (struct sockaddr_in *) c->sockaddr;    ctx->addr = sin->sin_addr.s_addr;    ctx->handler = ngx_mail_smtp_resolve_addr_handler;    ctx->data = s;    ctx->timeout = cscf->resolver_timeout;    if (ngx_resolve_addr(ctx) != NGX_OK) {        ngx_mail_close_connection(c);    }}static voidngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx){    ngx_connection_t          *c;    ngx_mail_session_t        *s;    ngx_mail_core_srv_conf_t  *cscf;    s = ctx->data;    c = s->connection;    if (ctx->state) {        ngx_log_error(NGX_LOG_ERR, c->log, 0,                      "%V could not be resolved (%i: %s)",                      &c->addr_text, ctx->state,                      ngx_resolver_strerror(ctx->state));        if (ctx->state == NGX_RESOLVE_NXDOMAIN) {            s->host = smtp_unavailable;        } else {            s->host = smtp_tempunavail;        }        ngx_resolve_addr_done(ctx);        ngx_mail_smtp_greeting(s, s->connection);        return;    }    c->log->action = "in resolving client hostname";    s->host.data = ngx_pstrdup(c->pool, &ctx->name);    if (s->host.data == NULL) {        ngx_resolve_addr_done(ctx);        ngx_mail_close_connection(c);        return;    }    s->host.len = ctx->name.len;    ngx_resolve_addr_done(ctx);    ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,                   "address resolved: %V", &s->host);    cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);    ctx = ngx_resolve_start(cscf->resolver, NULL);    if (ctx == NULL) {        ngx_mail_close_connection(c);        return;    }    ctx->name = s->host;    ctx->type = NGX_RESOLVE_A;    ctx->handler = ngx_mail_smtp_resolve_name_handler;    ctx->data = s;    ctx->timeout = cscf->resolver_timeout;    if (ngx_resolve_name(ctx) != NGX_OK) {        ngx_mail_close_connection(c);    }}static voidngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx){    in_addr_t            addr;    ngx_uint_t           i;    ngx_connection_t    *c;    struct sockaddr_in  *sin;    ngx_mail_session_t  *s;    s = ctx->data;    c = s->connection;    if (ctx->state) {        ngx_log_error(NGX_LOG_ERR, c->log, 0,                      "%V could not be resolved (%i: %s)",                      &ctx->name, ctx->state,                      ngx_resolver_strerror(ctx->state));        if (ctx->state == NGX_RESOLVE_NXDOMAIN) {            s->host = smtp_unavailable;        } else {            s->host = smtp_tempunavail;        }    } else {        /* AF_INET only */        sin = (struct sockaddr_in *) c->sockaddr;        for (i = 0; i < ctx->naddrs; i++) {            addr = ctx->addrs[i];            ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0,                           "name was resolved to %ud.%ud.%ud.%ud",                           (ntohl(addr) >> 24) & 0xff,                           (ntohl(addr) >> 16) & 0xff,                           (ntohl(addr) >> 8) & 0xff,                           ntohl(addr) & 0xff);            if (addr == sin->sin_addr.s_addr) {                goto found;            }        }        s->host = smtp_unavailable;    }found:    ngx_resolve_name_done(ctx);    ngx_mail_smtp_greeting(s, c);}static voidngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c){    ngx_msec_t                 timeout;    ngx_mail_core_srv_conf_t  *cscf;    ngx_mail_smtp_srv_conf_t  *sscf;    ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,                   "smtp greeting for \"%V\"", &s->host);    cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);    sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);    timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;    ngx_add_timer(c->read, timeout);    if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {        ngx_mail_close_connection(c);    }    if (sscf->greeting_delay) {         c->read->handler = ngx_mail_smtp_invalid_pipelining;         return;    }    c->read->handler = ngx_mail_smtp_init_protocol;    s->out = sscf->greeting;    ngx_mail_send(c->write);}static voidngx_mail_smtp_invalid_pipelining(ngx_event_t *rev){    ngx_connection_t          *c;    ngx_mail_session_t        *s;    ngx_mail_core_srv_conf_t  *cscf;    ngx_mail_smtp_srv_conf_t  *sscf;    c = rev->data;    s = c->data;    c->log->action = "in delay pipelining state";    if (rev->timedout) {        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "delay greeting");        rev->timedout = 0;        cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);        c->read->handler = ngx_mail_smtp_init_protocol;        ngx_add_timer(c->read, cscf->timeout);        if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {            ngx_mail_close_connection(c);            return;        }        sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);        s->out = sscf->greeting;    } else {        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "invalid pipelining");        if (s->buffer == NULL) {            if (ngx_mail_smtp_create_buffer(s, c) != NGX_OK) {                return;            }        }        if (ngx_mail_smtp_discard_command(s, c,                                "client was rejected before greeting: \"%V\"")            != NGX_OK)        {            return;        }        s->out.len = sizeof(smtp_invalid_pipelining) - 1;        s->out.data = smtp_invalid_pipelining;    }    ngx_mail_send(c->write);}voidngx_mail_smtp_init_protocol(ngx_event_t *rev){    ngx_connection_t    *c;    ngx_mail_session_t  *s;    c = rev->data;    c->log->action = "in auth state";    if (rev->timedout) {        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");        c->timedout = 1;        ngx_mail_close_connection(c);        return;    }    s = c->data;    if (s->buffer == NULL) {        if (ngx_mail_smtp_create_buffer(s, c) != NGX_OK) {            return;        }    }    s->mail_state = ngx_smtp_start;    c->read->handler = ngx_mail_smtp_auth_state;    ngx_mail_smtp_auth_state(rev);}static ngx_int_tngx_mail_smtp_create_buffer(ngx_mail_session_t *s, ngx_connection_t *c){    ngx_mail_smtp_srv_conf_t  *sscf;    if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {        ngx_mail_session_internal_server_error(s);        return NGX_ERROR;    }    sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);    s->buffer = ngx_create_temp_buf(c->pool, sscf->client_buffer_size);    if (s->buffer == NULL) {        ngx_mail_session_internal_server_error(s);        return NGX_ERROR;    }    return NGX_OK;}voidngx_mail_smtp_auth_state(ngx_event_t *rev){    ngx_int_t            rc;    ngx_connection_t    *c;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -