Mercurial > dovecot > core-2.2
changeset 10004:4c532d8222f3 HEAD
authtest binary is now accessed via "doveadm auth" and "doveadm user".
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 08 Oct 2009 18:43:17 -0400 |
parents | 3721ae3917fc |
children | 910059d94bbc |
files | .hgignore src/doveadm/Makefile.am src/doveadm/doveadm-auth.c src/doveadm/doveadm.c src/doveadm/doveadm.h src/util/Makefile.am src/util/authtest.c |
diffstat | 7 files changed, 237 insertions(+), 222 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Oct 08 18:33:50 2009 -0400 +++ b/.hgignore Thu Oct 08 18:43:17 2009 -0400 @@ -78,7 +78,6 @@ src/plugins/fts-squat/squat-test src/pop3-login/pop3-login src/pop3/pop3 -src/util/authtest src/util/gdbhelper src/util/idxview src/util/imap-utf7
--- a/src/doveadm/Makefile.am Thu Oct 08 18:33:50 2009 -0400 +++ b/src/doveadm/Makefile.am Thu Oct 08 18:43:17 2009 -0400 @@ -29,8 +29,9 @@ doveadm_SOURCES = \ doveadm.c \ - doveadm-pw.c \ - doveadm-mail.c + doveadm-auth.c \ + doveadm-mail.c \ + doveadm-pw.c noinst_HEADERS = \ doveadm-mail.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/doveadm/doveadm-auth.c Thu Oct 08 18:43:17 2009 -0400 @@ -0,0 +1,229 @@ +/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "array.h" +#include "askpass.h" +#include "base64.h" +#include "str.h" +#include "auth-client.h" +#include "auth-master.h" +#include "auth-server-connection.h" +#include "doveadm.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +struct authtest_input { + const char *username; + const char *password; + struct auth_user_info info; +}; + +static int +cmd_user_input(const char *auth_socket_path, const struct authtest_input *input) +{ + struct auth_master_connection *conn; + pool_t pool; + struct auth_user_reply reply; + const char *const *fields; + unsigned int i, count; + int ret; + + if (auth_socket_path == NULL) + auth_socket_path = PKG_RUNDIR"/auth-userdb"; + + pool = pool_alloconly_create("auth master lookup", 1024); + + conn = auth_master_init(auth_socket_path, FALSE); + ret = auth_master_user_lookup(conn, input->username, &input->info, + pool, &reply); + if (ret < 0) + i_fatal("userdb lookup failed"); + else if (ret == 0) { + printf("userdb lookup: user %s doesn't exist\n", + input->username); + } else { + printf("userdb: %s\n", input->username); + + if (reply.uid != (uid_t)-1) + printf("uid : %s\n", dec2str(reply.uid)); + if (reply.gid != (gid_t)-1) + printf("gid : %s\n", dec2str(reply.gid)); + if (reply.user != NULL) + printf("user : %s\n", reply.user); + if (reply.home != NULL) + printf("home : %s\n", reply.home); + if (reply.chroot != NULL) + printf("chroot: %s\n", reply.chroot); + fields = array_get(&reply.extra_fields, &count); + if (count > 0) { + printf("extra fields:\n"); + for (i = 0; i < count; i++) + printf(" %s\n", fields[i]); + } + } + auth_master_deinit(&conn); + return ret == 0 ? 1 : 0; +} +static void +auth_callback(struct auth_client_request *request ATTR_UNUSED, + enum auth_request_status status, + const char *data_base64 ATTR_UNUSED, + const char *const *args, void *context) +{ + const struct authtest_input *input = context; + + if (!io_loop_is_running(current_ioloop)) + return; + + if (status == 0) + i_fatal("passdb expects SASL continuation"); + + if (status < 0) + printf("passdb: %s auth failed\n", input->username); + else + printf("passdb: %s auth succeeded\n", input->username); + + if (*args != NULL) { + printf("extra fields:\n"); + for (; *args != NULL; args++) + printf(" %s\n", *args); + } + io_loop_stop(current_ioloop); +} + +static void auth_connected(struct auth_client *client, + bool connected, void *context) +{ + struct authtest_input *input = context; + struct auth_request_info info; + string_t *init_resp, *base64_resp; + + if (!connected) + i_fatal("Couldn't connect to auth socket"); + + init_resp = t_str_new(128); + str_append_c(init_resp, '\0'); + str_append(init_resp, input->username); + str_append_c(init_resp, '\0'); + str_append(init_resp, input->password); + + base64_resp = t_str_new(128); + base64_encode(str_data(init_resp), str_len(init_resp), base64_resp); + + memset(&info, 0, sizeof(info)); + info.mech = "PLAIN"; + info.service = input->info.service; + info.local_ip = input->info.local_ip; + info.local_port = input->info.local_port; + info.remote_ip = input->info.remote_ip; + 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); +} + +static int +cmd_auth_input(const char *auth_socket_path, struct authtest_input *input) +{ + struct auth_client *client; + + if (auth_socket_path == NULL) + auth_socket_path = PKG_RUNDIR"/auth-client"; + + client = auth_client_init(auth_socket_path, getpid(), FALSE); + auth_client_set_connect_notify(client, auth_connected, input); + + io_loop_run(current_ioloop); + + auth_client_set_connect_notify(client, NULL, NULL); + auth_client_deinit(&client); + return 0; +} + +static void auth_user_info_parse(struct auth_user_info *info, const char *arg) +{ + if (strncmp(arg, "service=", 8) == 0) + info->service = arg + 8; + else if (strncmp(arg, "lip=", 4) == 0) { + if (net_addr2ip(arg + 4, &info->local_ip) < 0) + i_fatal("lip: Invalid ip"); + } else if (strncmp(arg, "rip=", 4) == 0) { + if (net_addr2ip(arg + 4, &info->remote_ip) < 0) + i_fatal("rip: Invalid ip"); + } else if (strncmp(arg, "lport=", 6) == 0) { + info->local_port = atoi(arg + 6); + } else if (strncmp(arg, "rport=", 6) == 0) { + info->remote_port = atoi(arg + 6); + } else { + i_fatal("Unknown -x argument: %s", arg); + } +} + +static void +auth_cmd_common(const struct doveadm_cmd *cmd, int argc, char *argv[]) +{ + const char *auth_socket_path = NULL; + struct authtest_input input; + int c; + + memset(&input, 0, sizeof(input)); + input.info.service = "doveadm"; + + while ((c = getopt(argc, argv, "a:x:")) > 0) { + switch (c) { + case 'a': + auth_socket_path = optarg; + break; + case 'x': + auth_user_info_parse(&input.info, optarg); + break; + default: + help(cmd); + } + } + if (optind == argc) + help(cmd); + + if (cmd == &doveadm_cmd_auth) { + input.username = argv[optind++]; + input.password = argv[optind] != NULL ? argv[optind] : + t_askpass("Password: "); + if (cmd_auth_input(auth_socket_path, &input) < 0) + exit(1); + } else { + bool first = TRUE; + + while ((input.username = argv[optind++]) != NULL) { + if (first) + first = FALSE; + else + putchar('\n'); + if (cmd_user_input(auth_socket_path, &input) < 0) + exit(1); + } + } +} + +static void cmd_auth(int argc, char *argv[]) +{ + auth_cmd_common(&doveadm_cmd_auth, argc, argv); +} + +static void cmd_user(int argc, char *argv[]) +{ + auth_cmd_common(&doveadm_cmd_user, argc, argv); +} + +struct doveadm_cmd doveadm_cmd_auth = { + cmd_auth, "auth", + "[-a <auth socket path>] [-x <auth info>] <user> [<password>]", NULL +}; + +struct doveadm_cmd doveadm_cmd_user = { + cmd_user, "user", + "[-a <auth socket path>] [-x <auth info>] <user> [<user> ...]", NULL +};
--- a/src/doveadm/doveadm.c Thu Oct 08 18:33:50 2009 -0400 +++ b/src/doveadm/doveadm.c Thu Oct 08 18:43:17 2009 -0400 @@ -79,6 +79,8 @@ i_array_init(&doveadm_cmds, 32); doveadm_mail_init(); doveadm_register_cmd(&doveadm_cmd_help); + doveadm_register_cmd(&doveadm_cmd_auth); + doveadm_register_cmd(&doveadm_cmd_user); doveadm_register_cmd(&doveadm_cmd_pw); /* "+" is GNU extension to stop at the first non-option. @@ -96,7 +98,7 @@ argv += optind; if (!doveadm_try_run(cmd_name, argc, argv) && - doveadm_mail_try_run(cmd_name, argc, argv)) + !doveadm_mail_try_run(cmd_name, argc, argv)) usage(); master_service_deinit(&master_service);
--- a/src/doveadm/doveadm.h Thu Oct 08 18:33:50 2009 -0400 +++ b/src/doveadm/doveadm.h Thu Oct 08 18:43:17 2009 -0400 @@ -12,6 +12,8 @@ const char *long_usage; }; +extern struct doveadm_cmd doveadm_cmd_auth; +extern struct doveadm_cmd doveadm_cmd_user; extern struct doveadm_cmd doveadm_cmd_pw; void doveadm_register_cmd(const struct doveadm_cmd *cmd);
--- a/src/util/Makefile.am Thu Oct 08 18:33:50 2009 -0400 +++ b/src/util/Makefile.am Thu Oct 08 18:43:17 2009 -0400 @@ -1,7 +1,6 @@ pkglibexecdir = $(libexecdir)/dovecot pkglibexec_PROGRAMS = \ - authtest \ rawlog \ gdbhelper \ idxview \ @@ -24,11 +23,6 @@ -I$(top_srcdir)/src/auth \ -DPKG_RUNDIR=\""$(rundir)"\" -authtest_LDADD = $(LIBDOVECOT) -authtest_DEPENDENCIES = $(LIBDOVECOT) -authtest_SOURCES = \ - authtest.c - rawlog_LDADD = $(LIBDOVECOT) rawlog_DEPENDENCIES = $(LIBDOVECOT) rawlog_SOURCES = \
--- a/src/util/authtest.c Thu Oct 08 18:33:50 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "ioloop.h" -#include "array.h" -#include "base64.h" -#include "str.h" -#include "master-service.h" -#include "auth-client.h" -#include "auth-server-connection.h" -#include "auth-master.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -struct authtest_input { - const char *username; - const char *password; - struct auth_user_info info; -}; - -static const char *auth_socket_path = NULL; - -static int authtest_userdb(const struct authtest_input *input) -{ - struct auth_master_connection *conn; - pool_t pool; - struct auth_user_reply reply; - const char *const *fields; - unsigned int i, count; - int ret; - - if (auth_socket_path == NULL) - auth_socket_path = PKG_RUNDIR"/auth-userdb"; - - pool = pool_alloconly_create("auth master lookup", 1024); - - conn = auth_master_init(auth_socket_path, FALSE); - ret = auth_master_user_lookup(conn, input->username, &input->info, - pool, &reply); - if (ret < 0) - i_fatal("userdb lookup failed"); - else if (ret == 0) { - printf("userdb lookup: user %s doesn't exist\n", - input->username); - } else { - printf("userdb: %s\n", input->username); - - if (reply.uid != (uid_t)-1) - printf("uid : %s\n", dec2str(reply.uid)); - if (reply.gid != (gid_t)-1) - printf("gid : %s\n", dec2str(reply.gid)); - if (reply.user != NULL) - printf("user : %s\n", reply.user); - if (reply.home != NULL) - printf("home : %s\n", reply.home); - if (reply.chroot != NULL) - printf("chroot: %s\n", reply.chroot); - fields = array_get(&reply.extra_fields, &count); - if (count > 0) { - printf("extra fields:\n"); - for (i = 0; i < count; i++) - printf(" %s\n", fields[i]); - } - } - auth_master_deinit(&conn); - return ret == 0 ? 1 : 0; -} - -static void -auth_callback(struct auth_client_request *request ATTR_UNUSED, - enum auth_request_status status, - const char *data_base64 ATTR_UNUSED, - const char *const *args, void *context) -{ - const struct authtest_input *input = context; - - if (!io_loop_is_running(current_ioloop)) - return; - - if (status == 0) - i_fatal("passdb expects SASL continuation"); - - if (status < 0) - printf("passdb: %s auth failed\n", input->username); - else - printf("passdb: %s auth succeeded\n", input->username); - - if (*args != NULL) { - printf("extra fields:\n"); - for (; *args != NULL; args++) - printf(" %s\n", *args); - } - io_loop_stop(current_ioloop); -} - -static void auth_connected(struct auth_client *client, - bool connected, void *context) -{ - struct authtest_input *input = context; - struct auth_request_info info; - string_t *init_resp, *base64_resp; - - if (!connected) - i_fatal("Couldn't connect to auth socket"); - - init_resp = t_str_new(128); - str_append_c(init_resp, '\0'); - str_append(init_resp, input->username); - str_append_c(init_resp, '\0'); - str_append(init_resp, input->password); - - base64_resp = t_str_new(128); - base64_encode(str_data(init_resp), str_len(init_resp), base64_resp); - - memset(&info, 0, sizeof(info)); - info.mech = "PLAIN"; - info.service = input->info.service; - info.local_ip = input->info.local_ip; - info.local_port = input->info.local_port; - info.remote_ip = input->info.remote_ip; - 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); -} - -static int -authtest_passdb(struct authtest_input *input) -{ - struct auth_client *client; - - if (auth_socket_path == NULL) - auth_socket_path = PKG_RUNDIR"/auth-client"; - - client = auth_client_init(auth_socket_path, getpid(), FALSE); - auth_client_set_connect_notify(client, auth_connected, input); - - io_loop_run(current_ioloop); - - auth_client_set_connect_notify(client, NULL, NULL); - auth_client_deinit(&client); - return 0; -} - -static void auth_user_info_parse(struct auth_user_info *info, const char *arg) -{ - if (strncmp(arg, "service=", 8) == 0) - info->service = arg + 8; - else if (strncmp(arg, "lip=", 4) == 0) { - if (net_addr2ip(arg + 4, &info->local_ip) < 0) - i_fatal("lip: Invalid ip"); - } else if (strncmp(arg, "rip=", 4) == 0) { - if (net_addr2ip(arg + 4, &info->remote_ip) < 0) - i_fatal("rip: Invalid ip"); - } else if (strncmp(arg, "lport=", 6) == 0) { - info->local_port = atoi(arg + 6); - } else if (strncmp(arg, "rport=", 6) == 0) { - info->remote_port = atoi(arg + 6); - } else { - i_fatal("Unknown -x argument: %s", arg); - } -} - -static void usage(void) -{ - i_fatal( -"usage: authtest [-a <auth socket path>] [-x <auth info>] <user> [<password]"); -} - -int main(int argc, char *argv[]) -{ - const char *getopt_str; - struct authtest_input input; - int c, ret; - - memset(&input, 0, sizeof(input)); - input.info.service = "authtest"; - - master_service = master_service_init("authtest", - MASTER_SERVICE_FLAG_STANDALONE, - argc, argv); - getopt_str = t_strconcat("a:x:", master_service_getopt_string(), NULL); - while ((c = getopt(argc, argv, getopt_str)) > 0) { - switch (c) { - case 'a': - auth_socket_path = optarg; - break; - case 'x': - auth_user_info_parse(&input.info, optarg); - break; - default: - if (!master_service_parse_option(master_service, - c, optarg)) - usage(); - } - } - if (optind == argc) - usage(); - - input.username = argv[optind++]; - if (argv[optind] == NULL) - ret = authtest_userdb(&input); - else { - input.password = argv[optind]; - ret = authtest_passdb(&input); - } - master_service_deinit(&master_service); - return ret; -}