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

📄 ngx_mail_auth_http_module.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 3 页
字号:
            key.data = ctx->header_name_start;            value.len = ctx->header_end - ctx->header_start;            value.data = ctx->header_start;            ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,                           "mail auth http header: \"%V: %V\"",                           &key, &value);            }#endif            len = ctx->header_name_end - ctx->header_name_start;            if (len == sizeof("Auth-Status") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Status",                                   sizeof("Auth-Status") - 1)                   == 0)            {                len = ctx->header_end - ctx->header_start;                if (len == 2                    && ctx->header_start[0] == 'O'                    && ctx->header_start[1] == 'K')                {                    continue;                }                if (len == 4                    && ctx->header_start[0] == 'W'                    && ctx->header_start[1] == 'A'                    && ctx->header_start[2] == 'I'                    && ctx->header_start[3] == 'T')                {                    s->auth_wait = 1;                    continue;                }                ctx->errmsg.len = len;                ctx->errmsg.data = ctx->header_start;                switch (s->protocol) {                case NGX_MAIL_POP3_PROTOCOL:                    size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1;                    break;                case NGX_MAIL_IMAP_PROTOCOL:                    size = s->tag.len + sizeof("NO ") - 1 + len                           + sizeof(CRLF) - 1;                    break;                default: /* NGX_MAIL_SMTP_PROTOCOL */                    ctx->err = ctx->errmsg;                    continue;                }                p = ngx_pcalloc(s->connection->pool, size);                if (p == NULL) {                    ngx_close_connection(ctx->peer.connection);                    ngx_destroy_pool(ctx->pool);                    ngx_mail_session_internal_server_error(s);                    return;                }                ctx->err.data = p;                switch (s->protocol) {                case NGX_MAIL_POP3_PROTOCOL:                    *p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' ';                    break;                case NGX_MAIL_IMAP_PROTOCOL:                    p = ngx_cpymem(p, s->tag.data, s->tag.len);                    *p++ = 'N'; *p++ = 'O'; *p++ = ' ';                    break;                default: /* NGX_MAIL_SMTP_PROTOCOL */                    break;                }                p = ngx_cpymem(p, ctx->header_start, len);                *p++ = CR; *p++ = LF;                ctx->err.len = p - ctx->err.data;                continue;            }            if (len == sizeof("Auth-Server") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Server",                                   sizeof("Auth-Server") - 1)                    == 0)            {                ctx->addr.len = ctx->header_end - ctx->header_start;                ctx->addr.data = ctx->header_start;                continue;            }            if (len == sizeof("Auth-Port") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Port",                                   sizeof("Auth-Port") - 1)                   == 0)            {                ctx->port.len = ctx->header_end - ctx->header_start;                ctx->port.data = ctx->header_start;                continue;            }            if (len == sizeof("Auth-User") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-User",                                   sizeof("Auth-User") - 1)                   == 0)            {                s->login.len = ctx->header_end - ctx->header_start;                s->login.data = ngx_palloc(s->connection->pool, s->login.len);                if (s->login.data == NULL) {                    ngx_close_connection(ctx->peer.connection);                    ngx_destroy_pool(ctx->pool);                    ngx_mail_session_internal_server_error(s);                    return;                }                ngx_memcpy(s->login.data, ctx->header_start, s->login.len);                continue;            }            if (len == sizeof("Auth-Pass") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Pass",                                   sizeof("Auth-Pass") - 1)                   == 0)            {                s->passwd.len = ctx->header_end - ctx->header_start;                s->passwd.data = ngx_palloc(s->connection->pool, s->passwd.len);                if (s->passwd.data == NULL) {                    ngx_close_connection(ctx->peer.connection);                    ngx_destroy_pool(ctx->pool);                    ngx_mail_session_internal_server_error(s);                    return;                }                ngx_memcpy(s->passwd.data, ctx->header_start, s->passwd.len);                continue;            }            if (len == sizeof("Auth-Wait") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Wait",                                   sizeof("Auth-Wait") - 1)                   == 0)            {                n = ngx_atoi(ctx->header_start,                             ctx->header_end - ctx->header_start);                if (n != NGX_ERROR) {                    ctx->sleep = n;                }                continue;            }            if (len == sizeof("Auth-Error-Code") - 1                && ngx_strncasecmp(ctx->header_name_start,                                   (u_char *) "Auth-Error-Code",                                   sizeof("Auth-Error-Code") - 1)                   == 0)            {                ctx->errcode.len = ctx->header_end - ctx->header_start;                ctx->errcode.data = ngx_palloc(s->connection->pool,                                               ctx->errcode.len);                if (ctx->errcode.data == NULL) {                    ngx_close_connection(ctx->peer.connection);                    ngx_destroy_pool(ctx->pool);                    ngx_mail_session_internal_server_error(s);                    return;                }                ngx_memcpy(ctx->errcode.data, ctx->header_start,                           ctx->errcode.len);                continue;            }            /* ignore other headers */            continue;        }        if (rc == NGX_DONE) {            ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,                           "mail auth http header done");            ngx_close_connection(ctx->peer.connection);            if (ctx->err.len) {                ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,                              "client login failed: \"%V\"", &ctx->errmsg);                if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) {                    if (ctx->errcode.len == 0) {                        ctx->errcode = ngx_mail_smtp_errcode;                    }                    ctx->err.len = ctx->errcode.len + ctx->errmsg.len                                   + sizeof(" " CRLF) - 1;                    p = ngx_palloc(s->connection->pool, ctx->err.len);                    if (p == NULL) {                        ngx_close_connection(ctx->peer.connection);                        ngx_destroy_pool(ctx->pool);                        ngx_mail_session_internal_server_error(s);                        return;                    }                    ctx->err.data = p;                    p = ngx_cpymem(p, ctx->errcode.data, ctx->errcode.len);                    *p++ = ' ';                    p = ngx_cpymem(p, ctx->errmsg.data, ctx->errmsg.len);                    *p++ = CR; *p = LF;                }                s->out = ctx->err;                timer = ctx->sleep;                ngx_destroy_pool(ctx->pool);                if (timer == 0) {                    s->quit = 1;                    ngx_mail_send(s->connection->write);                    return;                }                ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000));                s->connection->read->handler = ngx_mail_auth_sleep_handler;                return;            }            if (s->auth_wait) {                timer = ctx->sleep;                ngx_destroy_pool(ctx->pool);                if (timer == 0) {                    ngx_mail_auth_http_init(s);                    return;                }                ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000));                s->connection->read->handler = ngx_mail_auth_sleep_handler;                return;            }            if (ctx->addr.len == 0 || ctx->port.len == 0) {                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,                              "auth http server %V did not send server or port",                              ctx->peer.name);                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            if (s->passwd.data == NULL                && s->protocol != NGX_MAIL_SMTP_PROTOCOL)            {                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,                              "auth http server %V did not send password",                              ctx->peer.name);                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));            if (peer == NULL) {                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            sin = ngx_pcalloc(s->connection->pool, sizeof(struct sockaddr_in));            if (sin == NULL) {                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            sin->sin_family = AF_INET;            port = ngx_atoi(ctx->port.data, ctx->port.len);            if (port == NGX_ERROR || port < 1 || port > 65536) {                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,                              "auth http server %V sent invalid server "                              "port:\"%V\"",                              ctx->peer.name, &ctx->port);                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            sin->sin_port = htons((in_port_t) port);            ctx->addr.data[ctx->addr.len] = '\0';            sin->sin_addr.s_addr = inet_addr((char *) ctx->addr.data);            if (sin->sin_addr.s_addr == INADDR_NONE) {                ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,                              "auth http server %V sent invalid server "                              "address:\"%V\"",                              ctx->peer.name, &ctx->addr);                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            peer->sockaddr = (struct sockaddr *) sin;            peer->socklen = sizeof(struct sockaddr_in);            len = ctx->addr.len + 1 + ctx->port.len;            peer->name.len = len;            peer->name.data = ngx_palloc(s->connection->pool, len);            if (peer->name.data == NULL) {                ngx_destroy_pool(ctx->pool);                ngx_mail_session_internal_server_error(s);                return;            }            len = ctx->addr.len;            ngx_memcpy(peer->name.data, ctx->addr.data, len);            peer->name.data[len++] = ':';            ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);            ngx_destroy_pool(ctx->pool);            ngx_mail_proxy_init(s, peer);            return;        }        if (rc == NGX_AGAIN ) {            return;        }        /* rc == NGX_ERROR */        ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,                      "auth http server %V sent invalid header in response",                      ctx->peer.name);        ngx_close_connection(ctx->peer.connection);        ngx_destroy_pool(ctx->pool);        ngx_mail_session_internal_server_error(s);        return;    }}static voidngx_mail_auth_sleep_handler(ngx_event_t *rev){    ngx_connection_t          *c;    ngx_mail_session_t        *s;    ngx_mail_core_srv_conf_t  *cscf;    ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth sleep handler");    c = rev->data;    s = c->data;    if (rev->timedout) {        rev->timedout = 0;        if (s->auth_wait) {            s->auth_wait = 0;            ngx_mail_auth_http_init(s);            return;        }        cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);        rev->handler = cscf->protocol->auth_state;        s->mail_state = 0;        s->auth_method = NGX_MAIL_AUTH_PLAIN;        c->log->action = "in auth state";        ngx_mail_send(c->write);        if (c->destroyed) {            return;        }        ngx_add_timer(rev, cscf->timeout);        if (rev->ready) {            rev->handler(rev);            return;        }        if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {            ngx_mail_close_connection(c);        }        return;    }    if (rev->active) {        if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {            ngx_mail_close_connection(c);        }    }}static ngx_int_tngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s,    ngx_mail_auth_http_ctx_t *ctx){    u_char      c, ch, *p;    ngx_uint_t  hash;    enum {        sw_start = 0,        sw_name,        sw_space_before_value,        sw_value,        sw_space_after_value,        sw_almost_done,        sw_header_almost_done    } state;    state = ctx->state;    hash = ctx->hash;    for (p = ctx->response->pos; p < ctx->response->last; p++) {        ch = *p;        switch (state) {        /* first char */        case sw_start:            switch (ch) {            case CR:                ctx->header_end = p;                state = sw_header_almost_done;                break;            case LF:                ctx->header_end = p;                goto header_done;            default:                state = sw_name;                ctx->header_name_start = p;

⌨️ 快捷键说明

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