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); } } }
static void ngx_mail_auth_http_read_handler(ngx_event_t *rev) { ssize_t n, size; ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_auth_http_ctx_t *ctx; c = rev->data; s = c->data; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth http read handler"); ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); if (rev->timedout) { ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, "auth http server %V timed out", ctx->peer.name); ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } if (ctx->response == NULL) { ctx->response = ngx_create_temp_buf(ctx->pool, 1024); if (ctx->response == NULL) { ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } } size = ctx->response->end - ctx->response->last; n = ngx_recv(c, ctx->response->pos, size); if (n > 0) { ctx->response->last += n; ctx->handler(s, ctx); return; } if (n == NGX_AGAIN) { return; } ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); }
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); } }
static void ngx_mail_auth_http_block_read(ngx_event_t *rev) { ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_auth_http_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth http block read"); if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { c = rev->data; s = c->data; ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); ngx_close_connection(ctx->peer.connection); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); } }
static void ngx_mail_auth_http_write_handler(ngx_event_t *wev) { ssize_t n, size; ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_auth_http_ctx_t *ctx; ngx_mail_auth_http_conf_t *ahcf; c = wev->data; s = c->data; ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail auth http write handler"); if (wev->timedout) { ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT, "auth http server %V timed out", ctx->peer.name); ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } size = ctx->request->last - ctx->request->pos; n = ngx_send(c, ctx->request->pos, size); if (n == NGX_ERROR) { ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); return; } if (n > 0) { ctx->request->pos += n; if (n == size) { wev->handler = ngx_mail_auth_http_dummy_handler; if (wev->timer_set) { ngx_del_timer(wev); } if (ngx_handle_write_event(wev, 0) == NGX_ERROR) { ngx_close_connection(c); ngx_destroy_pool(ctx->pool); ngx_mail_session_internal_server_error(s); } return; } } if (!wev->timer_set) { ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module); ngx_add_timer(wev, ahcf->timeout); } }
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; } }