Introduce logging of privilege checks (AUDIT) 77/35177/6
authorAdam Malinowski <a.malinowsk2@partner.samsung.com>
Fri, 6 Feb 2015 08:58:02 +0000 (09:58 +0100)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Mon, 23 Feb 2015 15:41:48 +0000 (07:41 -0800)
Added functionality saves privilege checking responses in systemd
journal. Such entries may be filtered using CYNARA_LOG_TYPE=AUDIT
field. Logging depends on configuration based on environment variable
CYNARA_AUDIT_LEVEL which may take one of following values:
  * NONE - nothing will be saved
  * DENY - only DENY responses will be saved (DEFAULT behaviour)
  * ALLOW - only ALLOW respones will be saved
  * OTHER - other policy types e.g. plugin specific
  * ALL - all above responses will be saved

Change-Id: Iaa46f3c579660784ffe5edc0c2120b822fb0061a

src/common/CMakeLists.txt
src/common/log/AuditLog.cpp [new file with mode: 0644]
src/common/log/AuditLog.h [new file with mode: 0644]
src/service/logic/Logic.cpp
src/service/logic/Logic.h
systemd/cynara.service

index 07167bc..be94ff8 100644 (file)
@@ -30,6 +30,7 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/containers/BinaryQueue.cpp
     ${COMMON_PATH}/error/api.cpp
     ${COMMON_PATH}/lock/FileLock.cpp
+    ${COMMON_PATH}/log/AuditLog.cpp
     ${COMMON_PATH}/log/log.cpp
     ${COMMON_PATH}/plugin/PluginManager.cpp
     ${COMMON_PATH}/protocol/ProtocolAdmin.cpp
diff --git a/src/common/log/AuditLog.cpp b/src/common/log/AuditLog.cpp
new file mode 100644 (file)
index 0000000..8ddf8f8
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/common/log/AuditLog.cpp
+ * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file implements privilege check logging utility.
+ */
+
+#include <systemd/sd-journal.h>
+
+#include "AuditLog.h"
+
+namespace Cynara {
+
+AuditLog::AuditLog() : m_logLevel(AL_DENY) {
+    init();
+}
+
+void AuditLog::init(void) {
+    char *env_val = getenv("CYNARA_AUDIT_LEVEL");
+    if (env_val) {
+        m_logLevel = stringToLevel(env_val);
+    }
+}
+
+AuditLog::AuditLevel AuditLog::stringToLevel(const std::string &name) {
+    if (name == "NONE")
+        return AL_NONE;
+
+    if (name == "DENY")
+        return AL_DENY;
+
+    if (name == "ALLOW")
+        return AL_ALLOW;
+
+    if (name == "OTHER")
+        return AL_OTHER;
+
+    if (name == "ALL")
+        return AL_ALL;
+
+    return AL_NONE;
+}
+
+const char *AuditLog::policyResultToString(const PolicyResult &policyResult) {
+    if (policyResult.policyType() == PredefinedPolicyType::DENY)
+        return "DENY";
+
+    if (policyResult.policyType() == PredefinedPolicyType::ALLOW)
+        return "ALLOW";
+
+    return "OTHER";
+}
+
+void AuditLog::log(const PolicyKey &policyKey, const PolicyResult &policyResult) {
+    if (m_logLevel == AL_NONE)
+        return;
+
+    PolicyType policyType = policyResult.policyType();
+    namespace PPT = PredefinedPolicyType;
+
+    if (m_logLevel == AL_ALL || (m_logLevel == AL_DENY && policyType == PPT::DENY) ||
+        (m_logLevel == AL_ALLOW && policyType == PPT::ALLOW) ||
+        (m_logLevel == AL_OTHER && policyType != PPT::ALLOW && policyType != PPT::DENY)) {
+            sd_journal_send("MESSAGE=%s;%s;%s => %s", policyKey.client().toString().c_str(),
+                            policyKey.user().toString().c_str(),
+                            policyKey.privilege().toString().c_str(),
+                            policyResultToString(policyResult), "PRIORITY=%i", LOG_INFO,
+                            "CYNARA_LOG_TYPE=AUDIT", NULL);
+    }
+}
+
+} /* namespace Cynara */
diff --git a/src/common/log/AuditLog.h b/src/common/log/AuditLog.h
new file mode 100644 (file)
index 0000000..996739d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/common/log/AuditLog.h
+ * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
+ * @version     1.0
+ * @brief       This file defines privilege check logging utility.
+ */
+
+#ifndef SRC_COMMON_LOG_AUDITLOG_H
+#define SRC_COMMON_LOG_AUDITLOG_H
+
+#include <string>
+
+#include <types/Policy.h>
+
+namespace Cynara {
+
+class AuditLog {
+public:
+    AuditLog();
+
+    void log(const PolicyKey &policyKey, const PolicyResult &policyResult);
+
+private:
+    typedef enum {
+        AL_NONE,
+        AL_DENY,
+        AL_ALLOW,
+        AL_OTHER,
+        AL_ALL
+    } AuditLevel;
+
+    int m_logLevel;
+
+    void init(void);
+    static AuditLevel stringToLevel(const std::string &name);
+    static const char *policyResultToString(const PolicyResult &policyResult);
+};
+
+#endif /* SRC_COMMON_LOG_AUDITLOG_H */
+
+} // namespace Cynara
index e92808e..6a1bece 100644 (file)
@@ -169,6 +169,7 @@ void Logic::execute(RequestContextPtr context, CancelRequestPtr request) {
 void Logic::execute(RequestContextPtr context, CheckRequestPtr request) {
     PolicyResult result(PredefinedPolicyType::DENY);
     if (check(context, request->key(), request->sequenceNumber(), result)) {
+        m_auditLog.log(request->key(), result);
         context->returnResponse(context, std::make_shared<CheckResponse>(result,
                                 request->sequenceNumber()));
     }
@@ -272,6 +273,7 @@ bool Logic::update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId,
     }
 
     if (answerReady && context->responseQueue()) {
+        m_auditLog.log(key, result);
         context->returnResponse(context, std::make_shared<CheckResponse>(result, checkId));
         return true;
     }
@@ -422,6 +424,7 @@ void Logic::execute(RequestContextPtr context, SimpleCheckRequestPtr request) {
         }
     }
     }
