From: RomanKubiak Date: Fri, 24 Jul 2015 13:14:34 +0000 (+0200) Subject: Fixed EOLs/TABs/spaces X-Git-Tag: submit/tizen/20151110.144250~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F75%2F44675%2F3;p=platform%2Fcore%2Fsecurity%2Fnether.git Fixed EOLs/TABs/spaces Included fixes and changes from change I16970c3dedd9071c970523a478fbf35e009d13ef as commented by Jan Olszak and Rafal Krypa refer to https://review.tizen.org/gerrit/#/c/44086/ for details Removed const qualifiers on method return types. Removed unused parameters from method definitions. Change-Id: Ic03f4b35cdb476005749d2c93a413a83c09490fd --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 18fbea1..ff080b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,12 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.6) PROJECT (nether) INCLUDE (FindPkgConfig) -SET (CMAKE_CXX_FLAGS "-std=c++11") +IF (CMAKE_BUILD_TYPE MATCHES DEBUG) + SET (CMAKE_CXX_FLAGS "-g -Wall -Wextra -std=c++11") +ELSE () + SET (CMAKE_CXX_FLAGS "-O3 -fomit-frame-pointer -std=c++11") +ENDIF (CMAKE_BUILD_TYPE MATCHES DEBUG) + SET (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) IF (NOT DEFINED SYSCONF_INSTALL_DIR) @@ -27,7 +32,7 @@ IF (NOT DEFINED SYSCONF_INSTALL_DIR) ENDIF (NOT DEFINED SYSCONF_INSTALL_DIR) IF (NOT DEFINED SYSTEMD_UNIT_DIR) - SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system") + SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system") ENDIF (NOT DEFINED SYSTEMD_UNIT_DIR) ADD_SUBDIRECTORY (src) diff --git a/include/logger/backend-file.hpp b/include/logger/backend-file.hpp index 2fc4822..1cf69d3 100644 --- a/include/logger/backend-file.hpp +++ b/include/logger/backend-file.hpp @@ -27,19 +27,21 @@ #include "logger/backend.hpp" -namespace logger { +namespace logger +{ -class FileBackend : public LogBackend { -public: - FileBackend(const std::string &filePath) : mfilePath(filePath) {} - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -private: - std::string mfilePath; -}; + class FileBackend : public LogBackend + { + public: + FileBackend(const std::string &filePath) : mfilePath(filePath) {} + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; + private: + std::string mfilePath; + }; } // namespace logger diff --git a/include/logger/backend-journal.hpp b/include/logger/backend-journal.hpp index e566ed1..b4ef77b 100644 --- a/include/logger/backend-journal.hpp +++ b/include/logger/backend-journal.hpp @@ -27,19 +27,21 @@ #include "logger/backend.hpp" -namespace logger { +namespace logger +{ -/** - * systemd journal logging backend - */ -class SystemdJournalBackend : public LogBackend { -public: - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -}; + /** + * systemd journal logging backend + */ + class SystemdJournalBackend : public LogBackend + { + public: + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; + }; } // namespace logger diff --git a/include/logger/backend-null.hpp b/include/logger/backend-null.hpp index 4a7e8a9..1ad2e5c 100644 --- a/include/logger/backend-null.hpp +++ b/include/logger/backend-null.hpp @@ -27,19 +27,21 @@ #include "logger/backend.hpp" -namespace logger { +namespace logger +{ -/** - * Null logging backend - */ -class NullLogger : public LogBackend { -public: - void log(LogLevel /*logLevel*/, - const std::string& /*file*/, - const unsigned int& /*line*/, - const std::string& /*func*/, - const std::string& /*message*/) override {} -}; + /** + * Null logging backend + */ + class NullLogger : public LogBackend + { + public: + void log(LogLevel /*logLevel*/, + const std::string& /*file*/, + const unsigned int& /*line*/, + const std::string& /*func*/, + const std::string& /*message*/) override {} + }; } // namespace logger diff --git a/include/logger/backend-stderr.hpp b/include/logger/backend-stderr.hpp index 919e24e..57741ff 100644 --- a/include/logger/backend-stderr.hpp +++ b/include/logger/backend-stderr.hpp @@ -27,22 +27,24 @@ #include "logger/backend.hpp" -namespace logger { +namespace logger +{ -/** - * Stderr logging backend - */ -class StderrBackend : public LogBackend { -public: - StderrBackend(const bool _useColours=true) : useColours(_useColours) {} - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -private: - bool useColours; -}; + /** + * Stderr logging backend + */ + class StderrBackend : public LogBackend + { + public: + StderrBackend(const bool _useColours=true) : useColours(_useColours) {} + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; + private: + bool useColours; + }; } // namespace logger diff --git a/include/logger/backend-syslog.hpp b/include/logger/backend-syslog.hpp index 045fdec..f6f709c 100644 --- a/include/logger/backend-syslog.hpp +++ b/include/logger/backend-syslog.hpp @@ -27,16 +27,18 @@ #include "logger/backend.hpp" -namespace logger { +namespace logger +{ -class SyslogBackend : public LogBackend { -public: - void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) override; -}; + class SyslogBackend : public LogBackend + { + public: + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; + }; } // namespace logger diff --git a/include/logger/backend.hpp b/include/logger/backend.hpp index 99b0c49..381d9b7 100644 --- a/include/logger/backend.hpp +++ b/include/logger/backend.hpp @@ -29,20 +29,22 @@ #include -namespace logger { - -/** - * Abstract class for logger - */ -class LogBackend { -public: - virtual void log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) = 0; - virtual ~LogBackend() {} -}; +namespace logger +{ + + /** + * Abstract class for logger + */ + class LogBackend + { + public: + virtual void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) = 0; + virtual ~LogBackend() {} + }; } // namespace logger diff --git a/include/logger/ccolor.hpp b/include/logger/ccolor.hpp index 47cc25e..c39b8ae 100644 --- a/include/logger/ccolor.hpp +++ b/include/logger/ccolor.hpp @@ -27,26 +27,29 @@ #include -namespace logger { - -enum class Color : unsigned int { - DEFAULT = 0, - BLACK = 90, - RED = 91, - GREEN = 92, - YELLOW = 93, - BLUE = 94, - MAGENTA = 95, - CYAN = 96, - WHITE = 97 -}; - -enum class Attributes : unsigned int { - DEFAULT = 0, - BOLD = 1 -}; - -std::string getConsoleEscapeSequence(Attributes attr, Color color); +namespace logger +{ + + enum class Color : unsigned int + { + DEFAULT = 0, + BLACK = 90, + RED = 91, + GREEN = 92, + YELLOW = 93, + BLUE = 94, + MAGENTA = 95, + CYAN = 96, + WHITE = 97 + }; + + enum class Attributes : unsigned int + { + DEFAULT = 0, + BOLD = 1 + }; + + std::string getConsoleEscapeSequence(Attributes attr, Color color); } // namespace logger diff --git a/include/logger/formatter.hpp b/include/logger/formatter.hpp index 3af0763..09a1c04 100644 --- a/include/logger/formatter.hpp +++ b/include/logger/formatter.hpp @@ -29,21 +29,23 @@ #include -namespace logger { - -class LogFormatter { -public: - static unsigned int getCurrentThread(void); - static std::string getCurrentTime(void); - static std::string getConsoleColor(LogLevel logLevel); - static std::string getDefaultConsoleColor(void); - static std::string stripProjectDir(const std::string& file, - const std::string& rootDir); - static std::string getHeader(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func); -}; +namespace logger +{ + + class LogFormatter + { + public: + static unsigned int getCurrentThread(void); + static std::string getCurrentTime(void); + static std::string getConsoleColor(LogLevel logLevel); + static std::string getDefaultConsoleColor(void); + static std::string stripProjectDir(const std::string& file, + const std::string& rootDir); + static std::string getHeader(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func); + }; } // namespace logger diff --git a/include/logger/level.hpp b/include/logger/level.hpp index 7902301..80e698d 100644 --- a/include/logger/level.hpp +++ b/include/logger/level.hpp @@ -27,28 +27,30 @@ #include -namespace logger { - -enum class LogLevel { - TRACE, - DEBUG, - INFO, - WARN, - ERROR, - HELP -}; - -/** - * @param logLevel LogLevel - * @return std::sting representation of the LogLevel value - */ -std::string toString(const LogLevel logLevel); - -/** - * @param level string representation of log level - * @return parsed LogLevel value - */ -LogLevel parseLogLevel(const std::string& level); +namespace logger +{ + + enum class LogLevel + { + TRACE, + DEBUG, + INFO, + WARN, + ERROR, + HELP + }; + + /** + * @param logLevel LogLevel + * @return std::sting representation of the LogLevel value + */ + std::string toString(const LogLevel logLevel); + + /** + * @param level string representation of log level + * @return parsed LogLevel value + */ + LogLevel parseLogLevel(const std::string& level); } // namespace logger diff --git a/include/logger/logger-scope.hpp b/include/logger/logger-scope.hpp index cefd912..fa4fc04 100644 --- a/include/logger/logger-scope.hpp +++ b/include/logger/logger-scope.hpp @@ -28,45 +28,46 @@ #include #include -namespace logger { - -class SStreamWrapper +namespace logger { -public: - operator std::string() const; - template - SStreamWrapper& operator<<(const T& b) - { - this->mSStream << b; - return *this; - } + class SStreamWrapper + { + public: + operator std::string() const; -private: - std::ostringstream mSStream; -}; + template + SStreamWrapper& operator<<(const T& b) + { + this->mSStream << b; + return *this; + } -/** - * Class specifically for scope debug logging. Should be used at the beggining of a scope. - * Constructor marks scope enterance, destructor marks scope leave. - */ -class LoggerScope -{ -public: - LoggerScope(const std::string& file, - const unsigned int line, - const std::string& func, - const std::string& message, - const std::string& rootDir); - ~LoggerScope(); + private: + std::ostringstream mSStream; + }; + + /** + * Class specifically for scope debug logging. Should be used at the beggining of a scope. + * Constructor marks scope enterance, destructor marks scope leave. + */ + class LoggerScope + { + public: + LoggerScope(const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& message, + const std::string& rootDir); + ~LoggerScope(); -private: - const std::string mFile; - const unsigned int mLine; - const std::string mFunc; - const std::string mMessage; - const std::string mRootDir; -}; + private: + const std::string mFile; + const unsigned int mLine; + const std::string mFunc; + const std::string mMessage; + const std::string mRootDir; + }; } // namespace logger diff --git a/include/logger/logger.hpp b/include/logger/logger.hpp index d596a20..050416e 100644 --- a/include/logger/logger.hpp +++ b/include/logger/logger.hpp @@ -36,24 +36,26 @@ #define PROJECT_SOURCE_DIR "" #endif -namespace logger { +namespace logger +{ -class LogBackend; + class LogBackend; -class Logger { -public: - static void logMessage(LogLevel logLevel, - const std::string& message, - const std::string& file, - const unsigned int line, - const std::string& func, - const std::string& rootDir); + class Logger + { + public: + static void logMessage(LogLevel logLevel, + const std::string& message, + const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& rootDir); - static void setLogLevel(const LogLevel level); - static void setLogLevel(const std::string& level); - static LogLevel getLogLevel(void); - static void setLogBackend(LogBackend* pBackend); -}; + static void setLogLevel(const LogLevel level); + static void setLogLevel(const std::string& level); + static LogLevel getLogLevel(void); + static void setLogBackend(LogBackend* pBackend); + }; } // namespace logger diff --git a/include/nether_CynaraBackend.h b/include/nether_CynaraBackend.h index fc21d68..c7f9fff 100644 --- a/include/nether_CynaraBackend.h +++ b/include/nether_CynaraBackend.h @@ -35,39 +35,38 @@ static const std::string cynaraErrorCodeToString(int cynaraErrorCode) { - char errorString[512]; - int ret; + char errorString[512]; + int ret; - if ((ret = cynara_strerror(cynaraErrorCode, errorString, 512)) == CYNARA_API_SUCCESS) - return (std::string(errorString, strlen(errorString))); - else - return ("Failed to get error string representation, code="+ret); + if((ret = cynara_strerror(cynaraErrorCode, errorString, 512)) == CYNARA_API_SUCCESS) + return (std::string(errorString, strlen(errorString))); + else + return ("Failed to get error string representation, code="+ret); } class NetherManager; class NetherCynaraBackend : public NetherPolicyBackend { - public: - NetherCynaraBackend(const NetherConfig &netherConfig); - ~NetherCynaraBackend(); - const bool initialize(); - const bool isValid(); - const bool enqueueVerdict (const NetherPacket &packet); - const bool processEvents(); - const int getDescriptor(); - const NetherDescriptorStatus getDescriptorStatus(); - void setCynaraDescriptor(const int _currentCynaraDescriptor, const NetherDescriptorStatus _currentCynaraDescriptorStatus); - void setCynaraVerdict(cynara_check_id checkId, int cynaraResult); - static void statusCallback(int oldFd, int newFd, cynara_async_status status, void *data); - static void checkCallback(cynara_check_id check_id, cynara_async_call_cause cause, int response, void *data); + public: + NetherCynaraBackend(const NetherConfig &netherConfig); + ~NetherCynaraBackend(); + bool initialize(); + bool enqueueVerdict(const NetherPacket &packet); + bool processEvents(); + int getDescriptor(); + NetherDescriptorStatus getDescriptorStatus(); + void setCynaraDescriptor(const int _currentCynaraDescriptor, const NetherDescriptorStatus _currentCynaraDescriptorStatus); + void setCynaraVerdict(cynara_check_id checkId, int cynaraResult); + static void statusCallback(int oldFd, int newFd, cynara_async_status status, void *data); + static void checkCallback(cynara_check_id check_id, cynara_async_call_cause cause, int response, void *data); - private: - cynara_async *cynaraContext; - NetherDescriptorStatus currentCynaraDescriptorStatus; - int currentCynaraDescriptor; - std::vector responseQueue; - int cynaraLastResult; + private: + cynara_async *cynaraContext; + NetherDescriptorStatus currentCynaraDescriptorStatus; + int currentCynaraDescriptor; + std::vector responseQueue; + int cynaraLastResult; }; #endif // HAVE_CYNARA diff --git a/include/nether_Daemon.h b/include/nether_Daemon.h index 03a9c79..760fadf 100644 --- a/include/nether_Daemon.h +++ b/include/nether_Daemon.h @@ -35,56 +35,58 @@ bool runAsDaemon() { - pid_t pid = fork(); + pid_t pid = fork(); - if (pid == -1) - return (false); - else if (pid != 0) - exit (0); + if(pid == -1) + return (false); + else + if(pid != 0) + exit(0); - if (setsid() == -1) - return (false); + if(setsid() == -1) + return (false); - /* Catch, ignore and handle signals */ - signal(SIGCHLD, SIG_IGN); - signal(SIGHUP, SIG_IGN); + /* Catch, ignore and handle signals */ + signal(SIGCHLD, SIG_IGN); + signal(SIGHUP, SIG_IGN); - pid = fork(); + pid = fork(); - /* - * Fork a second child and exit immediately to prevent zombies. This - * causes the second child process to be orphaned, making the init - * process responsible for its cleanup. And, since the first child is - * a session leader without a controlling terminal, it's possible for - * it to acquire one by opening a terminal in the future (System V- - * based systems). This second fork guarantees that the child is no - * longer a session leader, preventing the daemon from ever acquiring - * a controlling terminal. - */ - if (pid == -1) - return (false); - else if (pid != 0) - exit(0); + /* + * Fork a second child and exit immediately to prevent zombies. This + * causes the second child process to be orphaned, making the init + * process responsible for its cleanup. And, since the first child is + * a session leader without a controlling terminal, it's possible for + * it to acquire one by opening a terminal in the future (System V- + * based systems). This second fork guarantees that the child is no + * longer a session leader, preventing the daemon from ever acquiring + * a controlling terminal. + */ + if(pid == -1) + return (false); + else + if(pid != 0) + exit(0); - if (chdir("/") == -1) - return (false); + if(chdir("/") == -1) + return (false); - umask(0); + umask(0); - /** Close all open file descriptors */ - for (int x = sysconf(_SC_OPEN_MAX); x>0; x--) - { - close (x); - } + /** Close all open file descriptors */ + for(int x = sysconf(_SC_OPEN_MAX); x>0; x--) + { + close(x); + } - if (open("/dev/null",O_RDONLY) == -1) - return (false); + if(open("/dev/null",O_RDONLY) == -1) + return (false); - if (open("/dev/null",O_WRONLY) == -1) - return (false); + if(open("/dev/null",O_WRONLY) == -1) + return (false); - if (open("/dev/null",O_RDWR) == -1) - return (false); + if(open("/dev/null",O_RDWR) == -1) + return (false); - return (true); + return (true); } diff --git a/include/nether_DummyBackend.h b/include/nether_DummyBackend.h index 8bbee85..c5316eb 100644 --- a/include/nether_DummyBackend.h +++ b/include/nether_DummyBackend.h @@ -29,30 +29,25 @@ class NetherDummyBackend : public NetherPolicyBackend { - public: - NetherDummyBackend(const NetherConfig &netherConfig) - : NetherPolicyBackend(netherConfig) {} - ~NetherDummyBackend() {} - - const bool isValid() - { - return (true); - } - - const bool initialize() - { - return (true); - } - - const bool enqueueVerdict(const NetherPacket &packet) - { - return (castVerdict (packet, netherConfig.defaultVerdict)); - } - - const bool processEvents() - { - return (true); - } + public: + NetherDummyBackend(const NetherConfig &netherConfig) + : NetherPolicyBackend(netherConfig) {} + ~NetherDummyBackend() {} + + bool initialize() + { + return (true); + } + + bool enqueueVerdict(const NetherPacket &packet) + { + return (castVerdict(packet, netherConfig.defaultVerdict)); + } + + bool processEvents() + { + return (true); + } }; #endif diff --git a/include/nether_FileBackend.h b/include/nether_FileBackend.h index c3cd544..63c8a77 100644 --- a/include/nether_FileBackend.h +++ b/include/nether_FileBackend.h @@ -39,49 +39,56 @@ class NetherManager; enum PolicyFileTokens { - uidT, - gidT, - secctxT, - verdictT + uidToken, + gidToken, + secctxToken, + verdictToken }; struct PolicyEntry { - uid_t uid; - gid_t gid; - std::string securityContext; - NetherVerdict verdict; + uid_t uid; + gid_t gid; + std::string securityContext; + NetherVerdict verdict; }; static const std::string dumpPolicyEntry(const PolicyEntry &entry) { - std::stringstream stream; - stream << "UID="; - if (entry.uid == NETHER_INVALID_UID) stream << "*"; else stream << entry.uid; - stream << " GID="; - if (entry.gid == NETHER_INVALID_GID) stream << "*"; else stream << entry.gid; - stream << " SECCTX="; - if (entry.securityContext.empty()) stream << "*"; else stream << entry.securityContext; - stream << " VERDICT="; - stream << verdictToString(entry.verdict); + std::stringstream stream; + stream << "UID="; + if(entry.uid == NETHER_INVALID_UID) + stream << "*"; + else + stream << entry.uid; + stream << " GID="; + if(entry.gid == NETHER_INVALID_GID) + stream << "*"; + else stream << entry.gid; + stream << " SECCTX="; + if(entry.securityContext.empty()) + stream << "*"; + else + stream << entry.securityContext; + stream << " VERDICT="; + stream << verdictToString(entry.verdict); - return (stream.str()); + return (stream.str()); } class NetherFileBackend : public NetherPolicyBackend { - public: - NetherFileBackend(const NetherConfig &netherConfig); - ~NetherFileBackend(); - const bool isValid(); - const bool initialize(); - const bool reload(); - const bool enqueueVerdict(const NetherPacket &packet); - const bool parsePolicyFile(std::ifstream &policyFile); - const bool processEvents() { return (true); } - std::vector split(const std::string &str, const std::string &delim); - private: - std::vector policy; + public: + NetherFileBackend(const NetherConfig &netherConfig); + ~NetherFileBackend(); + bool initialize(); + bool reload(); + bool enqueueVerdict(const NetherPacket &packet); + bool parsePolicyFile(std::ifstream &policyFile); + bool processEvents() { return (true); } + std::vector split(const std::string &str, const std::string &delim); + private: + std::vector policy; }; #endif diff --git a/include/nether_Manager.h b/include/nether_Manager.h index 5407a63..5865fcf 100644 --- a/include/nether_Manager.h +++ b/include/nether_Manager.h @@ -32,34 +32,34 @@ class NetherManager : public NetherVerdictListener, public NetherProcessedPacketListener { - public: - NetherManager(const NetherConfig &_netherConfig); - ~NetherManager(); - const bool initialize(); - const bool process(); - NetherConfig &getConfig(); - 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(); + public: + NetherManager(const NetherConfig &_netherConfig); + ~NetherManager(); + bool initialize(); + bool process(); + NetherConfig &getConfig(); + 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); + 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 netherPrimaryPolicyBackend; - std::unique_ptr netherBackupPolicyBackend; - std::unique_ptr netherFallbackPolicyBackend; - std::unique_ptr netherNetlink; - NetherConfig netherConfig; - int netlinkDescriptor; - int backendDescriptor; - int signalDescriptor; + private: + static bool isCommandAvailable(const std::string &command); + void handleSignal(); + bool handleNetlinkpacket(); + void setupSelectSockets(fd_set &watchedReadDescriptorsSet, fd_set &watchedWriteDescriptorsSet, struct timeval &timeoutSpecification); + std::unique_ptr netherPrimaryPolicyBackend; + std::unique_ptr netherBackupPolicyBackend; + std::unique_ptr netherFallbackPolicyBackend; + std::unique_ptr netherNetlink; + NetherConfig netherConfig; + int netlinkDescriptor; + int backendDescriptor; + int signalDescriptor; #ifdef HAVE_AUDIT - int auditDescriptor; + int auditDescriptor; #endif // HAVE_AUDIT - sigset_t signalMask; + sigset_t signalMask; }; #endif diff --git a/include/nether_Netlink.h b/include/nether_Netlink.h index df852e9..39a1b44 100644 --- a/include/nether_Netlink.h +++ b/include/nether_Netlink.h @@ -22,36 +22,34 @@ * @brief netlink handler class for nether */ -#ifndef NETHER_NETLINK_H -#define NETHER_NETLINK_H - -#include "nether_Types.h" +#ifndef NETHER_NETLINK_H +#define NETHER_NETLINK_H + +#include "nether_Types.h" #include "nether_Utils.h" - -class NetherManager; - -class NetherNetlink : public NetherPacketProcessor -{ - public: - NetherNetlink(NetherConfig &netherConfig); - ~NetherNetlink(); - const bool initialize(); - const bool reload(); - static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data); - const bool processPacket (char *packetBuffer, const int packetReadSize); - void setVerdict(const u_int32_t packetId, const NetherVerdict verdict); - int getDescriptor(); - const bool isValid(); - - protected: - NetherPacket *processedPacket; - - private: - struct nfq_q_handle *queueHandle; - struct nfq_handle *nfqHandle; - struct nlif_handle *nlif; - int fd; - uint32_t queue; -}; - -#endif // NETLINK_H_INCLUDED + +class NetherManager; + +class NetherNetlink : public NetherPacketProcessor +{ + public: + NetherNetlink(NetherConfig &netherConfig); + ~NetherNetlink(); + bool initialize(); + bool reload(); + static int callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data); + bool processPacket(char *packetBuffer, const int packetReadSize); + void setVerdict(const u_int32_t packetId, const NetherVerdict verdict); + int getDescriptor(); + + protected: + NetherPacket *processedPacket; + + private: + struct nfq_q_handle *queueHandle; + struct nfq_handle *nfqHandle; + struct nlif_handle *nlif; + uint32_t queue; +}; + +#endif // NETLINK_H_INCLUDED diff --git a/include/nether_PolicyBackend.h b/include/nether_PolicyBackend.h index 4d2145f..c17bfe4 100644 --- a/include/nether_PolicyBackend.h +++ b/include/nether_PolicyBackend.h @@ -30,19 +30,27 @@ class NetherPolicyBackend : public NetherVerdictCaster { - public: - NetherPolicyBackend(const NetherConfig &_netherConfig) : netherConfig(_netherConfig) {} - virtual ~NetherPolicyBackend() {} - virtual const bool enqueueVerdict (const NetherPacket &packet) = 0; - virtual const bool initialize() = 0; - virtual const bool reload() { return (true); }; - virtual const bool isValid() = 0; - virtual const int getDescriptor() { return (-1); } - virtual const NetherDescriptorStatus getDescriptorStatus() { return (NetherDescriptorStatus::unknownStatus); } - virtual const bool processEvents() = 0; + public: + NetherPolicyBackend(const NetherConfig &_netherConfig) : netherConfig(_netherConfig) {} + virtual ~NetherPolicyBackend() {} + virtual bool enqueueVerdict(const NetherPacket &packet) = 0; + virtual bool initialize() = 0; + virtual bool reload() + { + return (true); + }; + virtual int getDescriptor() + { + return (-1); + } + virtual NetherDescriptorStatus getDescriptorStatus() + { + return (NetherDescriptorStatus::unknownStatus); + } + virtual bool processEvents() = 0; - protected: - NetherConfig netherConfig; + protected: + NetherConfig netherConfig; }; #endif diff --git a/include/nether_Types.h b/include/nether_Types.h index 8802b47..9991a30 100644 --- a/include/nether_Types.h +++ b/include/nether_Types.h @@ -44,12 +44,14 @@ #include #include #include +#include +#include #include #include #include #if defined(HAVE_AUDIT) - #include +#include #endif // HAVE_AUDIT #include @@ -59,15 +61,15 @@ #include "logger/backend-syslog.hpp" #if defined(HAVE_SYSTEMD_JOURNAL) - #include "logger/backend-journal.hpp" +#include "logger/backend-journal.hpp" #endif // HAVE_SYSTEMD_JOURNAL #if defined(HAVE_CYNARA) - #define NETHER_PRIMARY_BACKEND NetherPolicyBackendType::cynaraBackend - #define NETHER_BACKUP_BACKEND NetherPolicyBackendType::fileBackend +#define NETHER_PRIMARY_BACKEND NetherPolicyBackendType::cynaraBackend +#define NETHER_BACKUP_BACKEND NetherPolicyBackendType::fileBackend #else - #define NETHER_PRIMARY_BACKEND fileBackend - #define NETHER_BACKUP_BACKEND dummyBackend +#define NETHER_PRIMARY_BACKEND fileBackend +#define NETHER_BACKUP_BACKEND dummyBackend #endif // HAVE_CYNARA #define NETHER_DEFAULT_VERDICT NetherVerdict::allowAndLog @@ -83,159 +85,164 @@ #define NETHER_LOG_BACKEND NetherLogBackendType::stderrBackend #define NETHER_IPTABLES_RESTORE_PATH "/usr/sbin/iptables-restore" #ifndef NETHER_RULES_PATH - #define NETHER_RULES_PATH "/etc/nether/nether.rules" +#define NETHER_RULES_PATH "/etc/nether/nether.rules" #endif // NETHER_RULES_PATH #ifndef NETHER_POLICY_FILE - #define NETHER_POLICY_FILE "/etc/nether/nether.policy" +#define NETHER_POLICY_FILE "/etc/nether/nether.policy" #endif // NETHER_POLICY_FILE enum class NetherPolicyBackendType : std::uint8_t { - cynaraBackend, - fileBackend, - dummyBackend + cynaraBackend, + fileBackend, + dummyBackend }; enum class NetherLogBackendType : std::uint8_t { - stderrBackend, - syslogBackend, - journalBackend, - logfileBackend, - nullBackend + stderrBackend, + syslogBackend, + journalBackend, + logfileBackend, + nullBackend }; enum class NetherVerdict : std::uint8_t { - allow, - allowAndLog, - deny, - noVerdictYet + allow, + allowAndLog, + deny, + noVerdictYet }; enum class NetherDescriptorStatus : std::uint8_t { - readOnly, - writeOnly, - readWrite, - unknownStatus + readOnly, + writeOnly, + readWrite, + unknownStatus }; enum class NetherTransportType : std::uint8_t { - TCP, - UDP, - ICMP, - IGMP, - unknownTransportType + TCP, + UDP, + ICMP, + IGMP, + unknownTransportType }; enum class NetherProtocolType : std::uint8_t { - IPv4, - IPv6, - unknownProtocolType + IPv4, + IPv6, + unknownProtocolType }; struct NetherPacket { - u_int32_t id; - std::string securityContext; - uid_t uid; - gid_t gid; - pid_t pid; - NetherTransportType transportType; - NetherProtocolType protocolType; - char localAddress[NETHER_NETWORK_ADDR_LEN]; - int localPort; - char remoteAddress[NETHER_NETWORK_ADDR_LEN]; - int remotePort; + uid_t uid; + u_int32_t id; + std::string securityContext; + int remotePort; + int localPort; + gid_t gid; + pid_t pid; + char localAddress[NETHER_NETWORK_ADDR_LEN]; + char remoteAddress[NETHER_NETWORK_ADDR_LEN]; + NetherTransportType transportType; + NetherProtocolType protocolType; }; struct NetherConfig { - NetherVerdict defaultVerdict = NETHER_DEFAULT_VERDICT; - NetherPolicyBackendType primaryBackendType = NETHER_PRIMARY_BACKEND; - NetherPolicyBackendType backupBackendType = NETHER_BACKUP_BACKEND; - NetherLogBackendType logBackend = NETHER_LOG_BACKEND; - int primaryBackendRetries = 3; - int backupBackendRetries = 3; - int debugMode = 0; - int daemonMode = 0; - int queueNumber = 0; - 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; + NetherVerdict defaultVerdict = NETHER_DEFAULT_VERDICT; + NetherPolicyBackendType primaryBackendType = NETHER_PRIMARY_BACKEND; + NetherPolicyBackendType backupBackendType = NETHER_BACKUP_BACKEND; + NetherLogBackendType logBackend = NETHER_LOG_BACKEND; + uint8_t markDeny = NETLINK_DROP_MARK; + uint8_t markAllowAndLog = NETLINK_ALLOWLOG_MARK; + int primaryBackendRetries = 3; + int backupBackendRetries = 3; + int debugMode = 0; + int daemonMode = 0; + int queueNumber = 0; + int enableAudit = 0; + int noRules = 0; + 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; }; class NetherVerdictListener { - public: - virtual bool verdictCast (const u_int32_t packetId, const NetherVerdict verdict) = 0; + public: + virtual bool verdictCast(const u_int32_t packetId, const NetherVerdict verdict) = 0; }; class NetherVerdictCaster { - public: - NetherVerdictCaster() : verdictListener(nullptr) {} - virtual ~NetherVerdictCaster() {} - - void setListener(NetherVerdictListener *listenerToSet) - { - verdictListener = listenerToSet; - } - - bool castVerdict (const NetherPacket &packet, const NetherVerdict verdict) - { - if (verdictListener) - return (verdictListener->verdictCast(packet.id, verdict)); - return (false); - } - - bool castVerdict (const u_int32_t packetId, const NetherVerdict verdict) - { - if (verdictListener) - return (verdictListener->verdictCast(packetId, verdict)); - return (false); - } - - protected: - NetherVerdictListener *verdictListener; + public: + NetherVerdictCaster() : verdictListener(nullptr) {} + virtual ~NetherVerdictCaster() {} + + void setListener(NetherVerdictListener *listenerToSet) + { + verdictListener = listenerToSet; + } + + bool castVerdict(const NetherPacket &packet, const NetherVerdict verdict) + { + if(verdictListener) + return (verdictListener->verdictCast(packet.id, verdict)); + return (false); + } + + bool castVerdict(const u_int32_t packetId, const NetherVerdict verdict) + { + if(verdictListener) + return (verdictListener->verdictCast(packetId, verdict)); + return (false); + } + + protected: + NetherVerdictListener *verdictListener; }; class NetherProcessedPacketListener { - public: - virtual void packetReceived (const NetherPacket &packet) = 0; + public: + virtual void packetReceived(const NetherPacket &packet) = 0; }; class NetherPacketProcessor { - public: - NetherPacketProcessor(NetherConfig &_netherConfig) : netherConfig(_netherConfig), packetListener(nullptr) {} - virtual ~NetherPacketProcessor() {} - virtual const bool reload() { return (true); } - void setListener(NetherProcessedPacketListener *listenerToSet) - { - packetListener = listenerToSet; - } - - void processNetherPacket (NetherPacket packetInfoToWrite) - { - if (packetListener) packetListener->packetReceived(packetInfoToWrite); - } - - virtual void setVerdict(const NetherPacket &packet, const NetherVerdict verdict) {} - protected: - NetherProcessedPacketListener *packetListener; - NetherConfig netherConfig; + public: + NetherPacketProcessor(NetherConfig &_netherConfig) + : packetListener(nullptr), netherConfig(_netherConfig) {} + virtual ~NetherPacketProcessor() {} + virtual bool reload() + { + return (true); + } + void setListener(NetherProcessedPacketListener *listenerToSet) + { + packetListener = listenerToSet; + } + + void processNetherPacket(NetherPacket packetInfoToWrite) + { + if(packetListener) packetListener->packetReceived(packetInfoToWrite); + } + + virtual void setVerdict(const u_int32_t packetId, const NetherVerdict verdict) = 0; + + protected: + NetherProcessedPacketListener *packetListener; + NetherConfig netherConfig; }; #endif diff --git a/include/nether_Utils.h b/include/nether_Utils.h index 7298a5c..764ce78 100644 --- a/include/nether_Utils.h +++ b/include/nether_Utils.h @@ -22,168 +22,171 @@ * @brief utility functions */ - #ifndef NETHER_UTILS_H #define NETHER_UTILS_H + #include "nether_Types.h" void decodePacket(NetherPacket &packet, unsigned char *payload); void decodeIPv4Packet(NetherPacket &packet, unsigned char *payload); void decodeIPv6Packet(NetherPacket &packet, unsigned char *payload); void decodeTcp(NetherPacket &packet, unsigned char *payload); void decodeUdp(NetherPacket &packet, unsigned char *payload); -const std::string ipAddressToString(const char *src, enum NetherProtocolType type); +std::string ipAddressToString(const char *src, enum NetherProtocolType type); -template -inline void deleteAndZero (Type& pointer) { delete pointer; pointer = nullptr; } - -static const NetherVerdict stringToVerdict (char *verdictAsString) +static NetherVerdict stringToVerdict(char *verdictAsString) { - if (verdictAsString) - { - if (strncasecmp (verdictAsString, "allow_log", 9) == 0) - return (NetherVerdict::allowAndLog); - if (strncasecmp (verdictAsString, "allow", 6) == 0) - return (NetherVerdict::allow); - if (strncasecmp (verdictAsString, "deny", 4) == 0) - return (NetherVerdict::deny); - } - return (NetherVerdict::allowAndLog); + if(verdictAsString) + { + if(strncasecmp(verdictAsString, "allow_log", 9) == 0) + return (NetherVerdict::allowAndLog); + if(strncasecmp(verdictAsString, "allow", 6) == 0) + return (NetherVerdict::allow); + if(strncasecmp(verdictAsString, "deny", 4) == 0) + return (NetherVerdict::deny); + } + return (NetherVerdict::allowAndLog); } -static const NetherPolicyBackendType stringToBackendType (char *backendAsString) +static NetherPolicyBackendType stringToBackendType(char *backendAsString) { - if (strcasecmp (backendAsString, "cynara") == 0) - return (NetherPolicyBackendType::cynaraBackend); - if (strcasecmp (backendAsString, "file") == 0) - return (NetherPolicyBackendType::fileBackend); - if (strcasecmp (backendAsString, "dummy") == 0) - return (NetherPolicyBackendType::dummyBackend); - - return (NetherPolicyBackendType::dummyBackend); + if(strcasecmp(backendAsString, "cynara") == 0) + return (NetherPolicyBackendType::cynaraBackend); + if(strcasecmp(backendAsString, "file") == 0) + return (NetherPolicyBackendType::fileBackend); + if(strcasecmp(backendAsString, "dummy") == 0) + return (NetherPolicyBackendType::dummyBackend); + + return (NetherPolicyBackendType::dummyBackend); } -static const NetherLogBackendType stringToLogBackendType(char *backendAsString) +static NetherLogBackendType stringToLogBackendType(char *backendAsString) { - if (strcasecmp (backendAsString, "stderr") == 0) - return (NetherLogBackendType::stderrBackend); - if (strcasecmp (backendAsString, "syslog") == 0) - return (NetherLogBackendType::syslogBackend); - if (strcasecmp (backendAsString, "journal") == 0) - return (NetherLogBackendType::journalBackend); - if (strcasecmp (backendAsString, "file") == 0) - return (NetherLogBackendType::logfileBackend); - if (strcasecmp (backendAsString, "null") == 0) - return (NetherLogBackendType::nullBackend); - - return (NetherLogBackendType::nullBackend); + if(strcasecmp(backendAsString, "stderr") == 0) + return (NetherLogBackendType::stderrBackend); + if(strcasecmp(backendAsString, "syslog") == 0) + return (NetherLogBackendType::syslogBackend); + if(strcasecmp(backendAsString, "journal") == 0) + return (NetherLogBackendType::journalBackend); + if(strcasecmp(backendAsString, "file") == 0) + return (NetherLogBackendType::logfileBackend); + if(strcasecmp(backendAsString, "null") == 0) + return (NetherLogBackendType::nullBackend); + + return (NetherLogBackendType::nullBackend); } -static const std::string logBackendTypeToString(const NetherLogBackendType backendType) +static std::string logBackendTypeToString(const NetherLogBackendType backendType) { - switch (backendType) - { - case NetherLogBackendType::stderrBackend: - return ("stderr"); - case NetherLogBackendType::syslogBackend: - return ("syslog"); - case NetherLogBackendType::journalBackend: - return ("journal"); - case NetherLogBackendType::logfileBackend: - return ("file"); - case NetherLogBackendType::nullBackend: - return ("null"); - } - return ("null"); + switch(backendType) + { + case NetherLogBackendType::stderrBackend: + return ("stderr"); + case NetherLogBackendType::syslogBackend: + return ("syslog"); + case NetherLogBackendType::journalBackend: + return ("journal"); + case NetherLogBackendType::logfileBackend: + return ("file"); + case NetherLogBackendType::nullBackend: + return ("null"); + } + return ("null"); } -static const std::string backendTypeToString (const NetherPolicyBackendType backendType) +static std::string backendTypeToString(const NetherPolicyBackendType backendType) { - switch (backendType) - { - case NetherPolicyBackendType::cynaraBackend: - return ("cynara"); - case NetherPolicyBackendType::fileBackend: - return ("file"); - case NetherPolicyBackendType::dummyBackend: - default: - return ("dummy"); - } + switch(backendType) + { + case NetherPolicyBackendType::cynaraBackend: + return ("cynara"); + case NetherPolicyBackendType::fileBackend: + return ("file"); + case NetherPolicyBackendType::dummyBackend: + default: + return ("dummy"); + } } -static const std::string verdictToString (const NetherVerdict verdict) +static std::string verdictToString(const NetherVerdict verdict) { - switch (verdict) - { - case NetherVerdict::allow: - return ("ALLOW"); - case NetherVerdict::allowAndLog: - return ("ALLOW_LOG"); - case NetherVerdict::deny: - return ("DENY"); - } + switch(verdict) + { + case NetherVerdict::allow: + return ("ALLOW"); + case NetherVerdict::allowAndLog: + return ("ALLOW_LOG"); + case NetherVerdict::deny: + return ("DENY"); + case NetherVerdict::noVerdictYet: + return ("NO_VERDICT_YET"); + } + return ("NO_VERDICT_YET"); } -static const std::string transportToString(const NetherTransportType transportType) +static std::string transportToString(const NetherTransportType transportType) { - switch (transportType) - { - case NetherTransportType::TCP: - return ("TCP"); - case NetherTransportType::UDP: - return ("UDP"); - case NetherTransportType::ICMP: - return ("ICMP"); - case NetherTransportType::IGMP: - return ("IGMP"); - case NetherTransportType::unknownTransportType: - default: - return ("UNKNOWN"); - } + switch(transportType) + { + case NetherTransportType::TCP: + return ("TCP"); + case NetherTransportType::UDP: + return ("UDP"); + case NetherTransportType::ICMP: + return ("ICMP"); + case NetherTransportType::IGMP: + return ("IGMP"); + case NetherTransportType::unknownTransportType: + default: + return ("UNKNOWN"); + } } -static const std::string protocolToString(const NetherProtocolType protocolType) +static std::string protocolToString(const NetherProtocolType protocolType) { - switch (protocolType) - { - case NetherProtocolType::IPv4: - return ("IPv4"); - case NetherProtocolType::IPv6: - return ("IPv6"); - default: - return ("UNKNOWN"); - } + switch(protocolType) + { + case NetherProtocolType::IPv4: + return ("IPv4"); + case NetherProtocolType::IPv6: + return ("IPv6"); + default: + return ("UNKNOWN"); + } } -static const std::string packetToString (const NetherPacket &packet) +static std::string packetToString(const NetherPacket &packet) { - std::stringstream stream; - stream << "ID="; - stream << packet.id; - stream << " SECCTX="; - stream << packet.securityContext; - stream << " UID="; - stream << packet.uid; - stream << " PROTO="; - stream << protocolToString(packet.protocolType); - stream << " TRANSPORT="; - stream << transportToString(packet.transportType); - stream << " SADDR="; - stream << ipAddressToString(&packet.localAddress[0], packet.protocolType); - stream << ":"; - stream << packet.localPort; - stream << " DADDR="; - stream << ipAddressToString(&packet.remoteAddress[0], packet.protocolType); - stream << ":"; - stream << packet.remotePort; - return (stream.str()); + std::stringstream stream; + stream << "ID="; + stream << packet.id; + stream << " SECCTX="; + stream << packet.securityContext; + stream << " UID="; + stream << packet.uid; + stream << " GID="; + stream << packet.gid; + stream << " PROTO="; + stream << protocolToString(packet.protocolType); + stream << " TRANSPORT="; + stream << transportToString(packet.transportType); + stream << " SADDR="; + stream << ipAddressToString(&packet.localAddress[0], packet.protocolType); + stream << ":"; + stream << packet.localPort; + stream << " DADDR="; + stream << ipAddressToString(&packet.remoteAddress[0], packet.protocolType); + stream << ":"; + stream << packet.remotePort; + return (stream.str()); } template -std::string stringFormat( const char* format, Args ... args ) +std::string stringFormat(const char* format, Args ... args) { - size_t size = snprintf( nullptr, 0, format, args ... ) + 1; // Extra space for '\0' - std::unique_ptr buf( new char[ size ] ); - snprintf( buf.get(), size, format, args ... ); - return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside + size_t size = snprintf(nullptr, 0, format, args ...) + 1; // Extra space for '\0' + std::unique_ptr buf(new char[ size ]); + snprintf(buf.get(), size, format, args ...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } -#endif + +#endif // NETHER_UTILS_H diff --git a/nether.cbp b/nether.cbp deleted file mode 100644 index 1a6a84e..0000000 --- a/nether.cbp +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - diff --git a/packaging/nether.spec b/packaging/nether.spec index e491b08..1321e58 100644 --- a/packaging/nether.spec +++ b/packaging/nether.spec @@ -1,5 +1,4 @@ Name: nether -Epoch: 1 Version: 0.0.1 Release: 0 Source0: %{name}-%{version}.tar.gz @@ -7,7 +6,6 @@ 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 @@ -17,7 +15,7 @@ This is a network privilege enforcing service. %files %defattr(644,root,root,755) -%attr(755,root,root) %{_bindir}/nether +%caps(cap_sys_admin,cap_mac_override=ei) %attr(755,root,root) %{_bindir}/nether %dir %{_sysconfdir}/nether %config %{_sysconfdir}/nether/nether.policy %config %{_sysconfdir}/nether/nether.rules @@ -40,7 +38,7 @@ This is a network privilege enforcing service. -DBIN_INSTALL_DIR=%{_bindir} \ -DSYSCONF_INSTALL_DIR=%{_sysconfdir} -make -k %{?jobs:-j%jobs} +make %{?_smp_mflags} %install %make_install @@ -50,11 +48,13 @@ rm -rf %{buildroot} %post # Refresh systemd services list after installation +systemctl daemon-reload || : if [ $1 == 1 ]; then - systemctl daemon-reload || : + systemctl start nether.service || : +fi +if [ $1 == 2 ]; then + systemct restart nether.service || : 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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94d5e68..54cc564 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,14 +67,14 @@ INCLUDE_DIRECTORIES(../include ${SYSTEMD_INCLUDE_DIRS} ) -TARGET_LINK_LIBRARIES (nether +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" + -DNETHER_POLICY_FILE="${CMAKE_INSTALL_DIR}/etc/nether/nether.rules" ) INSTALL (TARGETS nether RUNTIME DESTINATION bin) diff --git a/src/logger/backend-file.cpp b/src/logger/backend-file.cpp index f5828e8..15877b5 100644 --- a/src/logger/backend-file.cpp +++ b/src/logger/backend-file.cpp @@ -28,19 +28,20 @@ #include -namespace logger { - -void FileBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) +namespace logger { - std::ofstream out(mfilePath, std::ios::app); - out << LogFormatter::getHeader(logLevel, file, line, func); - out << message; - out << std::endl; -} + + void FileBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) + { + std::ofstream out(mfilePath, std::ios::app); + out << LogFormatter::getHeader(logLevel, file, line, func); + out << message; + out << std::endl; + } } // namespace logger diff --git a/src/logger/backend-journal.cpp b/src/logger/backend-journal.cpp index af147cd..7144fba 100644 --- a/src/logger/backend-journal.cpp +++ b/src/logger/backend-journal.cpp @@ -28,45 +28,48 @@ #define SD_JOURNAL_SUPPRESS_LOCATION #include -namespace logger { +namespace logger +{ -namespace { + namespace + { -inline int toJournalPriority(LogLevel logLevel) -{ - switch (logLevel) { - case LogLevel::ERROR: - return LOG_ERR; // 3 - case LogLevel::WARN: - return LOG_WARNING; // 4 - case LogLevel::INFO: - return LOG_INFO; // 6 - case LogLevel::DEBUG: - return LOG_DEBUG; // 7 - case LogLevel::TRACE: - return LOG_DEBUG; // 7 - case LogLevel::HELP: - return LOG_DEBUG; // 7 - default: - return LOG_DEBUG; // 7 - } -} + inline int toJournalPriority(LogLevel logLevel) + { + switch(logLevel) + { + case LogLevel::ERROR: + return LOG_ERR; // 3 + case LogLevel::WARN: + return LOG_WARNING; // 4 + case LogLevel::INFO: + return LOG_INFO; // 6 + case LogLevel::DEBUG: + return LOG_DEBUG; // 7 + case LogLevel::TRACE: + return LOG_DEBUG; // 7 + case LogLevel::HELP: + return LOG_DEBUG; // 7 + default: + return LOG_DEBUG; // 7 + } + } -} // namespace + } // namespace -void SystemdJournalBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) -{ - sd_journal_send("PRIORITY=%d", toJournalPriority(logLevel), - "CODE_FILE=%s", file.c_str(), - "CODE_LINE=%d", line, - "CODE_FUNC=%s", func.c_str(), - "MESSAGE=%s", message.c_str(), - NULL); -} + void SystemdJournalBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) + { + sd_journal_send("PRIORITY=%d", toJournalPriority(logLevel), + "CODE_FILE=%s", file.c_str(), + "CODE_LINE=%d", line, + "CODE_FUNC=%s", func.c_str(), + "MESSAGE=%s", message.c_str(), + NULL); + } } // namespace logger #endif // HAVE_SYSTEMD_JOURNAL diff --git a/src/logger/backend-stderr.cpp b/src/logger/backend-stderr.cpp index 82e4c21..2088b5f 100644 --- a/src/logger/backend-stderr.cpp +++ b/src/logger/backend-stderr.cpp @@ -27,41 +27,44 @@ #include "logger/formatter.hpp" #if defined(HAVE_BOOST) - #include +#include #endif -namespace logger { - -void StderrBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) +namespace logger { + + void StderrBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) + { #if defined(HAVE_BOOST) - typedef boost::char_separator charSeparator; - typedef boost::tokenizer tokenizer; + typedef boost::char_separator charSeparator; + typedef boost::tokenizer tokenizer; - // example log string - // 06:52:35.123 [ERROR] src/util/fs.cpp:43 readFileContent: /file/file.txt is missing + // example log string + // 06:52:35.123 [ERROR] src/util/fs.cpp:43 readFileContent: /file/file.txt is missing - const std::string logColor = LogFormatter::getConsoleColor(logLevel); - const std::string defaultColor = LogFormatter::getDefaultConsoleColor(); - const std::string header = LogFormatter::getHeader(logLevel, file, line, func); - tokenizer tokens(message, charSeparator("\n")); - for (const auto& messageLine : tokens) { - if (!messageLine.empty()) { - fprintf(stderr, - "%s%s %s%s\n", - useColours ? logColor.c_str() : "", - header.c_str(), - messageLine.c_str(), - useColours ? defaultColor.c_str() : ""); - } - } + const std::string logColor = LogFormatter::getConsoleColor(logLevel); + const std::string defaultColor = LogFormatter::getDefaultConsoleColor(); + const std::string header = LogFormatter::getHeader(logLevel, file, line, func); + tokenizer tokens(message, charSeparator("\n")); + for(const auto& messageLine : tokens) + { + if(!messageLine.empty()) + { + fprintf(stderr, + "%s%s %s%s\n", + useColours ? logColor.c_str() : "", + header.c_str(), + messageLine.c_str(), + useColours ? defaultColor.c_str() : ""); + } + } #else - fprintf (stderr, "%s %s\n", LogFormatter::getHeader(logLevel, file, line, func).c_str(), message.c_str()); + fprintf(stderr, "%s %s\n", LogFormatter::getHeader(logLevel, file, line, func).c_str(), message.c_str()); #endif -} + } } // namespace logger diff --git a/src/logger/backend-syslog.cpp b/src/logger/backend-syslog.cpp index 42e8ca0..170de29 100644 --- a/src/logger/backend-syslog.cpp +++ b/src/logger/backend-syslog.cpp @@ -28,39 +28,42 @@ #include #include -namespace logger { +namespace logger +{ -namespace { + namespace + { -inline int toSyslogPriority(LogLevel logLevel) -{ - switch (logLevel) { - case LogLevel::ERROR: - return LOG_ERR; // 3 - case LogLevel::WARN: - return LOG_WARNING; // 4 - case LogLevel::INFO: - return LOG_INFO; // 6 - case LogLevel::DEBUG: - return LOG_DEBUG; // 7 - case LogLevel::TRACE: - return LOG_DEBUG; // 7 - case LogLevel::HELP: - return LOG_DEBUG; // 7 - default: - return LOG_DEBUG; // 7 - } -} + inline int toSyslogPriority(LogLevel logLevel) + { + switch(logLevel) + { + case LogLevel::ERROR: + return LOG_ERR; // 3 + case LogLevel::WARN: + return LOG_WARNING; // 4 + case LogLevel::INFO: + return LOG_INFO; // 6 + case LogLevel::DEBUG: + return LOG_DEBUG; // 7 + case LogLevel::TRACE: + return LOG_DEBUG; // 7 + case LogLevel::HELP: + return LOG_DEBUG; // 7 + default: + return LOG_DEBUG; // 7 + } + } -} // namespace + } // namespace -void SyslogBackend::log(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func, - const std::string& message) -{ - syslog(toSyslogPriority(logLevel), "%s %s", LogFormatter::getHeader(logLevel, file, line, func).c_str(), message.c_str()); -} + void SyslogBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) + { + syslog(toSyslogPriority(logLevel), "%s %s", LogFormatter::getHeader(logLevel, file, line, func).c_str(), message.c_str()); + } } // namespace logger diff --git a/src/logger/ccolor.cpp b/src/logger/ccolor.cpp index 9cc652d..f3eafec 100644 --- a/src/logger/ccolor.cpp +++ b/src/logger/ccolor.cpp @@ -27,15 +27,16 @@ #include -namespace logger { - -std::string getConsoleEscapeSequence(Attributes attr, Color color) +namespace logger { - char command[10]; - // Command is the control command to the terminal - snprintf(command, sizeof(command), "%c[%u;%um", 0x1B, (unsigned int)attr, (unsigned int)color); - return std::string(command); -} + std::string getConsoleEscapeSequence(Attributes attr, Color color) + { + char command[10]; + + // Command is the control command to the terminal + snprintf(command, sizeof(command), "%c[%u;%um", 0x1B, (unsigned int)attr, (unsigned int)color); + return std::string(command); + } } // namespace logger diff --git a/src/logger/formatter.cpp b/src/logger/formatter.cpp index 815a111..4d5cd20 100644 --- a/src/logger/formatter.cpp +++ b/src/logger/formatter.cpp @@ -33,99 +33,105 @@ #include #include -namespace logger { - -namespace { - -const int TIME_COLUMN_LENGTH = 12; -const int SEVERITY_COLUMN_LENGTH = 8; -const int THREAD_COLUMN_LENGTH = 3; -const int FILE_COLUMN_LENGTH = 60; - -std::atomic gNextThreadId(1); -thread_local unsigned int gThisThreadId(0); - -} // namespace - -unsigned int LogFormatter::getCurrentThread(void) -{ - unsigned int id = gThisThreadId; - if (id == 0) { - gThisThreadId = id = gNextThreadId++; - } - - return id; -} - -std::string LogFormatter::getCurrentTime(void) -{ - char time[TIME_COLUMN_LENGTH + 1]; - struct timeval tv; - gettimeofday(&tv, NULL); - struct tm* tm = localtime(&tv.tv_sec); - snprintf(time, - sizeof(time), - "%02d:%02d:%02d.%03d", - tm->tm_hour, - tm->tm_min, - tm->tm_sec, - int(tv.tv_usec / 1000)); - - return std::string(time); -} - -std::string LogFormatter::getConsoleColor(LogLevel logLevel) +namespace logger { - switch (logLevel) { - case LogLevel::ERROR: - return getConsoleEscapeSequence(Attributes::BOLD, Color::RED); - case LogLevel::WARN: - return getConsoleEscapeSequence(Attributes::BOLD, Color::YELLOW); - case LogLevel::INFO: - return getConsoleEscapeSequence(Attributes::BOLD, Color::BLUE); - case LogLevel::DEBUG: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::GREEN); - case LogLevel::TRACE: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::BLACK); - case LogLevel::HELP: - return getConsoleEscapeSequence(Attributes::BOLD, Color::MAGENTA); - default: - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); - } -} - -std::string LogFormatter::getDefaultConsoleColor(void) -{ - return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); -} -std::string LogFormatter::stripProjectDir(const std::string& file, - const std::string& rootDir) -{ - // If rootdir is empty then return full name - if (rootDir.empty()) { - return file; - } - const std::string sourceDir = rootDir + "/"; - // If file does not belong to rootDir then also return full name - if (0 != file.compare(0, sourceDir.size(), sourceDir)) { - return file; - } - return file.substr(sourceDir.size()); -} - -std::string LogFormatter::getHeader(LogLevel logLevel, - const std::string& file, - const unsigned int& line, - const std::string& func) -{ - std::ostringstream logLine; - logLine << getCurrentTime() << ' ' - << std::left << std::setw(SEVERITY_COLUMN_LENGTH) << '[' + toString(logLevel) + ']' - << std::right << std::setw(THREAD_COLUMN_LENGTH) << getCurrentThread() << ": " - << std::left << std::setw(FILE_COLUMN_LENGTH) - << file + ':' + std::to_string(line) + ' ' + func + ':'; - return logLine.str(); -} + namespace + { + + const int TIME_COLUMN_LENGTH = 12; + const int SEVERITY_COLUMN_LENGTH = 8; + const int THREAD_COLUMN_LENGTH = 3; + const int FILE_COLUMN_LENGTH = 60; + + std::atomic gNextThreadId(1); + thread_local unsigned int gThisThreadId(0); + + } // namespace + + unsigned int LogFormatter::getCurrentThread(void) + { + unsigned int id = gThisThreadId; + if(id == 0) + { + gThisThreadId = id = gNextThreadId++; + } + + return id; + } + + std::string LogFormatter::getCurrentTime(void) + { + char time[TIME_COLUMN_LENGTH + 1]; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm* tm = localtime(&tv.tv_sec); + snprintf(time, + sizeof(time), + "%02d:%02d:%02d.%03d", + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + int(tv.tv_usec / 1000)); + + return std::string(time); + } + + std::string LogFormatter::getConsoleColor(LogLevel logLevel) + { + switch(logLevel) + { + case LogLevel::ERROR: + return getConsoleEscapeSequence(Attributes::BOLD, Color::RED); + case LogLevel::WARN: + return getConsoleEscapeSequence(Attributes::BOLD, Color::YELLOW); + case LogLevel::INFO: + return getConsoleEscapeSequence(Attributes::BOLD, Color::BLUE); + case LogLevel::DEBUG: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::GREEN); + case LogLevel::TRACE: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::BLACK); + case LogLevel::HELP: + return getConsoleEscapeSequence(Attributes::BOLD, Color::MAGENTA); + default: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); + } + } + + std::string LogFormatter::getDefaultConsoleColor(void) + { + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); + } + + std::string LogFormatter::stripProjectDir(const std::string& file, + const std::string& rootDir) + { + // If rootdir is empty then return full name + if(rootDir.empty()) + { + return file; + } + const std::string sourceDir = rootDir + "/"; + // If file does not belong to rootDir then also return full name + if(0 != file.compare(0, sourceDir.size(), sourceDir)) + { + return file; + } + return file.substr(sourceDir.size()); + } + + std::string LogFormatter::getHeader(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func) + { + std::ostringstream logLine; + logLine << getCurrentTime() << ' ' + << std::left << std::setw(SEVERITY_COLUMN_LENGTH) << '[' + toString(logLevel) + ']' + << std::right << std::setw(THREAD_COLUMN_LENGTH) << getCurrentThread() << ": " + << std::left << std::setw(FILE_COLUMN_LENGTH) + << file + ':' + std::to_string(line) + ' ' + func + ':'; + return logLine.str(); + } } // namespace logger diff --git a/src/logger/level.cpp b/src/logger/level.cpp index 156d909..ee53cf8 100644 --- a/src/logger/level.cpp +++ b/src/logger/level.cpp @@ -27,69 +27,109 @@ #include #if defined(HAVE_BOOST) - #include +#include -namespace logger { - -LogLevel parseLogLevel(const std::string& level) +namespace logger { - if (boost::iequals(level, "ERROR")) { - return LogLevel::ERROR; - } else if (boost::iequals(level, "WARN")) { - return LogLevel::WARN; - } else if (boost::iequals(level, "INFO")) { - return LogLevel::INFO; - } else if (boost::iequals(level, "DEBUG")) { - return LogLevel::DEBUG; - } else if (boost::iequals(level, "TRACE")) { - return LogLevel::TRACE; - } else if (boost::iequals(level, "HELP")) { - return LogLevel::HELP; - } else { - throw std::runtime_error("Invalid LogLevel to parse"); - } -} + + LogLevel parseLogLevel(const std::string& level) + { + if(boost::iequals(level, "ERROR")) + { + return LogLevel::ERROR; + } + else + if(boost::iequals(level, "WARN")) + { + return LogLevel::WARN; + } + else + if(boost::iequals(level, "INFO")) + { + return LogLevel::INFO; + } + else + if(boost::iequals(level, "DEBUG")) + { + return LogLevel::DEBUG; + } + else + if(boost::iequals(level, "TRACE")) + { + return LogLevel::TRACE; + } + else + if(boost::iequals(level, "HELP")) + { + return LogLevel::HELP; + } + else + { + throw std::runtime_error("Invalid LogLevel to parse"); + } + } #else #include -namespace logger { - -LogLevel parseLogLevel(const std::string& level) +namespace logger { - 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"); - } -} + + 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) -{ - switch (logLevel) { - case LogLevel::ERROR: - return "ERROR"; - case LogLevel::WARN: - return "WARN"; - case LogLevel::INFO: - return "INFO"; - case LogLevel::DEBUG: - return "DEBUG"; - case LogLevel::TRACE: - return "TRACE"; - case LogLevel::HELP: - return "HELP"; - default: - return "UNKNOWN"; - } -} + std::string toString(const LogLevel logLevel) + { + switch(logLevel) + { + case LogLevel::ERROR: + return "ERROR"; + case LogLevel::WARN: + return "WARN"; + case LogLevel::INFO: + return "INFO"; + case LogLevel::DEBUG: + return "DEBUG"; + case LogLevel::TRACE: + return "TRACE"; + case LogLevel::HELP: + return "HELP"; + default: + return "UNKNOWN"; + } + } } // namespace logger + diff --git a/src/logger/logger-scope.cpp b/src/logger/logger-scope.cpp index a977adc..38125d3 100644 --- a/src/logger/logger-scope.cpp +++ b/src/logger/logger-scope.cpp @@ -25,36 +25,39 @@ #include "logger/logger-scope.hpp" #include "logger/logger.hpp" -namespace logger { - -SStreamWrapper::operator std::string() const +namespace logger { - return mSStream.str(); -} -LoggerScope::LoggerScope(const std::string& file, - const unsigned int line, - const std::string& func, - const std::string& message, - const std::string& rootDir): - mFile(file), - mLine(line), - mFunc(func), - mMessage(message), - mRootDir(rootDir) -{ - if (logger::Logger::getLogLevel() <= logger::LogLevel::TRACE) { - logger::Logger::logMessage(logger::LogLevel::TRACE, "Entering: " + mMessage, - mFile, mLine, mFunc, mRootDir); - } -} + SStreamWrapper::operator std::string() const + { + return mSStream.str(); + } -LoggerScope::~LoggerScope() -{ - if (logger::Logger::getLogLevel() <= logger::LogLevel::TRACE) { - logger::Logger::logMessage(logger::LogLevel::TRACE, "Leaving: " + mMessage, - mFile, mLine, mFunc, mRootDir); - } -} + LoggerScope::LoggerScope(const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& message, + const std::string& rootDir): + mFile(file), + mLine(line), + mFunc(func), + mMessage(message), + mRootDir(rootDir) + { + if(logger::Logger::getLogLevel() <= logger::LogLevel::TRACE) + { + logger::Logger::logMessage(logger::LogLevel::TRACE, "Entering: " + mMessage, + mFile, mLine, mFunc, mRootDir); + } + } + + LoggerScope::~LoggerScope() + { + if(logger::Logger::getLogLevel() <= logger::LogLevel::TRACE) + { + logger::Logger::logMessage(logger::LogLevel::TRACE, "Leaving: " + mMessage, + mFile, mLine, mFunc, mRootDir); + } + } } // namespace logger diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index ec0855b..53b96d5 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -30,47 +30,49 @@ #include #include -namespace logger { +namespace logger +{ -namespace { + namespace + { -volatile LogLevel gLogLevel = LogLevel::DEBUG; -std::unique_ptr gLogBackendPtr(new NullLogger()); -std::mutex gLogMutex; + volatile LogLevel gLogLevel = LogLevel::DEBUG; + std::unique_ptr gLogBackendPtr(new NullLogger()); + std::mutex gLogMutex; -} // namespace + } // namespace -void Logger::logMessage(LogLevel logLevel, - const std::string& message, - const std::string& file, - const unsigned int line, - const std::string& func, - const std::string& rootDir) -{ - std::string sfile = LogFormatter::stripProjectDir(file, rootDir); - std::unique_lock lock(gLogMutex); - gLogBackendPtr->log(logLevel, sfile, line, func, message); -} + void Logger::logMessage(LogLevel logLevel, + const std::string& message, + const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& rootDir) + { + std::string sfile = LogFormatter::stripProjectDir(file, rootDir); + std::unique_lock lock(gLogMutex); + gLogBackendPtr->log(logLevel, sfile, line, func, message); + } -void Logger::setLogLevel(const LogLevel level) -{ - gLogLevel = level; -} + void Logger::setLogLevel(const LogLevel level) + { + gLogLevel = level; + } -void Logger::setLogLevel(const std::string& level) -{ - gLogLevel = parseLogLevel(level); -} + void Logger::setLogLevel(const std::string& level) + { + gLogLevel = parseLogLevel(level); + } -LogLevel Logger::getLogLevel(void) -{ - return gLogLevel; -} + LogLevel Logger::getLogLevel(void) + { + return gLogLevel; + } -void Logger::setLogBackend(LogBackend* pBackend) -{ - std::unique_lock lock(gLogMutex); - gLogBackendPtr.reset(pBackend); -} + void Logger::setLogBackend(LogBackend* pBackend) + { + std::unique_lock lock(gLogMutex); + gLogBackendPtr.reset(pBackend); + } } // namespace logger diff --git a/src/nether_CynaraBackend.cpp b/src/nether_CynaraBackend.cpp index 589387c..67405ae 100644 --- a/src/nether_CynaraBackend.cpp +++ b/src/nether_CynaraBackend.cpp @@ -27,154 +27,147 @@ #ifdef HAVE_CYNARA NetherCynaraBackend::NetherCynaraBackend(const NetherConfig &netherConfig) - : NetherPolicyBackend(netherConfig), currentCynaraDescriptor(0), - cynaraLastResult(CYNARA_API_UNKNOWN_ERROR) + : NetherPolicyBackend(netherConfig), currentCynaraDescriptor(0), + cynaraLastResult(CYNARA_API_UNKNOWN_ERROR) { - responseQueue.reserve(1024); + responseQueue.reserve(1024); } NetherCynaraBackend::~NetherCynaraBackend() { } -const bool NetherCynaraBackend::initialize() +bool NetherCynaraBackend::initialize() { - cynaraLastResult = cynara_async_initialize(&cynaraContext, NULL, &statusCallback, this); - if (cynaraLastResult != CYNARA_API_SUCCESS) - { - LOGE("Failed to initialize cynara client " << cynaraErrorCodeToString(cynaraLastResult)); - return (false); - } - - return (true); + cynaraLastResult = cynara_async_initialize(&cynaraContext, NULL, &statusCallback, this); + if(cynaraLastResult != CYNARA_API_SUCCESS) + { + LOGE("Failed to initialize cynara client " << cynaraErrorCodeToString(cynaraLastResult)); + return (false); + } + + return (true); } -void NetherCynaraBackend::statusCallback(int oldFd, int newFd, cynara_async_status status, void *data) +void NetherCynaraBackend::statusCallback(int , int newFd, cynara_async_status status, void *data) { - NetherCynaraBackend *backend = static_cast(data); + NetherCynaraBackend *backend = static_cast(data); - if (status == CYNARA_STATUS_FOR_READ) - backend->setCynaraDescriptor(newFd, NetherDescriptorStatus::readOnly); + if(status == CYNARA_STATUS_FOR_READ) + backend->setCynaraDescriptor(newFd, NetherDescriptorStatus::readOnly); - if (status == CYNARA_STATUS_FOR_RW) - backend->setCynaraDescriptor(newFd, NetherDescriptorStatus::readWrite); + if(status == CYNARA_STATUS_FOR_RW) + backend->setCynaraDescriptor(newFd, NetherDescriptorStatus::readWrite); } void NetherCynaraBackend::checkCallback(cynara_check_id check_id, - cynara_async_call_cause cause, - int response, - void *data) + cynara_async_call_cause cause, + int response, + void *data) { - NetherCynaraBackend *backend = static_cast(data); + NetherCynaraBackend *backend = static_cast(data); - if (cause == CYNARA_CALL_CAUSE_ANSWER) - backend->setCynaraVerdict (check_id, response); - else - LOGI("unknown reason for call cause="<< cause <<" response="<< response); + if(cause == CYNARA_CALL_CAUSE_ANSWER) + backend->setCynaraVerdict(check_id, response); + else + LOGI("unknown reason for call cause="<< cause <<" response="<< response); } -const bool NetherCynaraBackend::enqueueVerdict (const NetherPacket &packet) +bool NetherCynaraBackend::enqueueVerdict(const NetherPacket &packet) { - char user[NETHER_MAX_USER_LEN]; - cynara_check_id checkId; - - 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: - LOGD(cynaraErrorCodeToString(cynaraLastResult).c_str()); - return (castVerdict(packet, NetherVerdict::allow)); - - case CYNARA_API_ACCESS_DENIED: - LOGD(cynaraErrorCodeToString(cynaraLastResult).c_str()); - return (castVerdict(packet, NetherVerdict::deny)); - - case CYNARA_API_CACHE_MISS: - cynaraLastResult = cynara_async_create_request(cynaraContext, - packet.securityContext.c_str(), - "", - user, - NETHER_CYNARA_INTERNET_PRIVILEGE, - &checkId, - &checkCallback, - this); - if (cynaraLastResult == CYNARA_API_SUCCESS) - { - responseQueue[checkId] = packet.id; - - return (true); - } - else if (cynaraLastResult == CYNARA_API_SERVICE_NOT_AVAILABLE) - { - LOGW("Cynara offline, fall back to another backend"); - return (false); - } - else - { - LOGW("Error on cynara request create after CYNARA_API_CACHE_MISS " << cynaraErrorCodeToString(cynaraLastResult)); - return (false); - } - - default: - LOGW("Error on cynara request create unhandled result from cynara_async_check_cache "<= 0) - { - responseQueue[checkId] = -1; + u_int32_t packetId = 0; + if((packetId = responseQueue[checkId]) >= 0) + { + responseQueue[checkId] = -1; - if (cynaraResult == CYNARA_API_ACCESS_ALLOWED) - castVerdict (packetId, NetherVerdict::allow); - else - castVerdict (packetId, NetherVerdict::deny); + if(cynaraResult == CYNARA_API_ACCESS_ALLOWED) + castVerdict(packetId, NetherVerdict::allow); + else + castVerdict(packetId, NetherVerdict::deny); - return; - } + return; + } - LOGW("checkId=" << checkId << " has no assosiated packetId"); + LOGW("checkId=" << checkId << " has no assosiated packetId"); } -const bool NetherCynaraBackend::isValid() +int NetherCynaraBackend::getDescriptor() { - return ((cynaraLastResult == CYNARA_API_SUCCESS ? true : false) && cynaraContext); + return (currentCynaraDescriptor); } -const int NetherCynaraBackend::getDescriptor() +NetherDescriptorStatus NetherCynaraBackend::getDescriptorStatus() { - return (currentCynaraDescriptor); -} - -const NetherDescriptorStatus NetherCynaraBackend::getDescriptorStatus() -{ - return (currentCynaraDescriptorStatus); + return (currentCynaraDescriptorStatus); } void NetherCynaraBackend::setCynaraDescriptor(const int _currentCynaraDescriptor, const NetherDescriptorStatus _currentCynaraDescriptorStatus) { - currentCynaraDescriptorStatus = _currentCynaraDescriptorStatus; - currentCynaraDescriptor = _currentCynaraDescriptor; + currentCynaraDescriptorStatus = _currentCynaraDescriptorStatus; + currentCynaraDescriptor = _currentCynaraDescriptor; } -const bool NetherCynaraBackend::processEvents() +bool NetherCynaraBackend::processEvents() { - int ret = cynara_async_process(cynaraContext); + int ret = cynara_async_process(cynaraContext); - if (ret == CYNARA_API_SUCCESS) - return (true); + if(ret == CYNARA_API_SUCCESS) + return (true); - LOGW("cynara_async_process failed " << cynaraErrorCodeToString(ret)); - return (false); + LOGW("cynara_async_process failed " << cynaraErrorCodeToString(ret)); + return (false); } #endif diff --git a/src/nether_FileBackend.cpp b/src/nether_FileBackend.cpp index 289014c..2a69733 100644 --- a/src/nether_FileBackend.cpp +++ b/src/nether_FileBackend.cpp @@ -24,8 +24,8 @@ #include "nether_FileBackend.h" -NetherFileBackend::NetherFileBackend (const NetherConfig &netherConfig) - : NetherPolicyBackend(netherConfig) +NetherFileBackend::NetherFileBackend(const NetherConfig &netherConfig) + : NetherPolicyBackend(netherConfig) { } @@ -33,93 +33,92 @@ NetherFileBackend::~NetherFileBackend() { } -const bool NetherFileBackend::isValid() +bool NetherFileBackend::initialize() { - return (true); -} - -const bool NetherFileBackend::initialize() -{ - std::ifstream policyFile; - policyFile.open (netherConfig.backupBackendArgs, std::ifstream::in); + std::ifstream policyFile; + policyFile.open(netherConfig.backupBackendArgs, std::ifstream::in); - if (!policyFile) - { - LOGE("Can't open policy file at: " << netherConfig.backupBackendArgs); - return (false); - } + if(!policyFile) + { + LOGE("Can't open policy file at: " << netherConfig.backupBackendArgs); + return (false); + } - return (parsePolicyFile(policyFile)); + return (parsePolicyFile(policyFile)); } -const bool NetherFileBackend::reload() +bool NetherFileBackend::reload() { - return (initialize()); + return (initialize()); } -const bool NetherFileBackend::enqueueVerdict(const NetherPacket &packet) +bool NetherFileBackend::enqueueVerdict(const NetherPacket &packet) { - for (auto &policyIterator : policy) - { - if ( - ( (policyIterator.uid == packet.uid) || policyIterator.uid == NETHER_INVALID_UID ) && - ( (policyIterator.gid == packet.gid) || policyIterator.gid == NETHER_INVALID_GID ) && - ( (policyIterator.securityContext == packet.securityContext) || policyIterator.securityContext.empty() ) - ) - { - LOGD("policy match " << dumpPolicyEntry(policyIterator)); - return (castVerdict(packet, policyIterator.verdict)); - } - } - - return (castVerdict(packet, netherConfig.defaultVerdict)); + for(auto &policyIterator : policy) + { + if( + ((policyIterator.uid == packet.uid) || policyIterator.uid == NETHER_INVALID_UID) && + ((policyIterator.gid == packet.gid) || policyIterator.gid == NETHER_INVALID_GID) && + ((policyIterator.securityContext == packet.securityContext) || policyIterator.securityContext.empty()) + ) + { + LOGD("policy match " << dumpPolicyEntry(policyIterator)); + return (castVerdict(packet, policyIterator.verdict)); + } + } + + return (castVerdict(packet, netherConfig.defaultVerdict)); } -const bool NetherFileBackend::parsePolicyFile(std::ifstream &policyFile) +bool NetherFileBackend::parsePolicyFile(std::ifstream &policyFile) { - std::string line; - std::vector tokens; - policy.clear(); - - while (!policyFile.eof()) - { - getline(policyFile, line); - if (line[0] == '#' || line.empty() || !line.find(NETHER_POLICY_CREDS_DELIM, 0)) - continue; - - tokens = split (line, NETHER_POLICY_CREDS_DELIM); - - if (tokens.size() > 0) - { - PolicyEntry entry { tokens[uidT].empty() ? NETHER_INVALID_UID : (uid_t)strtol(tokens[uidT].c_str(), NULL, 10), /* uid */ - tokens[gidT].empty() ? NETHER_INVALID_GID : (gid_t)strtol(tokens[gidT].c_str(), NULL, 10), /* gid */ - tokens[secctxT], /* security context */ - stringToVerdict((char *)tokens[verdictT].c_str()) /* verdict */ - }; - - LOGD("\t"< tokens; + policy.clear(); + + while(!policyFile.eof()) + { + getline(policyFile, line); + if(line[0] == '#' || line.empty() || !line.find(NETHER_POLICY_CREDS_DELIM, 0)) + continue; + + tokens = split(line, NETHER_POLICY_CREDS_DELIM); + + if(tokens.size() > 0) + { + PolicyEntry entry { tokens[PolicyFileTokens::uidToken].empty() ? + NETHER_INVALID_UID : + (uid_t)strtol(tokens[PolicyFileTokens::uidToken].c_str(), NULL, 10), + tokens[PolicyFileTokens::gidToken].empty() ? + NETHER_INVALID_GID : + (gid_t)strtol(tokens[PolicyFileTokens::gidToken].c_str(), NULL, 10), + tokens[PolicyFileTokens::secctxToken], + stringToVerdict((char *)tokens[PolicyFileTokens::verdictToken].c_str()) + }; + + LOGD("\t"< NetherFileBackend::split(const std::string &str, const std::string &delim) { - std::vector tokens; - size_t start = 0, end = 0; + std::vector tokens; + size_t start = 0, end = 0; - while (end != std::string::npos) - { - end = str.find(delim, start); + while(end != std::string::npos) + { + end = str.find(delim, start); - // If at end, use length=maxLength. Else use length=end-start. - tokens.push_back(str.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); + // If at end, use length=maxLength. Else use length=end-start. + tokens.push_back(str.substr(start, (end == std::string::npos) ? std::string::npos : end - start)); - // If at end, use start=maxSize. Else use start=end+delimiter. - start = ((end > (std::string::npos - delim.size())) ? std::string::npos : end + delim.size()); - } + // If at end, use start=maxSize. Else use start=end+delimiter. + start = ((end > (std::string::npos - delim.size())) ? std::string::npos : end + delim.size()); + } - return (tokens); + return (tokens); } diff --git a/src/nether_Main.cpp b/src/nether_Main.cpp index 8914a20..d5883e9 100644 --- a/src/nether_Main.cpp +++ b/src/nether_Main.cpp @@ -32,218 +32,218 @@ void showHelp(char *arg); int main(int argc, char *argv[]) { - int optionIndex, c; - struct NetherConfig netherConfig; + int optionIndex, c; + struct NetherConfig netherConfig; - static struct option longOptions[] = - { - #if defined(HAVE_AUDIT) - {"enable-audit", no_argument, &netherConfig.enableAudit, 0}, + static struct option longOptions[] = + { +#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, ":daxl:L:V:p:P:b:B:q:m:M:a:r:i:h", longOptions, &optionIndex); - - if (c == -1) - break; - - switch (c) - { - case 0: - break; - - case 'd': - netherConfig.daemonMode = 1; - break; - case 'x': - netherConfig.noRules = 1; - break; - - #if defined(HAVE_AUDIT) - case 'a': - netherConfig.enableAudit = 1; - break; + {"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, ":daxl:L:V:p:P:b:B:q:m:M:a:r:i:h", longOptions, &optionIndex); + + if(c == -1) + break; + + switch(c) + { + case 0: + break; + + 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; - - case 'L': - netherConfig.logBackendArgs = optarg; - break; - - case 'V': - netherConfig.defaultVerdict = stringToVerdict (optarg); - break; - - case 'p': - netherConfig.primaryBackendType = stringToBackendType (optarg); - break; - - case 'P': - netherConfig.primaryBackendArgs = optarg; - break; - - case 'b': - netherConfig.backupBackendType = stringToBackendType (optarg); - break; - - case 'B': - netherConfig.backupBackendArgs = optarg; - break; - - case 'q': - if (atoi(optarg) < 0 || atoi(optarg) >= 65535) - { - cerr << "Queue number is invalid (must be >= 0 and < 65535): " << atoi(optarg); - exit (1); - } - netherConfig.queueNumber = atoi(optarg); - break; - - case 'm': - if (atoi(optarg) <= 0 || atoi(optarg) >= 255) - { - cerr << "Packet mark for DENY is invalid (must be > 0 and < 255): " << atoi(optarg); - exit (1); - } - netherConfig.markDeny = atoi(optarg); - break; - - case 'M': - if (atoi(optarg) <= 0 || atoi(optarg) >= 255) - { - cerr << "Packet mark for ALLOW_LOG is invalid (must be > 0 and < 255): " << atoi(optarg); - exit (1); - } - netherConfig.markAllowAndLog = atoi(optarg); - break; - - case 'r': - netherConfig.rulesPath = optarg; - break; - - case 'i': - netherConfig.iptablesRestorePath = optarg; - break; - - case 'h': - showHelp (argv[0]); - exit (1); - } - } - switch (netherConfig.logBackend) - { - case NetherLogBackendType::stderrBackend: - logger::Logger::setLogBackend (new logger::StderrBackend(false)); - break; - case NetherLogBackendType::syslogBackend: - logger::Logger::setLogBackend (new logger::SyslogBackend()); - break; - case NetherLogBackendType::logfileBackend: - logger::Logger::setLogBackend (new logger::FileBackend(netherConfig.logBackendArgs)); - break; + case 'l': + netherConfig.logBackend = stringToLogBackendType(optarg); + break; + + case 'L': + netherConfig.logBackendArgs = optarg; + break; + + case 'V': + netherConfig.defaultVerdict = stringToVerdict(optarg); + break; + + case 'p': + netherConfig.primaryBackendType = stringToBackendType(optarg); + break; + + case 'P': + netherConfig.primaryBackendArgs = optarg; + break; + + case 'b': + netherConfig.backupBackendType = stringToBackendType(optarg); + break; + + case 'B': + netherConfig.backupBackendArgs = optarg; + break; + + case 'q': + if(atoi(optarg) < 0 || atoi(optarg) >= 65535) + { + cerr << "Queue number is invalid (must be >= 0 and < 65535): " << atoi(optarg); + exit(1); + } + netherConfig.queueNumber = atoi(optarg); + break; + + case 'm': + if(atoi(optarg) <= 0 || atoi(optarg) >= 255) + { + cerr << "Packet mark for DENY is invalid (must be > 0 and < 255): " << atoi(optarg); + exit(1); + } + netherConfig.markDeny = atoi(optarg); + break; + + case 'M': + if(atoi(optarg) <= 0 || atoi(optarg) >= 255) + { + cerr << "Packet mark for ALLOW_LOG is invalid (must be > 0 and < 255): " << atoi(optarg); + exit(1); + } + netherConfig.markAllowAndLog = atoi(optarg); + break; + + case 'r': + netherConfig.rulesPath = optarg; + break; + + case 'i': + netherConfig.iptablesRestorePath = optarg; + break; + + case 'h': + showHelp(argv[0]); + exit(1); + } + } + switch(netherConfig.logBackend) + { + case NetherLogBackendType::stderrBackend: + logger::Logger::setLogBackend(new logger::StderrBackend(false)); + break; + case NetherLogBackendType::syslogBackend: + logger::Logger::setLogBackend(new logger::SyslogBackend()); + break; + case NetherLogBackendType::logfileBackend: + logger::Logger::setLogBackend(new logger::FileBackend(netherConfig.logBackendArgs)); + break; #if defined(HAVE_SYSTEMD_JOURNAL) - case NetherLogBackendType::journalBackend: - logger::Logger::setLogBackend (new logger::SystemdJournalBackend()); - break; + case NetherLogBackendType::journalBackend: + logger::Logger::setLogBackend(new logger::SystemdJournalBackend()); + break; #endif - default: - logger::Logger::setLogBackend (new logger::StderrBackend(false)); - break; - } + default: + logger::Logger::setLogBackend(new logger::StderrBackend(false)); + break; + } - LOGD("NETHER OPTIONS:" + LOGD("NETHER OPTIONS:" #if defined(_DEBUG) - << " debug" + << " debug" #endif - << " daemon=" << netherConfig.daemonMode - << " queue=" << netherConfig.queueNumber); - LOGD("primary-backend=" << backendTypeToString (netherConfig.primaryBackendType) - << " primary-backend-args=" << netherConfig.primaryBackendArgs); - LOGD("backup-backend=" << backendTypeToString (netherConfig.backupBackendType) - << " backup-backend-args=" << netherConfig.backupBackendArgs); - LOGD("default-verdict=" << verdictToString(netherConfig.defaultVerdict) - << " mark-deny=" << (int)netherConfig.markDeny - << " 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); - - if (!manager.initialize()) - { - LOGE("NetherManager failed to initialize, exiting"); - return (1); - } - - if (netherConfig.daemonMode) - { - if (!runAsDaemon()) - { - LOGE("Failed to run as daemon: " << strerror(errno)); - exit (1); - } - } - - manager.process(); - - return (0); + << " daemon=" << netherConfig.daemonMode + << " queue=" << netherConfig.queueNumber); + LOGD("primary-backend=" << backendTypeToString(netherConfig.primaryBackendType) + << " primary-backend-args=" << netherConfig.primaryBackendArgs); + LOGD("backup-backend=" << backendTypeToString(netherConfig.backupBackendType) + << " backup-backend-args=" << netherConfig.backupBackendArgs); + LOGD("default-verdict=" << verdictToString(netherConfig.defaultVerdict) + << " mark-deny=" << (int)netherConfig.markDeny + << " 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); + + if(!manager.initialize()) + { + LOGE("NetherManager failed to initialize, exiting"); + return (1); + } + + if(netherConfig.daemonMode) + { + if(!runAsDaemon()) + { + LOGE("Failed to run as daemon: " << strerror(errno)); + exit(1); + } + } + + manager.process(); + + return (0); } void showHelp(char *arg) { - cout<< "Usage:\t"<< arg << " [OPTIONS]\n\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=\t\t\tSet logging backend STDERR,SYSLOG"; + cout<< "Usage:\t"<< arg << " [OPTIONS]\n\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=\t\t\tSet logging backend STDERR,SYSLOG"; #if defined(HAVE_SYSTEMD_JOURNAL) - cout << ",JOURNAL\n"; + cout << ",JOURNAL\n"; #endif - cout<< "(default:"<< logBackendTypeToString(NETHER_LOG_BACKEND) << ")\n"; - cout<< " -L,--log-args=\t\tSet logging backend arguments\n"; - cout<< " -V,--verdict=\t\tWhat verdict to cast when policy backend is not available\n\t\t\t\t\tACCEPT,ALLOW_LOG,DENY (default:"<\t\tPrimary policy backend\n\t\t\t\t\t"; + cout<< "(default:"<< logBackendTypeToString(NETHER_LOG_BACKEND) << ")\n"; + cout<< " -L,--log-args=\t\tSet logging backend arguments\n"; + cout<< " -V,--verdict=\t\tWhat verdict to cast when policy backend is not available\n\t\t\t\t\tACCEPT,ALLOW_LOG,DENY (default:"<\t\tPrimary policy backend\n\t\t\t\t\t"; #if defined(HAVE_CYNARA) - cout << "CYNARA"; + cout << "CYNARA"; #endif - cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_PRIMARY_BACKEND)<<")\n"; - cout<< " -P,--primary-backend-args=\tPrimary policy backend arguments\n"; - cout<< " -b,--backup-backend=\t\tBackup policy backend\n\t\t\t\t\t"; + cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_PRIMARY_BACKEND)<<")\n"; + cout<< " -P,--primary-backend-args=\tPrimary policy backend arguments\n"; + cout<< " -b,--backup-backend=\t\tBackup policy backend\n\t\t\t\t\t"; #if defined(HAVE_CYNARA) - cout<< "CYNARA"; + cout<< "CYNARA"; #endif - cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_BACKUP_BACKEND)<< ")\n"; - cout<< " -B,--backup-backend-args=\tBackup policy backend arguments (default:" << NETHER_POLICY_FILE << ")\n"; - cout<< " -q,--queue-num=\t\tNFQUEUE queue number to use for receiving packets\n"; - cout<< " -m,--mark-deny=\t\t\tPacket mark to use for DENY verdicts (default:"<< NETLINK_DROP_MARK << ")\n"; - cout<< " -M,--mark-allow-log=\t\tPacket mark to use for ALLOW_LOG verdicts (default:" << NETLINK_ALLOWLOG_MARK << ")\n"; + cout<< ",FILE,NONE (defualt:"<< backendTypeToString(NETHER_BACKUP_BACKEND)<< ")\n"; + cout<< " -B,--backup-backend-args=\tBackup policy backend arguments (default:" << NETHER_POLICY_FILE << ")\n"; + cout<< " -q,--queue-num=\t\tNFQUEUE queue number to use for receiving packets\n"; + cout<< " -m,--mark-deny=\t\t\tPacket mark to use for DENY verdicts (default:"<< NETLINK_DROP_MARK << ")\n"; + cout<< " -M,--mark-allow-log=\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"; + cout<< " -a,--enable-audit\t\t\tEnable the auditing subsystem (default: no)\n"; #endif - cout<< " -r,--rules-path=\t\tPath to iptables rules file (default:" << NETHER_RULES_PATH << ")\n"; - cout<< " -i,--iptables-restore-path=\tPath to iptables-restore command (default:" << NETHER_IPTABLES_RESTORE_PATH << ")\n"; - cout<< " -h,--help\t\t\t\tshow help information\n"; + cout<< " -r,--rules-path=\t\tPath to iptables rules file (default:" << NETHER_RULES_PATH << ")\n"; + cout<< " -i,--iptables-restore-path=\tPath to iptables-restore command (default:" << NETHER_IPTABLES_RESTORE_PATH << ")\n"; + cout<< " -h,--help\t\t\t\tshow help information\n"; } diff --git a/src/nether_Manager.cpp b/src/nether_Manager.cpp index 581296a..21f5d25 100644 --- a/src/nether_Manager.cpp +++ b/src/nether_Manager.cpp @@ -28,329 +28,333 @@ #include "nether_DummyBackend.h" NetherManager::NetherManager(const NetherConfig &_netherConfig) - : netherConfig(_netherConfig), - netherPrimaryPolicyBackend(nullptr), - netherBackupPolicyBackend(nullptr), - netherFallbackPolicyBackend(nullptr) + : netherPrimaryPolicyBackend(nullptr), + netherBackupPolicyBackend(nullptr), + netherFallbackPolicyBackend(nullptr), + netherConfig(_netherConfig) { - netherNetlink = std::unique_ptr (new NetherNetlink(netherConfig)); - netherNetlink->setListener (this); + netherNetlink = std::unique_ptr (new NetherNetlink(netherConfig)); + netherNetlink->setListener(this); - netherPrimaryPolicyBackend = std::unique_ptr (getPolicyBackend (netherConfig)); - netherPrimaryPolicyBackend->setListener (this); + netherPrimaryPolicyBackend = std::unique_ptr (getPolicyBackend(netherConfig)); + netherPrimaryPolicyBackend->setListener(this); - netherBackupPolicyBackend = std::unique_ptr (getPolicyBackend (netherConfig, false)); - netherBackupPolicyBackend->setListener (this); + netherBackupPolicyBackend = std::unique_ptr (getPolicyBackend(netherConfig, false)); + netherBackupPolicyBackend->setListener(this); - netherFallbackPolicyBackend = std::unique_ptr (new NetherDummyBackend(netherConfig)); + netherFallbackPolicyBackend = std::unique_ptr (new NetherDummyBackend(netherConfig)); } NetherManager::~NetherManager() { - close (signalDescriptor); + close(signalDescriptor); } -const bool NetherManager::initialize() +bool NetherManager::initialize() { - sigemptyset(&signalMask); - sigaddset(&signalMask, SIGHUP); - - if (sigprocmask(SIG_BLOCK, &signalMask, NULL) == -1) - { - LOGE("Failed to block signals sigprocmask()"); - return (false); - } - - signalDescriptor = signalfd(-1, &signalMask, 0); - if (signalDescriptor == -1) - { - LOGE("Failed acquire signalfd descriptor"); - return (false); - } - - if (netherConfig.noRules == 0 && restoreRules() == false) - { - LOGE("Failed to setup iptables rules"); - return (false); - } + sigemptyset(&signalMask); + sigaddset(&signalMask, SIGHUP); + + if(sigprocmask(SIG_BLOCK, &signalMask, NULL) == -1) + { + LOGE("Failed to block signals sigprocmask()"); + return (false); + } + + signalDescriptor = signalfd(-1, &signalMask, 0); + if(signalDescriptor == -1) + { + LOGE("Failed acquire signalfd descriptor"); + 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"); - } - } + 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"); - return (false); - } - - if (!netherPrimaryPolicyBackend->initialize()) - { - LOGE("Failed to initialize primary policy backend, exiting"); - return (false); - } - - if (!netherBackupPolicyBackend->initialize()) - { - LOGE("Failed to initialize backup backend, exiting"); - return (false); - } - - if ((netlinkDescriptor = netherNetlink->getDescriptor()) == -1) - { - LOGE("Netlink subsystem did not return a valid descriptor, exiting"); - return (false); - } - - if ((backendDescriptor = netherPrimaryPolicyBackend->getDescriptor()) == -1) - { - LOGI("Policy backend does not provide descriptor for select()"); - } - return (true); + if(!netherNetlink->initialize()) + { + LOGE("Failed to initialize netlink subsystem, exiting"); + return (false); + } + + if(!netherPrimaryPolicyBackend->initialize()) + { + LOGE("Failed to initialize primary policy backend, exiting"); + return (false); + } + + if(!netherBackupPolicyBackend->initialize()) + { + LOGE("Failed to initialize backup backend, exiting"); + return (false); + } + + if((netlinkDescriptor = netherNetlink->getDescriptor()) == -1) + { + LOGE("Netlink subsystem did not return a valid descriptor, exiting"); + return (false); + } + + if((backendDescriptor = netherPrimaryPolicyBackend->getDescriptor()) == -1) + { + LOGI("Policy backend does not provide descriptor for select()"); + } + return (true); } -const bool NetherManager::process() -{ - fd_set watchedReadDescriptorsSet, watchedWriteDescriptorsSet; - struct timeval timeoutSpecification; - - for (;;) - { - setupSelectSockets (watchedReadDescriptorsSet, watchedWriteDescriptorsSet, timeoutSpecification); - - if (select (FD_SETSIZE, &watchedReadDescriptorsSet, &watchedWriteDescriptorsSet, NULL, &timeoutSpecification) < 0) - { - LOGE("select error " << strerror(errno)); - return (false); - } - - if (FD_ISSET(signalDescriptor, &watchedReadDescriptorsSet)) - { - handleSignal(); - } - if (FD_ISSET(netlinkDescriptor, &watchedReadDescriptorsSet)) - { - if (!handleNetlinkpacket()) - break; - } - else if (FD_ISSET(backendDescriptor, &watchedReadDescriptorsSet) || FD_ISSET(backendDescriptor, &watchedWriteDescriptorsSet)) - { - netherPrimaryPolicyBackend->processEvents(); - } - else - { - LOGD("select() timeout"); - } - } +bool NetherManager::process() +{ + fd_set watchedReadDescriptorsSet, watchedWriteDescriptorsSet; + struct timeval timeoutSpecification; + + for(;;) + { + setupSelectSockets(watchedReadDescriptorsSet, watchedWriteDescriptorsSet, timeoutSpecification); + + if(select(FD_SETSIZE, &watchedReadDescriptorsSet, &watchedWriteDescriptorsSet, NULL, &timeoutSpecification) < 0) + { + LOGE("select error " << strerror(errno)); + return (false); + } + + if(FD_ISSET(signalDescriptor, &watchedReadDescriptorsSet)) + { + handleSignal(); + } + if(FD_ISSET(netlinkDescriptor, &watchedReadDescriptorsSet)) + { + if(!handleNetlinkpacket()) + break; + } + else + if(FD_ISSET(backendDescriptor, &watchedReadDescriptorsSet) || FD_ISSET(backendDescriptor, &watchedWriteDescriptorsSet)) + { + netherPrimaryPolicyBackend->processEvents(); + } + else + { + LOGD("select() timeout"); + } + } + + return (true); } void NetherManager::handleSignal() { - LOGD("received signal"); - ssize_t signalRead; - struct signalfd_siginfo signalfdSignalInfo; - - signalRead = read (signalDescriptor, &signalfdSignalInfo, sizeof(struct signalfd_siginfo)); - - if (signalRead != sizeof(struct signalfd_siginfo)) - { - LOGW("Received incomplete signal information, ignore"); - return; - } - - if (signalfdSignalInfo.ssi_signo == SIGHUP) - { - LOGI("SIGHUP received, reloading"); - if (!netherPrimaryPolicyBackend->reload()) - LOGW("primary backend failed to reload"); - if (!netherBackupPolicyBackend->reload()) - LOGW("backup backend failed to reload"); - if (!netherNetlink->reload()) - LOGW("netlink failed to reload"); - } + LOGD("received signal"); + ssize_t signalRead; + struct signalfd_siginfo signalfdSignalInfo; + + signalRead = read(signalDescriptor, &signalfdSignalInfo, sizeof(struct signalfd_siginfo)); + + if(signalRead != sizeof(struct signalfd_siginfo)) + { + LOGW("Received incomplete signal information, ignore"); + return; + } + + if(signalfdSignalInfo.ssi_signo == SIGHUP) + { + LOGI("SIGHUP received, reloading"); + if(!netherPrimaryPolicyBackend->reload()) + LOGW("primary backend failed to reload"); + if(!netherBackupPolicyBackend->reload()) + LOGW("backup backend failed to reload"); + if(!netherNetlink->reload()) + LOGW("netlink failed to reload"); + } } -const bool NetherManager::handleNetlinkpacket() +bool NetherManager::handleNetlinkpacket() { - LOGD("netlink descriptor active"); - int packetReadSize; - NetherPacket receivedPacket; - char packetBuffer[NETHER_PACKET_BUFFER_SIZE] __attribute__ ((aligned)); - - /* some data arrives on netlink, read it */ - if ((packetReadSize = recv(netlinkDescriptor, packetBuffer, sizeof(packetBuffer), 0)) >= 0) - { - /* try to process the packet using netfilter_queue library, fetch packet info - needed for making a decision about it */ - if (netherNetlink->processPacket (packetBuffer, packetReadSize)) - { - return (true); - } - else - { - /* if we can't process the incoming packets, it's bad. Let's exit now */ - LOGE("Failed to process netlink received packet, refusing to continue"); - return (false); - } - } - - if (packetReadSize < 0 && errno == ENOBUFS) - { - LOGI("NetherManager::process losing packets! [bad things might happen]"); - return (true); - } - - LOGE("NetherManager::process recv failed " << strerror(errno)); - return (false); + LOGD("netlink descriptor active"); + int packetReadSize; + NetherPacket receivedPacket; + char packetBuffer[NETHER_PACKET_BUFFER_SIZE] __attribute__((aligned)); + + /* some data arrives on netlink, read it */ + if((packetReadSize = recv(netlinkDescriptor, packetBuffer, sizeof(packetBuffer), 0)) >= 0) + { + /* try to process the packet using netfilter_queue library, fetch packet info + needed for making a decision about it */ + if(netherNetlink->processPacket(packetBuffer, packetReadSize)) + { + return (true); + } + else + { + /* if we can't process the incoming packets, it's bad. Let's exit now */ + LOGE("Failed to process netlink received packet, refusing to continue"); + return (false); + } + } + + if(packetReadSize < 0 && errno == ENOBUFS) + { + LOGI("NetherManager::process losing packets! [bad things might happen]"); + return (true); + } + + LOGE("NetherManager::process recv failed " << strerror(errno)); + return (false); } void NetherManager::setupSelectSockets(fd_set &watchedReadDescriptorsSet, fd_set &watchedWriteDescriptorsSet, struct timeval &timeoutSpecification) { - FD_ZERO (&watchedReadDescriptorsSet); - FD_ZERO (&watchedWriteDescriptorsSet); - - /* Always listen for signals */ - FD_SET (signalDescriptor, &watchedReadDescriptorsSet); - - if ((netlinkDescriptor = netherNetlink->getDescriptor()) >= 0) - { - FD_SET(netlinkDescriptor, &watchedReadDescriptorsSet); - } - - if ((backendDescriptor = netherPrimaryPolicyBackend->getDescriptor()) >= 0) - { - if (netherPrimaryPolicyBackend->getDescriptorStatus() == NetherDescriptorStatus::readOnly) - { - FD_SET(backendDescriptor, &watchedReadDescriptorsSet); - } - else if (netherPrimaryPolicyBackend->getDescriptorStatus() == NetherDescriptorStatus::readWrite) - { - FD_SET(backendDescriptor, &watchedReadDescriptorsSet); - FD_SET(backendDescriptor, &watchedWriteDescriptorsSet); - } - } - - timeoutSpecification.tv_sec = 240; - timeoutSpecification.tv_usec = 0; + FD_ZERO(&watchedReadDescriptorsSet); + FD_ZERO(&watchedWriteDescriptorsSet); + + /* Always listen for signals */ + FD_SET(signalDescriptor, &watchedReadDescriptorsSet); + + if((netlinkDescriptor = netherNetlink->getDescriptor()) >= 0) + { + FD_SET(netlinkDescriptor, &watchedReadDescriptorsSet); + } + + if((backendDescriptor = netherPrimaryPolicyBackend->getDescriptor()) >= 0) + { + if(netherPrimaryPolicyBackend->getDescriptorStatus() == NetherDescriptorStatus::readOnly) + { + FD_SET(backendDescriptor, &watchedReadDescriptorsSet); + } + else + if(netherPrimaryPolicyBackend->getDescriptorStatus() == NetherDescriptorStatus::readWrite) + { + FD_SET(backendDescriptor, &watchedReadDescriptorsSet); + FD_SET(backendDescriptor, &watchedWriteDescriptorsSet); + } + } + + timeoutSpecification.tv_sec = 240; + timeoutSpecification.tv_usec = 0; } NetherConfig &NetherManager::getConfig() { - return (netherConfig); + return (netherConfig); } NetherPolicyBackend *NetherManager::getPolicyBackend(const NetherConfig &netherConfig, const bool primary) { - switch (primary ? netherConfig.primaryBackendType : netherConfig.backupBackendType) - { - case NetherPolicyBackendType::cynaraBackend: + switch(primary ? netherConfig.primaryBackendType : netherConfig.backupBackendType) + { + case NetherPolicyBackendType::cynaraBackend: #ifdef HAVE_CYNARA - return new NetherCynaraBackend(netherConfig); + return new NetherCynaraBackend(netherConfig); #else - return new NetherDummyBackend(netherConfig); + return new NetherDummyBackend(netherConfig); #endif - case NetherPolicyBackendType::fileBackend: - return new NetherFileBackend(netherConfig); - case NetherPolicyBackendType::dummyBackend: - default: - return new NetherDummyBackend(netherConfig); - } + case NetherPolicyBackendType::fileBackend: + return new NetherFileBackend(netherConfig); + case NetherPolicyBackendType::dummyBackend: + default: + return new NetherDummyBackend(netherConfig); + } } -bool NetherManager::verdictCast (const u_int32_t packetId, const NetherVerdict verdict) +bool NetherManager::verdictCast(const u_int32_t packetId, const NetherVerdict verdict) { - if (netherNetlink) - { - netherNetlink->setVerdict(packetId, verdict); - } - else - { - LOGE("Netlink subsystem is invalid, can't decide on packet"); - return (false); - } - - return (true); + if(netherNetlink) + { + netherNetlink->setVerdict(packetId, verdict); + } + else + { + LOGE("Netlink subsystem is invalid, can't decide on packet"); + return (false); + } + + return (true); } -void NetherManager::packetReceived (const NetherPacket &packet) +void NetherManager::packetReceived(const NetherPacket &packet) { - LOGD(packetToString(packet).c_str()); - - if (netherPrimaryPolicyBackend && netherPrimaryPolicyBackend->enqueueVerdict (packet)) - { - LOGD("Primary policy accepted packet"); - return; - } - - if (netherBackupPolicyBackend && netherBackupPolicyBackend->enqueueVerdict (packet)) - { - LOGI("Primary policy backend failed, using backup policy backend"); - return; - } - - /* In this situation no policy backend wants to deal with this packet - there propably isn't any rule in either of them - - we need to make a generic decision based on whatever is hard-coded - or passed as a parameter to the service */ - LOGW("All policy backends failed, using DUMMY backend"); - netherFallbackPolicyBackend->enqueueVerdict (packet); + LOGD(packetToString(packet).c_str()); + + if(netherPrimaryPolicyBackend && netherPrimaryPolicyBackend->enqueueVerdict(packet)) + { + LOGD("Primary policy accepted packet"); + return; + } + + if(netherBackupPolicyBackend && netherBackupPolicyBackend->enqueueVerdict(packet)) + { + LOGI("Primary policy backend failed, using backup policy backend"); + return; + } + + /* In this situation no policy backend wants to deal with this packet + there propably isn't any rule in either of them + + we need to make a generic decision based on whatever is hard-coded + or passed as a parameter to the service */ + LOGW("All policy backends failed, using DUMMY backend"); + netherFallbackPolicyBackend->enqueueVerdict(packet); } -const bool NetherManager::restoreRules() +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); + 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) +bool NetherManager::isCommandAvailable(const std::string &command) { - struct stat iptablesRestoreStat; + 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); - } + 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); - } + return (true); + } - LOGE("Failed to stat command at: " << command << " error: " << strerror(errno)); - return (false); + LOGE("Failed to stat command at: " << command << " error: " << strerror(errno)); + return (false); } diff --git a/src/nether_Netlink.cpp b/src/nether_Netlink.cpp index 1b98bfa..c0a9994 100644 --- a/src/nether_Netlink.cpp +++ b/src/nether_Netlink.cpp @@ -22,155 +22,149 @@ * @brief netlink handler class for nether */ -#include "nether_Netlink.h" - -NetherNetlink::NetherNetlink(NetherConfig &netherConfig) - : nfqHandle(nullptr), queueHandle(nullptr), nlif(nullptr), - queue(netherConfig.queueNumber), - NetherPacketProcessor(netherConfig) -{ -} - -NetherNetlink::~NetherNetlink() +#include "nether_Netlink.h" + +NetherNetlink::NetherNetlink(NetherConfig &netherConfig) + : NetherPacketProcessor(netherConfig), queueHandle(nullptr), nfqHandle(nullptr), nlif(nullptr), queue(netherConfig.queueNumber) +{ +} + +NetherNetlink::~NetherNetlink() { - if (queueHandle) nfq_destroy_queue(queueHandle); - if (nfqHandle) nfq_close(nfqHandle); -} - -const bool NetherNetlink::initialize() -{ - nfqHandle = nfq_open(); - - if (!nfqHandle) - { - LOGE("Error during nfq_open()"); - return (false); - } - - if (nfq_unbind_pf(nfqHandle, AF_INET) < 0) - { - LOGE("Error during nfq_unbind_pf() (no permission?)"); - return (false); - } - - if (nfq_bind_pf(nfqHandle, AF_INET) < 0) - { - LOGE("Error during nfq_bind_pf()"); - return (false); - } - - queueHandle = nfq_create_queue(nfqHandle, queue, &callback, this); - - if (!queueHandle) - { - LOGE("Error during nfq_create_queue()"); - return (false); - } - - if (nfq_set_queue_flags(queueHandle, NFQA_CFG_F_SECCTX, NFQA_CFG_F_SECCTX)) - LOGI("This kernel version does not allow to retrieve security context"); - - if (nfq_set_mode(queueHandle, NFQNL_COPY_PACKET, 0xffff) < 0) - { - LOGE("Can't set packet_copy mode"); - nfq_destroy_queue (queueHandle); - return (false); - } - - if (nfq_set_queue_flags(queueHandle, NFQA_CFG_F_UID_GID, NFQA_CFG_F_UID_GID)) - { - LOGE("This kernel version does not allow to retrieve process UID/GID"); - nfq_destroy_queue (queueHandle); - return (false); - } - - nlif = nlif_open(); - if (!nlif) - LOGI("Failed to initialize NLIF subsystem, interface information won't be available"); - - return (true); -} + if(queueHandle) nfq_destroy_queue(queueHandle); + if(nfqHandle) nfq_close(nfqHandle); +} + +bool NetherNetlink::initialize() +{ + nfqHandle = nfq_open(); + + if(!nfqHandle) + { + LOGE("Error during nfq_open()"); + return (false); + } + + if(nfq_unbind_pf(nfqHandle, AF_INET) < 0) + { + LOGE("Error during nfq_unbind_pf() (no permission?)"); + return (false); + } + + if(nfq_bind_pf(nfqHandle, AF_INET) < 0) + { + LOGE("Error during nfq_bind_pf()"); + return (false); + } + + queueHandle = nfq_create_queue(nfqHandle, queue, &callback, this); + + if(!queueHandle) + { + LOGE("Error during nfq_create_queue()"); + return (false); + } + + if(nfq_set_queue_flags(queueHandle, NFQA_CFG_F_SECCTX, NFQA_CFG_F_SECCTX)) + LOGI("This kernel version does not allow to retrieve security context"); + + if(nfq_set_mode(queueHandle, NFQNL_COPY_META, 0xffff) < 0) + { + LOGE("Can't set packet_copy mode"); + nfq_destroy_queue(queueHandle); + return (false); + } + + if(nfq_set_queue_flags(queueHandle, NFQA_CFG_F_UID_GID, NFQA_CFG_F_UID_GID)) + { + LOGE("This kernel version does not allow to retrieve process UID/GID"); + nfq_destroy_queue(queueHandle); + return (false); + } + + nlif = nlif_open(); + if(!nlif) + LOGI("Failed to initialize NLIF subsystem, interface information won't be available"); + + return (true); +} int NetherNetlink::getDescriptor() { - if (nfqHandle) - return (nfq_fd(nfqHandle)); - else - LOGE("nfq not initialized"); + if(nfqHandle) + return (nfq_fd(nfqHandle)); + else + LOGE("nfq not initialized"); + return (-1); } -const bool NetherNetlink::processPacket (char *packetBuffer, const int packetReadSize) +bool NetherNetlink::processPacket(char *packetBuffer, const int packetReadSize) { - if (nfq_handle_packet (nfqHandle, packetBuffer, packetReadSize)) - { - LOGE("nfq_handle_packet failed"); - return (false); - } + if(nfq_handle_packet(nfqHandle, packetBuffer, packetReadSize)) + { + LOGE("nfq_handle_packet failed"); + return (false); + } - return (true); + return (true); } - -int NetherNetlink::callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) + +int NetherNetlink::callback(struct nfq_q_handle *, struct nfgenmsg *, struct nfq_data *nfa, void *data) { - NetherNetlink *me = static_cast(data); - NetherPacket packet; - unsigned char *secctx; - int secctxSize = 0; - struct nfqnl_msg_packet_hdr *ph; - unsigned char *payload; - - if ((ph = nfq_get_msg_packet_hdr(nfa))) - { - packet.id = ntohl(ph->packet_id); - } - else - { - LOGI("Failed to get packet id"); - return (1); - } - - if (nfq_get_uid(nfa, &packet.uid) == 0) - LOGW("Failed to get uid for packet id=" << packet.id); - - nfq_get_gid(nfa, &packet.gid); - - secctxSize = nfq_get_secctx(nfa, &secctx); - - if (secctxSize > 0) - packet.securityContext = std::string ((char *)secctx, secctxSize); - else - LOGD("Failed to get security context for packet id=" << packet.id); - - if (nfq_get_payload(nfa, &payload) > 0) - decodePacket(packet, payload); - - me->processNetherPacket (packet); /* this call if from the NetherPacketProcessor class */ - - return (0); -} - -const bool NetherNetlink::isValid() -{ - return (nfqHandle && queueHandle); + NetherNetlink *me = static_cast(data); + NetherPacket packet; + unsigned char *secctx; + int secctxSize = 0; + struct nfqnl_msg_packet_hdr *ph; + unsigned char *payload; + + if((ph = nfq_get_msg_packet_hdr(nfa))) + { + packet.id = ntohl(ph->packet_id); + } + else + { + LOGI("Failed to get packet id"); + return (1); + } + + if(nfq_get_uid(nfa, &packet.uid) == 0) + LOGW("Failed to get uid for packet id=" << packet.id); + + nfq_get_gid(nfa, &packet.gid); + + secctxSize = nfq_get_secctx(nfa, &secctx); + + if(secctxSize > 0) + packet.securityContext = std::string((char *)secctx, secctxSize); + else + LOGD("Failed to get security context for packet id=" << packet.id); + + if(nfq_get_payload(nfa, &payload) > 0) + decodePacket(packet, payload); + + me->processNetherPacket(packet); /* this call if from the NetherPacketProcessor class */ + + return (0); } void NetherNetlink::setVerdict(const u_int32_t packetId, const NetherVerdict verdict) { - int ret = 0; - LOGD("id=" << packetId << " verdict=" << verdictToString(verdict)); - - if (verdict == NetherVerdict::allow) - ret = nfq_set_verdict (queueHandle, packetId, NF_ACCEPT, 0, NULL); - if (verdict == NetherVerdict::deny) - ret = nfq_set_verdict2 (queueHandle, packetId, NF_ACCEPT, netherConfig.markDeny, 0, NULL); - if (verdict == NetherVerdict::allowAndLog) - ret = nfq_set_verdict2 (queueHandle, packetId, NF_ACCEPT, netherConfig.markAllowAndLog, 0, NULL); - - if (ret == -1) - LOGW("can't set verdict for packetId=" << packetId); + int ret = 0; + LOGD("id=" << packetId << " verdict=" << verdictToString(verdict)); + + if(verdict == NetherVerdict::allow) + ret = nfq_set_verdict(queueHandle, packetId, NF_ACCEPT, 0, NULL); + if(verdict == NetherVerdict::deny) + ret = nfq_set_verdict2(queueHandle, packetId, NF_ACCEPT, netherConfig.markDeny, 0, NULL); + if(verdict == NetherVerdict::allowAndLog) + ret = nfq_set_verdict2(queueHandle, packetId, NF_ACCEPT, netherConfig.markAllowAndLog, 0, NULL); + + if(ret == -1) + LOGW("can't set verdict for packetId=" << packetId); } -const bool NetherNetlink::reload() +bool NetherNetlink::reload() { - return (true); + return (true); } diff --git a/src/nether_NetworkUtils.cpp b/src/nether_NetworkUtils.cpp index 8fbe8fa..d2fe3d5 100644 --- a/src/nether_NetworkUtils.cpp +++ b/src/nether_NetworkUtils.cpp @@ -22,8 +22,6 @@ * @brief Network utility functions for nether */ -#include -#include #include "nether_Utils.h" #define IP_PROTOCOL_UDP (0x11) @@ -38,116 +36,116 @@ void decodePacket(NetherPacket &packet, unsigned char *payload) { - uint8_t ipVersion = (payload[0] >> 4) & 0x0F; - - switch(ipVersion) - { - case 4: - packet.protocolType = NetherProtocolType::IPv4; - decodeIPv4Packet(packet, payload); - break; - case 6: - packet.protocolType = NetherProtocolType::IPv6; - decodeIPv6Packet(packet, payload); - break; - default: - packet.transportType = NetherTransportType::unknownTransportType; - packet.protocolType = NetherProtocolType::unknownProtocolType; - break; - } + uint8_t ipVersion = (payload[0] >> 4) & 0x0F; + + switch(ipVersion) + { + case 4: + packet.protocolType = NetherProtocolType::IPv4; + decodeIPv4Packet(packet, payload); + break; + case 6: + packet.protocolType = NetherProtocolType::IPv6; + decodeIPv6Packet(packet, payload); + break; + default: + packet.transportType = NetherTransportType::unknownTransportType; + packet.protocolType = NetherProtocolType::unknownProtocolType; + break; + } } void decodeIPv6Packet(NetherPacket &packet, unsigned char *payload) { - const uint16_t startOfIpPayload = 40; - uint8_t nextProto; - - memcpy(packet.localAddress, &payload[8], NETHER_NETWORK_IPV6_ADDR_LEN); - memcpy(packet.remoteAddress, &payload[24], NETHER_NETWORK_IPV6_ADDR_LEN); - - nextProto = payload[6]; - - switch(nextProto) - { - case IP_PROTOCOL_UDP: - packet.transportType = NetherTransportType::UDP; - decodeUdp(packet, &payload[startOfIpPayload]); - break; - case IP_PROTOCOL_TCP: - packet.transportType = NetherTransportType::TCP; - decodeTcp(packet, &payload[startOfIpPayload]); - break; - case IP_PROTOCOL_ICMP: - packet.transportType = NetherTransportType::ICMP; - break; - case IP_PROTOCOL_IGMP: - packet.transportType = NetherTransportType::IGMP; - break; - default: - packet.transportType = NetherTransportType::unknownTransportType; - break; - } + const uint16_t startOfIpPayload = 40; + uint8_t nextProto; + + memcpy(packet.localAddress, &payload[8], NETHER_NETWORK_IPV6_ADDR_LEN); + memcpy(packet.remoteAddress, &payload[24], NETHER_NETWORK_IPV6_ADDR_LEN); + + nextProto = payload[6]; + + switch(nextProto) + { + case IPPROTO_UDP: + packet.transportType = NetherTransportType::UDP; + decodeUdp(packet, &payload[startOfIpPayload]); + break; + case IPPROTO_TCP: + packet.transportType = NetherTransportType::TCP; + decodeTcp(packet, &payload[startOfIpPayload]); + break; + case IPPROTO_ICMP: + packet.transportType = NetherTransportType::ICMP; + break; + case IPPROTO_IGMP: + packet.transportType = NetherTransportType::IGMP; + break; + default: + packet.transportType = NetherTransportType::unknownTransportType; + break; + } } void decodeIPv4Packet(NetherPacket &packet, unsigned char *payload) { - uint16_t startOfIpPayload = 0; - uint8_t nextProto; - - startOfIpPayload = (payload[0]&0x0F) << 2; - - memcpy(packet.localAddress, &payload[12], NETHER_NETWORK_IPV4_ADDR_LEN); - memcpy(packet.remoteAddress, &payload[16], NETHER_NETWORK_IPV4_ADDR_LEN); - - nextProto = payload[9]; - - switch(nextProto) - { - case IP_PROTOCOL_UDP: - packet.transportType = NetherTransportType::UDP; - decodeUdp(packet, &payload[startOfIpPayload]); - break; - case IP_PROTOCOL_TCP: - packet.transportType = NetherTransportType::TCP; - decodeTcp(packet, &payload[startOfIpPayload]); - break; - case IP_PROTOCOL_ICMP: - packet.transportType = NetherTransportType::ICMP; - break; - case IP_PROTOCOL_IGMP: - packet.transportType = NetherTransportType::IGMP; - default: - packet.transportType = NetherTransportType::unknownTransportType; - break; - } + uint16_t startOfIpPayload = 0; + uint8_t nextProto; + + startOfIpPayload = (payload[0]&0x0F) << 2; + + memcpy(packet.localAddress, &payload[12], NETHER_NETWORK_IPV4_ADDR_LEN); + memcpy(packet.remoteAddress, &payload[16], NETHER_NETWORK_IPV4_ADDR_LEN); + + nextProto = payload[9]; + + switch(nextProto) + { + case IPPROTO_UDP: + packet.transportType = NetherTransportType::UDP; + decodeUdp(packet, &payload[startOfIpPayload]); + break; + case IPPROTO_TCP: + packet.transportType = NetherTransportType::TCP; + decodeTcp(packet, &payload[startOfIpPayload]); + break; + case IPPROTO_ICMP: + packet.transportType = NetherTransportType::ICMP; + break; + case IPPROTO_IGMP: + packet.transportType = NetherTransportType::IGMP; + default: + packet.transportType = NetherTransportType::unknownTransportType; + break; + } } void decodeTcp(NetherPacket &packet, unsigned char *payload) { - packet.localPort = ntohs(*(unsigned short*) &payload[0]); - packet.remotePort = ntohs(*(unsigned short*) &payload[2]); + packet.localPort = ntohs(*(unsigned short*) &payload[0]); + packet.remotePort = ntohs(*(unsigned short*) &payload[2]); } void decodeUdp(NetherPacket &packet, unsigned char *payload) { - packet.localPort = ntohs(*(unsigned short*) &payload[0]); - packet.remotePort = ntohs(*(unsigned short*) &payload[2]); + packet.localPort = ntohs(*(unsigned short*) &payload[0]); + packet.remotePort = ntohs(*(unsigned short*) &payload[2]); } -const std::string ipAddressToString(const char *src, enum NetherProtocolType type) +std::string ipAddressToString(const char *src, enum NetherProtocolType type) { - switch(type) - { - case NetherProtocolType::IPv4: - return (stringFormat("%u.%u.%u.%u", src[0]&0xff,src[1]&0xff,src[2]&0xff,src[3]&0xff)); - case NetherProtocolType::IPv6: - return (stringFormat("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", - ntohs(*(uint16_t*) &src[0]), ntohs(*(uint16_t*) &src[2]), - ntohs(*(uint16_t*) &src[4]), ntohs(*(uint16_t*) &src[6]), - ntohs(*(uint16_t*) &src[8]), ntohs(*(uint16_t*) &src[10]), - ntohs(*(uint16_t*) &src[12]), ntohs(*(uint16_t*) &src[14]))); - default: - return ("(unknown)"); - } + switch(type) + { + case NetherProtocolType::IPv4: + return (stringFormat("%u.%u.%u.%u", src[0]&0xff,src[1]&0xff,src[2]&0xff,src[3]&0xff)); + case NetherProtocolType::IPv6: + return (stringFormat("%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", + ntohs(*(uint16_t*) &src[0]), ntohs(*(uint16_t*) &src[2]), + ntohs(*(uint16_t*) &src[4]), ntohs(*(uint16_t*) &src[6]), + ntohs(*(uint16_t*) &src[8]), ntohs(*(uint16_t*) &src[10]), + ntohs(*(uint16_t*) &src[12]), ntohs(*(uint16_t*) &src[14]))); + default: + return ("(unknown)"); + } }