From 0213c3f8102bdc934c629d11a44ca0b408762287 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 Jun 2010 15:41:29 +0200 Subject: [PATCH] socket: add optional libwrap support --- Makefile.am | 12 ++++++--- configure.ac | 25 +++++++++++++++++ m4/acx_libwrap.m4 | 19 +++++++++++++ src/dbus-socket.c | 2 ++ src/load-fragment.c | 1 + src/logger.c | 6 +++++ src/socket.c | 15 +++++++++++ src/socket.h | 2 ++ src/tcpwrap.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ src/tcpwrap.h | 29 ++++++++++++++++++++ 10 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 m4/acx_libwrap.m4 create mode 100644 src/tcpwrap.c create mode 100644 src/tcpwrap.h diff --git a/Makefile.am b/Makefile.am index e50ae8204..c78968fc0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -241,7 +241,8 @@ COMMON_SOURCES = \ src/specifier.c \ src/unit-name.c \ src/fdset.c \ - src/namespace.c + src/namespace.c \ + src/tcpwrap.c EXTRA_DIST += \ ${COMMON_SOURCES:.c=.h} \ @@ -288,7 +289,8 @@ systemd_CFLAGS = \ systemd_LDADD = \ $(DBUS_LIBS) \ $(UDEV_LIBS) \ - $(CGROUP_LIBS) + $(CGROUP_LIBS) \ + $(LIBWRAP_LIBS) test_engine_SOURCES = \ $(COMMON_SOURCES) \ @@ -325,7 +327,11 @@ test_daemon_SOURCES = \ systemd_logger_SOURCES = \ $(BASIC_SOURCES) \ src/logger.c \ - src/sd-daemon.c + src/sd-daemon.c \ + src/tcpwrap.c + +systemd_logger_LDADD = \ + $(LIBWRAP_LIBS) systemd_initctl_SOURCES = \ $(BASIC_SOURCES) \ diff --git a/configure.ac b/configure.ac index 02618ae63..ae2520044 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,30 @@ PKG_CHECK_MODULES(CGROUP, [ libcgroup >= 0.36 ]) AC_SUBST(CGROUP_CFLAGS) AC_SUBST(CGROUP_LIBS) +AC_ARG_ENABLE([tcpwrap], + AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]), + [case "${enableval}" in + yes) tcpwrap=yes ;; + no) tcpwrap=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;; + esac], + [tcpwrap=auto]) + +if test "x${tcpwrap}" != xno ; then + ACX_LIBWRAP + if test "x${LIBWRAP_LIBS}" = x ; then + if test "x$tcpwrap" = xyes ; then + AC_MSG_ERROR([*** TCP wrappers support not found]) + fi + else + tcpwrap=yes + fi +else + LIBWRAP_LIBS= +fi + +AC_SUBST(LIBWRAP_LIBS) + have_gtk=no AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools])) if test "x$enable_gtk" != "xno"; then @@ -312,6 +336,7 @@ echo " Syslog service: ${SPECIAL_SYSLOG_SERVICE} D-Bus service: ${SPECIAL_DBUS_SERVICE} Gtk: ${have_gtk} + tcpwrap: ${tcpwrap} prefix: ${prefix} root dir: ${with_rootdir} udev rules dir: ${with_udevrulesdir} diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4 new file mode 100644 index 000000000..e1602144b --- /dev/null +++ b/m4/acx_libwrap.m4 @@ -0,0 +1,19 @@ +AC_DEFUN([ACX_LIBWRAP], [ +LIBWRAP_LIBS= +saved_LIBS="$LIBS" +LIBS="$LIBS -lwrap" +AC_MSG_CHECKING([for tcpwrap library and headers]) +AC_LINK_IFELSE( +AC_LANG_PROGRAM( +[#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING;], +[struct request_info *req; +return hosts_access (req);]), +[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?]) +LIBWRAP_LIBS="-lwrap" +AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) +LIBS="$saved_LIBS" +]) diff --git a/src/dbus-socket.c b/src/dbus-socket.c index 426af2b4c..fa8419114 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -37,6 +37,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ #define INTROSPECTION \ @@ -66,6 +67,7 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusMessage *message) { { "org.freedesktop.systemd1.Socket", "DirectoryMode", bus_property_append_mode, "u", &u->socket.directory_mode }, { "org.freedesktop.systemd1.Socket", "SocketMode", bus_property_append_mode, "u", &u->socket.socket_mode }, { "org.freedesktop.systemd1.Socket", "Accept", bus_property_append_bool, "b", &u->socket.accept }, + { "org.freedesktop.systemd1.Socket", "TCPWrapName", bus_property_append_string, "s", u->socket.tcpwrap_name }, { NULL, NULL, NULL, NULL, NULL } }; diff --git a/src/load-fragment.c b/src/load-fragment.c index cf1434eb1..94a637541 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1444,6 +1444,7 @@ static int load_from_path(Unit *u, const char *path) { { "SocketMode", config_parse_mode, &u->socket.socket_mode, "Socket" }, { "KillMode", config_parse_kill_mode, &u->socket.kill_mode, "Socket" }, { "Accept", config_parse_bool, &u->socket.accept, "Socket" }, + { "TCPWrapName", config_parse_string, &u->socket.tcpwrap_name, "Socket" }, EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"), { "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" }, diff --git a/src/logger.c b/src/logger.c index 48eee6cd1..de4dfad38 100644 --- a/src/logger.c +++ b/src/logger.c @@ -36,6 +36,7 @@ #include "log.h" #include "list.h" #include "sd-daemon.h" +#include "tcpwrap.h" #define STREAM_BUFFER 2048 #define STREAMS_MAX 256 @@ -340,6 +341,11 @@ static int stream_new(Server *s, int server_fd) { return 0; } + if (!socket_tcpwrap(fd, "systemd-logger")) { + close_nointr_nofail(fd); + return 0; + } + if (!(stream = new0(Stream, 1))) { close_nointr_nofail(fd); return -ENOMEM; diff --git a/src/socket.c b/src/socket.c index 1852fe937..71f167202 100644 --- a/src/socket.c +++ b/src/socket.c @@ -36,6 +36,7 @@ #include "strv.h" #include "unit-name.h" #include "dbus-socket.h" +#include "tcpwrap.h" static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { [SOCKET_DEAD] = UNIT_INACTIVE, @@ -107,6 +108,9 @@ static void socket_done(Unit *u) { free(s->bind_to_device); s->bind_to_device = NULL; + free(s->tcpwrap_name); + s->tcpwrap_name = NULL; + unit_unwatch_timer(u, &s->timer_watch); } @@ -305,6 +309,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sBindToDevice: %s\n", prefix, s->bind_to_device); + if (s->tcpwrap_name) + fprintf(f, + "%sTCPWrapName: %s\n", + prefix, s->tcpwrap_name); + if (s->accept) fprintf(f, "%sAccepted: %u\n", @@ -1212,6 +1221,12 @@ static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { break; } + + if (s->tcpwrap_name) + if (!socket_tcpwrap(cfd, s->tcpwrap_name)) { + close_nointr_nofail(cfd); + return; + } } socket_enter_running(s, cfd); diff --git a/src/socket.h b/src/socket.h index 5a2cd06d9..de3e913f7 100644 --- a/src/socket.h +++ b/src/socket.h @@ -101,6 +101,8 @@ struct Socket { mode_t directory_mode; mode_t socket_mode; + char *tcpwrap_name; + bool accept; unsigned n_accepted; diff --git a/src/tcpwrap.c b/src/tcpwrap.c new file mode 100644 index 000000000..579aad56e --- /dev/null +++ b/src/tcpwrap.c @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#ifdef HAVE_LIBWRAP +#include +#endif + +#include "tcpwrap.h" +#include "log.h" + +bool socket_tcpwrap(int fd, const char *name) { +#ifdef HAVE_LIBWRAP + struct request_info req; + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; + } sa_union; + socklen_t l = sizeof(sa_union); + + if (getsockname(fd, &sa_union.sa, &l) < 0) + return true; + + if (sa_union.sa.sa_family != AF_INET && + sa_union.sa.sa_family != AF_INET6) + return true; + + request_init(&req, + RQ_DAEMON, name, + RQ_FILE, fd, + NULL); + + fromhost(&req); + + if (!hosts_access(&req)) { + log_warning("Connection refused by tcpwrap."); + return false; + } + + log_debug("Connection accepted by tcpwrap."); +#endif + return true; +} diff --git a/src/tcpwrap.h b/src/tcpwrap.h new file mode 100644 index 000000000..b47169610 --- /dev/null +++ b/src/tcpwrap.h @@ -0,0 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + +#ifndef foolibwraphfoo +#define foolibwraphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +bool socket_tcpwrap(int fd, const char *name); + +#endif -- 2.30.2