added tcp_wrappers support to the piler daemon

This commit is contained in:
SJ 2012-10-29 10:22:31 +01:00
parent 9dd3f39ceb
commit e969b3efc6
10 changed files with 187 additions and 15 deletions

128
configure vendored
View File

@ -676,6 +676,7 @@ enable_static_build
enable_clamd enable_clamd
enable_memcached enable_memcached
enable_starttls enable_starttls
enable_tcpwrappers
with_piler_user with_piler_user
' '
ac_precious_vars='build_alias ac_precious_vars='build_alias
@ -1300,6 +1301,7 @@ Optional Features:
--enable-clamd build clamd antivirus support --enable-clamd build clamd antivirus support
--enable-memcached build memcached support --enable-memcached build memcached support
--enable-starttls build starttls support --enable-starttls build starttls support
--enable-tcpwrappers build tcpwrappers support
Optional Packages: Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -3417,6 +3419,7 @@ have_tre="no"
have_zip="no" have_zip="no"
have_zlib="no" have_zlib="no"
have_starttls="no" have_starttls="no"
have_tcpwrappers="no"
pdftotext="no" pdftotext="no"
catdoc="no" catdoc="no"
@ -3497,6 +3500,118 @@ fi
# Check whether --enable-tcpwrappers was given.
if test "${enable_tcpwrappers+set}" = set; then :
enableval=$enable_tcpwrappers; want_tcpwrappers=$enableval
else
want_tcpwrappers"no"
fi
if test "$want_tcpwrappers" = "yes"; then
for ac_header in tcpd.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default"
if test "x$ac_cv_header_tcpd_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_TCPD_H 1
_ACEOF
have_tcpwrappers=yes
else
have_tcpwrappers=no
fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for hosts_access in -lwrap" >&5
$as_echo_n "checking for hosts_access in -lwrap... " >&6; }
if ${ac_cv_lib_wrap_hosts_access+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lwrap $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char hosts_access ();
int
main ()
{
return hosts_access ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_wrap_hosts_access=yes
else
ac_cv_lib_wrap_hosts_access=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wrap_hosts_access" >&5
$as_echo "$ac_cv_lib_wrap_hosts_access" >&6; }
if test "x$ac_cv_lib_wrap_hosts_access" = xyes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for hosts_access in -lwrap" >&5
$as_echo_n "checking for hosts_access in -lwrap... " >&6; }
if ${ac_cv_lib_wrap_hosts_access+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lwrap $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char hosts_access ();
int
main ()
{
return hosts_access ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_wrap_hosts_access=yes
else
ac_cv_lib_wrap_hosts_access=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wrap_hosts_access" >&5
$as_echo "$ac_cv_lib_wrap_hosts_access" >&6; }
if test "x$ac_cv_lib_wrap_hosts_access" = xyes; then :
have_tcpwrappers=yes
else
echo "libwrap is not found"; have_tcpwrappers=no
fi
fi
ac_cv_lib_wrap=ac_cv_lib_wrap_main
if test "$have_tcpwrappers" = "no"; then
echo "can't find either tcpd.h or libwrap";
exit 1;
fi
fi
for ac_header in math.h for ac_header in math.h
@ -4361,6 +4476,19 @@ _ACEOF
fi fi
if test "$have_tcpwrappers" = "yes"; then
echo "tcpwrappers support: yes"
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBWRAP 1
_ACEOF
antispam_libs="$antispam_libs -lwrap -lnsl"
else
echo "tcpwrappers support: no"
fi
echo echo
if test "$have_clamd" = "yes"; then if test "$have_clamd" = "yes"; then

View File

@ -41,6 +41,7 @@ have_tre="no"
have_zip="no" have_zip="no"
have_zlib="no" have_zlib="no"
have_starttls="no" have_starttls="no"
have_tcpwrappers="no"
pdftotext="no" pdftotext="no"
catdoc="no" catdoc="no"
@ -104,6 +105,20 @@ AC_ARG_ENABLE(starttls,
[ --enable-starttls build starttls support], have_starttls=$enableval, have_starttls="no") [ --enable-starttls build starttls support], have_starttls=$enableval, have_starttls="no")
AC_ARG_ENABLE(tcpwrappers,
[ --enable-tcpwrappers build tcpwrappers support], want_tcpwrappers=$enableval, want_tcpwrappers"no")
if test "$want_tcpwrappers" = "yes"; then
AC_CHECK_HEADERS(tcpd.h, have_tcpwrappers=yes, have_tcpwrappers=no)
AC_CHECK_LIB([wrap],[hosts_access],[AC_CHECK_LIB(wrap, hosts_access, have_tcpwrappers=yes, echo "libwrap is not found"; have_tcpwrappers=no)],[],[])ac_cv_lib_wrap=ac_cv_lib_wrap_main
if test "$have_tcpwrappers" = "no"; then
echo "can't find either tcpd.h or libwrap";
exit 1;
fi
fi
dnl math library dnl math library
@ -289,6 +304,15 @@ if test "$have_starttls" = "yes"; then
AC_DEFINE_UNQUOTED(HAVE_STARTTLS, 1, [starttls support]) AC_DEFINE_UNQUOTED(HAVE_STARTTLS, 1, [starttls support])
fi fi
if test "$have_tcpwrappers" = "yes"; then
echo "tcpwrappers support: yes"
AC_DEFINE_UNQUOTED(HAVE_LIBWRAP, 1, [tcpwrappers support])
antispam_libs="$antispam_libs -lwrap -lnsl"
else
echo "tcpwrappers support: no"
fi
echo echo
if test "$have_clamd" = "yes"; then if test "$have_clamd" = "yes"; then

