dovecot-2.2: auth: Handle proxy_maybe=yes with host=hostname pro...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 25 05:13:46 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/da43dc494753
changeset: 14155:da43dc494753
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 25 05:04:15 2012 +0200
description:
auth: Handle proxy_maybe=yes with host=hostname properly.

diffstat:

 src/auth/Makefile.am              |    1 +
 src/auth/auth-master-connection.c |   37 +++++++-
 src/auth/auth-request-handler.c   |  121 ++++++++++++++++++++-----------
 src/auth/auth-request.c           |  143 +++++++++++++++++++++++++++++++------
 src/auth/auth-request.h           |    8 +-
 5 files changed, 237 insertions(+), 73 deletions(-)

diffs (truncated from 469 to 300 lines):

diff -r 52e8a1346d2e -r da43dc494753 src/auth/Makefile.am
--- a/src/auth/Makefile.am	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/auth/Makefile.am	Sat Feb 25 05:04:15 2012 +0200
@@ -24,6 +24,7 @@
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib \
 	-I$(top_srcdir)/src/lib-auth \
+	-I$(top_srcdir)/src/lib-dns \
 	-I$(top_srcdir)/src/lib-sql \
 	-I$(top_srcdir)/src/lib-settings \
 	-I$(top_srcdir)/src/lib-ntlm \
diff -r 52e8a1346d2e -r da43dc494753 src/auth/auth-master-connection.c
--- a/src/auth/auth-master-connection.c	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/auth/auth-master-connection.c	Sat Feb 25 05:04:15 2012 +0200
@@ -287,18 +287,13 @@
 	return TRUE;
 }
 
-static void
-pass_callback(enum passdb_result result,
-	      const unsigned char *credentials ATTR_UNUSED,
-	      size_t size ATTR_UNUSED,
-	      struct auth_request *auth_request)
+static void pass_callback_finish(struct auth_request *auth_request,
+				 enum passdb_result result)
 {
 	struct auth_master_connection *conn = auth_request->master;
 	struct auth_stream_reply *reply = auth_request->extra_fields;
 	string_t *str;
 
-	auth_request_proxy_finish(auth_request, result == PASSDB_RESULT_OK);
-
 	str = t_str_new(128);
 	switch (result) {
 	case PASSDB_RESULT_OK:
@@ -331,6 +326,34 @@
 	auth_master_connection_unref(&conn);
 }
 
+static void
+auth_master_pass_proxy_finish(bool success, struct auth_request *auth_request)
+{
+	pass_callback_finish(auth_request, success ? PASSDB_RESULT_OK :
+			     PASSDB_RESULT_INTERNAL_FAILURE);
+}
+
+static void
+pass_callback(enum passdb_result result,
+	      const unsigned char *credentials ATTR_UNUSED,
+	      size_t size ATTR_UNUSED,
+	      struct auth_request *auth_request)
+{
+	int ret;
+
+	if (result != PASSDB_RESULT_OK)
+		auth_request_proxy_finish_failure(auth_request);
+	else {
+		ret = auth_request_proxy_finish(auth_request,
+						auth_master_pass_proxy_finish);
+		if (ret == 0)
+			return;
+		if (ret < 0)
+			result = PASSDB_RESULT_INTERNAL_FAILURE;
+	}
+	pass_callback_finish(auth_request, result);
+}
+
 static const char *auth_restricted_reason(struct auth_master_connection *conn)
 {
 	struct passwd pw;
diff -r 52e8a1346d2e -r da43dc494753 src/auth/auth-request-handler.c
--- a/src/auth/auth-request-handler.c	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/auth/auth-request-handler.c	Sat Feb 25 05:04:15 2012 +0200
@@ -237,6 +237,72 @@
 	}
 }
 
