--- 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-07-07 18:57:31.000000000 +0200 +++ dovecot-example.conf 2008-07-07 18:57:31.000000000 +0200 @@ -171,6 +171,11 @@ # Greeting message for clients. #login_greeting = Dovecot ready. +# 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 2008-10-26 16:03:45.000000000 +0100 +++ src/login-common/main.c 2008-11-06 13:54:01.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, greeting_capability; -bool verbose_proctitle, verbose_ssl, verbose_auth, auth_debug; +bool verbose_proctitle, verbose_ssl, verbose_auth, auth_debug, tcp_wrappers; bool ssl_require_client_cert; const char *greeting, *log_format; const char *const *log_format_elements; @@ -75,6 +83,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 wrapers 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); @@ -89,6 +136,7 @@ i_error("accept() failed: %m"); return; } + access_check(fd, &remote_ip, FALSE); if (net_getsockname(fd, &local_ip, &local_port) < 0) { memset(&local_ip, 0, sizeof(local_ip)); @@ -120,6 +168,7 @@ i_error("accept() failed: %m"); return; } + access_check(fd, &remote_ip, TRUE); if (net_getsockname(fd, &local_ip, &local_port) < 0) { memset(&local_ip, 0, sizeof(local_ip)); @@ -319,6 +368,7 @@ verbose_auth = getenv("VERBOSE_AUTH") != NULL; auth_debug = getenv("AUTH_DEBUG") != NULL; ssl_require_client_cert = getenv("SSL_REQUIRE_CLIENT_CERT") != NULL; + tcp_wrappers = getenv("TCP_WRAPPERS") != NULL; greeting = getenv("GREETING"); if (greeting == NULL) @@ -419,11 +469,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 2008-06-12 23:38:01.000000000 +0200 +++ src/master/login-process.c 2008-07-07 19:51:45.000000000 +0200 @@ -573,6 +573,8 @@ env_put(t_strconcat("LOG_FORMAT=", set->login_log_format, NULL)); if (set->login_greeting_capability) env_put("GREETING_CAPABILITY=1"); + if (set->login_tcp_wrappers) + env_put("TCP_WRAPPERS=1"); if (group->mail_process_type == PROCESS_TYPE_IMAP) { env_put(t_strconcat("CAPABILITY_STRING=", --- src/master/master-settings.c.orig 2008-06-21 15:09:16.000000000 +0200 +++ src/master/master-settings.c 2008-07-07 20:28:37.000000000 +0200 @@ -208,6 +208,7 @@ MEMBER(login_process_per_connection) TRUE, MEMBER(login_chroot) TRUE, MEMBER(login_greeting_capability) FALSE, + MEMBER(login_tcp_wrappers) FALSE, MEMBER(login_process_size) 64, MEMBER(login_processes_count) 3, @@ -479,6 +480,7 @@ fix_base_path(auth->parent->defaults, &s->master.path); fix_base_path(auth->parent->defaults, &s->client.path); } + return TRUE; } @@ -861,6 +863,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-07-07 20:06:11.000000000 +0200 +++ src/master/master-settings-defs.c 2008-07-07 19:55:08.000000000 +0200 @@ -46,6 +46,7 @@ DEF_BOOL(login_process_per_connection), DEF_BOOL(login_chroot), DEF_BOOL(login_greeting_capability), + DEF_BOOL(login_tcp_wrappers), DEF_INT(login_process_size), DEF_INT(login_processes_count), --- src/master/master-settings.h.orig 2008-06-12 08:45:10.000000000 +0200 +++ src/master/master-settings.h 2008-07-07 18:57:31.000000000 +0200 @@ -60,6 +60,7 @@ bool login_process_per_connection; bool login_chroot; bool login_greeting_capability; + 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 \