[dovecot-cvs] dovecot/src/pop3-login client-authenticate.c, 1.31,
1.32 client.c, 1.28, 1.29 client.h, 1.11, 1.12
cras at dovecot.org
cras at dovecot.org
Mon Oct 11 20:14:31 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/login-common Makefile.am, 1.5,
1.6 auth-common.c, 1.5, NONE auth-common.h, 1.2,
NONE client-common.h, 1.6, 1.7 sasl-server.c, NONE,
1.1 sasl-server.h, NONE, 1.1
- Next message: [dovecot-cvs] dovecot/src/lib-storage mail-storage.c,1.30,1.31
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/pop3-login
In directory talvi:/tmp/cvs-serv12396/pop3-login
Modified Files:
client-authenticate.c client.c client.h
Log Message:
Login process cleanups. Share more authentication code between pop3/imap.
Index: client-authenticate.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/client-authenticate.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- client-authenticate.c 8 Oct 2004 17:51:50 -0000 1.31
+++ client-authenticate.c 11 Oct 2004 17:14:28 -0000 1.32
@@ -13,14 +13,8 @@
#include "auth-client.h"
#include "../pop3/capability.h"
#include "ssl-proxy.h"
-#include "master.h"
-#include "auth-common.h"
#include "client.h"
#include "client-authenticate.h"
-#include "ssl-proxy.h"
-
-/* Used only for string sanitization while verbose_auth is set. */
-#define MAX_MECH_NAME 64
int cmd_capa(struct pop3_client *client, const char *args __attr_unused__)
{
@@ -53,212 +47,6 @@
return TRUE;
}
-static void client_auth_abort(struct pop3_client *client, const char *msg)
-{
- client->authenticating = FALSE;
-
- if (client->common.auth_request != NULL) {
- auth_client_request_abort(client->common.auth_request);
- client->common.auth_request = NULL;
- }
-
- if (msg != NULL && verbose_auth)
- client_syslog(client, "Authentication failed: %s", msg);
-
- client_send_line(client, msg != NULL ? t_strconcat("-ERR ", msg, NULL) :
- "-ERR Authentication failed.");
-
- /* get back to normal client input */
- if (client->common.io != NULL)
- io_remove(client->common.io);
- client->common.io = client->common.fd == -1 ? NULL :
- io_add(client->common.fd, IO_READ, client_input, client);
-
- client_unref(client);
-}
-
-static void master_callback(struct client *_client, int success)
-{
- struct pop3_client *client = (struct pop3_client *) _client;
- const char *reason = NULL;
-
- if (success) {
- reason = t_strconcat("Login: ", client->common.virtual_user,
- NULL);
- } else {
- reason = t_strconcat("Internal login failure: ",
- client->common.virtual_user, NULL);
- client_send_line(client, "* BYE Internal login failure. "
- "Error report written to server log.");
- }
-
- client_destroy(client, reason);
-}
-
-static void client_send_auth_data(struct pop3_client *client,
- const unsigned char *data, size_t size)
-{
- buffer_t *buf;
- const void *buf_data;
- size_t buf_size;
- ssize_t ret;
-
- t_push();
-
- buf = buffer_create_dynamic(pool_datastack_create(), size*2);
- buffer_append(buf, "+ ", 2);
- base64_encode(data, size, buf);
- buffer_append(buf, "\r\n", 2);
-
- buf_data = buffer_get_data(buf, &buf_size);
- if ((ret = o_stream_send(client->output, buf_data, buf_size)) < 0)
- client_destroy(client, "Disconnected");
- else if ((size_t)ret != buf_size)
- client_destroy(client, "Transmit buffer full");
-
- t_pop();
-}
-
-static void login_callback(struct auth_request *request,
- struct auth_client_request_reply *reply,
- const unsigned char *data, void *context)
-{
- struct pop3_client *client = context;
- const char *error;
-
- switch (auth_callback(request, reply, data, &client->common,
- master_callback, &error)) {
- case -1:
- case 0:
- /* login failed */
- client_auth_abort(client, error);
- break;
-
- default:
- /* success, we should be able to log in. if we fail, just
- disconnect the client. */
- client->authenticating = FALSE;
- client_send_line(client, "+OK Logged in.");
- client_unref(client);
- }
-}
-
-static enum auth_client_request_new_flags
-client_get_auth_flags(struct pop3_client *client)
-{
- enum auth_client_request_new_flags auth_flags = 0;
-
- if (client->common.proxy != NULL &&
- ssl_proxy_has_valid_client_cert(client->common.proxy))
- auth_flags |= AUTH_CLIENT_FLAG_SSL_VALID_CLIENT_CERT;
- if (client->tls)
- auth_flags |= AUTH_CLIENT_FLAG_SSL_ENABLED;
- return auth_flags;
-}
-
-int cmd_user(struct pop3_client *client, const char *args)
-{
- if (!client->secured && disable_plaintext_auth) {
- if (verbose_auth) {
- client_syslog(client, "Login failed: "
- "Plaintext authentication disabled");
- }
- client_send_line(client,
- "-ERR Plaintext authentication disabled.");
- return TRUE;
- }
-
- i_free(client->last_user);
- client->last_user = i_strdup(args);
-
- client_send_line(client, "+OK");
- return TRUE;
-}
-
-int cmd_pass(struct pop3_client *client, const char *args)
-{
- const char *error;
- struct auth_request_info info;
- string_t *plain_login;
-
- if (client->last_user == NULL) {
- client_send_line(client, "-ERR No username given.");
- return TRUE;
- }
-
- /* authorization ID \0 authentication ID \0 pass */
- plain_login = t_str_new(128);
- str_append_c(plain_login, '\0');
- str_append(plain_login, client->last_user);
- str_append_c(plain_login, '\0');
- str_append(plain_login, args);
-
- memset(&info, 0, sizeof(info));
- info.mech = "PLAIN";
- info.protocol = "POP3";
- info.flags = client_get_auth_flags(client);
- info.local_ip = client->common.local_ip;
- info.remote_ip = client->common.ip;
- info.initial_resp_data = str_data(plain_login);
- info.initial_resp_size = str_len(plain_login);
-
- client_ref(client);
-
- client->common.auth_request =
- auth_client_request_new(auth_client, NULL, &info,
- login_callback, client, &error);
- if (client->common.auth_request == NULL) {
- if (verbose_auth)
- client_syslog(client, "Login failed: %s", error);
- client_send_line(client,
- t_strconcat("-ERR Login failed: ", error, NULL));
- client_unref(client);
- return TRUE;
- }
-
- /* don't read any input from client until login is finished */
- if (client->common.io != NULL) {
- io_remove(client->common.io);
- client->common.io = NULL;
- }
-
- client->authenticating = TRUE;
- return TRUE;
-}
-
-static void authenticate_callback(struct auth_request *request,
- struct auth_client_request_reply *reply,
- const unsigned char *data, void *context)
-{
- struct pop3_client *client = context;
- const char *error;
-
- if (!client->authenticating) {
- /* client aborted */
- i_assert(reply == NULL);
- return;
- }
-
- switch (auth_callback(request, reply, data, &client->common,
- master_callback, &error)) {
- case -1:
- /* login failed */
- client_auth_abort(client, error);
- break;
-
- case 0:
- client_send_auth_data(client, data, reply->data_size);
- break;
-
- default:
- /* success, we should be able to log in. if we fail, just
- disconnect the client. */
- client->authenticating = FALSE;
- client_send_line(client, "+OK Logged in.");
- client_unref(client);
- }
-}
-
static void client_auth_input(void *context)
{
struct pop3_client *client = context;
@@ -275,7 +63,8 @@
return;
if (strcmp(line, "*") == 0) {
- client_auth_abort(client, "Authentication aborted");
+ sasl_server_auth_cancel(&client->common,
+ "Authentication aborted");
return;
}
@@ -284,13 +73,13 @@
if (base64_decode(line, linelen, NULL, buf) < 0) {
/* failed */
- client_auth_abort(client, "Invalid base64 data");
+ sasl_server_auth_cancel(&client->common, "Invalid base64 data");
} else if (client->common.auth_request == NULL) {
- client_auth_abort(client, "Don't send unrequested data");
+ sasl_server_auth_cancel(&client->common,
+ "Don't send unrequested data");
} else {
auth_client_request_continue(client->common.auth_request,
- buffer_get_data(buf, NULL),
- buffer_get_used_size(buf));
+ buf->data, buf->used);
}
/* clear sensitive data */
@@ -300,11 +89,66 @@
safe_memset(buffer_free_without_data(buf), 0, bufsize);
}
+static void sasl_callback(struct client *_client, enum sasl_server_reply reply,
+ const char *data)
+{
+ struct pop3_client *client = (struct pop3_client *)_client;
+ struct const_iovec iov[3];
+ size_t data_len;
+ ssize_t ret;
+
+ switch (reply) {
+ case SASL_SERVER_REPLY_SUCCESS:
+ client_send_line(client, "+OK Logged in.");
+ client_destroy(client, t_strconcat(
+ "Login: ", client->common.virtual_user, NULL));
+ break;
+ case SASL_SERVER_REPLY_AUTH_FAILED:
+ if (data == NULL)
+ client_send_line(client, "-ERR Authentication failed");
+ else {
+ client_send_line(client, t_strconcat(
+ "-ERR Authentication failed: ", data, NULL));
+ }
+
+ /* get back to normal client input. */
+ io_remove(client->io);
+ client->io = io_add(client->common.fd, IO_READ,
+ client_input, client);
+ break;
+ case SASL_SERVER_REPLY_MASTER_FAILED:
+ client_destroy(client, t_strconcat("Internal login failure: ",
+ client->common.virtual_user,
+ NULL));
+ break;
+ case SASL_SERVER_REPLY_CONTINUE:
+ data_len = strlen(data);
+ iov[0].iov_base = "+ ";
+ iov[0].iov_len = 2;
+ iov[1].iov_base = data;
+ iov[1].iov_len = data_len;
+ iov[2].iov_base = "\r\n";
+ iov[2].iov_len = 2;
+
+ ret = o_stream_sendv(client->output, iov, 3);
+ if (ret < 0)
+ client_destroy(client, "Disconnected");
+ else if ((size_t)ret != 2 + data_len + 2)
+ client_destroy(client, "Transmit buffer full");
+ else {
+ /* continue */
+ return;
+ }
+ break;
+ }
+
+ client_unref(client);
+}
+
int cmd_auth(struct pop3_client *client, const char *args)
{
- struct auth_request_info info;
const struct auth_mech_desc *mech;
- const char *mech_name, *error, *p;
+ const char *mech_name, *p;
string_t *buf;
size_t argslen;
@@ -332,81 +176,89 @@
args = p+1;
}
- mech = auth_client_find_mech(auth_client, mech_name);
- if (mech == NULL) {
- if (verbose_auth) {
- client_syslog(client, "Authenticate %s failed: "
- "Unsupported mechanism",
- str_sanitize(mech_name, MAX_MECH_NAME));
- }
- client_send_line(client,
- "-ERR Unsupported authentication mechanism.");
+ argslen = strlen(args);
+ buf = buffer_create_static_hard(pool_datastack_create(), argslen);
+
+ if (base64_decode(args, argslen, NULL, buf) < 0) {
+ /* failed */
+ client_send_line(client, "-ERR Invalid base64 data.");
return TRUE;
}
- if (!client->secured && mech->plaintext && disable_plaintext_auth) {
+ client_ref(client);
+ sasl_server_auth_begin(&client->common, "POP3", mech_name,
+ buf->data, buf->used, sasl_callback);
+ if (!client->common.authenticating)
+ return TRUE;
+
+ /* following input data will go to authentication */
+ if (client->io != NULL)
+ io_remove(client->io);
+ client->io = io_add(client->common.fd, IO_READ,
+ client_auth_input, client);
+ return TRUE;
+}
+
+int cmd_user(struct pop3_client *client, const char *args)
+{
+ if (!client->secured && disable_plaintext_auth) {
if (verbose_auth) {
- client_syslog(client, "Authenticate %s failed: "
- "Plaintext authentication disabled",
- str_sanitize(mech_name, MAX_MECH_NAME));
+ client_syslog(&client->common, "Login failed: "
+ "Plaintext authentication disabled");
}
client_send_line(client,
"-ERR Plaintext authentication disabled.");
return TRUE;
}
- argslen = strlen(args);
- buf = buffer_create_static_hard(pool_datastack_create(), argslen);
+ i_free(client->last_user);
+ client->last_user = i_strdup(args);
- if (base64_decode(args, argslen, NULL, buf) < 0) {
- /* failed */
- client_send_line(client, "-ERR Invalid base64 data.");
+ client_send_line(client, "+OK");
+ return TRUE;
+}
+
+int cmd_pass(struct pop3_client *client, const char *args)
+{
+ string_t *plain_login;
+
+ if (client->last_user == NULL) {
+ client_send_line(client, "-ERR No username given.");
return TRUE;
}
- memset(&info, 0, sizeof(info));
- info.mech = mech->name;
- info.protocol = "POP3";
- info.flags = client_get_auth_flags(client);
- info.local_ip = client->common.local_ip;
- info.remote_ip = client->common.ip;
- info.initial_resp_data = str_data(buf);
- info.initial_resp_size = str_len(buf);
+ /* authorization ID \0 authentication ID \0 pass */
+ plain_login = t_str_new(128);
+ str_append_c(plain_login, '\0');
+ str_append(plain_login, client->last_user);
+ str_append_c(plain_login, '\0');
+ str_append(plain_login, args);
client_ref(client);
- client->common.auth_request =
- auth_client_request_new(auth_client, NULL, &info,
- authenticate_callback, client, &error);
- if (client->common.auth_request != NULL) {
- /* following input data will go to authentication */
- if (client->common.io != NULL)
- io_remove(client->common.io);
- client->common.io = io_add(client->common.fd, IO_READ,
- client_auth_input, client);
- client->authenticating = TRUE;
- } else {
- if (verbose_auth) {
- client_syslog(client, "Authenticate %s failed: %s",
- str_sanitize(mech_name, MAX_MECH_NAME),
- error);
- }
- client_send_line(client, t_strconcat(
- "-ERR Authentication failed: ", error, NULL));
- client_unref(client);
- }
+ sasl_server_auth_begin(&client->common, "POP3", "PLAIN",
+ plain_login->data, plain_login->used,
+ sasl_callback);
+ if (!client->common.authenticating)
+ return TRUE;
+ /* don't read any input from client until login is finished */
+ if (client->io != NULL) {
+ io_remove(client->io);
+ client->io = NULL;
+ }
return TRUE;
}
int cmd_apop(struct pop3_client *client, const char *args)
{
- struct auth_request_info info;
- const char *error, *p;
buffer_t *apop_data;
+ const char *p;
if (client->apop_challenge == NULL) {
- if (verbose_auth)
- client_syslog(client, "APOP failed: APOP not enabled");
+ if (verbose_auth) {
+ client_syslog(&client->common,
+ "APOP failed: APOP not enabled");
+ }
client_send_line(client, "-ERR APOP not enabled.");
return TRUE;
}
@@ -415,8 +267,8 @@
p = strchr(args, ' ');
if (p == NULL || strlen(p+1) != 32) {
if (verbose_auth) {
- client_syslog(client, "APOP failed: "
- "Invalid parameters");
+ client_syslog(&client->common,
+ "APOP failed: Invalid parameters");
}
client_send_line(client, "-ERR Invalid parameters.");
return TRUE;
@@ -431,7 +283,7 @@
if (hex_to_binary(p+1, apop_data) < 0) {
if (verbose_auth) {
- client_syslog(client, "APOP failed: "
+ client_syslog(&client->common, "APOP failed: "
"Invalid characters in MD5 response");
}
client_send_line(client,
@@ -439,41 +291,16 @@
return TRUE;
}
- memset(&info, 0, sizeof(info));
- info.mech = "APOP";
- info.protocol = "POP3";
- info.flags = client_get_auth_flags(client);
- info.local_ip = client->common.local_ip;
- info.remote_ip = client->common.ip;
- info.initial_resp_data =
- buffer_get_data(apop_data, &info.initial_resp_size);
-
client_ref(client);
- o_stream_uncork(client->output);
-
- client->common.auth_request =
- auth_client_request_new(auth_client, &client->auth_id, &info,
- login_callback, client, &error);
+ sasl_server_auth_begin(&client->common, "POP3", "APOP",
+ apop_data->data, apop_data->used, sasl_callback);
+ if (!client->common.authenticating)
+ return TRUE;
- if (client->common.auth_request != NULL) {
- /* don't read any input from client until login is finished */
- if (client->common.io != NULL) {
- io_remove(client->common.io);
- client->common.io = NULL;
- }
- client->authenticating = TRUE;
- } else if (error == NULL) {
- /* the auth connection was lost. we have no choice
- but to fail the APOP logins completely since the
- challenge is auth connection-specific. disconnect. */
- client_destroy(client, "APOP auth connection lost");
- client_unref(client);
- } else {
- if (verbose_auth)
- client_syslog(client, "APOP failed: %s", error);
- client_send_line(client,
- t_strconcat("-ERR Login failed: ", error, NULL));
- client_unref(client);
+ /* don't read any input from client until login is finished */
+ if (client->io != NULL) {
+ io_remove(client->io);
+ client->io = NULL;
}
return TRUE;
}
Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/client.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- client.c 5 Oct 2004 16:00:18 -0000 1.28
+++ client.c 11 Oct 2004 17:14:28 -0000 1.29
@@ -88,8 +88,7 @@
o_stream_unref(client->output);
client_open_streams(client, fd_ssl);
- client->common.io = io_add(client->common.fd, IO_READ,
- client_input, client);
+ client->io = io_add(client->common.fd, IO_READ, client_input, client);
}
static void client_output_starttls(void *context)
@@ -120,9 +119,9 @@
/* remove input handler, SSL proxy gives us a new fd. we also have to
remove it in case we have to wait for buffer to be flushed */
- if (client->common.io != NULL) {
- io_remove(client->common.io);
- client->common.io = NULL;
+ if (client->io != NULL) {
+ io_remove(client->io);
+ client->io = NULL;
}
client_send_line(client, "+OK Begin TLS negotiation now.");
@@ -282,8 +281,7 @@
static void client_auth_ready(struct pop3_client *client)
{
- client->common.io =
- io_add(client->common.fd, IO_READ, client_input, client);
+ client->io = io_add(client->common.fd, IO_READ, client_input, client);
client->apop_challenge = get_apop_challenge(client);
client_send_line(client, t_strconcat("+OK ", greeting,
@@ -340,7 +338,7 @@
client->destroyed = TRUE;
if (reason != NULL)
- client_syslog(client, "%s", reason);
+ client_syslog(&client->common, "%s", reason);
hash_remove(clients, client);
@@ -355,9 +353,9 @@
if (client->common.master_tag != 0)
master_request_abort(&client->common);
- if (client->common.io != NULL) {
- io_remove(client->common.io);
- client->common.io = NULL;
+ if (client->io != NULL) {
+ io_remove(client->io);
+ client->io = NULL;
}
net_disconnect(client->common.fd);
@@ -405,22 +403,6 @@
client_destroy(client, "Transmit buffer full");
}
-void client_syslog(struct pop3_client *client, const char *format, ...)
-{
- const char *addr;
- va_list args;
-
- addr = net_ip2addr(&client->common.ip);
- if (addr == NULL)
- addr = "??";
-
- t_push();
- va_start(args, format);
- i_info("%s [%s]", t_strdup_vprintf(format, args), addr);
- va_end(args);
- t_pop();
-}
-
static void client_check_idle(struct pop3_client *client)
{
if (ioloop_time - client->last_input >= CLIENT_LOGIN_IDLE_TIMEOUT)
Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/client.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- client.h 5 Oct 2004 16:00:18 -0000 1.11
+++ client.h 11 Oct 2004 17:14:28 -0000 1.12
@@ -12,6 +12,7 @@
time_t created;
int refcount;
+ struct io *io;
struct istream *input;
struct ostream *output;
@@ -33,8 +34,6 @@
void client_destroy(struct pop3_client *client, const char *reason);
void client_send_line(struct pop3_client *client, const char *line);
-void client_syslog(struct pop3_client *client, const char *format, ...)
- __attr_format__(2, 3);
int client_read(struct pop3_client *client);
void client_input(void *context);
- Previous message: [dovecot-cvs] dovecot/src/login-common Makefile.am, 1.5,
1.6 auth-common.c, 1.5, NONE auth-common.h, 1.2,
NONE client-common.h, 1.6, 1.7 sasl-server.c, NONE,
1.1 sasl-server.h, NONE, 1.1
- Next message: [dovecot-cvs] dovecot/src/lib-storage mail-storage.c,1.30,1.31
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list