diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/scripts/MakeLinks exim-4.43/scripts/MakeLinks --- exim-4.43.vanilla/scripts/MakeLinks 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/scripts/MakeLinks 2004-12-09 15:38:46.000000000 +0300 @@ -167,6 +167,8 @@ ln -s ../../src/auths/auth-spa.h ln -s ../../src/auths/sha1.c sha1.c ln -s ../../src/auths/spa.c spa.c ln -s ../../src/auths/spa.h spa.h +ln -s ../../src/auths/dovecot.c dovecot.c +ln -s ../../src/auths/dovecot.h dovecot.h cd .. # The basic source files for Exim and utilities. NB local_scan.h gets linked, diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/auths/dovecot.c exim-4.43/src/auths/dovecot.c --- exim-4.43.vanilla/src/auths/dovecot.c 1970-01-01 03:00:00.000000000 +0300 +++ exim-4.43/src/auths/dovecot.c 2004-12-09 15:38:46.000000000 +0300 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2004 Andrey Panin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "../exim.h" +#include "dovecot.h" + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 0 + +/* Options specific to the authentication mechanism. */ +optionlist auth_dovecot_options[] = { + { + "server_socket", + opt_stringptr, + (void *)(offsetof(auth_dovecot_options_block, server_socket)) + }, +}; + +/* Size of the options list. An extern variable has to be used so that its +address can appear in the tables drtables.c. */ +int auth_dovecot_options_count = + sizeof(auth_dovecot_options) / sizeof(optionlist); + +/* Default private options block for the authentication method. */ +auth_dovecot_options_block auth_dovecot_option_defaults = { + NULL, /* server_socket */ +}; + +/************************************************* + * Initialization entry point * + *************************************************/ + +/* Called for each instance, after its options have been read, to +enable consistency checks to be done, or anything else that needs +to be set up. */ +void auth_dovecot_init(auth_instance *ablock) +{ + auth_dovecot_options_block *ob = + (auth_dovecot_options_block *)(ablock->options_block); + + if (ablock->public_name == NULL) + ablock->public_name = ablock->name; + if (ob->server_socket != NULL) + ablock->server = TRUE; + ablock->client = FALSE; +} + +static int strcut(char *str, char **ptrs, int nptrs) +{ + char *tmp = str; + int n; + + for (n = 0; n < nptrs; n++) + ptrs[n] = NULL; + n = 1; + + while (*str) { + if (*str == '\t') { + if (n <= nptrs) { + *ptrs++ = tmp; + tmp = str + 1; + *str = 0; + } + n++; + } + str++; + } + + if (n < nptrs) + *ptrs = tmp; + + return n; +} + +#define CHECK_COMMAND(str, arg_min, arg_max) do { \ + if (strcasecmp((str), args[0]) != 0) \ + goto out; \ + if (nargs - 1 < (arg_min)) \ + goto out; \ + if (nargs - 1 > (arg_max)) \ + goto out; \ +} while (0) + +#define OUT(msg) do { \ + auth_defer_msg = (msg); \ + goto out; \ +} while(0) + +/************************************************* + * Server entry point * + *************************************************/ + +int auth_dovecot_server(auth_instance *ablock, uschar *data) +{ + auth_dovecot_options_block *ob = + (auth_dovecot_options_block *)(ablock->options_block); + struct sockaddr_un sa; + char buffer[4096]; + char *args[8]; + int nargs, tmp; + int cuid = 0, cont = 1, found = 0, fd, ret = DEFER; + FILE *f; + + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + if (strncpy(sa.sun_path, ob->server_socket, sizeof(sa.sun_path)) < 0) { + auth_defer_msg = "authentication socket path too long"; + return DEFER; + } + + auth_defer_msg = "authentication socket connection error"; + + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return DEFER; + + if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) + goto out; + + f = fdopen(fd, "a+"); + if (f == NULL) + goto out; + + auth_defer_msg = "authentication socket protocol error"; + + while (cont) { + if (fgets(buffer, sizeof(buffer), f) == NULL) + OUT("authentication socket read error or premature eof"); + + buffer[strlen(buffer) - 1] = 0; + nargs = strcut(buffer, args, sizeof(args) / sizeof(args[0])); + + switch (toupper(*args[0])) { + case 'C': + CHECK_COMMAND("CUID", 1, 1); + cuid = atoi(args[1]); + break; + + case 'D': + CHECK_COMMAND("DONE", 0, 0); + cont = 0; + break; + + case 'M': + CHECK_COMMAND("MECH", 1, INT_MAX); + if (!strcasecmp(args[1], ablock->public_name)) + found = 1; + break; + + case 'S': + CHECK_COMMAND("SPID", 1, 1); + break; + + case 'V': + CHECK_COMMAND("VERSION", 2, 2); + if (atoi(args[1]) != VERSION_MAJOR) + OUT("authentication socket protocol version mismatch"); + break; + + default: + goto out; + } + } + + if (!found) + goto out; + + fprintf(f, "VERSION\t%d\t%d\r\nSERVICE\tSMTP\r\nCPID\t%d\r\n" + "AUTH\t%d\t%s\trip=%s\tlip=%s\tresp=%s\r\n", + VERSION_MAJOR, VERSION_MINOR, getpid(), cuid, + ablock->public_name, sender_host_address, interface_address, + data ? (char *) data : ""); + + while (1) { + if (fgets(buffer, sizeof(buffer), f) == NULL) { + auth_defer_msg = "authentication socket read error or premature eof"; + goto out; + } + + buffer[strlen(buffer) - 1] = 0; + nargs = strcut(buffer, args, sizeof(args) / sizeof(args[0])); + + if (atoi(args[1]) != cuid) + OUT("authentication socket connection id mismatch"); + + switch (toupper(*args[0])) { + case 'C': + CHECK_COMMAND("CONT", 1, 2); + + tmp = auth_get_no64_data(&data, args[2]); + if (tmp != OK) { + ret = tmp; + goto out; + } + + if (fprintf(f, "CONT\t%d\t%s\r\n", cuid, data) < 0) + OUT("authentication socket write error"); + + break; + + case 'F': + CHECK_COMMAND("FAIL", 1, 2); + + /* FIXME: add proper response handling */ + if (args[2]) { + char *p = strchr(args[2], '='); + if (p) { + ++p; + expand_nstring[1] = p; + expand_nlength[1] = strlen(p); + expand_nmax = 1; + } + } + + ret = FAIL; + goto out; + + case 'O': + CHECK_COMMAND("OK", 2, 2); + { + /* FIXME: add proper response handling */ + char *p = strchr(args[2], '='); + if (!p) + OUT("authentication socket protocol error, username missing"); + + p++; + expand_nstring[1] = p; + expand_nlength[1] = strlen(p); + expand_nmax = 1; + } + ret = OK; + /* fallthrough */ + + default: + goto out; + } + } + +out: close(fd); + return ret; +} diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/auths/dovecot.h exim-4.43/src/auths/dovecot.h --- exim-4.43.vanilla/src/auths/dovecot.h 1970-01-01 03:00:00.000000000 +0300 +++ exim-4.43/src/auths/dovecot.h 2004-12-09 15:47:43.000000000 +0300 @@ -0,0 +1,28 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) University of Cambridge 1995 - 2003 */ +/* See the file NOTICE for conditions of use and distribution. */ + +/* Private structure for the private options. */ + +typedef struct { + uschar *server_socket; +} auth_dovecot_options_block; + +/* Data for reading the private options. */ + +extern optionlist auth_dovecot_options[]; +extern int auth_dovecot_options_count; + +/* Block containing default values. */ + +extern auth_dovecot_options_block auth_dovecot_option_defaults; + +/* The entry points for the mechanism */ + +extern void auth_dovecot_init(auth_instance *); +extern int auth_dovecot_server(auth_instance *, uschar *); + +/* End of dovecot.h */ diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/auths/Makefile exim-4.43/src/auths/Makefile --- exim-4.43.vanilla/src/auths/Makefile 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/src/auths/Makefile 2004-12-09 15:46:44.000000000 +0300 @@ -7,7 +7,7 @@ OBJ = b64encode.o b64decode.o call_pam.o call_pwcheck.o call_radius.o \ xtextencode.o xtextdecode.o get_data.o get_no64_data.o md5.o \ - cram_md5.o cyrus_sasl.o plaintext.o pwcheck.o sha1.o auth-spa.o spa.o + cram_md5.o cyrus_sasl.o plaintext.o pwcheck.o sha1.o auth-spa.o spa.o dovecot.o auths.a: $(OBJ) /bin/rm -f auths.a @@ -37,4 +37,6 @@ cyrus_sasl.o: $(HDRS) cyrus_sasl.c cy plaintext.o: $(HDRS) plaintext.c plaintext.h spa.o: $(HDRS) spa.c spa.h +dovecot.o: $(HDRS) dovecot.c dovecot.h + # End diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/config.h.defaults exim-4.43/src/config.h.defaults --- exim-4.43.vanilla/src/config.h.defaults 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/src/config.h.defaults 2004-12-09 15:38:46.000000000 +0300 @@ -20,6 +20,7 @@ in config.h unless some value is defined #define AUTH_CYRUS_SASL #define AUTH_PLAINTEXT #define AUTH_SPA +#define AUTH_DOVECOT #define BIN_DIRECTORY diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/drtables.c exim-4.43/src/drtables.c --- exim-4.43.vanilla/src/drtables.c 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/src/drtables.c 2004-12-09 15:47:14.000000000 +0300 @@ -515,6 +515,10 @@ set to NULL for those that are not compi #include "auths/spa.h" #endif +#ifdef AUTH_DOVECOT +#include "auths/dovecot.h" +#endif + auth_info auths_available[] = { /* Checking by an expansion condition on plain text */ @@ -571,6 +575,18 @@ auth_info auths_available[] = { }, #endif +#ifdef AUTH_DOVECOT + { + US"dovecot", /* lookup name */ + auth_dovecot_options, + &auth_dovecot_options_count, + &auth_dovecot_option_defaults, + sizeof(auth_dovecot_options_block), + auth_dovecot_init, /* init function */ + auth_dovecot_server, /* server function */ + }, +#endif + { US"", NULL, NULL, NULL, 0, NULL, NULL, NULL } }; diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/EDITME exim-4.43/src/EDITME --- exim-4.43.vanilla/src/EDITME 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/src/EDITME 2004-12-09 16:00:00.000000000 +0300 @@ -410,6 +410,7 @@ FIXED_NEVER_USERS=root # AUTH_CYRUS_SASL=yes # AUTH_PLAINTEXT=yes # AUTH_SPA=yes +# AUTH_DOVECOT=yes #------------------------------------------------------------------------------ diff -urdpNx build-Linux-i386 -x Local exim-4.43.vanilla/src/exim.c exim-4.43/src/exim.c --- exim-4.43.vanilla/src/exim.c 2004-10-05 12:32:08.000000000 +0400 +++ exim-4.43/src/exim.c 2004-12-09 15:38:46.000000000 +0300 @@ -895,6 +895,10 @@ fprintf(f, "Authenticators:"); #ifdef AUTH_SPA fprintf(f, " spa"); #endif +#ifdef AUTH_DOVECOT + fprintf(f, " dovecot"); +#endif + fprintf(f, "\n"); fprintf(f, "Routers:");