# # tcp_wrappers.patch for AMANDA 2.4.5 # #Hi, # #as threatened earlier I've done the attached patch to amanda-2.4.5 to #add support for tcp_wrappers (libwrap). It adds a new configure option #--with-tcp-wrappers (autoconf code taken from OpenSSH-4.1p1) and calls #to tcp_wrappers_ok() in dgram_recv() and stream_accept(). #tcp_wrappers_ok() is added to security.c and calls hosts_ctl to limit #access. Without --with-tcp-wrappers no additional code is compiled in #and everything should behave as before. # #Because of its central point of implementation it affects all amanda #components using those functions. Therefore on a client you'd need # #amandad: server #sendbackup: server # #in /etc/hosts.allow. On a server it's going to be # #planner: client-subnet other-client #dumper: client-subnet other-client #amcheck: client-subnet other-client #taper: 127.0.0.1 # #I'm not really sure about taper since although I've added a dbopen() #call to it debug output still seems to go somewhere completely #different. # #amindexd and amidxtaped are not affected by this patch since they don't #use stream_accept. # #Since access to amandad is often already checked against tcp_wrappers by #(x)inetd the check is doubled which might increase the number of dns #lookups made and the like. # #Hope it's of any help to anyone. Any suggestions and experience reports #are highly welcome. #-- bye, Micha # --- amanda-2.4.5.tw/common-src/amanda.h.tcp_wrappers Mon Aug 2 20:56:32 2004 +++ amanda-2.4.5.tw/common-src/amanda.h Wed Jun 29 20:22:24 2005 @@ -782,6 +782,9 @@ extern int security_ok P((struct sockaddr_in *addr, char *str, uint32_t cksum, char **errstr)); extern char *get_bsd_security P((void)); +#ifdef WITH_TCP_WRAPPERS +extern int tcp_wrappers_ok P((const struct sockaddr_in *)); +#endif /* WITH_TCP_WRAPPERS */ /* * Handle functions which are not always declared on all systems. This --- amanda-2.4.5.tw/common-src/dgram.c.tcp_wrappers Wed Jun 29 20:22:02 2005 +++ amanda-2.4.5.tw/common-src/dgram.c Thu Jun 30 19:05:38 2005 @@ -298,6 +298,18 @@ errno = save_errno; return -1; } + +#ifdef WITH_TCP_WRAPPERS + if(tcp_wrappers_ok(fromaddr) == 0) { + save_errno = errno; + dbprintf(("%s: dgram_recv: client %s denied by tcp_wrappers\n", + debug_prefix(NULL), + inet_ntoa(fromaddr->sin_addr))); + errno = save_errno; + return -1; + } +#endif /* WITH_TCP_WRAPPERS */ + dgram->len = size; dgram->data[size] = '\0'; dgram->cur = dgram->data; --- amanda-2.4.5.tw/common-src/security.c.tcp_wrappers Thu Apr 29 22:47:22 2004 +++ amanda-2.4.5.tw/common-src/security.c Wed Jun 29 20:22:24 2005 @@ -32,6 +32,15 @@ #include "amanda.h" #include "clock.h" +#ifdef WITH_TCP_WRAPPERS +# include + +int allow_severity = LOG_INFO; +int deny_severity = LOG_NOTICE; + +int hosts_ctl(char *, char *, char *, char *); +#endif /* WITH_TCP_WRAPPERS */ + /* * Change the following from #undef to #define to cause detailed logging * of the security steps, e.g. into /tmp/amanda/amandad*debug. @@ -528,6 +537,48 @@ #endif /* ! BSD_SECURITY */ /* } */ +#ifdef WITH_TCP_WRAPPERS +int tcp_wrappers_ok(sin) +const struct sockaddr_in *sin; +{ + struct hostent *he; + char *peeraddr; + char *peername = STRING_UNKNOWN; + int granted = 0; + + /* convert peer address to quaded dot notation */ + peeraddr = inet_ntoa(sin->sin_addr); + + /* ignore error condition but log a message */ + if (peeraddr == NULL) { + dbprintf(("%s: tcp_wrappers: error converting peer internet address to quadded " + "dot notation\n", + debug_prefix_time(NULL))); + peeraddr = STRING_UNKNOWN; + } + + /* lookup peer's hostname */ + he = gethostbyaddr(&sin->sin_addr, sizeof(sin->sin_addr), AF_INET); + + /* gethostbyaddr is not supposed to fail because of memory shortness - + ** only network errors regarding the nameserver can occur which we + ** silently ignore by leaving peername at STRING_UNKNOWN */ + if (he != NULL && he->h_name != NULL) { + peername = he->h_name; + } + + /* check with tcp_wrappers for clearance */ + granted = hosts_ctl(get_pname(), peername, peeraddr, STRING_UNKNOWN); + dbprintf(("%s: tcp_wrappers: access %s to %s (%s)\n", + debug_prefix_time(NULL), + granted ? "granted" : "denied", + peername == STRING_UNKNOWN ? "unknown" : peername, + peeraddr == STRING_UNKNOWN ? "unknown" : peeraddr)); + + return granted; +} +#endif /* WITH_TCP_WRAPPERS */ + #if defined(TEST) /* { */ int @@ -607,6 +658,17 @@ dbprintf(("%s: security check of %s@%s passed\n", debug_prefix_time(NULL), remoteuser, remotehost)); } + +#ifdef WITH_TCP_WRAPPERS + if (tcp_wrappers_ok(&fake.sin_addr) == 0) { + dbprintf(("%s: tcp_wrappers check of %s failed\n", + debug_prefix_time(NULL), remotehost)); + } else { + dbprintf(("%s: tcp_wrappers check of %s passed\n", + debug_prefix_time(NULL), remotehost)); + } +#endif /* WITH_TCP_WRAPPERS */ + return r; } --- amanda-2.4.5.tw/common-src/stream.c.tcp_wrappers Wed Jun 29 20:22:02 2005 +++ amanda-2.4.5.tw/common-src/stream.c Thu Jun 30 19:05:38 2005 @@ -333,10 +333,6 @@ 0); } -/* don't care about these values */ -static struct sockaddr_in addr; -static int addrlen; - int stream_accept(server_socket, timeout, sendsize, recvsize) int server_socket, timeout, sendsize, recvsize; { @@ -345,6 +345,9 @@ int nfound, connected_socket; int save_errno; + struct sockaddr_in addr; + int addrlen; + assert(server_socket >= 0); tv.tv_sec = timeout; @@ -406,21 +406,32 @@ * Make certain we got an inet connection and that it is not * from port 20 (a favorite unauthorized entry tool). */ - if(addr.sin_family == AF_INET && ntohs(addr.sin_port) != 20) { - break; - } if(addr.sin_family != AF_INET) { dbprintf(("%s: family is %d instead of %d(AF_INET): ignored\n", debug_prefix_time(NULL), addr.sin_family, AF_INET)); + aclose(connected_socket); + continue; } if(ntohs(addr.sin_port) == 20) { dbprintf(("%s: remote port is %d: ignored\n", debug_prefix_time(NULL), ntohs(addr.sin_port))); + aclose(connected_socket); + continue; } - aclose(connected_socket); +#ifdef WITH_TCP_WRAPPERS + if(tcp_wrappers_ok(&addr) == 0) { + dbprintf(("%s: client %s denied by tcp_wrappers\n", + debug_prefix_time(NULL), + inet_ntoa(addr.sin_addr))); + aclose(connected_socket); + continue; + } +#endif /* WITH_TCP_WRAPPERS */ + + break; } if(sendsize >= 0) --- amanda-2.4.5.tw/configure.in.tcp_wrappers Wed Jun 29 20:22:55 2005 +++ amanda-2.4.5.tw/configure.in Thu Jun 30 00:25:39 2005 @@ -2741,6 +2741,51 @@ AC_MSG_WARN([*** Be VERY VERY careful.]) fi +# Check whether user wants TCP wrappers support +# (taken from OpenSSH 2.9p2) +AC_ARG_WITH(tcp_wrappers, + [ --with-tcp_wrappers enable tcp_wrappers support], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + LIBS="-lwrap $LIBS" + AC_MSG_CHECKING(for libwrap) + AC_TRY_LINK( + [ +#include +int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_TCP_WRAPPERS,1,[Define if you want to use tcp_wrappers.]) + ], + [ + AC_MSG_RESULT(no) + + LIBS="-lwrap -lnsl $saved_LIBS" + AC_MSG_CHECKING(whether libwrap needs libnsl) + AC_TRY_LINK( + [ +#include +int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_TCP_WRAPPERS,1,[Define if you want to use tcp_wrappers.]) + ], + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([*** libwrap missing]) + ] + ) + ] + ) + fi + ] +) + dnl extra substitution parameters AC_SUBST(CHS) AC_SUBST(MTX)