dovecot-2.2: doveadm: Added new "auth login" command to simulate...

dovecot at dovecot.org dovecot at dovecot.org
Mon Sep 7 18:55:34 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/caaaa7c12edd
changeset: 19111:caaaa7c12edd
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Sep 07 21:54:20 2015 +0300
description:
doveadm: Added new "auth login" command to simulate an actual client login.
This performs both passdb and userdb lookups and prints their results.

diffstat:

 src/doveadm/doveadm-auth.c |  127 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 125 insertions(+), 2 deletions(-)

diffs (183 lines):

diff -r b7f7ad2bc4d0 -r caaaa7c12edd src/doveadm/doveadm-auth.c
--- a/src/doveadm/doveadm-auth.c	Mon Sep 07 21:24:01 2015 +0300
+++ b/src/doveadm/doveadm-auth.c	Mon Sep 07 21:54:20 2015 +0300
@@ -5,6 +5,7 @@
 #include "array.h"
 #include "askpass.h"
 #include "base64.h"
+#include "hex-binary.h"
 #include "str.h"
 #include "wildcard-match.h"
 #include "settings-parser.h"
@@ -13,6 +14,8 @@
 #include "auth-client.h"
 #include "auth-master.h"
 #include "auth-server-connection.h"
+#include "master-auth.h"
+#include "master-login-auth.h"
 #include "mail-storage-service.h"
 #include "mail-user.h"
 #include "doveadm.h"
@@ -23,10 +26,19 @@
 #include <unistd.h>
 
 struct authtest_input {
+	pool_t pool;
 	const char *username;
 	const char *password;
 	struct auth_user_info info;
 	bool success;
+
+	struct auth_client_request *request;
+	struct master_auth_request master_auth_req;
+
+	unsigned int auth_id;
+	unsigned int auth_pid;
+	const char *auth_cookie;
+
 };
 
 static void auth_cmd_help(doveadm_command_t *cmd);
@@ -106,6 +118,12 @@
 {
 	struct authtest_input *input = context;
 
+	input->request = NULL;
+	input->auth_id = auth_client_request_get_id(request);
+	input->auth_pid = auth_client_request_get_server_pid(request);
+	input->auth_cookie = input->pool == NULL ? NULL :
+		p_strdup(input->pool, auth_client_request_get_cookie(request));
+
 	if (!io_loop_is_running(current_ioloop))
 		return;
 
@@ -155,8 +173,8 @@
 	info.remote_port = input->info.remote_port;
 	info.initial_resp_base64 = str_c(base64_resp);
 
-	(void)auth_client_request_new(client, &info,
-				      auth_callback, input);
+	input->request = auth_client_request_new(client, &info,
+						 auth_callback, input);
 }
 
 static void
@@ -293,6 +311,109 @@
 		doveadm_exit_code = EX_NOPERM;
 }
 
+static void
+master_auth_callback(const char *const *auth_args,
+		     const char *errormsg, void *context)
+{
+	struct authtest_input *input = context;
+	unsigned int i;
+
+	io_loop_stop(current_ioloop);
+	if (errormsg != NULL) {
+		i_error("userdb lookup failed: %s", errormsg);
+		return;
+	}
+	printf("userdb extra fields:\n");
+	for (i = 0; auth_args[i] != NULL; i++)
+		printf("  %s\n", auth_args[i]);
+	input->success = TRUE;
+}
+
+static void
+cmd_auth_master_input(const char *auth_master_socket_path,
+		      struct authtest_input *input)
+{
+	struct master_login_auth *master_auth;
+	struct master_auth_request master_auth_req;
+	buffer_t buf;
+
+	memset(&master_auth_req, 0, sizeof(master_auth_req));
+	master_auth_req.tag = 1;
+	master_auth_req.auth_pid = input->auth_pid;
+	master_auth_req.auth_id = input->auth_id;
+	master_auth_req.client_pid = getpid();
+	master_auth_req.local_ip = input->info.local_ip;
+	master_auth_req.remote_ip = input->info.remote_ip;
+
+	buffer_create_from_data(&buf, master_auth_req.cookie,
+				sizeof(master_auth_req.cookie));
+	if (strlen(input->auth_cookie) == MASTER_AUTH_COOKIE_SIZE*2)
+		(void)hex_to_binary(input->auth_cookie, &buf);
+
+	input->success = FALSE;
+	master_auth = master_login_auth_init(auth_master_socket_path, FALSE);
+	io_loop_set_running(current_ioloop);
+	master_login_auth_request(master_auth, &master_auth_req,
+				  master_auth_callback, input);
+	if (io_loop_is_running(current_ioloop))
+		io_loop_run(current_ioloop);
+	master_login_auth_deinit(&master_auth);
+}
+
+static void cmd_auth_login(int argc, char *argv[])
+{
+	const char *auth_login_socket_path, *auth_master_socket_path;
+	struct auth_client *auth_client;
+	struct authtest_input input;
+	int c;
+
+	memset(&input, 0, sizeof(input));
+	input.info.service = "doveadm";
+
+	auth_login_socket_path = t_strconcat(doveadm_settings->base_dir,
+					     "/auth-login", NULL);
+	auth_master_socket_path = t_strconcat(doveadm_settings->base_dir,
+					      "/auth-master", NULL);
+	while ((c = getopt(argc, argv, "a:m:x:")) > 0) {
+		switch (c) {
+		case 'a':
+			auth_login_socket_path = optarg;
+			break;
+		case 'm':
+			auth_master_socket_path = optarg;
+			break;
+		case 'x':
+			auth_user_info_parse(&input.info, optarg);
+			break;
+		default:
+			auth_cmd_help(cmd_auth_login);
+		}
+	}
+
+	if (optind == argc)
+		auth_cmd_help(cmd_auth_login);
+
+	input.pool = pool_alloconly_create("auth login", 256);
+	input.username = argv[optind++];
+	input.password = argv[optind] != NULL ? argv[optind++] :
+		t_askpass("Password: ");
+	if (argv[optind] != NULL)
+			i_fatal("Unexpected parameter: %s", argv[optind]);
+	/* authenticate */
+	auth_client = auth_client_init(auth_login_socket_path, getpid(), FALSE);
+	auth_client_set_connect_notify(auth_client, auth_connected, &input);
+	if (!auth_client_is_disconnected(auth_client))
+		io_loop_run(current_ioloop);
+	auth_client_set_connect_notify(auth_client, NULL, NULL);
+	/* finish login with userdb lookup */
+	if (input.success)
+		cmd_auth_master_input(auth_master_socket_path, &input);
+	if (!input.success)
+		doveadm_exit_code = EX_NOPERM;
+	auth_client_deinit(&auth_client);
+	pool_unref(&input.pool);
+}
+
 static void cmd_auth_lookup(int argc, char *argv[])
 {
 	const char *auth_socket_path = doveadm_settings->auth_socket_path;
@@ -522,6 +643,8 @@
 struct doveadm_cmd doveadm_cmd_auth[] = {
 	{ cmd_auth_test, "auth test",
 	  "[-a <auth socket path>] [-x <auth info>] <user> [<password>]" },
+	{ cmd_auth_login, "auth login",
+	  "[-a <auth-login socket path>] [-m <auth-master socket path>] [-x <auth info>] <user> [<password>]" },
 	{ cmd_auth_lookup, "auth lookup",
 	  "[-a <userdb socket path>] [-x <auth info>] [-f field] <user> [...]" },
 	{ cmd_auth_cache_flush, "auth cache flush",


More information about the dovecot-cvs mailing list