http://dovecot.org/list/dovecot/2009-June/040650.html --- configure.in.orig 2008-06-22 13:02:27.000000000 +0200 +++ configure.in 2008-07-23 15:05:00.000000000 +0200 @@ -61,6 +61,15 @@ notify=$withval, notify=) +AC_ARG_WITH(libwrap, +[ --with-libwrap Build with libwrap, ie. TCP-wrappers (default)], + if test x$withval = xno; then + want_libwrap=no + else + want_libwrap=yes + fi, + want_libwrap=yes) + AC_ARG_WITH(linux-quota, [ --with-linux-quota=n Linux quota version to use (default: system's)], AC_DEFINE_UNQUOTED(_LINUX_QUOTA_VERSION, $withval, @@ -1554,6 +1563,30 @@ fi dnl ** +dnl ** TCP wrappers +dnl ** + +if test "$want_libwrap" = "yes"; then + AC_CHECK_HEADER(tcpd.h, [ + old_LIBS=$LIBS + LIBS="$LIBS -lwrap" + AC_TRY_LINK([ + #include + int allow_severity; + int deny_severity; + struct request_info request; + ], [ + request_init(&request, 0); + ], [ + AC_DEFINE(HAVE_LIBWRAP,, Define if you have libwrap) + LIBWRAP_LIBS=-lwrap + AC_SUBST(LIBWRAP_LIBS) + ]) + LIBS=$old_LIBS + ]) +fi + +dnl ** dnl ** userdb and passdb checks dnl ** --- dovecot-example.conf.orig 2008-11-07 19:11:37.000000000 +0100 +++ dovecot-example.conf 2008-11-07 19:15:54.000000000 +0100 @@ -176,6 +176,11 @@ # these networks. Typically you'd specify your IMAP proxy servers here. #login_trusted_networks = +# Use TCP wrappers for incoming connection access checks. This requires that +# Dovecot was compiled with libwrap. Note that this setting requires +# login_process_per_connection=yes. +#login_tcp_wrappers = no + # Space-separated list of elements we want to log. The elements which have # a non-empty variable value are joined together to form a comma-separated # string. --- src/imap-login/Makefile.am.orig 2008-06-12 08:45:10.000000000 +0200 +++ src/imap-login/Makefile.am 2008-07-07 18:57:31.000000000 +0200 @@ -13,7 +13,8 @@ ../lib-imap/libimap.a \ ../lib-auth/libauth.a \ ../lib/liblib.a \ - $(SSL_LIBS) + $(SSL_LIBS) \ + $(LIBWRAP_LIBS) imap_login_SOURCES = \ client.c \ --- src/login-common/main.c.orig 2009-01-23 19:13:01.000000000 +0100 +++ src/login-common/main.c 2009-02-21 14:11:00.000000000 +0100 @@ -19,8 +19,16 @@ #include #include +#ifdef HAVE_LIBWRAP +# include +# include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +# include "str.h" +#endif + bool disable_plaintext_auth, process_per_connection; -bool verbose_proctitle, verbose_ssl, verbose_auth, auth_debug; +bool verbose_proctitle, verbose_ssl, verbose_auth, auth_debug, tcp_wrappers; bool ssl_required, ssl_require_client_cert; const char *greeting, *log_format; const char *const *log_format_elements; @@ -76,6 +84,45 @@ io_loop_stop(ioloop); } +static void access_check(int fd, const struct ip_addr *ip, bool ssl) +{ +#ifdef HAVE_LIBWRAP + struct request_info req; + char *daemon; + string_t *process_name_ssl; + + if (!tcp_wrappers) + return; + if (!process_per_connection) + i_fatal("Tried to use TCP wrappers with process_per_connection=no"); + + if (ssl) { + process_name_ssl = t_str_new(20); + str_append(process_name_ssl, process_name); + str_append(process_name_ssl, "-ssl"); + daemon = str_c(process_name_ssl); + } else { + daemon = process_name; + } + request_init(&req, + RQ_FILE, fd, + RQ_CLIENT_ADDR, net_ip2addr(ip), + RQ_DAEMON, daemon, + 0); + fromhost(&req); + + if (!hosts_access(&req)) { + i_error("Connection refused by tcp-wrappers: %s", + net_ip2addr(ip)); + refuse(&req); + i_unreached(); + } + if (ssl) { + str_free(&process_name_ssl); + } +#endif +} + static void login_accept(void *context) { int listen_fd = POINTER_CAST_TO(context, int); @@ -91,6 +138,7 @@ return; } i_set_failure_ip(&remote_ip); + access_check(fd, &remote_ip, FALSE); if (net_getsockname(fd, &local_ip, &local_port) < 0) { memset(&local_ip, 0, sizeof(local_ip)); @@ -123,6 +171,7 @@ return; } i_set_failure_ip(&remote_ip); + access_check(fd, &remote_ip, TRUE); if (net_getsockname(fd, &local_ip, &local_port) < 0) { memset(&local_ip, 0, sizeof(local_ip)); @@ -323,6 +372,7 @@ ssl_require_client_cert = getenv("SSL_REQUIRE_CLIENT_CERT") != NULL; disable_plaintext_auth = ssl_required || getenv("DISABLE_PLAINTEXT_AUTH") != NULL; + tcp_wrappers = getenv("TCP_WRAPPERS") != NULL; greeting = getenv("GREETING"); if (greeting == NULL) @@ -417,11 +467,12 @@ restrict_access_by_env() is called */ lib_init(); + process_name = strrchr(argv[0], '/'); + process_name = process_name == NULL ? argv[0] : process_name+1; + if (is_inetd) { /* running from inetd. create master process before dropping privileges. */ - process_name = strrchr(argv[0], '/'); - process_name = process_name == NULL ? argv[0] : process_name+1; group_name = t_strcut(process_name, '-'); for (i = 1; i < argc; i++) { --- src/master/login-process.c.orig 2009-01-20 21:04:17.000000000 +0100 +++ src/master/login-process.c 2009-02-21 14:13:18.000000000 +0100 @@ -624,6 +624,8 @@ env_put(t_strconcat("TRUSTED_NETWORKS=", set->login_trusted_networks, NULL)); } + if (set->login_tcp_wrappers) + env_put("TCP_WRAPPERS=1"); env_put(t_strconcat("LOGIN_DIR=", set->login_dir, NULL)); } --- src/master/master-settings.c.orig 2008-08-21 01:17:31.000000000 +0200 +++ src/master/master-settings.c 2008-11-07 19:21:14.000000000 +0100 @@ -208,6 +208,8 @@ MEMBER(login_process_per_connection) TRUE, MEMBER(login_chroot) TRUE, MEMBER(login_trusted_networks) "", + MEMBER(login_tcp_wrappers) FALSE, + MEMBER(login_process_size) 64, MEMBER(login_processes_count) 3, @@ -481,6 +483,7 @@ fix_base_path(auth->parent->defaults, &s->master.path); fix_base_path(auth->parent->defaults, &s->client.path); } + return TRUE; } @@ -866,6 +869,20 @@ return FALSE; } #endif + + if (!set->login_process_per_connection && set->login_tcp_wrappers) { + i_error("login_process_per_connection=no can't be used with " + "login_tcp_wrappers=yes"); + return FALSE; + } +#ifndef HAVE_LIBWRAP + if (set->login_tcp_wrappers) { + i_error("login_tcp_wrappers can't be used because " + "Dovecot wasn't built with libwrap"); + return FALSE; + } +#endif + return TRUE; } --- src/master/master-settings-defs.c.orig 2008-06-21 09:27:01.000000000 +0200 +++ src/master/master-settings-defs.c 2008-11-07 19:21:55.000000000 +0100 @@ -46,6 +46,8 @@ DEF_BOOL(login_process_per_connection), DEF_BOOL(login_chroot), DEF_STR(login_trusted_networks), + DEF_BOOL(login_tcp_wrappers), + DEF_INT(login_process_size), DEF_INT(login_processes_count), --- src/master/master-settings.h.orig 2008-08-21 01:17:31.000000000 +0200 +++ src/master/master-settings.h 2008-11-07 19:23:00.000000000 +0100 @@ -60,6 +60,7 @@ bool login_process_per_connection; bool login_chroot; const char *login_trusted_networks; + bool login_tcp_wrappers; unsigned int login_process_size; unsigned int login_processes_count; --- src/pop3-login/Makefile.am.orig 2008-06-12 08:45:10.000000000 +0200 +++ src/pop3-login/Makefile.am 2008-07-07 18:57:31.000000000 +0200 @@ -11,7 +11,8 @@ ../login-common/liblogin-common.a \ ../lib-auth/libauth.a \ ../lib/liblib.a \ - $(SSL_LIBS) + $(SSL_LIBS) \ + $(LIBWRAP_LIBS) pop3_login_SOURCES = \ client.c \