+    m_auditLog.log(request->key(), result);
     context->returnResponse(context, std::make_shared<SimpleCheckResponse>(retValue, result,
                                                                   request->sequenceNumber()));
 }
@@ -476,6 +479,7 @@ void Logic::handleAgentTalkerDisconnection(const AgentTalkerPtr &agentTalkerPtr)
 
     if (!checkContextPtr->cancelled() && checkContextPtr->m_requestContext->responseQueue()) {
         PolicyResult result(PredefinedPolicyType::DENY);
+        m_auditLog.log(checkContextPtr->m_key, result);
         checkContextPtr->m_requestContext->returnResponse(checkContextPtr->m_requestContext,
                 std::make_shared<CheckResponse>(result, checkContextPtr->m_checkId));
     }
index 444f734..2a4ff8a 100644 (file)
@@ -27,6 +27,7 @@
 #include <map>
 #include <vector>
 
+#include <log/AuditLog.h>
 #include <types/Policy.h>
 #include <types/PolicyBucketId.h>
 #include <types/PolicyKey.h>
@@ -93,6 +94,7 @@ private:
     PluginManagerPtr m_pluginManager;
     StoragePtr m_storage;
     SocketManagerPtr m_socketManager;
+    AuditLog m_auditLog;
 
     bool check(const RequestContextPtr &context, const PolicyKey &key,
                ProtocolFrameSequenceNumber checkId, PolicyResult &result);
index 99176fa..4d09d5d 100644 (file)
@@ -20,6 +20,7 @@ Group=cynara
 NoNewPrivileges=true
 
 #Environment="CYNARA_LOG_LEVEL=LOG_DEBUG"
+#Environment="CYNARA_AUDIT_LEVEL=ALL"
 
 [Install]
 WantedBy=multi-user.target