[dovecot-cvs] dovecot/src/auth Makefile.am, 1.42,
1.43 auth-client-connection.c, 1.32,
1.33 auth-client-connection.h, 1.8,
1.9 auth-master-connection.c, 1.24,
1.25 auth-master-connection.h, 1.7, 1.8 auth-request-handler.c,
NONE, 1.1 auth-request-handler.h, NONE, 1.1 auth-request.c,
1.6, 1.7 auth-request.h, 1.6, 1.7 main.c, 1.36,
1.37 mech-apop.c, 1.14, 1.15
cras at dovecot.org
cras at dovecot.org
Sun Jan 9 02:49:21 EET 2005
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv27365/auth
Modified Files:
Makefile.am auth-client-connection.c auth-client-connection.h
auth-master-connection.c auth-master-connection.h
auth-request.c auth-request.h main.c mech-apop.c
Added Files:
auth-request-handler.c auth-request-handler.h
Log Message:
Moving code around.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/Makefile.am,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- Makefile.am 7 Jan 2005 19:55:49 -0000 1.42
+++ Makefile.am 9 Jan 2005 00:49:18 -0000 1.43
@@ -38,6 +38,7 @@
auth-master-connection.c \
auth-module.c \
auth-request.c \
+ auth-request-handler.c \
db-ldap.c \
db-sql.c \
db-passwd-file.c \
@@ -80,6 +81,7 @@
auth-master-connection.h \
auth-module.h \
auth-request.h \
+ auth-request-handler.h \
db-ldap.h \
db-sql.h \
db-passwd-file.h \
Index: auth-client-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-client-connection.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- auth-client-connection.c 8 Jan 2005 21:37:32 -0000 1.32
+++ auth-client-connection.c 9 Jan 2005 00:49:18 -0000 1.33
@@ -1,39 +1,32 @@
-/* Copyright (C) 2002-2003 Timo Sirainen */
+/* Copyright (C) 2002-2005 Timo Sirainen */
#include "common.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "network.h"
-#include "base64.h"
-#include "buffer.h"
-#include "hash.h"
#include "str.h"
-#include "str-sanitize.h"
#include "safe-memset.h"
-#include "auth-request.h"
+#include "auth-request-handler.h"
+#include "auth-client-interface.h"
#include "auth-client-connection.h"
#include "auth-master-connection.h"
#include <stdlib.h>
-/* Used only for string sanitization. */
-#define MAX_MECH_NAME_LEN 64
-
-#define MAX_OUTBUF_SIZE (1024*50)
+#define OUTBUF_THROTTLE_SIZE (1024*50)
static void auth_client_connection_unref(struct auth_client_connection *conn);
-static void
-auth_client_connection_destroy_wait(struct auth_client_connection *conn);
+static void auth_client_input(void *context);
static void auth_client_send(struct auth_client_connection *conn,
const char *fmt, ...) __attr_format__(2, 3);
+
static void auth_client_send(struct auth_client_connection *conn,
const char *fmt, ...)
{
va_list args;
string_t *str;
- ssize_t ret;
i_assert(conn->refcount > 1);
@@ -42,114 +35,32 @@
str = t_str_new(256);
str_vprintfa(str, fmt, args);
str_append_c(str, '\n');
- ret = o_stream_send(conn->output, str_data(str), str_len(str));
- if (ret != (ssize_t)str->used) {
- i_warning("Authentication client %u: "
- "Transmit buffer full, killing it", conn->pid);
- auth_client_connection_destroy_wait(conn);
- }
- va_end(args);
- t_pop();
-}
-
-static const char *get_client_extra_fields(struct auth_request *request)
-{
- const char **fields;
- unsigned int src, dest;
-
- if (request->extra_fields == NULL)
- return NULL;
-
- /* we only wish to remove all fields prefixed with "userdb_" */
- if (strstr(request->extra_fields, "userdb_") == NULL)
- return request->extra_fields;
-
- fields = t_strsplit(request->extra_fields, "\t");
- for (src = dest = 0; fields[src] != NULL; src++) {
- if (strncmp(fields[src], "userdb_", 7) == 0)
- fields[dest++] = fields[src];
- }
- fields[dest] = NULL;
- return t_strarray_join(fields, "\t");
-}
-
-static void auth_callback(struct auth_request *request,
- enum auth_client_result result,
- const void *reply, size_t reply_size)
-{
- string_t *str = NULL;
- const char *fields;
- ssize_t ret;
-
- t_push();
+ (void)o_stream_send(conn->output, str_data(str), str_len(str));
- switch (result) {
- case AUTH_CLIENT_RESULT_CONTINUE:
- str = t_str_new(32 + MAX_BASE64_ENCODED_SIZE(reply_size));
- str_printfa(str, "CONT\t%u\t", request->id);
- base64_encode(reply, reply_size, str);
- request->accept_input = TRUE;
- break;
- case AUTH_CLIENT_RESULT_SUCCESS:
- str = t_str_new(128 + MAX_BASE64_ENCODED_SIZE(reply_size));
- str_printfa(str, "OK\t%u\tuser=%s", request->id, request->user);
- if (reply_size > 0) {
- str_append(str, "\tresp=");
- base64_encode(reply, reply_size, str);
- }
- t_push();
- fields = get_client_extra_fields(request);
- if (fields != NULL) {
- str_append_c(str, '\t');
- str_append(str, fields);
- }
- t_pop();
- break;
- case AUTH_CLIENT_RESULT_FAILURE:
- str = t_str_new(128);
- str_printfa(str, "FAIL\t%u", request->id);
- if (request->user != NULL)
- str_printfa(str, "\tuser=%s", request->user);
- if (request->internal_failure)
- str_append(str, "\ttemp");
- t_push();
- fields = get_client_extra_fields(request);
- if (fields != NULL) {
- str_append_c(str, '\t');
- str_append(str, fields);
+ if (o_stream_get_buffer_used_size(conn->output) >=
+ OUTBUF_THROTTLE_SIZE) {
+ /* stop reading new requests until client has read the pending
+ replies. */
+ if (conn->io != NULL) {
+ io_remove(conn->io);
+ conn->io = NULL;
}
- t_pop();
- break;
- }
-
- str_append_c(str, '\n');
-
- ret = o_stream_send(request->conn->output, str->data, str->used);
- if (ret < 0)
- auth_client_connection_destroy(request->conn);
- else if ((size_t)ret != str->used) {
- i_warning("Authentication client %u: "
- "Transmit buffer full, killing it",
- request->conn->pid);
- auth_client_connection_destroy_wait(request->conn);
}
+ va_end(args);
t_pop();
-
- auth_client_connection_unref(request->conn);
}
-struct auth_client_connection *
-auth_client_connection_lookup(struct auth_master_connection *master,
- unsigned int pid)
+static void auth_callback(const char *reply, void *context)
{
- struct auth_client_connection *conn;
+ struct auth_client_connection *conn = context;
- for (conn = master->clients; conn != NULL; conn = conn->next) {
- if (conn->pid == pid)
- return conn;
+ if (reply == NULL) {
+ /* handler destroyed */
+ auth_client_connection_unref(conn);
+ return;
}
- return NULL;
+ auth_client_send(conn, "%s", reply);
}
static int
@@ -158,10 +69,7 @@
struct auth_client_connection *old;
unsigned int pid;
- if (conn->pid != 0) {
- i_error("BUG: Authentication client re-handshaking");
- return FALSE;
- }
+ i_assert(conn->pid == 0);
pid = (unsigned int)strtoul(args, NULL, 10);
if (pid == 0) {
@@ -173,6 +81,7 @@
if (old != NULL) {
/* already exists. it's possible that it just reconnected,
see if the old connection is still there. */
+ i_assert(old != conn);
if (i_stream_read(old->input) == -1) {
auth_client_connection_destroy(old);
old = NULL;
@@ -185,167 +94,54 @@
return FALSE;
}
+ /* handshake complete, we can now actually start serving requests */
+ conn->refcount++;
+ if (!AUTH_MASTER_IS_DUMMY(conn->master)) {
+ conn->request_handler =
+ auth_request_handler_create(conn->auth,
+ conn->connect_uid, pid, auth_callback, conn,
+ auth_master_request_callback, conn->master);
+ } else {
+ conn->request_handler =
+ auth_request_handler_create(conn->auth,
+ conn->connect_uid, pid,
+ auth_callback, conn,
+ NULL, NULL);
+ }
conn->pid = pid;
return TRUE;
}
-static int
-auth_client_input_auth(struct auth_client_connection *conn, const char *args)
+static int auth_client_output(void *context)
{
- struct mech_module *mech;
- struct auth_request *request;
- const char *const *list, *name, *arg, *initial_resp;
- const void *initial_resp_data;
- size_t initial_resp_len;
- unsigned int id;
- buffer_t *buf;
- int valid_client_cert;
-
- if (conn->pid == 0) {
- i_error("BUG: Authentication client %u didn't send handshake",
- conn->pid);
- return FALSE;
- }
-
- /* <id> <mechanism> [...] */
- list = t_strsplit(args, "\t");
- if (list[0] == NULL || list[1] == NULL) {
- i_error("BUG: Authentication client %u "
- "sent broken AUTH request", conn->pid);
- return FALSE;
- }
-
- id = (unsigned int)strtoul(list[0], NULL, 10);
-
- mech = mech_module_find(list[1]);
- if (mech == NULL) {
- /* unsupported mechanism */
- i_error("BUG: Authentication client %u requested unsupported "
- "authentication mechanism %s", conn->pid,
- str_sanitize(list[1], MAX_MECH_NAME_LEN));
- return FALSE;
- }
-
- request = auth_request_new(conn->auth, mech, auth_callback);
- hash_insert(conn->auth_requests, POINTER_CAST(id), request);
-
- request->conn = conn;
- request->id = id;
-
- /* parse optional parameters */
- initial_resp = NULL;
- valid_client_cert = FALSE;
- for (list += 2; *list != NULL; list++) {
- arg = strchr(*list, '=');
- if (arg == NULL) {
- name = *list;
- arg = "";
- } else {
- name = t_strdup_until(*list, arg);
- arg++;
- }
-
- if (strcmp(name, "lip") == 0)
- (void)net_addr2ip(arg, &request->local_ip);
- else if (strcmp(name, "rip") == 0)
- (void)net_addr2ip(arg, &request->remote_ip);
- else if (strcmp(name, "service") == 0)
- request->service = p_strdup(request->pool, arg);
- else if (strcmp(name, "resp") == 0)
- initial_resp = arg;
- else if (strcmp(name, "valid-client-cert") == 0)
- valid_client_cert = TRUE;
- }
-
- if (request->service == NULL) {
- i_error("BUG: Authentication client %u "
- "didn't specify service in request", conn->pid);
- auth_request_destroy(request);
- return FALSE;
- }
+ struct auth_client_connection *conn = context;
- if (request->auth->ssl_require_client_cert && !valid_client_cert) {
- /* we fail without valid certificate */
- auth_request_log_info(request, "ssl-cert-check",
- "Client didn't present valid SSL certificate");
- auth_request_destroy(request);
- auth_client_send(conn, "FAIL\t%u", id);
- return TRUE;
+ if (o_stream_flush(conn->output) < 0) {
+ auth_client_connection_destroy(conn);
+ return 1;
}
- if (initial_resp == NULL) {
- initial_resp_data = NULL;
- initial_resp_len = 0;
- } else {
- size_t len = strlen(initial_resp);
- buf = buffer_create_dynamic(pool_datastack_create(),
- MAX_BASE64_DECODED_SIZE(len));
- if (base64_decode(initial_resp, len, NULL, buf) < 0) {
- auth_request_log_info(request, mech->mech_name,
- "Invalid base64 data in initial response");
- auth_request_destroy(request);
- auth_client_send(conn, "FAIL\t%u\t"
- "reason=Invalid base64 data in initial "
- "response", id);
- return TRUE;
- }
- initial_resp_data = buf->data;
- initial_resp_len = buf->used;
+ if (o_stream_get_buffer_used_size(conn->output) <=
+ OUTBUF_THROTTLE_SIZE/3 && conn->io == NULL) {
+ /* allow input again */
+ conn->io = io_add(conn->fd, IO_READ, auth_client_input, conn);
}
-
- /* connection is referenced only until auth_callback is called. */
- conn->refcount++;
- auth_request_initial(request, initial_resp_data, initial_resp_len);
- return TRUE;
+ return 1;
}
static int
-auth_client_input_cont(struct auth_client_connection *conn, const char *args)
+auth_client_handle_line(struct auth_client_connection *conn, const char *line)
{
- struct auth_request *request;
- const char *data;
- size_t data_len;
- buffer_t *buf;
- unsigned int id;
-
- data = strchr(args, '\t');
- if (data++ == NULL) {
- i_error("BUG: Authentication client %u "
- "sent broken CONT request", conn->pid);
- return FALSE;
- }
-
- id = (unsigned int)strtoul(args, NULL, 10);
-
- request = hash_lookup(conn->auth_requests, POINTER_CAST(id));
- if (request == NULL) {
- /* timeouted */
- auth_client_send(conn, "FAIL\t%u\treason=Timeouted", id);
- return TRUE;
- }
-
- if (!request->accept_input) {
- auth_client_send(conn, "FAIL\t%u"
- "\treason=Unexpected continuation", id);
- auth_request_destroy(request);
- return TRUE;
+ if (strncmp(line, "AUTH\t", 5) == 0) {
+ return auth_request_handler_auth_begin(conn->request_handler,
+ line + 5);
}
- request->accept_input = FALSE;
-
- data_len = strlen(data);
- buf = buffer_create_dynamic(pool_datastack_create(),
- MAX_BASE64_DECODED_SIZE(data_len));
- if (base64_decode(data, data_len, NULL, buf) < 0) {
- auth_request_log_info(request, request->mech->mech_name,
- "Invalid base64 data in continued response");
- auth_client_send(conn, "FAIL\t%u\treason=Invalid base64 data "
- "in continued response", id);
- auth_request_destroy(request);
- return TRUE;
+ if (strncmp(line, "CONT\t", 5) == 0) {
+ return auth_request_handler_auth_continue(conn->request_handler,
+ line + 5);
}
- conn->refcount++;
- auth_request_continue(request, buf->data, buf->used);
+ /* ignore unknown command */
return TRUE;
}
@@ -366,46 +162,48 @@
/* buffer full */
i_error("BUG: Auth client %u sent us more than %d bytes",
conn->pid, (int)AUTH_CLIENT_MAX_LINE_LENGTH);
- auth_client_connection_destroy_wait(conn);
+ auth_client_connection_destroy(conn);
return;
}
- if (!conn->version_received) {
+ while (conn->request_handler == NULL) {
+ /* still handshaking */
line = i_stream_next_line(conn->input);
if (line == NULL)
return;
- /* make sure the major version matches */
- if (strncmp(line, "VERSION\t", 8) != 0 ||
- atoi(t_strcut(line + 8, '\t')) !=
- AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
- i_error("Authentication client %u "
- "not compatible with this server "
- "(mixed old and new binaries?)", conn->pid);
- auth_client_connection_destroy_wait(conn);
- return;
+ if (!conn->version_received) {
+ /* make sure the major version matches */
+ if (strncmp(line, "VERSION\t", 8) != 0 ||
+ atoi(t_strcut(line + 8, '\t')) !=
+ AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+ i_error("Authentication client "
+ "not compatible with this server "
+ "(mixed old and new binaries?)");
+ auth_client_connection_destroy(conn);
+ return;
+ }
+ conn->version_received = TRUE;
+ continue;
+ }
+
+ if (strncmp(line, "CPID\t", 5) == 0) {
+ if (!auth_client_input_cpid(conn, line + 5)) {
+ auth_client_connection_destroy(conn);
+ return;
+ }
}
- conn->version_received = TRUE;
}
- conn->refcount++;
+ conn->refcount++;
while ((line = i_stream_next_line(conn->input)) != NULL) {
t_push();
- if (strncmp(line, "AUTH\t", 5) == 0)
- ret = auth_client_input_auth(conn, line + 5);
- else if (strncmp(line, "CONT\t", 5) == 0)
- ret = auth_client_input_cont(conn, line + 5);
- else if (strncmp(line, "CPID\t", 5) == 0)
- ret = auth_client_input_cpid(conn, line + 5);
- else {
- /* ignore unknown command */
- ret = TRUE;
- }
+ ret = auth_client_handle_line(conn, line);
safe_memset(line, 0, strlen(line));
t_pop();
if (!ret) {
- auth_client_connection_destroy_wait(conn);
+ auth_client_connection_destroy(conn);
break;
}
}
@@ -420,27 +218,21 @@
struct const_iovec iov[2];
string_t *str;
- pool_t pool;
-
- pool = pool_alloconly_create("Auth client", 4096);
- conn = p_new(pool, struct auth_client_connection, 1);
- conn->pool = pool;
+ conn = i_new(struct auth_client_connection, 1);
conn->auth = master->auth;
conn->master = master;
conn->refcount = 1;
conn->connect_uid = ++connect_uid_counter;
conn->fd = fd;
- conn->input = i_stream_create_file(fd, default_pool,
- AUTH_CLIENT_MAX_LINE_LENGTH,
- FALSE);
- conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE,
- FALSE);
+ conn->input =
+ i_stream_create_file(fd, default_pool,
+ AUTH_CLIENT_MAX_LINE_LENGTH, FALSE);
+ conn->output =
+ o_stream_create_file(fd, default_pool, (size_t)-1, FALSE);
+ o_stream_set_flush_callback(conn->output, auth_client_output, conn);
conn->io = io_add(fd, IO_READ, auth_client_input, conn);
- conn->auth_requests = hash_create(default_pool, conn->pool,
- 0, NULL, NULL);
-
conn->next = master->clients;
master->clients = conn;
@@ -488,86 +280,46 @@
net_disconnect(conn->fd);
conn->fd = -1;
+ if (conn->request_handler != NULL)
+ auth_request_handler_unref(conn->request_handler);
+
conn->master = NULL;
auth_client_connection_unref(conn);
}
-static void
-auth_client_connection_destroy_wait(struct auth_client_connection *conn)
-{
- conn->delayed_destroy = TRUE;
-
- if (conn->io != NULL) {
- io_remove(conn->io);
- conn->io = NULL;
- }
-}
-
static void auth_client_connection_unref(struct auth_client_connection *conn)
{
- struct hash_iterate_context *iter;
- void *key, *value;
-
if (--conn->refcount > 0)
return;
- iter = hash_iterate_init(conn->auth_requests);
- while (hash_iterate(iter, &key, &value)) {
- struct auth_request *auth_request = value;
-
- auth_request->conn = NULL;
- auth_request_unref(auth_request);
- }
- hash_iterate_deinit(iter);
- hash_destroy(conn->auth_requests);
-
i_stream_unref(conn->input);
o_stream_unref(conn->output);
-
- pool_unref(conn->pool);
+ i_free(conn);
}
-static void
-auth_client_connection_check_timeouts(struct auth_client_connection *conn)
+struct auth_client_connection *
+auth_client_connection_lookup(struct auth_master_connection *master,
+ unsigned int pid)
{
- struct hash_iterate_context *iter;
- void *key, *value;
- unsigned int secs;
- int destroy = FALSE;
-
- if (conn->delayed_destroy) {
- auth_client_connection_destroy(conn);
- return;
- }
-
- iter = hash_iterate_init(conn->auth_requests);
- while (hash_iterate(iter, &key, &value)) {
- struct auth_request *auth_request = value;
-
- if (auth_request->created + AUTH_REQUEST_TIMEOUT < ioloop_time) {
- secs = (unsigned int) (ioloop_time -
- auth_request->created);
- i_warning("Login process has too old (%us) requests, "
- "killing it.", secs);
+ struct auth_client_connection *conn;
- destroy = TRUE;
- break;
- }
+ for (conn = master->clients; conn != NULL; conn = conn->next) {
+ if (conn->pid == pid)
+ return conn;
}
- hash_iterate_deinit(iter);
- if (destroy)
- auth_client_connection_destroy(conn);
+ return NULL;
}
static void request_timeout(void *context __attr_unused__)
{
struct auth_master_connection *master = context;
- struct auth_client_connection *conn, *next;
+ struct auth_client_connection *conn;
- for (conn = master->clients; conn != NULL; conn = next) {
- next = conn->next;
- auth_client_connection_check_timeouts(conn);
+ for (conn = master->clients; conn != NULL; conn = conn->next) {
+ if (conn->request_handler == NULL)
+ continue;
+ auth_request_handler_check_timeouts(conn->request_handler);
}
}
Index: auth-client-connection.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-client-connection.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- auth-client-connection.h 8 Jan 2005 19:01:34 -0000 1.8
+++ auth-client-connection.h 9 Jan 2005 00:49:18 -0000 1.9
@@ -13,14 +13,11 @@
struct istream *input;
struct ostream *output;
- pool_t pool;
- struct hash_table *auth_requests;
-
unsigned int pid;
unsigned int connect_uid;
+ struct auth_request_handler *request_handler;
unsigned int version_received:1;
- unsigned int delayed_destroy:1;
};
struct auth_client_connection *
Index: auth-master-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-master-connection.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- auth-master-connection.c 8 Jan 2005 16:56:04 -0000 1.24
+++ auth-master-connection.c 9 Jan 2005 00:49:18 -0000 1.25
@@ -9,7 +9,7 @@
#include "ostream.h"
#include "network.h"
#include "userdb.h"
-#include "auth-request.h"
+#include "auth-request-handler.h"
#include "auth-master-interface.h"
#include "auth-client-connection.h"
#include "auth-master-connection.h"
@@ -38,81 +38,23 @@
static void auth_master_connection_close(struct auth_master_connection *conn);
static int auth_master_connection_unref(struct auth_master_connection *conn);
-static void master_send(struct auth_master_connection *conn,
- const char *fmt, ...) __attr_format__(2, 3);
-static void master_send(struct auth_master_connection *conn,
- const char *fmt, ...)
-{
- va_list args;
- string_t *str;
-
- t_push();
- va_start(args, fmt);
- str = t_str_new(256);
- str_vprintfa(str, fmt, args);
- str_append_c(str, '\n');
- (void)o_stream_send(conn->output, str_data(str), str_len(str));
- va_end(args);
- t_pop();
-}
-
-static void append_user_reply(string_t *str, const struct user_data *user)
-{
- const char *p;
-
- str_printfa(str, "%s\tuid=%s\tgid=%s", user->virtual_user,
- dec2str(user->uid), dec2str(user->gid));
-
- if (user->system_user != NULL)
- str_printfa(str, "\tsystem_user=%s", user->system_user);
- if (user->mail != NULL)
- str_printfa(str, "\tmail=%s", user->mail);
-
- p = user->home != NULL ? strstr(user->home, "/./") : NULL;
- if (p == NULL) {
- if (user->home != NULL)
- str_printfa(str, "\thome=%s", user->home);
- } else {
- /* wu-ftpd like <chroot>/./<home> */
- str_printfa(str, "\thome=%s\tchroot=%s",
- p + 3, t_strdup_until(user->home, p));
- }
-}
-
-static void userdb_callback(const struct user_data *user, void *context)
+void auth_master_request_callback(const char *reply, void *context)
{
- struct master_userdb_request *master_request = context;
- string_t *str;
+ struct auth_master_connection *conn = context;
+ struct const_iovec iov[2];
- if (user != NULL) {
- auth_request_log_debug(master_request->auth_request, "userdb",
- "uid=%s gid=%s home=%s mail=%s",
- dec2str(user->uid), dec2str(user->gid),
- user->home != NULL ? user->home : "",
- user->mail != NULL ? user->mail : "");
- }
+ iov[0].iov_base = reply;
+ iov[0].iov_len = strlen(reply);
+ iov[1].iov_base = "\n";
+ iov[1].iov_len = 1;
- if (auth_master_connection_unref(master_request->conn)) {
- if (user == NULL) {
- master_send(master_request->conn, "NOTFOUND\t%u",
- master_request->id);
- } else {
- str = t_str_new(256);
- str_printfa(str, "USER\t%u\t", master_request->id);
- append_user_reply(str, user);
- master_send(master_request->conn, "%s", str_c(str));
- }
- }
- auth_request_destroy(master_request->auth_request);
- i_free(master_request);
+ (void)o_stream_sendv(conn->output, iov, 2);
}
static int
master_input_request(struct auth_master_connection *conn, const char *args)
{
struct auth_client_connection *client_conn;
- struct master_userdb_request *master_request;
- struct auth_request *request;
const char *const *list;
unsigned int id, client_pid, client_id;
@@ -128,27 +70,14 @@
client_id = (unsigned int)strtoul(list[2], NULL, 10);
client_conn = auth_client_connection_lookup(conn, client_pid);
- request = client_conn == NULL ? NULL :
- hash_lookup(client_conn->auth_requests,
- POINTER_CAST(client_id));
-
- if (request == NULL) {
- i_error("Master request %u.%u not found",
- client_pid, client_id);
- master_send(conn, "NOTFOUND\t%u", id);
- } else if (!request->successful) {
- i_error("Master requested unfinished authentication request "
- "%u.%u", client_pid, client_id);
- master_send(conn, "NOTFOUND\t%u", id);
+ if (client_conn == NULL) {
+ i_error("Master requested auth for nonexisting client %u",
+ client_pid);
+ (void)o_stream_send_str(conn->output,
+ t_strdup_printf("NOTFOUND\t%u\n", id));
} else {
- master_request = i_new(struct master_userdb_request, 1);
- master_request->conn = conn;
- master_request->id = id;
- master_request->auth_request = request;
-
- conn->refcount++;
- auth_request_lookup_user(request, userdb_callback,
- master_request);
+ auth_request_handler_master_request(
+ client_conn->request_handler, id, client_id);
}
return TRUE;
}
@@ -255,14 +184,14 @@
}
struct auth_master_connection *
-auth_master_connection_create(struct auth *auth, int fd, unsigned int pid)
+auth_master_connection_create(struct auth *auth, int fd)
{
struct auth_master_connection *conn;
conn = i_new(struct auth_master_connection, 1);
conn->auth = auth;
conn->refcount = 1;
- conn->pid = pid;
+ conn->pid = (unsigned int)getpid();
conn->fd = fd;
conn->listeners_buf = buffer_create_dynamic(default_pool, 64);
if (fd != -1)
@@ -272,11 +201,15 @@
void auth_master_connection_send_handshake(struct auth_master_connection *conn)
{
- if (conn->output != NULL) {
- master_send(conn, "VERSION\t%u\t%u\nSPID\t%u\n",
- AUTH_MASTER_PROTOCOL_MAJOR_VERSION,
- AUTH_MASTER_PROTOCOL_MINOR_VERSION, conn->pid);
- }
+ const char *line;
+
+ if (conn->output == NULL)
+ return;
+
+ line = t_strdup_printf("VERSION\t%u\t%u\nSPID\t%u\n",
+ AUTH_MASTER_PROTOCOL_MAJOR_VERSION,
+ AUTH_MASTER_PROTOCOL_MINOR_VERSION, conn->pid);
+ (void)o_stream_send_str(conn->output, line);
}
static void auth_master_connection_close(struct auth_master_connection *conn)
Index: auth-master-connection.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-master-connection.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- auth-master-connection.h 7 Jan 2005 19:55:49 -0000 1.7
+++ auth-master-connection.h 9 Jan 2005 00:49:18 -0000 1.8
@@ -23,10 +23,12 @@
#define AUTH_MASTER_IS_DUMMY(master) (master->fd == -1)
struct auth_master_connection *
-auth_master_connection_create(struct auth *auth, int fd, unsigned int pid);
+auth_master_connection_create(struct auth *auth, int fd);
void auth_master_connection_send_handshake(struct auth_master_connection *conn);
void auth_master_connection_destroy(struct auth_master_connection *conn);
+void auth_master_request_callback(const char *reply, void *context);
+
void auth_master_connection_add_listener(struct auth_master_connection *conn,
int fd, const char *path, int client);
--- NEW FILE: auth-request-handler.c ---
/* Copyright (C) 2005 Timo Sirainen */
#include "common.h"
#include "ioloop.h"
#include "buffer.h"
#include "base64.h"
#include "hash.h"
#include "str.h"
#include "str-sanitize.h"
#include "auth-request.h"
#include "auth-request-handler.h"
#include <stdlib.h>
/* Used only for string sanitization. */
#define MAX_MECH_NAME_LEN 64
struct auth_request_handler {
int refcount;
pool_t pool;
struct hash_table *requests;
struct auth *auth;
unsigned int connect_uid, client_pid;
auth_request_callback_t *callback;
void *context;
auth_request_callback_t *master_callback;
void *master_context;
};
static buffer_t *auth_failures_buf;
static struct timeout *to_auth_failures;
struct auth_request_handler *
auth_request_handler_create(struct auth *auth,
unsigned int connect_uid, unsigned int client_pid,
auth_request_callback_t *callback, void *context,
auth_request_callback_t *master_callback,
void *master_context)
{
struct auth_request_handler *handler;
pool_t pool;
pool = pool_alloconly_create("auth request handler", 4096);
handler = p_new(pool, struct auth_request_handler, 1);
handler->refcount = 1;
handler->pool = pool;
handler->requests = hash_create(default_pool, pool, 0, NULL, NULL);
handler->auth = auth;
handler->connect_uid = connect_uid;
handler->client_pid = client_pid;
handler->callback = callback;
handler->context = context;
handler->master_callback = master_callback;
handler->master_context = master_context;
return handler;
}
void auth_request_handler_unref(struct auth_request_handler *handler)
{
struct hash_iterate_context *iter;
void *key, *value;
i_assert(handler->refcount > 0);
if (--handler->refcount > 0)
return;
iter = hash_iterate_init(handler->requests);
while (hash_iterate(iter, &key, &value))
auth_request_unref(value);
hash_iterate_deinit(iter);
/* notify parent that we're done with all requests */
handler->callback(NULL, handler->context);
hash_destroy(handler->requests);
pool_unref(handler->pool);
}
void auth_request_handler_check_timeouts(struct auth_request_handler *handler)
{
struct hash_iterate_context *iter;
void *key, *value;
iter = hash_iterate_init(handler->requests);
while (hash_iterate(iter, &key, &value)) {
struct auth_request *auth_request = value;
if (auth_request->created + AUTH_REQUEST_TIMEOUT < ioloop_time)
hash_remove(handler->requests, key);
}
hash_iterate_deinit(iter);
}
static void auth_request_handler_remove(struct auth_request_handler *handler,
struct auth_request *request)
{
hash_remove(handler->requests, POINTER_CAST(request->id));
auth_request_unref(request);
}
static const char *get_client_extra_fields(struct auth_request *request)
{
const char **fields;
unsigned int src, dest;
if (request->extra_fields == NULL)
return NULL;
/* we only wish to remove all fields prefixed with "userdb_" */
if (strstr(request->extra_fields, "userdb_") == NULL)
return request->extra_fields;
fields = t_strsplit(request->extra_fields, "\t");
for (src = dest = 0; fields[src] != NULL; src++) {
if (strncmp(fields[src], "userdb_", 7) == 0)
fields[dest++] = fields[src];
}
fields[dest] = NULL;
return t_strarray_join(fields, "\t");
}
static void auth_callback(struct auth_request *request,
enum auth_client_result result,
const void *reply, size_t reply_size)
{
struct auth_request_handler *handler = request->context;
string_t *str = NULL;
const char *fields;
t_push();
switch (result) {
case AUTH_CLIENT_RESULT_CONTINUE:
str = t_str_new(32 + MAX_BASE64_ENCODED_SIZE(reply_size));
str_printfa(str, "CONT\t%u\t", request->id);
base64_encode(reply, reply_size, str);
request->accept_input = TRUE;
handler->callback(str_c(str), handler->context);
break;
case AUTH_CLIENT_RESULT_SUCCESS:
str = t_str_new(128 + MAX_BASE64_ENCODED_SIZE(reply_size));
str_printfa(str, "OK\t%u\tuser=%s", request->id, request->user);
if (reply_size > 0) {
str_append(str, "\tresp=");
base64_encode(reply, reply_size, str);
}
fields = get_client_extra_fields(request);
if (fields != NULL) {
str_append_c(str, '\t');
str_append(str, fields);
}
if (request->no_login || handler->master_callback == NULL) {
/* this request doesn't have to wait for master
process to pick it up. delete it */
auth_request_handler_remove(handler, request);
}
handler->callback(str_c(str), handler->context);
break;
case AUTH_CLIENT_RESULT_FAILURE:
str = t_str_new(128);
str_printfa(str, "FAIL\t%u", request->id);
if (request->user != NULL)
str_printfa(str, "\tuser=%s", request->user);
if (request->internal_failure)
str_append(str, "\ttemp");
fields = get_client_extra_fields(request);
if (fields != NULL) {
str_append_c(str, '\t');
str_append(str, fields);
}
if (request->delayed_failure) {
/* we came here from flush_failures() */
handler->callback(str_c(str), handler->context);
break;
}
/* remove the request from requests-list */
auth_request_ref(request);
auth_request_handler_remove(handler, request);
if (request->no_failure_delay) {
/* passdb specifically requested not to delay the
reply. */
handler->callback(str_c(str), handler->context);
} else {
/* failure. don't announce it immediately to avoid
a) timing attacks, b) flooding */
request->delayed_failure = TRUE;
handler->refcount++;
buffer_append(auth_failures_buf,
&request, sizeof(request));
}
break;
}
/* NOTE: request may be destroyed now */
auth_request_handler_unref(handler);
t_pop();
}
static void auth_request_handler_auth_fail(struct auth_request_handler *handler,
struct auth_request *request,
const char *reason)
{
const char *reply;
auth_request_log_info(request, request->mech->mech_name, "%s", reason);
reply = t_strdup_printf("FAIL\t%u\treason=%s", request->id, reason);
handler->callback(reply, handler->context);
auth_request_handler_remove(handler, request);
}
int auth_request_handler_auth_begin(struct auth_request_handler *handler,
const char *args)
{
struct mech_module *mech;
struct auth_request *request;
const char *const *list, *name, *arg, *initial_resp;
const void *initial_resp_data;
size_t initial_resp_len;
unsigned int id;
buffer_t *buf;
int valid_client_cert;
/* <id> <mechanism> [...] */
list = t_strsplit(args, "\t");
if (list[0] == NULL || list[1] == NULL) {
i_error("BUG: Authentication client %u "
"sent broken AUTH request", handler->client_pid);
return FALSE;
}
id = (unsigned int)strtoul(list[0], NULL, 10);
mech = mech_module_find(list[1]);
if (mech == NULL) {
/* unsupported mechanism */
i_error("BUG: Authentication client %u requested unsupported "
"authentication mechanism %s", handler->client_pid,
str_sanitize(list[1], MAX_MECH_NAME_LEN));
return FALSE;
}
request = auth_request_new(handler->auth, mech, auth_callback, handler);
request->connect_uid = handler->connect_uid;
request->client_pid = handler->client_pid;
request->id = id;
/* parse optional parameters */
initial_resp = NULL;
valid_client_cert = FALSE;
for (list += 2; *list != NULL; list++) {
arg = strchr(*list, '=');
if (arg == NULL) {
name = *list;
arg = "";
} else {
name = t_strdup_until(*list, arg);
arg++;
}
if (strcmp(name, "lip") == 0)
(void)net_addr2ip(arg, &request->local_ip);
else if (strcmp(name, "rip") == 0)
(void)net_addr2ip(arg, &request->remote_ip);
else if (strcmp(name, "service") == 0)
request->service = p_strdup(request->pool, arg);
else if (strcmp(name, "resp") == 0)
initial_resp = arg;
else if (strcmp(name, "valid-client-cert") == 0)
valid_client_cert = TRUE;
}
if (request->service == NULL) {
i_error("BUG: Authentication client %u "
"didn't specify service in request",
handler->client_pid);
auth_request_unref(request);
return FALSE;
}
hash_insert(handler->requests, POINTER_CAST(id), request);
if (request->auth->ssl_require_client_cert && !valid_client_cert) {
/* we fail without valid certificate */
auth_request_handler_auth_fail(handler, request,
"Client didn't present valid SSL certificate");
return TRUE;
}
if (initial_resp == NULL) {
initial_resp_data = NULL;
initial_resp_len = 0;
} else {
size_t len = strlen(initial_resp);
buf = buffer_create_dynamic(pool_datastack_create(),
MAX_BASE64_DECODED_SIZE(len));
if (base64_decode(initial_resp, len, NULL, buf) < 0) {
auth_request_handler_auth_fail(handler, request,
"Invalid base64 data in initial response");
return TRUE;
}
initial_resp_data = buf->data;
initial_resp_len = buf->used;
}
/* handler is referenced until auth_callback is called. */
handler->refcount++;
auth_request_initial(request, initial_resp_data, initial_resp_len);
return TRUE;
}
int auth_request_handler_auth_continue(struct auth_request_handler *handler,
const char *args)
{
struct auth_request *request;
const char *data;
size_t data_len;
buffer_t *buf;
unsigned int id;
data = strchr(args, '\t');
if (data++ == NULL) {
i_error("BUG: Authentication client sent broken CONT request");
return FALSE;
}
id = (unsigned int)strtoul(args, NULL, 10);
request = hash_lookup(handler->requests, POINTER_CAST(id));
if (request == NULL) {
data = t_strdup_printf("FAIL\t%u\treason=Timeouted", id);
handler->callback(data, handler->context);
return TRUE;
}
/* accept input only once after mechanism has sent a CONT reply */
if (!request->accept_input) {
auth_request_handler_auth_fail(handler, request,
"Unexpected continuation");
return TRUE;
}
request->accept_input = FALSE;
data_len = strlen(data);
buf = buffer_create_dynamic(pool_datastack_create(),
MAX_BASE64_DECODED_SIZE(data_len));
if (base64_decode(data, data_len, NULL, buf) < 0) {
auth_request_handler_auth_fail(handler, request,
"Invalid base64 data in continued response");
return TRUE;
}
/* handler is referenced until auth_callback is called. */
handler->refcount++;
auth_request_continue(request, buf->data, buf->used);
return TRUE;
}
static void append_user_reply(string_t *str, const struct user_data *user)
{
const char *p;
str_printfa(str, "%s\tuid=%s\tgid=%s", user->virtual_user,
dec2str(user->uid), dec2str(user->gid));
if (user->system_user != NULL)
str_printfa(str, "\tsystem_user=%s", user->system_user);
if (user->mail != NULL)
str_printfa(str, "\tmail=%s", user->mail);
p = user->home != NULL ? strstr(user->home, "/./") : NULL;
if (p == NULL) {
if (user->home != NULL)
str_printfa(str, "\thome=%s", user->home);
} else {
/* wu-ftpd like <chroot>/./<home> */
str_printfa(str, "\thome=%s\tchroot=%s",
p + 3, t_strdup_until(user->home, p));
}
}
static void userdb_callback(const struct user_data *user, void *context)
{
struct auth_request *request = context;
struct auth_request_handler *handler = request->context;
string_t *reply;
if (user != NULL) {
auth_request_log_debug(request, "userdb",
"uid=%s gid=%s home=%s mail=%s",
dec2str(user->uid), dec2str(user->gid),
user->home != NULL ? user->home : "",
user->mail != NULL ? user->mail : "");
}
reply = t_str_new(256);
if (user == NULL)
str_printfa(reply, "NOTFOUND\t%u", request->id);
else {
str_printfa(reply, "USER\t%u\t", request->id);
append_user_reply(reply, user);
}
handler->master_callback(str_c(reply), handler->master_context);
auth_request_unref(request);
auth_request_handler_unref(handler);
}
void auth_request_handler_master_request(struct auth_request_handler *handler,
unsigned int id,
unsigned int client_id)
{
struct auth_request *request;
const char *reply;
request = hash_lookup(handler->requests, POINTER_CAST(client_id));
if (request == NULL) {
i_error("Master request %u.%u not found",
handler->client_pid, client_id);
reply = t_strdup_printf("NOTFOUND\t%u", id);
handler->master_callback(reply, handler->master_context);
return;
}
auth_request_ref(request);
auth_request_handler_remove(handler, request);
if (!request->successful) {
i_error("Master requested unfinished authentication request "
"%u.%u", handler->client_pid, client_id);
reply = t_strdup_printf("NOTFOUND\t%u", id);
handler->master_callback(reply, handler->master_context);
} else {
/* the request isn't being referenced anywhere anymore,
so we can do a bit of kludging.. replace the request's
old client_id with master's id. */
request->id = id;
request->context = handler;
/* handler is referenced until userdb_callback is called. */
handler->refcount++;
auth_request_lookup_user(request, userdb_callback, request);
}
}
void auth_request_handlers_flush_failures(void)
{
struct auth_request **auth_request;
size_t i, size;
auth_request = buffer_get_modifyable_data(auth_failures_buf, &size);
size /= sizeof(*auth_request);
for (i = 0; i < size; i++) {
auth_request[i]->callback(auth_request[i],
AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
auth_request_unref(auth_request[i]);
}
buffer_set_used_size(auth_failures_buf, 0);
}
static void auth_failure_timeout(void *context __attr_unused__)
{
auth_request_handlers_flush_failures();
}
void auth_request_handlers_init(void)
{
auth_failures_buf = buffer_create_dynamic(default_pool, 1024);
to_auth_failures = timeout_add(2000, auth_failure_timeout, NULL);
}
void auth_request_handlers_deinit(void)
{
buffer_free(auth_failures_buf);
timeout_remove(to_auth_failures);
}
--- NEW FILE: auth-request-handler.h ---
#ifndef __AUTH_REQUEST_HANDLER_H
#define __AUTH_REQUEST_HANDLER_H
typedef void auth_request_callback_t(const char *reply, void *context);
struct auth_request_handler *
auth_request_handler_create(struct auth *auth,
unsigned int connect_uid, unsigned int client_pid,
auth_request_callback_t *callback, void *context,
auth_request_callback_t *master_callback,
void *master_context);
void auth_request_handler_unref(struct auth_request_handler *handler);
void auth_request_handler_check_timeouts(struct auth_request_handler *handler);
int auth_request_handler_auth_begin(struct auth_request_handler *handler,
const char *args);
int auth_request_handler_auth_continue(struct auth_request_handler *handler,
const char *args);
void auth_request_handler_master_request(struct auth_request_handler *handler,
unsigned int id,
unsigned int client_id);
void auth_request_handlers_flush_failures(void);
void auth_request_handlers_init(void);
void auth_request_handlers_deinit(void);
#endif
Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- auth-request.c 8 Jan 2005 21:37:32 -0000 1.6
+++ auth-request.c 9 Jan 2005 00:49:18 -0000 1.7
@@ -20,81 +20,41 @@
char *user_password, *password;
};
-static buffer_t *auth_failures_buf;
-static struct timeout *to_auth_failures;
-
struct auth_request *
auth_request_new(struct auth *auth, struct mech_module *mech,
- mech_callback_t *callback)
+ mech_callback_t *callback, void *context)
{
struct auth_request *request;
request = mech->auth_new();
request->refcount = 1;
+ request->created = ioloop_time;
+
request->auth = auth;
request->mech = mech;
request->callback = callback;
- request->created = ioloop_time;
+ request->context = context;
return request;
}
-void auth_request_destroy(struct auth_request *request)
-{
- i_assert(request->refcount > 0);
-
- if (request->destroyed)
- return;
- request->destroyed = TRUE;
-
- if (request->conn != NULL) {
- hash_remove(request->conn->auth_requests,
- POINTER_CAST(request->id));
- }
- auth_request_unref(request);
-}
-
void auth_request_success(struct auth_request *request,
const void *data, size_t data_size)
{
- request->successful = TRUE;
- if (request->conn != NULL) {
- request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
- data, data_size);
- }
+ i_assert(!request->finished);
+ request->finished = TRUE;
- if (request->no_login || request->conn == NULL ||
- AUTH_MASTER_IS_DUMMY(request->conn->master)) {
- /* we don't have master process, the request is no longer
- needed */
- auth_request_destroy(request);
- }
+ request->successful = TRUE;
+ request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
+ data, data_size);
}
void auth_request_fail(struct auth_request *request)
{
- if (request->no_failure_delay) {
- /* passdb specifically requested to to delay the reply. */
- request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
- auth_request_destroy(request);
- return;
- }
-
- /* failure. don't announce it immediately to avoid
- a) timing attacks, b) flooding */
- if (auth_failures_buf->used > 0) {
- const struct auth_request *const *requests;
-
- requests = auth_failures_buf->data;
- requests += auth_failures_buf->used/sizeof(*requests)-1;
- i_assert(*requests != request);
- }
-
- buffer_append(auth_failures_buf, &request, sizeof(request));
+ i_assert(!request->finished);
+ request->finished = TRUE;
- /* make sure the request isn't found anymore */
- auth_request_ref(request);
- auth_request_destroy(request);
+ request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
}
void auth_request_internal_failure(struct auth_request *request)
@@ -320,7 +280,7 @@
tab[5].value = net_ip2addr(&auth_request->local_ip);
if (auth_request->remote_ip.family != 0)
tab[6].value = net_ip2addr(&auth_request->remote_ip);
- tab[7].value = dec2str(auth_request->conn->pid);
+ tab[7].value = dec2str(auth_request->client_pid);
return tab;
}
@@ -397,39 +357,3 @@
t_pop();
va_end(va);
}
-
-void auth_failure_buf_flush(void)
-{
- struct auth_request **auth_request;
- size_t i, size;
-
- auth_request = buffer_get_modifyable_data(auth_failures_buf, &size);
- size /= sizeof(*auth_request);
-
- for (i = 0; i < size; i++) {
- if (auth_request[i]->conn != NULL) {
- auth_request[i]->callback(auth_request[i],
- AUTH_CLIENT_RESULT_FAILURE,
- NULL, 0);
- }
- auth_request_destroy(auth_request[i]);
- }
- buffer_set_used_size(auth_failures_buf, 0);
-}
-
-static void auth_failure_timeout(void *context __attr_unused__)
-{
- auth_failure_buf_flush();
-}
-
-void auth_requests_init(void)
-{
- auth_failures_buf = buffer_create_dynamic(default_pool, 1024);
- to_auth_failures = timeout_add(2000, auth_failure_timeout, NULL);
-}
-
-void auth_requests_deinit(void)
-{
- buffer_free(auth_failures_buf);
- timeout_remove(to_auth_failures);
-}
Index: auth-request.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- auth-request.h 8 Jan 2005 21:37:32 -0000 1.6
+++ auth-request.h 9 Jan 2005 00:49:18 -0000 1.7
@@ -17,37 +17,40 @@
struct mech_module *mech;
struct auth *auth;
- struct auth_client_connection *conn;
+ unsigned int connect_uid;
+ unsigned int client_pid;
unsigned int id;
time_t created;
const char *service;
struct ip_addr local_ip, remote_ip;
+
mech_callback_t *callback;
+ void *context;
unsigned int successful:1;
unsigned int internal_failure:1;
+ unsigned int finished:1;
+ unsigned int delayed_failure:1;
unsigned int accept_input:1;
unsigned int no_failure_delay:1;
unsigned int no_login:1;
unsigned int proxy:1;
- unsigned int destroyed:1;
/* ... mechanism specific data ... */
};
-void auth_request_success(struct auth_request *request,
- const void *data, size_t data_size);
-void auth_request_fail(struct auth_request *request);
-void auth_request_internal_failure(struct auth_request *request);
-
struct auth_request *
auth_request_new(struct auth *auth, struct mech_module *mech,
- mech_callback_t *callback);
-void auth_request_destroy(struct auth_request *request);
+ mech_callback_t *callback, void *context);
void auth_request_ref(struct auth_request *request);
int auth_request_unref(struct auth_request *request);
+void auth_request_success(struct auth_request *request,
+ const void *data, size_t data_size);
+void auth_request_fail(struct auth_request *request);
+void auth_request_internal_failure(struct auth_request *request);
+
void auth_request_initial(struct auth_request *request,
const unsigned char *data, size_t data_size);
void auth_request_continue(struct auth_request *request,
@@ -86,9 +89,4 @@
const char *subsystem,
const char *format, ...) __attr_format__(3, 4);
-void auth_failure_buf_flush(void);
-
-void auth_requests_init(void);
-void auth_requests_deinit(void);
-
#endif
Index: main.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/main.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- main.c 9 Jan 2005 00:48:03 -0000 1.36
+++ main.c 9 Jan 2005 00:49:18 -0000 1.37
@@ -11,7 +11,7 @@
#include "password-scheme.h"
#include "mech.h"
#include "auth.h"
-#include "auth-request.h"
+#include "auth-request-handler.h"
#include "auth-master-connection.h"
#include "auth-client-connection.h"
@@ -153,7 +153,7 @@
str = t_strdup_printf("AUTH_%u_MASTER", i);
master_fd = create_unix_listener(str);
- master = auth_master_connection_create(auth, -1, getpid());
+ master = auth_master_connection_create(auth, -1);
if (master_fd != -1) {
auth_master_connection_add_listener(master, master_fd,
master_path, FALSE);
@@ -191,19 +191,18 @@
{
struct auth_master_connection *master, **master_p;
size_t i, size;
- const char *env;
- unsigned int pid;
+
+ process_start_time = ioloop_time;
process_start_time = ioloop_time;
mech_init();
auth_init(auth);
- auth_requests_init();
+ auth_request_handlers_init();
lib_init_signals(sig_quit);
- env = getenv("AUTH_PROCESS");
- standalone = env == NULL;
+ standalone = getenv("DOVECOT_MASTER") == NULL;
if (standalone) {
/* starting standalone */
if (getenv("AUTH_1") == NULL) {
@@ -230,12 +229,7 @@
i_fatal("chdir(/) failed: %m");
}
} else {
- pid = atoi(env);
- if (pid == 0)
- i_fatal("AUTH_PROCESS can't be 0");
-
- master = auth_master_connection_create(auth, MASTER_SOCKET_FD,
- pid);
+ master = auth_master_connection_create(auth, MASTER_SOCKET_FD);
auth_master_connection_add_listener(master, LOGIN_LISTEN_FD,
NULL, TRUE);
auth_client_connections_init(master);
@@ -257,7 +251,7 @@
if (lib_signal_kill != 0)
i_warning("Killed with signal %d", lib_signal_kill);
- auth_failure_buf_flush();
+ auth_request_handlers_flush_failures();
master = buffer_get_modifyable_data(masters_buf, &size);
size /= sizeof(*master);
@@ -265,7 +259,7 @@
auth_master_connection_destroy(master[i]);
password_schemes_deinit();
- auth_requests_deinit();
+ auth_request_handlers_deinit();
auth_deinit(auth);
mech_deinit();
Index: mech-apop.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-apop.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mech-apop.c 9 Jan 2005 00:48:03 -0000 1.14
+++ mech-apop.c 9 Jan 2005 00:49:18 -0000 1.15
@@ -101,7 +101,7 @@
if (sscanf((const char *)data, "<%lx.%lx.%lx.",
&pid, &connect_uid, ×tamp) != 3 ||
- connect_uid != auth_request->conn->connect_uid ||
+ connect_uid != auth_request->connect_uid ||
pid != (unsigned long)getpid() ||
(time_t)timestamp < process_start_time) {
auth_request_log_info(auth_request, "apop",
More information about the dovecot-cvs
mailing list