コード例 #1
0
static void
ngx_mail_zmauth_wait_handler(ngx_event_t *ev) {
    ngx_connection_t *c;
    ngx_mail_session_t *s;
    ngx_mail_zmauth_ctx_t *ctx;

    ngx_log_debug0(NGX_LOG_DEBUG_MAIL, ev->log, 0, "mail zmauth wait handler");

    c = ev->data;
    s = c->data;
    ctx = ngx_mail_get_module_ctx(s, ngx_mail_zmauth_module);

    if (ev->timedout) {
        /* we need to close the connection immediately */

        ngx_destroy_pool(ctx->pool);
        ngx_mail_set_ctx(s, NULL, ngx_mail_zmauth_module);
        s->quit = 1;
        ngx_mail_send(c->write);

        return;
    }

    if (ev->active) {
        if (ngx_handle_read_event(ev, 0) != NGX_OK) {
            ngx_mail_close_connection(c);
        }
    }
}
コード例 #2
0
static void
ngx_mail_zmauth_cleanup (void * data)
{
    ngx_mail_session_t * s;
    ngx_mail_zmauth_ctx_t * ctx;
    s = (ngx_mail_session_t *)data;
    ctx = ngx_mail_get_module_ctx(s, ngx_mail_zmauth_module);
    if (ctx != NULL) {
        ngx_zm_lookup_finalize(ctx->work);
        ngx_destroy_pool(ctx->pool);
        ngx_mail_set_ctx(s, NULL, ngx_mail_zmauth_module);
    }
}
コード例 #3
0
void
ngx_mail_auth_http_init(ngx_mail_session_t *s)
{
    ngx_int_t                   rc;
    ngx_pool_t                 *pool;
    ngx_mail_auth_http_ctx_t   *ctx;
    ngx_mail_auth_http_conf_t  *ahcf;

    s->connection->log->action = "in http auth state";

    pool = ngx_create_pool(2048, s->connection->log);
    if (pool == NULL) {
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ctx = ngx_pcalloc(pool, sizeof(ngx_mail_auth_http_ctx_t));
    if (ctx == NULL) {
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ctx->pool = pool;

    ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module);

    ctx->request = ngx_mail_auth_http_create_request(s, pool, ahcf);
    if (ctx->request == NULL) {
        ngx_destroy_pool(ctx->pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ngx_mail_set_ctx(s, ctx, ngx_mail_auth_http_module);

    ctx->peer.sockaddr = ahcf->peer->sockaddr;
    ctx->peer.socklen = ahcf->peer->socklen;
    ctx->peer.name = &ahcf->peer->name;
    ctx->peer.get = ngx_event_get_peer;
    ctx->peer.log = s->connection->log;
    ctx->peer.log_error = NGX_ERROR_ERR;

    rc = ngx_event_connect_peer(&ctx->peer);

    if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
        if (ctx->peer.connection) {
            ngx_close_connection(ctx->peer.connection);
        }

        ngx_destroy_pool(ctx->pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ctx->peer.connection->data = s;
    ctx->peer.connection->pool = s->connection->pool;

    s->connection->read->handler = ngx_mail_auth_http_block_read;
    ctx->peer.connection->read->handler = ngx_mail_auth_http_read_handler;
    ctx->peer.connection->write->handler = ngx_mail_auth_http_write_handler;

    ctx->handler = ngx_mail_auth_http_ignore_status_line;

    ngx_add_timer(ctx->peer.connection->read, ahcf->timeout);
    ngx_add_timer(ctx->peer.connection->write, ahcf->timeout);

    if (rc == NGX_OK) {
        ngx_mail_auth_http_write_handler(ctx->peer.connection->write);
        return;
    }
}
コード例 #4
0
void
ngx_mail_zmauth_init(ngx_mail_session_t *s) {
    ngx_pool_t *pool;
    ngx_mail_zmauth_ctx_t    *ctx;
    ngx_zm_lookup_work_t     *work;
    ngx_str_t                 escaped_login, escaped_account_name;
    ngx_mail_cleanup_t       *cln;
    ngx_flag_t                proxy_ssl;

    s->connection->log->action = "in mail zmauth state";

    /* create pool and module context */
    pool = ngx_create_pool(2048, s->connection->log);
    if (pool == NULL) {
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ctx = ngx_pcalloc(pool, sizeof(ngx_mail_zmauth_ctx_t));
    if (ctx == NULL) {
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    ctx->pool = pool;
    ngx_mail_set_ctx(s, ctx, ngx_mail_zmauth_module);

    /* init clean up */
    cln = ngx_mail_cleanup_add(s, 0);
    cln->data = s;
    cln->handler = ngx_mail_zmauth_cleanup;

    /* init wait event */
    ctx->wait_ev = ngx_palloc(pool, sizeof(ngx_event_t));
    if (ctx->wait_ev == NULL) {
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }
    ngx_memzero (ctx->wait_ev, sizeof (ngx_event_t));
    ctx->wait_ev->handler = ngx_mail_zmauth_wait_handler;
    ctx->wait_ev->log = s->connection->log;
    ctx->wait_ev->data = s->connection;

    work = ngx_pcalloc(pool, sizeof(ngx_zm_lookup_work_t));
    if (work == NULL) {
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    if (s->auth_method == NGX_MAIL_AUTH_PASSWD    ||
        s->auth_method == NGX_MAIL_AUTH_PLAIN     ||
        s->auth_method == NGX_MAIL_AUTH_PLAIN_IR  ||
        s->auth_method == NGX_MAIL_AUTH_LOGIN     ||
        s->auth_method == NGX_MAIL_AUTH_LOGIN_USERNAME) {
        work->auth_method = ZM_AUTHMETH_USERNAME;
    } else if (s->auth_method == NGX_MAIL_AUTH_GSSAPI ||
               s->auth_method == NGX_MAIL_AUTH_GSSAPI_IR) {
        work->auth_method = ZM_AUTHMETH_GSSAPI;
        work->auth_id = s->authid;
    } else {
        ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
                "unsupported auth method %V",
                &ngx_mail_zmauth_method[s->auth_method]);
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    proxy_ssl = ngx_mail_get_proxy_ssl(s);

    switch (s->protocol) {
    case NGX_MAIL_POP3_PROTOCOL:
        work->protocol = proxy_ssl?ZM_PROTO_POP3S:ZM_PROTO_POP3;
        break;
    case NGX_MAIL_IMAP_PROTOCOL:
        work->protocol = proxy_ssl?ZM_PROTO_IMAPS:ZM_PROTO_IMAP;
        break;
    default:
        ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
                "unsupported auth protocol %V",
                &ngx_mail_zmauth_proto[s->protocol]);
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }

    if (ngx_mail_zmauth_escape(pool, &s->login, &escaped_login) != NGX_OK) {
        ngx_destroy_pool(pool);
        ngx_mail_session_internal_server_error(s);
        return;
    }
    work->username = escaped_login;

    work->connection = s->connection;
    work->login_attempts = s->login_attempt;
    work->log = s->connection->log;
    work->pool = s->connection->pool;
    work->data = s;
    work->on_success = ngx_mail_zmauth_lookup_result_handler;
    work->on_failure = ngx_mail_zmauth_lookup_result_handler;

    switch (s->vlogin) {
    case 0:
        work->alias_check_stat = ZM_ALIAS_NOT_CHECKED;
        break;
    case 1:
        work->alias_check_stat = ZM_ALIAS_NOT_FOUND;
        work->account_name = work->username;
        work->alias_key = s->key_alias;
        break;
    case 2:
        work->alias_check_stat = ZM_ALIAS_FOUND;
        if (ngx_mail_zmauth_escape(pool, &s->qlogin,
                                   &escaped_account_name) != NGX_OK) {
            ngx_destroy_pool(pool);
            ngx_mail_session_internal_server_error(s);
            return;
        }
        work->account_name = escaped_account_name;
        work->alias_key = s->key_alias;
        break;
    default:
        ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
                "Should never reach here");
        return;
    }

    ctx->work = work;

    s->connection->read->handler = ngx_mail_zmauth_block_read;

    ngx_zm_lookup(work);
}
コード例 #5
0
static void
ngx_mail_zmauth_lookup_result_handler(ngx_zm_lookup_work_t * work) {
    ngx_mail_session_t     *s;
    ngx_mail_zmauth_ctx_t  *ctx;
    size_t                  size;
    u_char                 *p;
    ngx_addr_t             *peer;
    ngx_str_t               errmsg;

    s = (ngx_mail_session_t *) work->data;
    ctx = (ngx_mail_zmauth_ctx_t *)ngx_mail_get_module_ctx(s, ngx_mail_zmauth_module);

    if (work->result == ZM_LOOKUP_SUCCESS) {
        ngx_mail_zmauth_unescape(&work->account_name);

        /* copy the lookup result from zmauth pool to s->connection pool */
        s->qlogin = *(ngx_pstrcpy(s->connection->pool, &work->account_name));
        s->key_alias = *(ngx_pstrcpy(s->connection->pool, &work->alias_key));
        s->key_route = *(ngx_pstrcpy(s->connection->pool, &work->route_key));
        if (s->auth_method == NGX_MAIL_AUTH_GSSAPI ||
            s->auth_method == NGX_MAIL_AUTH_GSSAPI_IR) {
            s->dusr = *(ngx_pstrcpy(s->connection->pool, &work->auth_id));
            s->dpasswd = *(ngx_pstrcpy(s->connection->pool, &work->zm_auth_token));
        }
        peer = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));

        peer->name = *(ngx_pstrcpy(s->connection->pool, &work->route->name));
        peer->socklen = work->route->socklen;
        peer->sockaddr = ngx_palloc(s->connection->pool, peer->socklen);
        if(peer->sockaddr == NULL) {
            return; /* NO MEM */
        }
        ngx_memcpy(peer->sockaddr, work->route->sockaddr, peer->socklen);

        switch (work->alias_check_stat) {
           case ZM_ALIAS_NOT_FOUND:
               s->vlogin = 1;
               break;
           case ZM_ALIAS_FOUND:
               s->vlogin = 2;
               break;
           default:
               break;
               /* do nothing */
           }

        ngx_destroy_pool(ctx->pool);
        ngx_mail_set_ctx(s, NULL, ngx_mail_zmauth_module);
        ngx_mail_proxy_init(s, peer);
        return;
    } else {
        ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
                      "An error occurred in mail zmauth: %V",
                       &work->err);

        /* construct error msg */
        if (work->result != ZM_LOOKUP_LOGIN_FAILED) {
            /* zmauth clean up will destroy the ctx->pool */
            ngx_mail_session_internal_server_error(s);
            return;
        }

        errmsg = LOGIN_FAILED; /* should we return the real err msg to user? */

        switch (s->protocol) {

        case NGX_MAIL_POP3_PROTOCOL:
            size = sizeof("-ERR ") - 1 + errmsg.len + sizeof(CRLF) - 1;
            if (s->command == NGX_POP3_AUTH) {
                size +=  AUTHENTICATION_FAILED.len;
            }
            break;

        case NGX_MAIL_IMAP_PROTOCOL:
            if (s->command == NGX_IMAP_AUTHENTICATE) {
                errmsg = AUTHENTICATE_FAILED;
            }
            size = s->tag.len + 1 /*for space*/+ sizeof("NO ") - 1 + errmsg.len
                   + sizeof(CRLF) - 1;
            break;

        default: /* NGX_MAIL_SMTP_PROTOCOL */
            ngx_log_error(NGX_LOG_CRIT, s->connection->log, 0, "smtp is not supported!!");
            return;
        }

        p = ngx_pnalloc(s->connection->pool, size);
        if (p == NULL) {
            ngx_destroy_pool(ctx->pool);
            ngx_mail_session_internal_server_error(s);
            return;
        }

        ctx->errmsg.data = p;

        switch (s->protocol) {

        case NGX_MAIL_POP3_PROTOCOL:
            *p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' ';
            if (s->command == NGX_POP3_AUTH) {
                p = ngx_cpymem(p, AUTHENTICATION_FAILED.data, AUTHENTICATION_FAILED.len);
            }
            break;

        case NGX_MAIL_IMAP_PROTOCOL:
            p = ngx_cpymem(p, s->tag.data, s->tag.len);
            *p++ = ' '; *p++ = 'N'; *p++ = 'O'; *p++ = ' ';
            break;

        default: /* NGX_MAIL_SMTP_PROTOCOL */
            break;
        }

        p = ngx_cpymem(p, errmsg.data, errmsg.len);
        *p++ = CR; *p++ = LF;

        ctx->errmsg.len = p - ctx->errmsg.data;
        s->out = ctx->errmsg;

        if (work->result == ZM_LOOKUP_LOGIN_FAILED && work->wait_time > 0) {
            ngx_add_timer(ctx->wait_ev, (ngx_msec_t) (work->wait_time * 1000));

            s->connection->read->handler = ngx_mail_zmauth_block_read;
        } else {
            s->quit = 1;
            ngx_mail_send(s->connection->write);
            ngx_mail_set_ctx(s, NULL, ngx_mail_zmauth_module);
            ngx_destroy_pool(ctx->pool);
        }
        return;
    }
}