Mercurial > dovecot > original-hg > dovecot-1.2
view src/auth/login-connection.c @ 0:3b1985cbc908 HEAD
Initial revision
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 09 Aug 2002 12:15:38 +0300 |
parents | |
children | 1b34ec11fff8 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "common.h" #include "network.h" #include "iobuffer.h" #include "login-connection.h" #include <stdlib.h> #include <syslog.h> #define MAX_INBUF_SIZE \ (sizeof(AuthContinuedRequestData) + AUTH_MAX_REQUEST_DATA_SIZE) #define MAX_OUTBUF_SIZE \ (10 * (sizeof(AuthReplyData) + AUTH_MAX_REPLY_DATA_SIZE)) struct _LoginConnection { LoginConnection *next; int fd; IO io; IOBuffer *inbuf, *outbuf; AuthRequestType type; }; static AuthInitData auth_init_data; static LoginConnection *connections; static void request_callback(AuthReplyData *reply, const unsigned char *data, void *user_data) { LoginConnection *conn = user_data; i_assert(reply->data_size <= AUTH_MAX_REPLY_DATA_SIZE); if (io_buffer_send(conn->outbuf, reply, sizeof(AuthReplyData)) < 0) login_connection_destroy(conn); else if (reply->data_size > 0) { if (io_buffer_send(conn->outbuf, data, reply->data_size) < 0) login_connection_destroy(conn); } } static void login_input(void *user_data, int fd __attr_unused__, IO io __attr_unused__) { LoginConnection *conn = user_data; unsigned char *data; unsigned int size; switch (io_buffer_read(conn->inbuf)) { case 0: return; case -1: /* disconnected */ login_connection_destroy(conn); return; case -2: /* buffer full */ i_error("BUG: imap-login sent us more than %d bytes of data", (int)MAX_INBUF_SIZE); login_connection_destroy(conn); return; } data = io_buffer_get_data(conn->inbuf, &size); if (size < sizeof(AuthRequestType)) return; /* note that we can't directly cast the received data pointer into structures, as it may not be aligned properly. */ if (conn->type == AUTH_REQUEST_NONE) { /* get the request type */ memcpy(&conn->type, data, sizeof(AuthRequestType)); } if (conn->type == AUTH_REQUEST_INIT) { AuthInitRequestData request; if (size < sizeof(request)) return; memcpy(&request, data, sizeof(request)); conn->inbuf->skip += sizeof(request); /* we have a full init request */ auth_init_request(&request, request_callback, conn); conn->type = AUTH_REQUEST_NONE; } else if (conn->type == AUTH_REQUEST_CONTINUE) { AuthContinuedRequestData request; if (size < sizeof(request)) return; memcpy(&request, data, sizeof(request)); if (size < sizeof(request) + request.data_size) return; conn->inbuf->skip += sizeof(request) + request.data_size; /* we have a full continued request */ auth_continue_request(&request, data + sizeof(request), request_callback, conn); conn->type = AUTH_REQUEST_NONE; } else { /* unknown request */ i_error("BUG: imap-login sent us unknown request %u", conn->type); login_connection_destroy(conn); } } LoginConnection *login_connection_create(int fd) { LoginConnection *conn; conn = i_new(LoginConnection, 1); conn->fd = fd; conn->inbuf = io_buffer_create(fd, default_pool, IO_PRIORITY_DEFAULT, MAX_INBUF_SIZE); conn->outbuf = io_buffer_create(fd, default_pool, IO_PRIORITY_DEFAULT, MAX_OUTBUF_SIZE); conn->io = io_add(fd, IO_READ, login_input, conn); conn->type = AUTH_REQUEST_NONE; conn->next = connections; connections = conn; if (io_buffer_send(conn->outbuf, &auth_init_data, sizeof(auth_init_data)) < 0) { login_connection_destroy(conn); conn = NULL; } return conn; } void login_connection_destroy(LoginConnection *conn) { LoginConnection **pos; for (pos = &connections; *pos != NULL; pos = &(*pos)->next) { if (*pos == conn) { *pos = conn->next; break; } } io_buffer_close(conn->inbuf); io_buffer_close(conn->outbuf); io_remove(conn->io); net_disconnect(conn->fd); i_free(conn); } void login_connections_init(void) { const char *env; env = getenv("AUTH_PROCESS"); if (env == NULL) i_fatal("AUTH_PROCESS environment is unset"); memset(&auth_init_data, 0, sizeof(auth_init_data)); auth_init_data.auth_process = atoi(env); auth_init_data.auth_methods = auth_methods; connections = NULL; } void login_connections_deinit(void) { LoginConnection *next; while (connections != NULL) { next = connections->next; login_connection_destroy(connections); connections = next; } }