+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT (nether)
-INCLUDE(FindPkgConfig)
+INCLUDE (FindPkgConfig)
SET (CMAKE_CXX_FLAGS "-std=c++11")
-ADD_SUBDIRECTORY(src)
+SET (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+IF (NOT DEFINED SYSCONF_INSTALL_DIR)
+ SET(SYSCONF_INSTALL_DIR "/etc")
+ENDIF (NOT DEFINED SYSCONF_INSTALL_DIR)
+
+IF (NOT DEFINED SYSTEMD_UNIT_DIR)
+ SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system")
+ENDIF (NOT DEFINED SYSTEMD_UNIT_DIR)
+
+ADD_SUBDIRECTORY (src)
+ADD_SUBDIRECTORY (conf)
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+FIND_PATH (AUDIT_INCLUDE_DIR libaudit.h /usr/include /usr/local/include)
+FIND_LIBRARY (AUDIT_LIBRARY NAMES libaudit.a PATH /usr/lib /usr/local/lib)
+
+IF (AUDIT_INCLUDE_DIR AND AUDIT_LIBRARY)
+ SET (AUDIT_FOUND TRUE)
+ENDIF (AUDIT_INCLUDE_DIR AND AUDIT_LIBRARY)
+
+
+IF (AUDIT_FOUND)
+ IF (NOT audit_FIND_QUIETLY)
+ MESSAGE(STATUS "Found audit: ${AUDIT_LIBRARY}")
+ ENDIF (NOT audit_FIND_QUIETLY)
+ELSE (AUDIT_FOUND)
+ IF (audit_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find audit")
+ ENDIF (audit_FIND_REQUIRED)
+ENDIF (AUDIT_FOUND)
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+MESSAGE(STATUS "Installing config files")
+
+CONFIGURE_FILE(systemd/nether.service.in systemd/nether.service)
+
+INSTALL(FILES nether.policy DESTINATION ${SYSCONF_INSTALL_DIR}/nether)
+INSTALL(FILES nether.rules DESTINATION ${SYSCONF_INSTALL_DIR}/nether)
+INSTALL(FILES systemd/nether.service DESTINATION ${SYSTEMD_UNIT_DIR})
+INSTALL(FILES systemd/nether.service DESTINATION ${SYSTEMD_UNIT_DIR}/multi-user.target.wants)
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+#
+# Nether policy
+# $UID:$GID:$SECCTX ALLOW|DENY|ALLOW_LOG
+# If no match is found for a pcket
+# the default verdict is used (can be set via
+# command line)
+#
+
+0::_:ALLOW
+5002::_:DENY
+1354787703::_:ALLOW
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+# nether iptables rules
+*mangle
+:PREROUTING ACCEPT [1008811:2134498122]
+:INPUT ACCEPT [948545:2129919738]
+:FORWARD ACCEPT [0:0]
+:OUTPUT ACCEPT [816152:74580343]
+:POSTROUTING ACCEPT [824147:75308906]
+-A OUTPUT -p tcp -j NFQUEUE --queue-num 0 --queue-bypass
+-A OUTPUT -p udp -j NFQUEUE --queue-num 0 --queue-bypass
+-A OUTPUT -p icmp -j NFQUEUE --queue-num 0 --queue-bypass
+COMMIT
+*filter
+:INPUT ACCEPT [927054:2081201095]
+:FORWARD ACCEPT [0:0]
+:OUTPUT ACCEPT [805408:74228055]
+:NETHER-ALLOWLOG - [0:0]
+:NETHER-DENY - [0:0]
+-A OUTPUT -m mark --mark 0x3 -j NETHER-DENY
+-A OUTPUT -m mark --mark 0x4 -j NETHER-ALLOWLOG
+-A NETHER-ALLOWLOG -j AUDIT --type accept
+-A NETHER-DENY -j AUDIT --type reject
+-A NETHER-DENY -j REJECT --reject-with icmp-port-unreachable
+COMMIT
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+[Unit]
+Description=nether service
+
+[Service]
+Type=simple
+ExecStart=${CMAKE_INSTALL_PREFIX}/bin/nether -d -l JOURNAL -B ${SYSCONF_INSTALL_DIR}/nether/nether.policy -r ${SYSCONF_INSTALL_DIR}/nether/nether.rules
+Restart=on-failure
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
+++ /dev/null
-# Nether policy
-# $UID:$GID:$SECCTX ALLOW|DENY|ALLOW_LOG
-#
-
-0::_:ALLOW
-5002::_:DENY
-1354787703::_:ALLOW
\ No newline at end of file
+++ /dev/null
-# nether iptables rules
-*nat
-:PREROUTING ACCEPT [214977:18048203]
-:INPUT ACCEPT [24506:3910785]
-:OUTPUT ACCEPT [46836:3016993]
-:POSTROUTING ACCEPT [45527:2930737]
-COMMIT
-*mangle
-:PREROUTING ACCEPT [1008811:2134498122]
-:INPUT ACCEPT [948545:2129919738]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [816152:74580343]
-:POSTROUTING ACCEPT [824147:75308906]
--A OUTPUT -p tcp -m state --state NEW -m tcp --dport 443 -j NFQUEUE --queue-num 0 --queue-bypass
--A OUTPUT -p udp -j NFQUEUE --queue-num 0 --queue-bypass
--A OUTPUT -p icmp -j NFQUEUE --queue-num 0 --queue-bypass
-COMMIT
-*filter
-:INPUT ACCEPT [927054:2081201095]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [805408:74228055]
-:NETHER-ALLOWLOG - [0:0]
-:NETHER-DENY - [0:0]
--A OUTPUT -m mark --mark 0x3 -j NETHER-DENY
--A OUTPUT -m mark --mark 0x4 -j NETHER-ALLOWLOG
--A NETHER-ALLOWLOG -j AUDIT --type accept
--A NETHER-DENY -j AUDIT --type reject
--A NETHER-DENY -j REJECT --reject-with icmp-port-unreachable
-COMMIT
+++ /dev/null
-#
-# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
-#
-# Contact: Roman Kubiak (r.kubiak@samsung.com)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License
-#
-#!/bin/bash
-DENY_CHAIN="NETHER-DENY"
-ALLOWLOG_CHAIN="NETHER-ALLOWLOG"
-TEST_HOST="198.145.20.7"
-TEST_PORT=443
-TEST_PROTO="tcp"
-TEST_QUEUE=0
-AUDITCTL=auditctl
-DENY_MARK="0x3"
-ALLOWLOG_MARK="0x4"
-
-function runcmd {
- echo -ne "\t>> $@\n"
- $@
-}
-
-function clean {
- echo "Cleanup"
- echo
- iptables -t mangle -D OUTPUT -m state --state NEW -p $TEST_PROTO -d $TEST_HOST --dport $TEST_PORT -j NFQUEUE --queue-num 0 --queue-bypass 2> /dev/null
- iptables -D OUTPUT -m mark --mark $DENY_MARK -j $DENY_CHAIN 2> /dev/null
- iptables -D OUTPUT -m mark --mark $ALLOWLOG_MARK -j $ALLOWLOG_CHAIN 2> /dev/null
- iptables -F $DENY_CHAIN 2> /dev/null
- iptables -F $ALLOWLOG_CHAIN 2> /dev/null
- iptables -X $DENY_CHAIN 2> /dev/null
- iptables -X $ALLOWLOG_CHAIN 2> /dev/null
- echo
-}
-
-function create {
- echo "Creating chain"
- echo
- runcmd iptables -N $DENY_CHAIN
- runcmd iptables -N $ALLOWLOG_CHAIN
- runcmd iptables -A $DENY_CHAIN -j AUDIT --type REJECT
- runcmd iptables -A $DENY_CHAIN -j REJECT
- runcmd iptables -A $ALLOWLOG_CHAIN -j AUDIT --type ACCEPT
- echo
-}
-
-function create_rules {
- echo "Writing rules to output chain $OUTPUT_CHAIN"
- echo
- runcmd iptables -t mangle -A OUTPUT -m state --state NEW -p $TEST_PROTO -d $TEST_HOST --dport $TEST_PORT -j NFQUEUE --queue-num 0 --queue-bypass
- runcmd iptables -A OUTPUT -m mark --mark $DENY_MARK -j $DENY_CHAIN
- runcmd iptables -A OUTPUT -m mark --mark $ALLOWLOG_MARK -j $ALLOWLOG_CHAIN
- echo
-}
-
-function enable_audit {
- if type $AUDITCTL; then
- echo -n "Enable audit: "
- runcmd $AUDITCTL -e 1 >/dev/null
- if [ $? == 0 ]; then
- echo "OK"
- else
- echo "Failed"
- fi
- else
- echo "$AUDITCTL does not exist, can't enable audit"
- fi
- echo
-}
-
-clean
-create
-create_rules
-enable_audit
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
#ifndef NETHER_CYNARA_BACKEND_H
#define NETHER_CYNARA_BACKEND_H
-// #ifdef HAVE_CYNARA
+#ifdef HAVE_CYNARA
#include <cynara-client-async.h>
#include "nether_PolicyBackend.h"
int cynaraLastResult;
};
-// #endif
-#endif
+#endif // HAVE_CYNARA
+#endif // NETHER_CYNARA_BACKEND_H
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Roman Kubiak (r.kubiak@samsung.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Roman Kubiak (r.kubiak@samsung.com)
+ * @brief Dummy policy backend
+ */
#ifndef NETHER_DUMMY_BACKEND_H
#define NETHER_DUMMY_BACKEND_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
static NetherPolicyBackend *getPolicyBackend(const NetherConfig &netherConfig, const bool primary = true);
bool verdictCast (const u_int32_t packetId, const NetherVerdict verdict);
void packetReceived (const NetherPacket &packet);
+ const bool restoreRules();
private:
+ static const bool isCommandAvailable(const std::string &command);
void handleSignal();
const bool handleNetlinkpacket();
void setupSelectSockets(fd_set &watchedReadDescriptorsSet, fd_set &watchedWriteDescriptorsSet, struct timeval &timeoutSpecification);
- std::unique_ptr <NetherPolicyBackend> netherPrimaryPolicyBackend, netherBackupPolicyBackend, netherFallbackPolicyBackend;
+ std::unique_ptr <NetherPolicyBackend> netherPrimaryPolicyBackend;
+ std::unique_ptr <NetherPolicyBackend> netherBackupPolicyBackend;
+ std::unique_ptr <NetherPolicyBackend> netherFallbackPolicyBackend;
std::unique_ptr <NetherNetlink> netherNetlink;
NetherConfig netherConfig;
- int netlinkDescriptor, backendDescriptor, signalDescriptor;
+ int netlinkDescriptor;
+ int backendDescriptor;
+ int signalDescriptor;
+#ifdef HAVE_AUDIT
+ int auditDescriptor;
+#endif // HAVE_AUDIT
sigset_t signalMask;
};
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
#include <memory>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <linux/types.h>
#include <linux/netfilter.h>
+
+#if defined(HAVE_AUDIT)
+ #include <libaudit.h>
+#endif // HAVE_AUDIT
+
#include <libnetfilter_queue/libnetfilter_queue.h>
#include "logger/logger.hpp"
#include "logger/backend-file.hpp"
#include "logger/backend-stderr.hpp"
#include "logger/backend-syslog.hpp"
-#ifdef HAVE_CYNARA
+#if defined(HAVE_SYSTEMD_JOURNAL)
+ #include "logger/backend-journal.hpp"
+#endif // HAVE_SYSTEMD_JOURNAL
+
+#if defined(HAVE_CYNARA)
#define NETHER_PRIMARY_BACKEND cynaraBackend
#define NETHER_BACKUP_BACKEND fileBackend
#else
#define NETHER_PRIMARY_BACKEND fileBackend
#define NETHER_BACKUP_BACKEND dummyBackend
-#endif
+#endif // HAVE_CYNARA
#define NETHER_DEFAULT_VERDICT allowAndLog
#define NETHER_PACKET_BUFFER_SIZE 4096
#define NETLINK_DROP_MARK 3
#define NETLINK_ALLOWLOG_MARK 4
#define NETHER_LOG_BACKEND stderrBackend
+#define NETHER_IPTABLES_RESTORE_PATH "/usr/sbin/iptables-restore"
+#ifndef NETHER_RULES_PATH
+ #define NETHER_RULES_PATH "/etc/nether/nether.rules"
+#endif // NETHER_RULES_PATH
+
+#ifndef NETHER_POLICY_FILE
+ #define NETHER_POLICY_FILE "/etc/nether/nether.policy"
+#endif // NETHER_POLICY_FILE
enum NetherPolicyBackendType
{
int primaryBackendRetries = 3;
int backupBackendRetries = 3;
int debugMode = 0;
- int nodaemonMode = 0;
+ int daemonMode = 0;
int queueNumber = 0;
- std::string backupBackendArgs;
+ std::string backupBackendArgs = NETHER_POLICY_FILE;
std::string primaryBackendArgs;
std::string logBackendArgs;
+ std::string rulesPath = NETHER_RULES_PATH;
+ std::string iptablesRestorePath = NETHER_IPTABLES_RESTORE_PATH;
uint8_t markDeny = NETLINK_DROP_MARK;
uint8_t markAllowAndLog = NETLINK_ALLOWLOG_MARK;
+ int enableAudit = 0;
+ int noRules = 0;
};
class NetherVerdictListener
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
<Option object_output="obj/Debug/" />
<Option type="0" />
<Option compiler="gcc" />
- <Option parameters="-B /etc/nether.policy -l stderr" />
+ <Option parameters="-B /etc/nether/nether.policy -l stderr -a 1" />
<Compiler>
<Add option="-std=c++11" />
<Add option="-Wfatal-errors" />
<Add option="-g" />
<Add option="-DHAVE_CYNARA" />
<Add option="-D_DEBUG" />
+ <Add option="-DHAVE_AUDIT" />
<Add directory="include" />
<Add directory="/usr/local/include/cynara" />
</Compiler>
<Add library="libnfnetlink" />
<Add library="libcynara-client-async" />
<Add library="libcynara-commons" />
+ <Add library="libaudit" />
<Add directory="/usr/local/lib" />
</Linker>
<MakeCommands>
<Add option="-fPIC" />
</Compiler>
<Unit filename="CMakeLists.txt" />
- <Unit filename="config/nether.policy" />
- <Unit filename="config/nether.rules" />
- <Unit filename="config/setrules.sh" />
+ <Unit filename="cmake/Findaudit.cmake" />
+ <Unit filename="conf/CMakeLists.txt" />
+ <Unit filename="conf/nether.policy" />
+ <Unit filename="conf/nether.rules" />
+ <Unit filename="conf/systemd/nether.service.in" />
<Unit filename="include/logger/backend-file.hpp" />
<Unit filename="include/logger/backend-journal.hpp" />
<Unit filename="include/logger/backend-null.hpp" />
+++ /dev/null
-<manifest>
- <request>
- <domain name="_"/>
- </request>
-</manifest>
-Name: nether
-Epoch: 1
-Version: 0.0.1
-Release: 0
-Source0: %{name}-%{version}.tar.gz
-License: Apache-2.0
-Group: Security/Other
-Summary: Daemon for enforcing network privileges
-BuildRequires: cmake
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: libnetfilter_queue-devel
-Requires: iptables
+Name: nether
+Epoch: 1
+Version: 0.0.1
+Release: 0
+Source0: %{name}-%{version}.tar.gz
+License: Apache-2.0
+Group: Security/Other
+Summary: Daemon for enforcing network privileges
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: libnetfilter_queue-devel
+BuildRequires: pkgconfig(cynara-client-async)
+Requires: iptables
%description
-This package provides a daemon used to manage zones - start, stop and switch
-between them. A process from inside a zone can request a switch of context
-(display, input devices) to the other zone.
+This is a network privilege enforcing service.
%files
-%manifest packaging/nether.manifest
%defattr(644,root,root,755)
%attr(755,root,root) %{_bindir}/nether
-%dir /etc/nether
-%config /etc/nether/nether.policy
-%config /etc/nether/setrules.sh
-%config /etc/nether/nether.rules
+%dir %{_sysconfdir}/nether
+%config %{_sysconfdir}/nether/nether.policy
+%config %{_sysconfdir}/nether/nether.rules
+%{_unitdir}/nether.service
+%{_unitdir}/multi-user.target.wants/nether.service
%prep
%setup -q
%{!?build_type:%define build_type "RELEASE"}
%if %{build_type} == "DEBUG" || %{build_type} == "PROFILING" || %{build_type} == "CCOV"
- CFLAGS="$CFLAGS -Wp,-U_FORTIFY_SOURCE"
- CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE"
+ CFLAGS="$CFLAGS -Wp,-U_FORTIFY_SOURCE"
+ CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE"
%endif
%cmake . -DVERSION=%{version} \
- -DCMAKE_BUILD_TYPE=%{build_type} \
- -DSCRIPT_INSTALL_DIR=%{script_dir} \
- -DSYSTEMD_UNIT_DIR=%{_unitdir}
+ -DCMAKE_BUILD_TYPE=%{build_type} \
+ -DSYSTEMD_UNIT_DIR=%{_unitdir} \
+ -DBIN_INSTALL_DIR=%{_bindir} \
+ -DSYSCONF_INSTALL_DIR=%{_sysconfdir}
+
make -k %{?jobs:-j%jobs}
%install
%post
# Refresh systemd services list after installation
if [ $1 == 1 ]; then
- systemctl daemon-reload || :
+ systemctl daemon-reload || :
fi
# set needed caps on the binary to allow restart without loosing them
setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE+ei %{_bindir}/nether
%preun
# Stop the service before uninstall
if [ $1 == 0 ]; then
- systemctl stop nether.service || :
+ systemctl stop nether.service || :
fi
%postun
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Contact: Roman Kubiak (r.kubiak@samsung.com)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
FILE (GLOB NETHER_SOURCES *.cpp)
FILE (GLOB VASUM_LOGGER logger/*.cpp)
-PKG_CHECK_MODULES (CYNARA cynara-client-async QUIET)
+
PKG_CHECK_MODULES (NETFILTER libnetfilter_queue REQUIRED)
-PKG_CHECK_MODULES (LOGGER libsystemd-journal QUIET)
-ADD_EXECUTABLE(nether ${NETHER_SOURCES} ${VASUM_LOGGER})
+IF (NOT DISABLE_CYNARA)
+ PKG_CHECK_MODULES (CYNARA cynara-client-async)
+endif()
-INCLUDE_DIRECTORIES(../include
- ${EXTERNAL_INCLUDE_DIRS}
- ${CYNARA_INCLUDE_DIRS}
- ${NETFILTER_INCLUDE_DIRS}
- ${LOGGER_INCLUDE_DIRS}
-)
+IF (NOT DISABLE_SYSTEMD)
+ PKG_CHECK_MODULES (SYSTEMD libsystemd-journal)
+ENDIF()
-if(CYNARA_FOUND)
- ADD_DEFINITIONS (-DHAVE_CYNARA=${CYNARA_FOUND})
-endif()
+IF (NOT DISABLE_AUDIT)
+ FIND_PACKAGE(audit)
+ENDIF()
-if(LOGGER_FOUND)
- ADD_DEFINITIONS (-DHAVE_SYSTEMD_JOURNAL=${LOGGER_FOUND})
-endif()
+IF (NOT DISABLE_BOOST)
+ FIND_PACKAGE(Boost)
+ENDIF()
+
+ADD_EXECUTABLE(nether ${NETHER_SOURCES} ${VASUM_LOGGER})
-IF(CMAKE_BUILD_TYPE MATCHES DEBUG)
+IF (CMAKE_BUILD_TYPE MATCHES DEBUG)
ADD_DEFINITIONS (-D_DEBUG=1)
-ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG)
+ENDIF (CMAKE_BUILD_TYPE MATCHES DEBUG)
-TARGET_LINK_LIBRARIES(nether ${CYNARA_LIBRARIES}
- ${NETFILTER_LIBRARIES}
- ${LOGGER_LIBRARIES}
+IF (CYNARA_FOUND)
+ ADD_DEFINITIONS (-DHAVE_CYNARA=1)
+ENDIF ()
+
+IF (SYSTEMD_FOUND)
+ ADD_DEFINITIONS (-DHAVE_SYSTEMD_JOURNAL=1)
+ENDIF ()
+
+IF (AUDIT_FOUND)
+ ADD_DEFINITIONS (-DHAVE_AUDIT=1)
+ INCLUDE_DIRECTORIES (${AUDIT_INCLUDE_DIR})
+ TARGET_LINK_LIBRARIES (nether ${AUDIT_LIBRARY})
+ENDIF ()
+
+IF (Boost_FOUND)
+ ADD_DEFINITIONS (-DHAVE_BOOST=1)
+ENDIF ()
+
+INCLUDE_DIRECTORIES(../include
+ ${CYNARA_INCLUDE_DIRS}
+ ${NETFILTER_INCLUDE_DIRS}
+ ${SYSTEMD_INCLUDE_DIRS}
)
+
+TARGET_LINK_LIBRARIES (nether
+ ${CYNARA_LIBRARIES}
+ ${NETFILTER_LIBRARIES}
+ ${SYSTEMD_LIBRARIES}
+)
+
+ADD_DEFINITIONS (-DNETHER_RULES_PATH="${CMAKE_INSTALL_DIR}/etc/nether/nether.rules"
+ -DNETHER_POLICY_FILE="${CMAKE_INSTALL_DIR}/etc/nether/nether.rules"
+)
+
+INSTALL (TARGETS nether RUNTIME DESTINATION bin)
#include "logger/backend-stderr.hpp"
#include "logger/formatter.hpp"
-#include <boost/tokenizer.hpp>
+#if defined(HAVE_BOOST)
+ #include <boost/tokenizer.hpp>
+#endif
namespace logger {
const std::string& func,
const std::string& message)
{
+#if defined(HAVE_BOOST)
typedef boost::char_separator<char> charSeparator;
typedef boost::tokenizer<charSeparator> tokenizer;
useColours ? defaultColor.c_str() : "");
}
}
+#else
+ fprintf (stderr, "%s %s\n", LogFormatter::getHeader(logLevel, file, line, func).c_str(), message.c_str());
+#endif
}
} // namespace logger
#include "logger/level.hpp"
#include <stdexcept>
-#include <boost/algorithm/string.hpp>
+#if defined(HAVE_BOOST)
+ #include <boost/algorithm/string.hpp>
namespace logger {
throw std::runtime_error("Invalid LogLevel to parse");
}
}
+#else
+#include <string.h>
+namespace logger {
+
+LogLevel parseLogLevel(const std::string& level)
+{
+ if (strcmp(level.c_str(), "ERROR")) {
+ return LogLevel::ERROR;
+ } else if (strcmp(level.c_str(), "WARN") == 0) {
+ return LogLevel::WARN;
+ } else if (strcmp(level.c_str(), "INFO") == 0) {
+ return LogLevel::INFO;
+ } else if (strcmp(level.c_str(), "DEBUG") == 0) {
+ return LogLevel::DEBUG;
+ } else if (strcmp(level.c_str(), "TRACE") == 0) {
+ return LogLevel::TRACE;
+ } else if (strcmp(level.c_str(), "HELP") == 0) {
+ return LogLevel::HELP;
+ } else {
+ throw std::runtime_error("Invalid LogLevel to parse");
+ }
+}
+#endif
std::string toString(const LogLevel logLevel)
{
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
void NetherCynaraBackend::statusCallback(int oldFd, int newFd, cynara_async_status status, void *data)
{
- LOGD("oldFd=" << oldFd << "newFd=" << newFd);
-
NetherCynaraBackend *backend = static_cast<NetherCynaraBackend *>(data);
if (status == CYNARA_STATUS_FOR_READ)
char user[NETHER_MAX_USER_LEN];
cynara_check_id checkId;
- snprintf (user, sizeof(user), "%du", packet.uid);
+ snprintf (user, sizeof(user), "%d", packet.uid);
cynaraLastResult = cynara_async_check_cache(cynaraContext, packet.securityContext.c_str(), "", user, NETHER_CYNARA_INTERNET_PRIVILEGE);
+ LOGD ("cynara_async_check_cache ctx=" << packet.securityContext.c_str() << " user=" << user << " privilege=" << NETHER_CYNARA_INTERNET_PRIVILEGE);
+
switch (cynaraLastResult)
{
case CYNARA_API_ACCESS_ALLOWED:
this);
if (cynaraLastResult == CYNARA_API_SUCCESS)
{
- responseQueue.insert (responseQueue.begin() + checkId, packet.id);
+ responseQueue[checkId] = packet.id;
return (true);
}
void NetherCynaraBackend::setCynaraVerdict(cynara_check_id checkId, int cynaraResult)
{
u_int32_t packetId = 0;
- if ((packetId = responseQueue.at(checkId)) >= 0)
+ if ((packetId = responseQueue[checkId]) >= 0)
{
- responseQueue.erase(responseQueue.begin() + checkId);
+ responseQueue[checkId] = -1;
if (cynaraResult == CYNARA_API_ACCESS_ALLOWED)
castVerdict (packetId, allow);
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
}
}
- return (false);
+ return (castVerdict(packet, netherConfig.defaultVerdict));
}
const bool NetherFileBackend::parsePolicyFile(std::ifstream &policyFile)
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
static struct option longOptions[] =
{
- {"nodaemon", no_argument, &netherConfig.nodaemonMode, 1},
- {"log", required_argument, 0, 'l'},
- {"log-args", required_argument, 0, 'L'},
- {"default-verdict", required_argument, 0, 'V'},
- {"primary-backend", required_argument, 0, 'p'},
- {"primary-backend-args", required_argument, 0, 'P'},
- {"backup-backend", required_argument, 0, 'b'},
- {"backup-backend-args", required_argument, 0, 'B'},
- {"queue-num", required_argument, 0, 'q'},
- {"mark-deny", required_argument, 0, 'm'},
- {"mark-allow-log", required_argument, 0, 'M'},
- {"help", no_argument, 0, 'h'},
+ #if defined(HAVE_AUDIT)
+ {"enable-audit", no_argument, &netherConfig.enableAudit, 0},
+#endif
+ {"daemon", no_argument, &netherConfig.daemonMode, 0},
+ {"no-rules", no_argument, &netherConfig.noRules, 0},
+ {"log", required_argument, 0, 'l'},
+ {"log-args", required_argument, 0, 'L'},
+ {"default-verdict", required_argument, 0, 'V'},
+ {"primary-backend", required_argument, 0, 'p'},
+ {"primary-backend-args", required_argument, 0, 'P'},
+ {"backup-backend", required_argument, 0, 'b'},
+ {"backup-backend-args", required_argument, 0, 'B'},
+ {"queue-num", required_argument, 0, 'q'},
+ {"mark-deny", required_argument, 0, 'm'},
+ {"mark-allow-log", required_argument, 0, 'M'},
+ {"rules-path", required_argument, 0, 'r'},
+ {"iptables-restore-path", required_argument, 0, 'i'},
+ {"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
while (1)
{
- c = getopt_long (argc, argv, ":nl:L:V:p:P:b:B:q:m:M:h", longOptions, &optionIndex);
+ c = getopt_long (argc, argv, ":daxl:L:V:p:P:b:B:q:m:M:a:r:i:h", longOptions, &optionIndex);
if (c == -1)
break;
case 0:
break;
- case 'n':
- netherConfig.nodaemonMode = 1;
+ case 'd':
+ netherConfig.daemonMode = 1;
+ break;
+ case 'x':
+ netherConfig.noRules = 1;
break;
+ #if defined(HAVE_AUDIT)
+ case 'a':
+ netherConfig.enableAudit = 1;
+ break;
+#endif
case 'l':
netherConfig.logBackend = stringToLogBackendType(optarg);
break;
netherConfig.markAllowAndLog = atoi(optarg);
break;
+ case 'r':
+ netherConfig.rulesPath = optarg;
+ break;
+
+ case 'i':
+ netherConfig.iptablesRestorePath = optarg;
+ break;
+
case 'h':
showHelp (argv[0]);
exit (1);
#if defined(_DEBUG)
<< " debug"
#endif
- << " nodaemon=" << netherConfig.nodaemonMode
+ << " daemon=" << netherConfig.daemonMode
<< " queue=" << netherConfig.queueNumber);
LOGD("primary-backend=" << backendTypeToString (netherConfig.primaryBackendType)
<< " primary-backend-args=" << netherConfig.primaryBackendArgs);
<< " mark-allow-log=" << (int)netherConfig.markAllowAndLog);
LOGD("log-backend=" << logBackendTypeToString(netherConfig.logBackend)
<< " log-backend-args=" << netherConfig.logBackendArgs);
+ LOGD("enable-audit=" << (netherConfig.enableAudit ? "yes" : "no")
+ << " rules-path=" << netherConfig.rulesPath);
+ LOGD("no-rules=" << (netherConfig.noRules ? "yes" : "no")
+ << " iptables-restore-path=" << netherConfig.iptablesRestorePath);
NetherManager manager (netherConfig);
void showHelp(char *arg)
{
cout<< "Usage:\t"<< arg << " [OPTIONS]\n\n";
- cout<< " -n,--nodaemon\t\t\t\tDon't run as daemon in the background\n";
- cout<< " -d,--debug\t\t\t\tRun in debug mode (implies --nodaemon)\n";
- cout<< " -l,--log=<backend>\t\t\tSet logging backend STDERR,SYSLOG,JOURNAL (default:"<< logBackendTypeToString(NETHER_LOG_BACKEND) << ")\n";
+ cout<< " -d,--daemon\t\t\t\tRun as daemon in the background (default:no)\n";
+ cout<< " -x,--no-rules\t\t\t\tDon't load iptables rules on start (default:no)\n";
+ cout<< " -l,--log=<backend>\t\t\tSet logging backend STDERR,SYSLOG";
+#if defined(HAVE_SYSTEMD_JOURNAL)
+ cout << ",JOURNAL\n";
+#endif
+ cout<< "(default:"<< logBackendTypeToString(NETHER_LOG_BACKEND) << ")\n";
cout<< " -L,--log-args=<arguments>\t\tSet logging backend arguments\n";
cout<< " -V,--verdict=<verdict>\t\tWhat verdict to cast when policy backend is not available\n\t\t\t\t\tACCEPT,ALLOW_LOG,DENY (default:"<<verdictToString(NETHER_DEFAULT_VERDICT)<<")\n";
- cout<< " -p,--primary-backend=<module>\t\tPrimary policy backend\n\t\t\t\t\tCYNARA,FILE,NONE (defualt:"<< backendTypeToString(NETHER_PRIMARY_BACKEND)<<")\n";
+ cout<< " -p,--primary-backend=<module>\t\tPrimary policy backend\n\t\t\t\t\t";
+#if defined(HAVE_CYNARA)
+ cout << "CYNARA";
+#endif
+ cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_PRIMARY_BACKEND)<<")\n";
cout<< " -P,--primary-backend-args=<arguments>\tPrimary policy backend arguments\n";
- cout<< " -b,--backup-backend=<module>\t\tBackup policy backend\n\t\t\t\t\tCYNARA,FILE,NONE (defualt:"<< backendTypeToString(NETHER_BACKUP_BACKEND)<< ")\n";
- cout<< " -B,--backup-backend-args=<arguments>\tBackup policy backend arguments\n";
+ cout<< " -b,--backup-backend=<module>\t\tBackup policy backend\n\t\t\t\t\t";
+#if defined(HAVE_CYNARA)
+ cout<< "CYNARA";
+#endif
+ cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_BACKUP_BACKEND)<< ")\n";
+ cout<< " -B,--backup-backend-args=<arguments>\tBackup policy backend arguments (default:" << NETHER_POLICY_FILE << ")\n";
cout<< " -q,--queue-num=<queue number>\t\tNFQUEUE queue number to use for receiving packets\n";
cout<< " -m,--mark-deny=<mark>\t\t\tPacket mark to use for DENY verdicts (default:"<< NETLINK_DROP_MARK << ")\n";
cout<< " -M,--mark-allow-log=<mark>\t\tPacket mark to use for ALLOW_LOG verdicts (default:" << NETLINK_ALLOWLOG_MARK << ")\n";
+#if defined(HAVE_AUDIT)
+ cout<< " -a,--enable-audit\t\t\tEnable the auditing subsystem (default: no)\n";
+#endif
+ cout<< " -r,--rules-path=<path>\t\tPath to iptables rules file (default:" << NETHER_RULES_PATH << ")\n";
+ cout<< " -i,--iptables-restore-path=<path>\tPath to iptables-restore command (default:" << NETHER_IPTABLES_RESTORE_PATH << ")\n";
cout<< " -h,--help\t\t\t\tshow help information\n";
}
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
return (false);
}
+ if (netherConfig.noRules == 0 && restoreRules() == false)
+ {
+ LOGE("Failed to setup iptables rules");
+ return (false);
+ }
+
+#ifdef HAVE_AUDIT
+ if (netherConfig.enableAudit)
+ {
+ if ( (auditDescriptor = audit_open ()) == -1)
+ {
+ LOGE("Failed to open an audit netlink socket: " << strerror(errno));
+ return (false);
+ }
+
+ if (audit_set_enabled (auditDescriptor, 1) <= 0)
+ {
+ LOGE("Failed to enable auditing: " << strerror(errno));
+ return (false);
+ }
+ else
+ {
+ LOGD("Auditing enabled");
+ }
+ }
+#endif // HAVE_AUDIT
+
if (!netherNetlink->initialize())
{
LOGE("Failed to initialize netlink subsystem, exiting");
LOGW("All policy backends failed, using DUMMY backend");
netherFallbackPolicyBackend->enqueueVerdict (packet);
}
+
+const bool NetherManager::restoreRules()
+{
+ if (!isCommandAvailable(netherConfig.iptablesRestorePath))
+ {
+ return (false);
+ }
+
+ std::stringstream cmdline;
+ cmdline << netherConfig.iptablesRestorePath;
+ cmdline << " ";
+ cmdline << netherConfig.rulesPath;
+
+ if (system (cmdline.str().c_str()))
+ {
+ LOGE("system() failed for: " << cmdline.str());
+ return (false);
+ }
+
+ LOGD("iptables-restore succeeded with rules from: " << netherConfig.rulesPath);
+ return (true);
+}
+
+const bool NetherManager::isCommandAvailable(const std::string &command)
+{
+ struct stat iptablesRestoreStat;
+
+ if (stat(command.c_str(), &iptablesRestoreStat) == 0)
+ {
+ if (! iptablesRestoreStat.st_mode & S_IXUSR)
+ {
+ LOGE("Execute bit is not set for owner on:" << command);
+ return (false);
+ }
+
+ return (true);
+ }
+
+ LOGE("Failed to stat command at: " << command << " error: " << strerror(errno));
+ return (false);
+}
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*
unsigned char *payload;
\r
if ((ph = nfq_get_msg_packet_hdr(nfa)))
+ {
packet.id = ntohl(ph->packet_id);
+ }
else
{
LOGI("Failed to get packet id");
return (1);
}
\r
- if (!nfq_get_uid(nfa, &packet.uid))
+ if (nfq_get_uid(nfa, &packet.uid) == 0)
LOGW("Failed to get uid for packet id=" << packet.id);
\r
nfq_get_gid(nfa, &packet.gid);
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Roman Kubiak (r.kubiak@samsung.com)
*