dovecot-2.0: Added support for tcpwrappers and potentially other...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 6 19:46:45 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/51a978045f47
changeset: 10647:51a978045f47
user: Timo Sirainen <tss at iki.fi>
date: Sat Feb 06 19:46:40 2010 +0200
description:
Added support for tcpwrappers and potentially other login access checks.
diffstat:
12 files changed, 434 insertions(+), 1 deletion(-)
.hgignore | 2
configure.in | 27 +++++++
doc/example-config/dovecot.conf | 3
src/login-common/Makefile.am | 2
src/login-common/access-lookup.c | 119 ++++++++++++++++++++++++++++++++++
src/login-common/access-lookup.h | 11 +++
src/login-common/login-settings.c | 2
src/login-common/login-settings.h | 1
src/login-common/main.c | 100 +++++++++++++++++++++++++++++
src/util/Makefile.am | 10 ++
src/util/tcpwrap-settings.c | 32 +++++++++
src/util/tcpwrap.c | 126 +++++++++++++++++++++++++++++++++++++
diffs (truncated from 601 to 300 lines):
diff -r d4fd28f07507 -r 51a978045f47 .hgignore
--- a/.hgignore Sat Feb 06 17:31:14 2010 +0200
+++ b/.hgignore Sat Feb 06 19:46:40 2010 +0200
@@ -60,6 +60,7 @@ src/config/doveconf
src/config/doveconf
src/lda/dovecot-lda
src/dict/dict
+src/dns/dns-client
src/doveadm/doveadm
src/dsync/dsync
src/imap-login/imap-login
@@ -84,6 +85,7 @@ src/util/maildirlock
src/util/maildirlock
src/util/rawlog
src/util/script
+src/util/tcpwrap
src/plugins/quota/rquota_xdr.c
src/plugins/quota/rquota.h
diff -r d4fd28f07507 -r 51a978045f47 configure.in
--- a/configure.in Sat Feb 06 17:31:14 2010 +0200
+++ b/configure.in Sat Feb 06 19:46:40 2010 +0200
@@ -168,6 +168,11 @@ AC_ARG_WITH(libcap,
[ --with-libcap Build with libcap support (Dropping capabilities).],
TEST_WITH(libcap, $withval),
want_libcap=auto)
+
+AC_ARG_WITH(libwrap,
+[ --with-libwrap Build with libwrap, ie. TCP-wrappers (auto)],
+ TEST_WITH(libwrap, $withval),
+ want_libwrap=auto)
AC_ARG_WITH(ssl,
[ --with-ssl=gnutls|openssl Build with GNUTLS or OpenSSL (default)],
@@ -328,6 +333,28 @@ if test $want_libcap != no; then
fi
])
fi
+
+have_libwrap=no
+if test $want_libwrap != no; then
+ AC_CHECK_HEADER(tcpd.h, [
+ AC_CHECK_LIB(wrap, request_init, [
+ AC_DEFINE(HAVE_LIBWRAP,, Define if you have libwrap)
+ LIBWRAP_LIBS=-lwrap
+ AC_SUBST(LIBWRAP_LIBS)
+ have_libwrap=yes
+ ], [
+ if test "$want_libwrap" = "yes"; then
+ AC_ERROR([Can't build with libwrap support: libwrap not found])
+ fi
+ ])
+ LIBS=$old_LIBS
+ ], [
+ if test "$want_libwrap" = "yes"; then
+ AC_ERROR([Can't build with libwrap support: tcpd.h not found])
+ fi
+ ])
+fi
+AM_CONDITIONAL(TCPWRAPPERS, test "$have_libwrap" = "yes")
AC_DEFINE(PACKAGE_WEBPAGE, "http://www.dovecot.org/", Support URL)
diff -r d4fd28f07507 -r 51a978045f47 doc/example-config/dovecot.conf
--- a/doc/example-config/dovecot.conf Sat Feb 06 17:31:14 2010 +0200
+++ b/doc/example-config/dovecot.conf Sat Feb 06 19:46:40 2010 +0200
@@ -46,6 +46,9 @@
# these networks. Typically you'd specify your IMAP proxy servers here.
#login_trusted_networks =
+# Sepace separated list of login access check sockets (e.g. tcpwrap)
+#login_access_sockets =
+
# Show more verbose process titles (in ps). Currently shows user name and
# IP address. Useful for seeing who are actually using the IMAP processes
# (eg. shared mailboxes or if same uid is used for multiple accounts).
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/Makefile.am
--- a/src/login-common/Makefile.am Sat Feb 06 17:31:14 2010 +0200
+++ b/src/login-common/Makefile.am Sat Feb 06 19:46:40 2010 +0200
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
-DPKG_STATEDIR=\""$(statedir)"\"
liblogin_la_SOURCES = \
+ access-lookup.c \
client-common.c \
client-common-auth.c \
login-proxy.c \
@@ -24,6 +25,7 @@ liblogin_la_LIBADD = \
$(SSL_LIBS)
headers = \
+ access-lookup.h \
client-common.h \
login-common.h \
login-proxy.h \
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/access-lookup.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/login-common/access-lookup.c Sat Feb 06 19:46:40 2010 +0200
@@ -0,0 +1,119 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "network.h"
+#include "fdpass.h"
+#include "access-lookup.h"
+
+#include <unistd.h>
+
+#define ACCESS_LOOKUP_TIMEOUT_MSECS (1000*60)
+
+struct access_lookup {
+ int refcount;
+
+ int fd;
+ char *path;
+
+ struct io *io;
+ struct timeout *to;
+
+ access_lookup_callback_t *callback;
+ void *context;
+};
+
+static void access_lookup_input(struct access_lookup *lookup)
+{
+ unsigned char buf[3];
+ ssize_t ret;
+ bool success = FALSE;
+
+ ret = read(lookup->fd, buf, sizeof(buf));
+ if (ret < 0) {
+ i_error("read(%s) failed: %m", lookup->path);
+ } else if (ret == 0) {
+ /* connection close -> no success */
+ } else if (ret == 2 && buf[0] == '0' && buf[1] == '\n') {
+ /* no success */
+ } else if (ret == 2 && buf[0] == '1' && buf[1] == '\n') {
+ success = TRUE;
+ } else {
+ i_error("access(%s): Invalid input", lookup->path);
+ }
+
+ lookup->refcount++;
+ lookup->callback(success, lookup->context);
+ if (lookup->refcount > 1)
+ access_lookup_destroy(&lookup);
+ access_lookup_destroy(&lookup);
+}
+
+static void access_lookup_timeout(struct access_lookup *lookup)
+{
+ i_error("access(%s): Timed out while waiting for reply", lookup->path);
+
+ lookup->refcount++;
+ lookup->callback(FALSE, lookup->context);
+ if (lookup->refcount > 1)
+ access_lookup_destroy(&lookup);
+ access_lookup_destroy(&lookup);
+}
+
+struct access_lookup *
+access_lookup(const char *path, int client_fd, const char *daemon_name,
+ access_lookup_callback_t *callback, void *context)
+{
+ struct access_lookup *lookup;
+ const char *cmd;
+ ssize_t ret;
+ int fd;
+
+ fd = net_connect_unix(path);
+ if (fd == -1) {
+ i_error("connect(%s) failed: %m", path);
+ return NULL;
+ }
+
+ cmd = t_strconcat(daemon_name, "\n", NULL);
+ ret = fd_send(fd, client_fd, cmd, strlen(cmd));
+ if (ret != (ssize_t)strlen(cmd)) {
+ if (ret < 0)
+ i_error("fd_send(%s) failed: %m", path);
+ else
+ i_error("fd_send(%s) didn't write enough bytes", path);
+ (void)close(fd);
+ return NULL;
+ }
+
+ lookup = i_new(struct access_lookup, 1);
+ lookup->refcount = 1;
+ lookup->fd = fd;
+ lookup->path = i_strdup(path);
+ lookup->io = io_add(fd, IO_READ, access_lookup_input, lookup);
+ lookup->to = timeout_add(ACCESS_LOOKUP_TIMEOUT_MSECS,
+ access_lookup_timeout, lookup);
+ lookup->callback = callback;
+ lookup->context = context;
+ return lookup;
+}
+
+void access_lookup_destroy(struct access_lookup **_lookup)
+{
+ struct access_lookup *lookup = *_lookup;
+
+ i_assert(lookup->refcount > 0);
+ if (--lookup->refcount > 0)
+ return;
+
+ *_lookup = NULL;
+
+ if (lookup->to != NULL)
+ timeout_remove(&lookup->to);
+ io_remove(&lookup->io);
+ if (close(lookup->fd) < 0)
+ i_error("close(%s) failed: %m", lookup->path);
+
+ i_free(lookup->path);
+ i_free(lookup);
+}
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/access-lookup.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/login-common/access-lookup.h Sat Feb 06 19:46:40 2010 +0200
@@ -0,0 +1,11 @@
+#ifndef ACCESS_LOOKUP_H
+#define ACCESS_LOOKUP_H
+
+typedef void access_lookup_callback_t(bool success, void *context);
+
+struct access_lookup *
+access_lookup(const char *path, int client_fd, const char *daemon_name,
+ access_lookup_callback_t *callback, void *context);
+void access_lookup_destroy(struct access_lookup **lookup);
+
+#endif
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/login-settings.c
--- a/src/login-common/login-settings.c Sat Feb 06 17:31:14 2010 +0200
+++ b/src/login-common/login-settings.c Sat Feb 06 19:46:40 2010 +0200
@@ -21,6 +21,7 @@ static const struct setting_define login
DEF(SET_STR_VARS, login_greeting),
DEF(SET_STR, login_log_format_elements),
DEF(SET_STR, login_log_format),
+ DEF(SET_STR, login_access_sockets),
DEF(SET_ENUM, ssl),
DEF(SET_STR, ssl_ca),
@@ -50,6 +51,7 @@ static const struct login_settings login
.login_greeting = PACKAGE_NAME" ready.",
.login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l %c",
.login_log_format = "%$: %s",
+ .login_access_sockets = "",
.ssl = "yes:no:required",
.ssl_ca = "",
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/login-settings.h
--- a/src/login-common/login-settings.h Sat Feb 06 17:31:14 2010 +0200
+++ b/src/login-common/login-settings.h Sat Feb 06 19:46:40 2010 +0200
@@ -7,6 +7,7 @@ struct login_settings {
const char *login_trusted_networks;
const char *login_greeting;
const char *login_log_format_elements, *login_log_format;
+ const char *login_access_sockets;
const char *ssl;
const char *ssl_ca;
diff -r d4fd28f07507 -r 51a978045f47 src/login-common/main.c
--- a/src/login-common/main.c Sat Feb 06 17:31:14 2010 +0200
+++ b/src/login-common/main.c Sat Feb 06 19:46:40 2010 +0200
@@ -10,6 +10,7 @@
#include "master-service.h"
#include "master-interface.h"
#include "client-common.h"
+#include "access-lookup.h"
#include "anvil-client.h"
#include "auth-client.h"
#include "ssl-proxy.h"
@@ -19,6 +20,14 @@
#include <unistd.h>
#include <syslog.h>
+struct login_access_lookup {
+ struct master_service_connection conn;
+ struct io *io;
+
+ char **sockets, **next_socket;
+ struct access_lookup *access;
+};
+
struct auth_client *auth_client;
struct master_auth *master_auth;
bool closing_down;
@@ -29,6 +38,8 @@ void **global_other_settings;
static bool shutting_down = FALSE;
static bool ssl_connections = FALSE;
+
+static void login_access_lookup_next(struct login_access_lookup *lookup);
void login_refresh_proctitle(void)
{
@@ -62,7 +73,8 @@ static void login_die(void)
}
More information about the dovecot-cvs
mailing list