View File

@ -18,3 +18,5 @@
#undef HAVE_ZIP #undef HAVE_ZIP
#undef HAVE_STARTTLS #undef HAVE_STARTTLS
#undef HAVE_LIBWRAP

View File

@ -11,9 +11,9 @@
#define PROGNAME "piler" #define PROGNAME "piler"
#define VERSION "0.1.21" #define VERSION "0.1.22"
#define BUILD 722 #define BUILD 723
#define HOSTID "mailarchiver" #define HOSTID "mailarchiver"

View File

@ -22,6 +22,9 @@
#include <tre/tre.h> #include <tre/tre.h>
#include <tre/regex.h> #include <tre/regex.h>
#endif #endif
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
#endif
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>

View File

@ -47,7 +47,7 @@ static void child_main(struct child *ptr);
static pid_t child_make(struct child *ptr); static pid_t child_make(struct child *ptr);
int search_slot_by_pid(pid_t pid); int search_slot_by_pid(pid_t pid);
void kill_children(int sig); void kill_children(int sig);
void clean_exit(); void p_clean_exit();
void fatal(char *s); void fatal(char *s);
void initialise_configuration(); void initialise_configuration();
@ -85,7 +85,7 @@ static void takesig(int sig){
case SIGTERM: case SIGTERM:
case SIGKILL: case SIGKILL:
quit = 1; quit = 1;
clean_exit(); p_clean_exit();
break; break;
case SIGCHLD: case SIGCHLD:
@ -206,7 +206,7 @@ int child_pool_create(){
if(children[i].pid == -1){ if(children[i].pid == -1){
syslog(LOG_PRIORITY, "error: failed to fork a child"); syslog(LOG_PRIORITY, "error: failed to fork a child");
clean_exit(); p_clean_exit();
} }
} }
@ -237,7 +237,7 @@ void kill_children(int sig){
} }
void clean_exit(){ void p_clean_exit(){
if(sd != -1) close(sd); if(sd != -1) close(sd);
kill_children(SIGTERM); kill_children(SIGTERM);
@ -262,7 +262,7 @@ void clean_exit(){
void fatal(char *s){ void fatal(char *s){
syslog(LOG_PRIORITY, "%s\n", s); syslog(LOG_PRIORITY, "%s\n", s);
clean_exit(); p_clean_exit();
} }
@ -439,7 +439,7 @@ int main(int argc, char **argv){
for(;;){ sleep(1); } for(;;){ sleep(1); }
clean_exit(); p_clean_exit();
return 0; return 0;
} }

View File

@ -41,7 +41,7 @@ void usage(){
} }
void clean_exit(char *msg, int rc){ void p_clean_exit(char *msg, int rc){
if(msg) printf("error: %s\n", msg); if(msg) printf("error: %s\n", msg);
if(query) free(query); if(query) free(query);
@ -207,7 +207,7 @@ int main(int argc, char **argv){
if(regcomp(&regexp, "^([\\+a-z0-9_\\.@\\-]+)$", REG_ICASE | REG_EXTENDED)){ if(regcomp(&regexp, "^([\\+a-z0-9_\\.@\\-]+)$", REG_ICASE | REG_EXTENDED)){
clean_exit("cannot compile rule!", 1); p_clean_exit("cannot compile rule!", 1);
} }
@ -380,7 +380,7 @@ int main(int argc, char **argv){
rc += append_string_to_buffer(&query, " ORDER BY id ASC"); rc += append_string_to_buffer(&query, " ORDER BY id ASC");
if(rc) clean_exit("malloc problem building query", 1); if(rc) p_clean_exit("malloc problem building query", 1);
@ -388,7 +388,7 @@ int main(int argc, char **argv){
cfg = read_config(configfile); cfg = read_config(configfile);
if(read_key(&cfg)) clean_exit(ERR_READING_KEY, 1); if(read_key(&cfg)) p_clean_exit(ERR_READING_KEY, 1);
init_session_data(&sdata); init_session_data(&sdata);
@ -397,7 +397,7 @@ int main(int argc, char **argv){
mysql_init(&(sdata.mysql)); mysql_init(&(sdata.mysql));
mysql_options(&(sdata.mysql), MYSQL_OPT_CONNECT_TIMEOUT, (const char*)&cfg.mysql_connect_timeout); mysql_options(&(sdata.mysql), MYSQL_OPT_CONNECT_TIMEOUT, (const char*)&cfg.mysql_connect_timeout);
if(mysql_real_connect(&(sdata.mysql), cfg.mysqlhost, cfg.mysqluser, cfg.mysqlpwd, cfg.mysqldb, cfg.mysqlport, cfg.mysqlsocket, 0) == 0){ if(mysql_real_connect(&(sdata.mysql), cfg.mysqlhost, cfg.mysqluser, cfg.mysqlpwd, cfg.mysqldb, cfg.mysqlport, cfg.mysqlsocket, 0) == 0){
clean_exit("cannot connect to mysql server", 1); p_clean_exit("cannot connect to mysql server", 1);
} }
mysql_real_query(&(sdata.mysql), "SET NAMES utf8", strlen("SET NAMES utf8")); mysql_real_query(&(sdata.mysql), "SET NAMES utf8", strlen("SET NAMES utf8"));

View File

@ -34,7 +34,7 @@ void usage(){
} }
void clean_exit(char *msg, int rc){ void p_clean_exit(char *msg, int rc){
if(msg) printf("error: %s\n", msg); if(msg) printf("error: %s\n", msg);
exit(rc); exit(rc);
@ -188,7 +188,7 @@ int main(int argc, char **argv){
mysql_init(&(sdata.mysql)); mysql_init(&(sdata.mysql));
mysql_options(&(sdata.mysql), MYSQL_OPT_CONNECT_TIMEOUT, (const char*)&cfg.mysql_connect_timeout); mysql_options(&(sdata.mysql), MYSQL_OPT_CONNECT_TIMEOUT, (const char*)&cfg.mysql_connect_timeout);
if(mysql_real_connect(&(sdata.mysql), cfg.mysqlhost, cfg.mysqluser, cfg.mysqlpwd, cfg.mysqldb, cfg.mysqlport, cfg.mysqlsocket, 0) == 0){ if(mysql_real_connect(&(sdata.mysql), cfg.mysqlhost, cfg.mysqluser, cfg.mysqlpwd, cfg.mysqldb, cfg.mysqlport, cfg.mysqlsocket, 0) == 0){
clean_exit("cannot connect to mysql server", 1); p_clean_exit("cannot connect to mysql server", 1);
} }
mysql_real_query(&(sdata.mysql), "SET NAMES utf8", strlen("SET NAMES utf8")); mysql_real_query(&(sdata.mysql), "SET NAMES utf8", strlen("SET NAMES utf8"));

View File

@ -38,6 +38,20 @@ int handle_smtp_session(int new_sd, struct __data *data, struct __config *cfg){
char ssl_error[SMALLBUFSIZE]; char ssl_error[SMALLBUFSIZE];
#endif #endif
#ifdef HAVE_LIBWRAP
struct request_info req;
request_init(&req, RQ_DAEMON, PROGNAME, RQ_FILE, new_sd, 0);
fromhost(&req);
if(!hosts_access(&req)){
send(new_sd, SMTP_RESP_550_ERR_YOU_ARE_BANNED_BY_LOCAL_POLICY, strlen(SMTP_RESP_550_ERR_YOU_ARE_BANNED_BY_LOCAL_POLICY), 0);
syslog(LOG_PRIORITY, "denied connection from %s by tcp_wrappers", eval_client(&req));
return 0;
}
#endif
state = SMTP_STATE_INIT; state = SMTP_STATE_INIT;
init_session_data(&sdata); init_session_data(&sdata);

View File

@ -52,6 +52,7 @@
#define SMTP_RESP_550_ERR_PREF "550 Access denied." #define SMTP_RESP_550_ERR_PREF "550 Access denied."
#define SMTP_RESP_550_INVALID_RECIPIENT "550 Unknown recipient\r\n" #define SMTP_RESP_550_INVALID_RECIPIENT "550 Unknown recipient\r\n"
#define SMTP_RESP_550_ERR_TOO_LONG_RCPT_TO "550 too long recipient\r\n" #define SMTP_RESP_550_ERR_TOO_LONG_RCPT_TO "550 too long recipient\r\n"
#define SMTP_RESP_550_ERR_YOU_ARE_BANNED_BY_LOCAL_POLICY "550 You are banned by local policy\r\n"
#define SMTP_RESP_552_ERR "552 Too many recipients\r\n" #define SMTP_RESP_552_ERR "552 Too many recipients\r\n"