+static void
+auth_request_handler_reply_success_finish(struct auth_request *request)
+{
+        struct auth_request_handler *handler = request->handler;
+	struct auth_stream_reply *reply;
+
+	reply = auth_stream_reply_init(pool_datastack_create());
+
+	if (request->last_penalty != 0 && auth_penalty != NULL) {
+		/* reset penalty */
+		auth_penalty_update(auth_penalty, request, 0);
+	}
+
+	auth_stream_reply_add(reply, "OK", NULL);
+	auth_stream_reply_add(reply, NULL, dec2str(request->id));
+	auth_stream_reply_add(reply, "user", request->user);
+	get_client_extra_fields(request, reply);
+	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(reply, handler->context);
+}
+
+static void
+auth_request_handler_reply_failure_finish(struct auth_request *request)
+{
+	struct auth_stream_reply *reply;
+
+	reply = auth_stream_reply_init(pool_datastack_create());
+	auth_stream_reply_add(reply, "FAIL", NULL);
+	auth_stream_reply_add(reply, NULL, dec2str(request->id));
+	if (request->user != NULL)
+		auth_stream_reply_add(reply, "user", request->user);
+	else if (request->original_username != NULL) {
+		auth_stream_reply_add(reply, "user",
+				      request->original_username);
+	}
+
+	if (request->internal_failure)
+		auth_stream_reply_add(reply, "temp", NULL);
+	else if (request->master_user != NULL) {
+		/* authentication succeeded, but we can't log in
+		   as the wanted user */
+		auth_stream_reply_add(reply, "authz", NULL);
+	}
+	if (request->no_failure_delay)
+		auth_stream_reply_add(reply, "nodelay", NULL);
+	get_client_extra_fields(request, reply);
+
+	auth_request_handle_failure(request, reply);
+}
+
+static void
+auth_request_handler_proxy_callback(bool success, struct auth_request *request)
+{
+        struct auth_request_handler *handler = request->handler;
+
+	if (success)
+		auth_request_handler_reply_success_finish(request);
+	else
+		auth_request_handler_reply_failure_finish(request);
+        auth_request_handler_unref(&handler);
+}
+
 void auth_request_handler_reply(struct auth_request *request,
 				enum auth_client_result result,
 				const void *auth_reply, size_t reply_size)
@@ -244,6 +310,7 @@
         struct auth_request_handler *handler = request->handler;
 	struct auth_stream_reply *reply;
 	string_t *str;
+	int ret;
 
 	if (handler->destroyed) {
 		/* the client connection was already closed. we can't do
@@ -255,9 +322,9 @@
 		auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
 	}
 
-	reply = auth_stream_reply_init(pool_datastack_create());
 	switch (result) {
 	case AUTH_CLIENT_RESULT_CONTINUE:
+		reply = auth_stream_reply_init(pool_datastack_create());
 		auth_stream_reply_add(reply, "CONT", NULL);
 		auth_stream_reply_add(reply, NULL, dec2str(request->id));
 
@@ -269,53 +336,23 @@
 		handler->callback(reply, handler->context);
 		break;
 	case AUTH_CLIENT_RESULT_SUCCESS:
-		auth_request_proxy_finish(request, TRUE);
-
-		if (request->last_penalty != 0 && auth_penalty != NULL) {
-			/* reset penalty */
-			auth_penalty_update(auth_penalty, request, 0);
-		}
-
-		auth_stream_reply_add(reply, "OK", NULL);
-		auth_stream_reply_add(reply, NULL, dec2str(request->id));
-		auth_stream_reply_add(reply, "user", request->user);
 		if (reply_size > 0) {
 			str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size));
 			base64_encode(auth_reply, reply_size, str);
-			auth_stream_reply_add(reply, "resp", str_c(str));
+			auth_stream_reply_add(request->extra_fields, "resp", str_c(str));
 		}
-		get_client_extra_fields(request, reply);
-		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(reply, handler->context);
+		ret = auth_request_proxy_finish(request,
+				auth_request_handler_proxy_callback);
+		if (ret < 0)
+			auth_request_handler_reply_failure_finish(request);
+		else if (ret > 0)
+			auth_request_handler_reply_success_finish(request);
+		else
+			return;
 		break;
 	case AUTH_CLIENT_RESULT_FAILURE:
