<label name="security-server::api-get-gid" />
<label name="security-server::api-password-check" />
<label name="security-server::api-password-set" />
+ <label name="security-server::audit-files" />
</provide>
</define>
<request>
<domain name="_" />
</request>
+ <assign>
+ <filesystem path="/etc/security/security-server-audit.conf" label="security-server::audit-files" />
+ </assign>
</manifest>
mkdir -p %{buildroot}/usr/share/license
cp LICENSE %{buildroot}/usr/share/license/%{name}
cp LICENSE %{buildroot}/usr/share/license/libsecurity-server-client
+mkdir -p %{buildroot}/etc/security/
+cp security-server-audit.conf %{buildroot}/etc/security/
%make_install
mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-check.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-cookie-check-tmp.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-check-tmp.socket
+%attr(-,root,root) /etc/security/security-server-audit.conf
%{_datadir}/license/%{name}
${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp
${COMMON_PATH}/dpl/log/src/log.cpp
${COMMON_PATH}/dpl/log/src/old_style_log_provider.cpp
+ ${COMMON_PATH}/dpl/log/src/audit-smack-log.cpp
${COMMON_PATH}/dpl/core/src/assert.cpp
${COMMON_PATH}/dpl/core/src/binary_queue.cpp
${COMMON_PATH}/dpl/core/src/colors.cpp
const char *fileName,
int line,
const char *function) = 0;
+ virtual void SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
protected:
static const char *LocateSourceFileName(const char *filename);
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file audit-smack-log.h
+ * @author Marek Smolinski (m.smolinski@samsung.com)
+ * @version 1.0
+ * @brief AuditSmackLog loging SMACK access deny sequentially into files
+ */
+
+#ifndef _AUDIT_SMACK_LOG_
+#define _AUDIT_SMACK_LOG_
+
+#include <dpl/log/abstract_log_provider.h>
+
+#include <map>
+#include <fstream>
+#include <mutex>
+#include <memory>
+#include <functional>
+
+namespace SecurityServer {
+namespace Log {
+
+class AuditSmackLog :
+ public AbstractLogProvider
+{
+public:
+ AuditSmackLog();
+ virtual ~AuditSmackLog();
+
+ bool Fail() const;
+
+ virtual void Debug(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Info(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Warning(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Error(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Pedantic(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void SecureDebug(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void SecureInfo(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void SecureWarning(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void SecureError(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+
+ virtual void SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+
+private:
+ void HandleWrite(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+
+ int CreateLogFile();
+ int RemoveOldestLogFile();
+ int ParseConfig();
+ int ProcessLogDir();
+ bool IsFileFull(std::ofstream &fs) const;
+
+ bool m_state;
+ unsigned int m_filesCount;
+ unsigned int m_fileMaxBytesSize;
+
+ std::map<time_t, std::string> m_fileNameMap;
+ std::ofstream m_outputStream;
+
+ std::mutex m_writeMtx;
+};
+
+} // namespace Log
+} // namespace SecurityServer
+#endif // _AUDIT_SMACK_LOG_
const char *fileName,
int line,
const char *function);
+ virtual void SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
// Set global Tag according to DLOG
void SetTag(const char *tag);
};
-}
+
+} // namespace Log
} // namespace SecurityServer
#endif // SECURITYSERVER_DLOG_LOG_PROVIDER_H
const char *function);
/**
+ * Log SS_SMACK into files
+ */
+ void SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+
+ /**
* Set default's DLOG provider Tag
*/
void SetTag(const char *tag);
#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error)
#define LogSecureError(message) DPL_MACRO_FOR_LOGGING(message, SecureError)
+#define LogSmackAudit(message) DPL_MACRO_FOR_LOGGING(message, SmackAudit)
+
#ifdef BUILD_TYPE_DEBUG
#define LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug)
#define LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info)
const char *fileName,
int line,
const char *function);
+ virtual void SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
};
}
} // namespace SecurityServer
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file audit-smack-log.cpp
+ * @author Marek Smolinski (m.smolinski@samsung.com)
+ * @version 1.0
+ * @brief AuditSmackLog loging SMACK access deny sequentially into files
+ */
+
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <cstring>
+#include <mutex>
+
+#include <dirent.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <cassert>
+
+#include <sys/smack.h>
+#include <sys/stat.h>
+
+#include <dpl/log/audit-smack-log.h>
+#include <dpl/log/log.h>
+
+#define UNUSED __attribute__((unused))
+
+namespace {
+
+const std::string AUDIT_CONFIG_LOG_PATH = "/etc/security/";
+const std::string AUDIT_CONFIG_FILENAME = "security-server-audit.conf";
+const std::string AUDIT_LOG_DIRECTORY = "/var/log/audit/";
+const std::string AUDIT_LOG_FILENAME_PREFIX = "audit-smack";
+const std::string AUDIT_LOG_SMACK_LABEL = "security-server::audit-files";
+
+} // namespace anonymous
+
+namespace SecurityServer {
+namespace Log {
+
+AuditSmackLog::AuditSmackLog()
+ : m_state(true), m_filesCount(0), m_fileMaxBytesSize(0)
+{
+ if (ParseConfig() != 0) {
+ goto error;
+ }
+
+ if (ProcessLogDir() != 0) {
+ goto error;
+ }
+
+ if (m_state) {
+
+ // reduce existing files count in log dir if config file was changed
+ while (m_fileNameMap.size() > m_filesCount) {
+ if (RemoveOldestLogFile() != 0) {
+ goto error;
+ }
+ }
+
+ if (m_fileNameMap.size() == 0) {
+ if (CreateLogFile() != 0) {
+ goto error;
+ }
+ } else {
+ std::string filename(AUDIT_LOG_DIRECTORY);
+ filename += m_fileNameMap.rbegin()->second;
+ m_outputStream.open(filename, std::ios_base::app);
+ }
+ }
+
+ return;
+
+error:
+ m_state = false;
+
+}
+
+AuditSmackLog::~AuditSmackLog(){}
+
+bool AuditSmackLog::Fail() const
+{
+ return !m_state;
+}
+
+void AuditSmackLog::SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function)
+{
+ if (m_state) {
+ HandleWrite(message, fileName, line, function);
+ }
+}
+
+void AuditSmackLog::HandleWrite(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ std::lock_guard<std::mutex> lock(m_writeMtx);
+ if (IsFileFull(m_outputStream)) {
+ if (CreateLogFile() != 0) {
+ m_state = false;
+ return;
+ }
+
+ if (m_fileNameMap.size() > m_filesCount) {
+ if (RemoveOldestLogFile() != 0) {
+ m_state = false;
+ return;
+ }
+ }
+ }
+
+ m_outputStream << std::string("[") <<
+ LocateSourceFileName(filename) << std::string(":") << line <<
+ std::string("] ") << function << std::string("(): ") << message << '\n';
+}
+
+int AuditSmackLog::CreateLogFile()
+{
+ time_t sec = time(NULL);
+ std::string fname(AUDIT_LOG_FILENAME_PREFIX);
+ std::string pathname(AUDIT_LOG_DIRECTORY);
+
+ fname += std::to_string(sec);
+ fname += ".log";
+ pathname += fname;
+
+ if (m_outputStream.is_open())
+ m_outputStream.close();
+
+ m_outputStream.open(pathname.c_str());
+
+ if (!m_outputStream) {
+ return -1;
+ }
+
+ if (smack_setlabel(pathname.c_str(),
+ AUDIT_LOG_SMACK_LABEL.c_str(),
+ SMACK_LABEL_ACCESS) != 0) {
+ return -1;
+ }
+
+ m_fileNameMap.insert(std::make_pair(sec, fname));
+ return 0;
+}
+
+int AuditSmackLog::RemoveOldestLogFile()
+{
+ assert(m_fileNameMap.size() > 0);
+
+ auto it = m_fileNameMap.begin();
+ std::string filename(AUDIT_LOG_DIRECTORY);
+ filename += it->second;
+
+ if (unlink(filename.c_str()) == 0) {
+ m_fileNameMap.erase(it);
+ return 0;
+ }
+
+ return -1;
+}
+
+int AuditSmackLog::ParseConfig()
+{
+ struct stat sb;
+ if (stat(AUDIT_CONFIG_LOG_PATH.c_str(), &sb) != 0) {
+ return -1;
+ }
+
+ std::ifstream in(AUDIT_CONFIG_LOG_PATH + AUDIT_CONFIG_FILENAME,
+ std::ios_base::in);
+ if (!in) {
+ return -1;
+ }
+
+ in >> m_filesCount >> m_fileMaxBytesSize;
+
+ if (in.fail()) {
+ return -1;
+ }
+
+ return (m_filesCount > 0 && m_fileMaxBytesSize > 0) ? 0 : -1;
+}
+
+int AuditSmackLog::ProcessLogDir()
+{
+ DIR *dir;
+ dirent *dp;
+
+ if ((dir = opendir(AUDIT_LOG_DIRECTORY.c_str())) == NULL) {
+ return -1;
+ }
+
+ while ((dp = readdir(dir)) != NULL) {
+ if (AUDIT_LOG_FILENAME_PREFIX.compare(0, std::string::npos,
+ dp->d_name,
+ AUDIT_LOG_FILENAME_PREFIX.size()) == 0) {
+ errno = 0;
+ char *pEnd;
+ time_t fUnxTime = static_cast<time_t>(
+ strtoull(dp->d_name + AUDIT_LOG_FILENAME_PREFIX.size(),
+ &pEnd, 10));
+
+ if (errno != 0) {
+ closedir(dir);
+ return -1;
+ }
+
+ m_fileNameMap.insert(
+ std::make_pair(fUnxTime, std::string(dp->d_name)));
+ }
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+bool AuditSmackLog::IsFileFull(std::ofstream &fs) const
+{
+ return fs.tellp() > m_fileMaxBytesSize;
+}
+
+void AuditSmackLog::Debug(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::Info(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::Warning(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::Error(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::Pedantic(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::SecureDebug(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::SecureInfo(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::SecureWarning(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+void AuditSmackLog::SecureError(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
+}
+
+} // namespace Log
+} // namespace SecurityServer
FormatMessage(message, filename, line, function).c_str());
}
+void DLOGLogProvider::SmackAudit(const char *message UNUSED,
+ const char *filename UNUSED,
+ int line UNUSED,
+ const char *function UNUSED)
+{
}
+
+} // nemespace Log
} // namespace SecurityServer
#include <dpl/singleton_impl.h>
#include <dpl/log/dlog_log_provider.h>
#include <dpl/log/old_style_log_provider.h>
+#include <dpl/log/audit-smack-log.h>
IMPLEMENT_SINGLETON(SecurityServer::Log::LogSystem)
#else // BUILD_TYPE_DEBUG
AddProvider(new DLOGLogProvider());
#endif // BUILD_TYPE_DEBUG
+
+ AuditSmackLog * smackLog = new AuditSmackLog();
+ if (smackLog->Fail()) {
+ delete smackLog;
+ } else {
+ AddProvider(smackLog);
+ }
}
LogSystem::~LogSystem()
(*iterator)->SecureWarning(message, filename, line, function);
}
}
+
+void LogSystem::SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->SmackAudit(message, fileName, line, function);
+ }
+}
+
}
} // namespace SecurityServer
#endif
}
+void OldStyleLogProvider::SmackAudit(const char *message,
+ const char *fileName,
+ int line,
+ const char *function)
+{
+ (void)message;
+ (void)fileName;
+ (void)line;
+ (void)function;
+}
+
}
} // namespace SecurityServer
// echoService->Create();
// manager.RegisterSocketService(echoService);
-
SecurityServer::CookieService *cookieService = new SecurityServer::CookieService;
cookieService->Create();
manager.RegisterSocketService(cookieService);
Serialization::Serialize(send, (int)SECURITY_SERVER_API_SUCCESS);
} else {
subject = searchResult->smackLabel;
+ int retval;
- if (smack_have_access(subject.c_str(), object.c_str(), access.c_str()) == 1)
+ if ((retval = smack_have_access(subject.c_str(), object.c_str(), access.c_str())) == 1)
Serialization::Serialize(send, (int)SECURITY_SERVER_API_SUCCESS);
- else
+ else {
Serialization::Serialize(send, (int)SECURITY_SERVER_API_ERROR_ACCESS_DENIED);
+ LogSmackAudit("SS_SMACK: "
+ << " subject=" << subject
+ << ", object=" << object
+ << ", access=" << access
+ << ", result=" << retval);
+ }
}
} else {
Serialization::Serialize(send, (int)SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
LogDebug("SMACK is not available. Subject label has not been read.");
retval = 1;
}
-
// char *path = read_exe_path_from_proc(pid);
//
// if (retval > 0)
// if (path != NULL)
// free(path);
+
if (retval == 1) //there is permission
retCode = SECURITY_SERVER_API_SUCCESS;
else //there is no permission
MessageBuffer sendBuffer;
Serialization::Serialize(sendBuffer, retCode);
m_serviceManager->Write(conn, sendBuffer.Pop());
+
+ if (retval != 1) {
+ char *path = read_exe_path_from_proc(pid);
+
+ LogSmackAudit("SS_SMACK: "
+ << "caller_pid=" << pid
+ << ", subject=" << subject
+ << ", object=" << object
+ << ", access=" << access_rights
+ << ", result=" << retval
+ << ", caller_path=" << (path ? path : ""));
+
+ free(path);
+ }
+
return true;
}