diff options
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | m4/acx_libwrap.m4 | 19 | ||||
-rw-r--r-- | src/dbus-socket.c | 2 | ||||
-rw-r--r-- | src/load-fragment.c | 1 | ||||
-rw-r--r-- | src/logger.c | 6 | ||||
-rw-r--r-- | src/socket.c | 15 | ||||
-rw-r--r-- | src/socket.h | 2 | ||||
-rw-r--r-- | src/tcpwrap.c | 66 | ||||
-rw-r--r-- | src/tcpwrap.h | 29 |
10 files changed, 174 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am index e50ae82040..c78968fc03 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 02618ae637..ae25200442 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 0000000000..e1602144b5 --- /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 <tcpd.h> +#include <syslog.h> +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 426af2b4cf..fa84191140 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -37,6 +37,7 @@ " <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \ " <property name=\"SocketMode\" type=\"u\" access=\"read\"/>\n" \ " <property name=\"Accept\" type=\"b\" access=\"read\"/>\n" \ + " <property name=\"TCPWrapName\" type=\"s\" access=\"read\"/>\n" \ " </interface>\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 cf1434eb1e..94a637541f 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 48eee6cd12..de4dfad386 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 1852fe9375..71f1672027 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 5a2cd06d9d..de3e913f7c 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 0000000000..579aad56e9 --- /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 <http://www.gnu.org/licenses/>. +***/ + +#include <sys/socket.h> +#include <sys/un.h> + +#ifdef HAVE_LIBWRAP +#include <tcpd.h> +#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 0000000000..b47169610c --- /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 <http://www.gnu.org/licenses/>. +***/ + +#include <stdbool.h> + +bool socket_tcpwrap(int fd, const char *name); + +#endif |