-		auth_request_proxy_finish(request, FALSE);
-
-		auth_stream_reply_add(reply, "FAIL", NULL);
-		auth_stream_reply_add(reply, NULL, dec2str(request->id));
-		if (request->user != NULL)
-			auth_stream_reply_add(reply, "user", request->user);
-		else if (request->original_username != NULL) {
-			auth_stream_reply_add(reply, "user",
-					      request->original_username);
-		}
-
-		if (request->internal_failure)
-			auth_stream_reply_add(reply, "temp", NULL);
-		else if (request->master_user != NULL) {
-			/* authentication succeeded, but we can't log in
-			   as the wanted user */
-			auth_stream_reply_add(reply, "authz", NULL);
-		}
-		if (request->no_failure_delay)
-			auth_stream_reply_add(reply, "nodelay", NULL);
-		get_client_extra_fields(request, reply);
-
-		auth_request_handle_failure(request, reply);
+		auth_request_proxy_finish_failure(request);
+		auth_request_handler_reply_failure_finish(request);
 		break;
 	}
 	/* NOTE: request may be destroyed now */
diff -r 52e8a1346d2e -r da43dc494753 src/auth/auth-request.c
--- a/src/auth/auth-request.c	Sat Feb 25 04:38:01 2012 +0200
+++ b/src/auth/auth-request.c	Sat Feb 25 05:04:15 2012 +0200
@@ -11,6 +11,7 @@
 #include "str-sanitize.h"
 #include "strescape.h"
 #include "var-expand.h"
+#include "dns-lookup.h"
 #include "auth-cache.h"
 #include "auth-request.h"
 #include "auth-request-handler.h"
@@ -27,6 +28,8 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 
+#define AUTH_DNS_SOCKET_PATH "dns-client"
+#define AUTH_DNS_TIMEOUT_MSECS (1000*10)
 #define CACHED_PASSWORD_SCHEME "SHA1"
 
 unsigned int auth_request_state_count[AUTH_REQUEST_STATE_MAX];
@@ -158,6 +161,11 @@
 	auth_request_state_count[request->state]--;
 	auth_refresh_proctitle();
 
+	if (request->mech_password != NULL) {
+		safe_memset(request->mech_password, 0,
+			    strlen(request->mech_password));
+	}
+
 	if (request->to_abort != NULL)
 		timeout_remove(&request->to_abort);
 	if (request->to_penalty != NULL)
@@ -543,8 +551,6 @@
 	} else {
 		auth_request_ref(request);
 		request->private_callback.verify_plain(result, request);
-		safe_memset(request->mech_password, 0,
-			    strlen(request->mech_password));
 		auth_request_unref(&request);
 	}
 }
@@ -1410,53 +1416,144 @@
 
 static bool auth_request_proxy_is_self(struct auth_request *request)
 {
-	const char *const *tmp, *host = NULL, *port = NULL, *destuser = NULL;
-	struct ip_addr ip;
+	const char *const *tmp, *port = NULL, *destuser = NULL;
+
+	if (!request->proxy_host_is_self)
+		return FALSE;
 
 	tmp = auth_stream_split(request->extra_fields);
 	for (; *tmp != NULL; tmp++) {
-		if (strncmp(*tmp, "host=", 5) == 0)
-			host = *tmp + 5;
-		else if (strncmp(*tmp, "port=", 5) == 0)
+		if (strncmp(*tmp, "port=", 5) == 0)
 			port = *tmp + 5;
-		if (strncmp(*tmp, "destuser=", 9) == 0)
+		else if (strncmp(*tmp, "destuser=", 9) == 0)
 			destuser = *tmp + 9;
 	}
 
-	if (host == NULL || net_addr2ip(host, &ip) < 0) {
-		/* broken setup */
-		return FALSE;
-	}
-	if (!net_ip_compare(&ip, &request->local_ip))
-		return FALSE;


More information about the dovecot-cvs mailing list