From: yeji01.kim Date: Thu, 26 Apr 2018 00:28:51 +0000 (+0900) Subject: Add audit-trail rule verification tool X-Git-Tag: submit/tizen/20180515.013128~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dba0f0c40d618885c971acebf3fa2599301f177e;p=platform%2Fcore%2Fsecurity%2Faudit-trail.git Add audit-trail rule verification tool Change-Id: Ic637e71f53629273fd440afcdd6a78dccfd89995 Signed-off-by: yeji01.kim --- diff --git a/packaging/audit-trail.spec b/packaging/audit-trail.spec index 5e0f677..80c6a03 100755 --- a/packaging/audit-trail.spec +++ b/packaging/audit-trail.spec @@ -144,3 +144,5 @@ The audit-trail-tests package contains the testcases needed to test audit functi %defattr(644,root,root,755) %attr(700,root,root) %{_sbindir}/audit-trail-send-test %attr(700,root,root) %{_sbindir}/audit-trail-speed-test +%attr(700,root,root) %{_sbindir}/audit-trail-rules-test +%{audit_base_dir}/test_module.ko \ No newline at end of file diff --git a/tools/tests/CMakeLists.txt b/tools/tests/CMakeLists.txt index 004797f..d442f6a 100644 --- a/tools/tests/CMakeLists.txt +++ b/tools/tests/CMakeLists.txt @@ -16,12 +16,25 @@ FILE(GLOB SEND_SRCS send.cpp) FILE(GLOB SPEED_SRCS speed.cpp) +SET(RULES_SRCS rule_verification.cpp + groups/group.cpp + groups/audit.cpp + groups/file.cpp + groups/mac.cpp + groups/ipc.cpp + groups/system.cpp + groups/time.cpp + groups/account.cpp + groups/network.cpp +) SET(SEND_NAME ${PROJECT_NAME}-send-test) SET(SPEED_NAME ${PROJECT_NAME}-speed-test) +SET(RULES_NAME ${PROJECT_NAME}-rules-test) ADD_EXECUTABLE(${SEND_NAME} ${SEND_SRCS}) ADD_EXECUTABLE(${SPEED_NAME} ${SPEED_SRCS}) +ADD_EXECUTABLE(${RULES_NAME} ${RULES_SRCS}) SET_TARGET_PROPERTIES(${SEND_NAME} PROPERTIES PREFIX "" @@ -38,8 +51,10 @@ PKG_CHECK_MODULES(CLI_DEPS REQUIRED glib-2.0 ) -INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${AUDIT_TRAIL_LIB}) +INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${AUDIT_TRAIL_LIB} groups) TARGET_LINK_LIBRARIES(${SPEED_NAME} ${CLI_DEPS_LIBRARIES} ${PROJECT_NAME} audit-trail) INSTALL(TARGETS ${SEND_NAME} DESTINATION sbin) INSTALL(TARGETS ${SPEED_NAME} DESTINATION sbin) +INSTALL(TARGETS ${RULES_NAME} DESTINATION sbin) +INSTALL(FILES data/test_module.ko DESTINATION ${DATA_INSTALL_DIR}) diff --git a/tools/tests/data/test_module.ko b/tools/tests/data/test_module.ko new file mode 100644 index 0000000..5c846f9 Binary files /dev/null and b/tools/tests/data/test_module.ko differ diff --git a/tools/tests/groups/account.cpp b/tools/tests/groups/account.cpp new file mode 100644 index 0000000..ce0f834 --- /dev/null +++ b/tools/tests/groups/account.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include +#include + +#include "group.h" + +class AccountGroup : public AbstractGroup { +public: + AccountGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "Account group test start"); + loginAccounts(); + createDestroyAccounts(); + useSetuid(); + } + + virtual ~AccountGroup() + { + } + + void loginAccounts() { + std::vector testfiles; + + testfiles.emplace_back("/var/run/utmp"); + testfiles.emplace_back("/var/log/btmp"); + testfiles.emplace_back("/var/log/wtmp"); + + for (auto entry : testfiles) { + struct stat st; + std::string logStr(entry + " change"); + lstat(entry.c_str(), &st); + chmod(entry.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, logStr); + } + } + + void createDestroyAccounts() { + std::vector commands; + + commands.emplace_back("groupadd audit-test -g 7777"); + commands.emplace_back("groupdel audit-test"); + + for (auto entry : commands) { + if (system(entry.c_str()) == -1) { + Display::printError(); + Display::printResult(Display::FAIL, entry); + } else { + Display::printResult(Display::SUCCESS, entry); + } + } + } + + void useSetuid() { + int ret; + //setuid(23) system call positive + { + uid_t originUid = getuid(); + + if (setuid(originUid) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "setuid(23) positive"); + } + + //setresuid(164) system call positive + { + uid_t ruid, euid, suid; + + if (getresuid(&ruid, &euid, &suid) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + + if (setresuid(ruid, euid, suid) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "setresuid(164) positive"); + } + } +}; + +GroupBuilder accountGroup("Account"); diff --git a/tools/tests/groups/audit.cpp b/tools/tests/groups/audit.cpp new file mode 100644 index 0000000..3210cdc --- /dev/null +++ b/tools/tests/groups/audit.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include + +#include "group.h" + +class AuditGroup : public AbstractGroup { +public: + AuditGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "Audit group test start"); + accessAuditSocketFile(); + } + + virtual ~AuditGroup() + { + } + + void accessAuditSocketFile() { + int fd = -1; + std::string auditSocketPath("/tmp/.audit-trail.sock"); + fd = open(auditSocketPath.c_str(), O_RDWR); + if (fd > 0) + close(fd); + + Display::printResult(Display::SUCCESS, "accessAuditSocketFile"); + } +}; + +GroupBuilder auditGroup("Audit"); diff --git a/tools/tests/groups/file.cpp b/tools/tests/groups/file.cpp new file mode 100644 index 0000000..492e9f7 --- /dev/null +++ b/tools/tests/groups/file.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "group.h" + +class FileGroup : public AbstractGroup { +public: + FileGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "File group test start"); + accessFiles(); + destroyFile(); + createLink(); + changeFileConfDAC(); + changeFileConfMAC(); + } + + virtual ~FileGroup() + { + } + + void accessFiles() { + int fd, ret; + std::string fileName("/tmp/audit-test"); + + //open(5) system call positive + { + if ((fd = open(fileName.c_str(), O_CREAT|O_RDONLY, 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + close(fd); + ret = Display::SUCCESS; + } + Display::printResult(ret, "open(5) positive"); + } + + //openat(322) system call positive + { + int pathFd; + if ((pathFd = open("/tmp", O_PATH)) < 0) { + ret = Display::FAIL; + Display::printError(); + goto openat_result; + } + + if ((fd = openat(pathFd, "audit-test", O_CREAT|O_RDONLY, 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + close(fd); + ret = Display::SUCCESS; + } + close(pathFd); + + openat_result: + Display::printResult(ret, "openat(322) positive"); + } + + //creat(8) system call positive + { + if ((fd = creat(fileName.c_str(), 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + close(fd); + ret = Display::SUCCESS; + } + Display::printResult(ret, "creat(8) positive"); + } + + //open_by_handle_at(371) system call positive + { + struct file_handle *handle = NULL; + int mntId; + int mountFd = -1; + + handle = (struct file_handle *)malloc(sizeof(struct file_handle)); + if (handle == NULL) { + ret = Display::FAIL; + Display::printError(); + goto open_by_handle_at_result; + } + + handle->handle_bytes = 0; + if (name_to_handle_at(AT_FDCWD, fileName.c_str(), handle, &mntId, 0) != -1 || errno != EOVERFLOW) { + ret = Display::FAIL; + Display::printError(); + goto open_by_handle_at_result; + } + + handle = (struct file_handle *)realloc(handle, (sizeof(struct file_handle) + handle->handle_bytes)); + if (handle == NULL) { + ret = Display::FAIL; + Display::printError(); + goto open_by_handle_at_result; + } + + if (name_to_handle_at(AT_FDCWD, fileName.c_str(), handle, &mntId, 0) == -1) { + ret = Display::FAIL; + Display::printError(); + goto open_by_handle_at_result; + } + if ((mountFd = open("/tmp", O_RDONLY)) < 0) { + ret = Display::FAIL; + Display::printError(); + goto open_by_handle_at_result; + } + + if ((fd = open_by_handle_at(mountFd, handle, O_RDONLY)) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + close(fd); + } + + open_by_handle_at_result: + if (handle) + free(handle); + if (mountFd > 0) + close(mountFd); + Display::printResult(ret, "open_by_handle_at(371) positive"); + } + + //truncate(92) system call positive + { + if (truncate(fileName.c_str(), 10) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "truncate(92) positive"); + } + + //ftruncate(93) system call positive + { + if ((fd = open(fileName.c_str(), O_WRONLY, 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + goto ftruncate_result; + } + + if (ftruncate(fd, 20) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + close(fd); + + ftruncate_result: + Display::printResult(ret, "ftruncate(93) positive"); + } + + //fallocate(352) system call positive + { + if ((fd = open(fileName.c_str(), O_WRONLY, 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + goto fallocate_result; + } + + if (fallocate(fd, 0, 0, 30) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + close(fd); + + fallocate_result: + Display::printResult(ret, "fallocate(352) positive"); + } + + //restore + { + struct stat st; + if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) { + Display::printError(); + Display::printResult(Display::FAIL, "accessFile restore"); + } + } + } + + void destroyFile() { + //prepare + std::string fileName("/tmp/audit-test"); + int ret; + int fd = creat(fileName.c_str(), 0644); + if (fd < 0) { + Display::printResult(Display::FAIL, "destroyFile prepare"); + return; + } + close(fd); + + //rename(38), renameat(329) system call positive + { + std::string newName("/tmp/audit-test2"); + if (rename(fileName.c_str(), newName.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "rename(38) positive"); + + if (renameat(AT_FDCWD, newName.c_str(), AT_FDCWD, fileName.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "renameat(329) positive"); + } + + //unlink(10) system call positive + { + if (unlink(fileName.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + fd = -1; + } + Display::printResult(ret, "unlink(10) positive"); + } + + //unlinkat(328) system call positive + { + if (fd < 0) { + if ((fd = creat(fileName.c_str(), 0644)) < 0) { + ret = Display::FAIL; + Display::printError(); + goto unlinkat_result; + } + close(fd); + } + + if (unlinkat(AT_FDCWD, fileName.c_str(), 0) < 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + unlinkat_result: + Display::printResult(ret, "unlinkat(328) positive"); + } + + //restore + { + struct stat st; + if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) { + Display::printError(); + Display::printResult(Display::FAIL, "destroyFile restore"); + } + } + } + void createLink() { + // prepare + std::string fileName("/tmp/audit-test"); + int ret; + int fd = creat(fileName.c_str(), 0644); + if (fd < 0) { + Display::printError(); + Display::printResult(Display::FAIL, "destroyFile prepare"); + return; + } + + //link(9) system call positive + { + std::string newPath("/tmp/audit-test-link"); + if (link(fileName.c_str(), newPath.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "link(9) positive"); + + if (unlink(newPath.c_str()) != 0) + Display::printResult(Display::FAIL, "link positive restore"); + } + + //linkat(330) system call positive + { + std::string newPath("/tmp/audit-test-linkat"); + if (linkat(AT_FDCWD, fileName.c_str(), AT_FDCWD, newPath.c_str(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "linkat(330) positive"); + + if (unlink(newPath.c_str()) != 0) + Display::printResult(Display::FAIL, "linkat positive restore"); + } + + //symlink(83) system call positive + { + std::string linkPath("/tmp/audit-test-symlink"); + if (symlink(fileName.c_str(), linkPath.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "symlink(83) positive"); + + if (unlink(linkPath.c_str()) != 0) + Display::printResult(Display::FAIL, "symlink positive restore"); + } + + //symlinkat(331) system call positive + { + std::string linkPath("/tmp/audit-test-symlinkat"); + if (symlinkat(fileName.c_str(), AT_FDCWD, linkPath.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "symlinkat(331) positive"); + + if (unlink(linkPath.c_str()) != 0) + Display::printResult(Display::FAIL, "symlinkat positive restore"); + } + + //mknod(14) system call positive + { + std::string pathName("/tmp/audit-test-mknod"); + if (mknod(pathName.c_str(), 0664 | S_IFREG, 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "mknod(14) positive"); + + if (unlink(pathName.c_str()) != 0) + Display::printResult(Display::FAIL, "mknod positive restore"); + } + + //mknodat(324) system call positive + { + std::string pathName("/tmp/audit-test-mknodat"); + if (mknodat(AT_FDCWD, pathName.c_str(), 0644|S_IFREG, 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "mknodat(324) positive"); + + if (unlink(pathName.c_str()) != 0) + Display::printResult(Display::FAIL, "mknodat positive restore"); + } + + //restore + { + struct stat st; + if (fd > 0) + close(fd); + if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) { + Display::printError(); + Display::printResult(Display::FAIL, "createLink restore"); + } + } + } + + void modifyDirectories() { + std::string mkdirPath("/tmp/audit-test-mkdir"); + std::string mkdiratPath("/tmp/audit-test-mkdirat"); + int ret; + + //mkdir(39) system call positive + { + if (mkdir(mkdirPath.c_str(), 0644) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "mkdir(39) positive"); + } + + //mkdirat(323) system call positive + { + if (mkdirat(AT_FDCWD, mkdiratPath.c_str(), 0644) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "mkdirat(323) positive"); + } + + //rmdir(40) system call positive + { + if (rmdir(mkdirPath.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + + if (rmdir(mkdiratPath.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "rmdir(40) positive"); + } + } + + void changeFileConfDAC() { + //prepare + std::string fileName("/tmp/audit-test"); + int ret; + int fd = creat(fileName.c_str(), 0644); + if (fd < 0) { + Display::printResult(Display::FAIL, "changeFileConf prepare failed"); + return; + } + close(fd); + + //chown(182) system call positive + { + if (chown(fileName.c_str(), getuid(), getgid()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "chown(182) positive"); + } + + //fchown(95) system call positive + { + int fd = -1; + fd = open(fileName.c_str(), O_RDONLY); + if (fd < 0) { + ret = Display::FAIL; + goto fchown_result; + } + + if (fchown(fd, getuid(), getgid()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + + close(fd); + fchown_result: + Display::printResult(ret, "fchown(95) positive"); + } + + //fchownat(325) system call positive + { + if (fchownat(AT_FDCWD, fileName.c_str(), getuid(), getgid(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "fchownat(325) positive"); + } + + //lchown(16) system call positive + { + if (lchown(fileName.c_str(), getuid(), getgid()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "lchown(16) positive"); + } + + //restore + { + struct stat st; + if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) { + Display::printError(); + Display::printResult(Display::FAIL, "changeFileConf restore"); + } + } + } + + void changeFileConfMAC() { + //prepare + std::string fileName("/opt/audit-test"); + std::string testsetxattr("user.testsetxattr"); + std::string testlsetxattr("user.testlsetxattr"); + std::string testfsetxattr("user.testfsetxattr"); + + int ret; + int fd = creat(fileName.c_str(), 0644); + if (fd < 0) { + Display::printResult(Display::FAIL, "changeFileConf prepare"); + return; + } + close(fd); + + //setxattr(226), removexattr(235) system call positive + { + std::string value("test setxattr"); + if (setxattr(fileName.c_str(), testsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "setxattr(226) positive"); + + if (removexattr(fileName.c_str(), testsetxattr.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "removexattr(235) positive"); + } + + //lsetxattr(227), lremovexattr(236) system call positive + { + std::string value("test lsetxattr"); + if (lsetxattr(fileName.c_str(), testlsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "lsetxattr(227) positive"); + + if (lremovexattr(fileName.c_str(), testlsetxattr.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "lremovexattr(235) positive"); + } + + //fsetxattr(228) system call positive + { + std::string value("test fsetxattr"); + int fd; + fd = open(fileName.c_str(), O_RDONLY); + if (fd < 0) { + Display::printError(); + ret = Display::FAIL; + goto fsetxattr_result; + } + if (fsetxattr(fd, testfsetxattr.c_str(), value.c_str(), value.size(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + close(fd); + fsetxattr_result: + Display::printResult(ret, "fsetxattr(228) positive"); + } + + //fremovexattr(237) system call positive + { + std::string value("test fsetxattr"); + int fd; + fd = open(fileName.c_str(), O_RDONLY); + if (fd < 0) { + Display::printError(); + ret = Display::FAIL; + goto fremovexattr_result; + } + if (fremovexattr(fd, testfsetxattr.c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + close(fd); + fremovexattr_result: + Display::printResult(ret, "fremovexattr(237) positive"); + } + + //restore + { + struct stat st; + if ((lstat(fileName.c_str(), &st) == 0) && (unlink(fileName.c_str()) != 0)) { + Display::printError(); + Display::printResult(Display::FAIL, "changeFileConfMAC restore"); + } + } + } +}; + +GroupBuilder fileGroup("File"); diff --git a/tools/tests/groups/group.cpp b/tools/tests/groups/group.cpp new file mode 100644 index 0000000..aa8bef0 --- /dev/null +++ b/tools/tests/groups/group.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include "group.h" + +std::vector managedGroup; \ No newline at end of file diff --git a/tools/tests/groups/group.h b/tools/tests/groups/group.h new file mode 100644 index 0000000..2d5ad20 --- /dev/null +++ b/tools/tests/groups/group.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#ifndef __ABSTRACT_GROUP_H__ +#define __ABSTRACT_GROUP_H__ + +#include +#include + +#include +#include +#include + +class AbstractGroup { +public: + virtual ~AbstractGroup() {} + virtual void run() = 0; +protected: + AbstractGroup(const std::string& groupName) : name(groupName) { } + +public: + std::string name; +}; + +class Display { +public: + enum Type { + NONE, + SUCCESS, + FAIL + }; + + static void printResult(int flag, const std::string& message) { + switch(flag) { + case NONE: + std::cout << "\x1B[33m" << std::setw(9) << message; + break; + case SUCCESS: + std::cout << "\x1B[32m[" << std::setw(9) << "SUCCESS] " << message; + break; + case FAIL: + std::cout << "\x1B[31m[" << std::setw(9) << "FAIL] " << message; + break; + default: + return; + } + std::cout << "\x1B[0m" << std::endl; + } + + static int returnErrorCode() { + return errno; + } + + static void printError(int errNum) { + char errmsg[256]; + std::cout << "\x1B[33m" << strerror_r(errNum, errmsg, sizeof(errmsg)) << std::endl; + } + static void printError() { + printError(returnErrorCode()); + } +}; + +extern std::vector managedGroup; + +template +class GroupBuilder { +public: + GroupBuilder(const std::string& name) { + managedGroup.emplace_back(new T(name)); + } +}; + +class GroupCleaner { +public: + static void deleteGroups() { + std::vector::iterator iter; + for (iter = managedGroup.begin(); iter != managedGroup.end(); ++iter) { + delete(*iter); + } + managedGroup.clear(); + } +}; +#endif /* __ABSTRACT_GROUP_H__ */ diff --git a/tools/tests/groups/ipc.cpp b/tools/tests/groups/ipc.cpp new file mode 100644 index 0000000..8c3882f --- /dev/null +++ b/tools/tests/groups/ipc.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "group.h" + +class IpcGroup : public AbstractGroup { +public: + IpcGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "Ipc group test start"); + useIpc(); + } + + virtual ~IpcGroup() + { + } + + void useIpc() { + //msgctl(303), msgget(304) system call positive + { + std::string msgKeyPath("/tmp/msg_key"); + int ret; + int msgKey, qid; + + if (mkdir(msgKeyPath.c_str(), 0644) != 0) { + ret = Display::FAIL; + Display::printError(); + Display::printResult(Display::FAIL, "msgget(304) positive"); + goto msgctl_result; + } + + if ((msgKey = ftok(msgKeyPath.c_str(), 'M')) == -1) { + ret = Display::FAIL; + Display::printError(); + goto msgctl_result; + } + + if ((qid = msgget(msgKey, IPC_CREAT|0666)) == -1) { + ret = Display::FAIL; + Display::printError(); + Display::printResult(Display::FAIL, "msgget(304) positive"); + goto msgctl_result; + } else { + Display::printResult(Display::SUCCESS, "msgget(304) positive"); + } + + if (msgctl(qid, IPC_RMID, NULL) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + + msgctl_result: + struct stat st; + if (lstat(msgKeyPath.c_str(), &st) == 0) + rmdir(msgKeyPath.c_str()); + Display::printResult(ret, "msgctl(303) positive"); + } + + //semctl(300), semget(299), semop(298), semtimedop(312) system call positive + { + int ret; + int semId; + struct sembuf buf; + struct timespec timeout; + + if ((semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0666)) == -1) { + ret = Display::FAIL; + Display::printError(); + Display::printResult(Display::FAIL, "semget(299) positive"); + goto semctl_result; + } else { + Display::printResult(Display::SUCCESS, "semget(299) positive"); + } + + buf.sem_num = 0; + buf.sem_op = 1; + buf.sem_flg = SEM_UNDO; + if (semop(semId, &buf, 1) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "semop(298) positive"); + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + if (semtimedop(semId, &buf, 1, &timeout) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "semtimedop(312) positive"); + + if (semctl(semId, 0, IPC_RMID, 0) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + + semctl_result: + Display::printResult(ret, "semctl(300) positive"); + } + + //shmctl(308), shmget(307) system call positive + { + int shmId; + int ret; + + const int keyNum = 8427; + const int memSize = 1024; + + if ((shmId = shmget(keyNum, memSize, IPC_CREAT|IPC_EXCL|0666)) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "shmget(307) positive"); + + if (shmctl(shmId, IPC_RMID, 0) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "shmctl(308) positive"); + } + } +}; + +GroupBuilder ipcGroup("Ipc"); diff --git a/tools/tests/groups/mac.cpp b/tools/tests/groups/mac.cpp new file mode 100644 index 0000000..ac0c9f4 --- /dev/null +++ b/tools/tests/groups/mac.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include + +#include "group.h" + +#define _unused(x) ((void)(x)) + +class MacGroup : public AbstractGroup { +public: + MacGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "MAC group test start"); + changeMacPolicy(); + } + + virtual ~MacGroup() + { + } + + void changeMacPolicy() { + std::string smackPath("/etc/smack/test"); + std::string smackfsPath("/sys/fs/smackfs/test"); + std::string cynaraPath("/etc/cynara/test"); + std::string netherPath("/etc/nether/test"); + std::string writeString("changeMacPolicy test"); + int writeRet; + + //samck path access + { + int fd = -1; + fd = creat(smackPath.c_str(), 0644); + if (fd > 0) { + writeRet = write(fd, writeString.c_str(), writeString.size()); + _unused(writeRet); + close(fd); + unlink(smackPath.c_str()); + } + Display::printResult(Display::SUCCESS, "/etc/smack access"); + } + + //smackfs path access + { + int fd = -1; + fd = creat(smackfsPath.c_str(), 0644); + if (fd > 0) { + writeRet = write(fd, writeString.c_str(), writeString.size()); + _unused(writeRet); + close(fd); + unlink(smackfsPath.c_str()); + } + Display::printResult(Display::SUCCESS, "/sys/fs/smackfs access"); + } + + //cynara path access + { + int fd = -1; + fd = creat(cynaraPath.c_str(), 0644); + if (fd > 0) { + writeRet = write(fd, writeString.c_str(), writeString.size()); + _unused(writeRet); + close(fd); + unlink(cynaraPath.c_str()); + } + Display::printResult(Display::SUCCESS, "/etc/cynara access"); + } + + //nether path access + { + int fd = -1; + fd = creat(netherPath.c_str(), 0644); + if (fd > 0) { + writeRet = write(fd, writeString.c_str(), writeString.size()); + _unused(writeRet); + close(fd); + unlink(netherPath.c_str()); + } + Display::printResult(Display::SUCCESS, "/etc/nether access"); + } + } +}; + +GroupBuilder macGroup("Mac"); diff --git a/tools/tests/groups/network.cpp b/tools/tests/groups/network.cpp new file mode 100644 index 0000000..dbebca6 --- /dev/null +++ b/tools/tests/groups/network.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include + +#include "group.h" + +class NetworkGroup : public AbstractGroup { +public: + NetworkGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "Network group test start"); + changeNetConfig(); + } + + virtual ~NetworkGroup() + { + } + + void changeNetConfig() { + int ret; + { + std::vector paths; + std::string testfile("/tmp/audit-test/testing"); + + paths.emplace_back("/etc/hosts"); + paths.emplace_back("/etc/sysconfig/network"); + paths.emplace_back("/etc/system-release"); + paths.emplace_back("/etc/sysconfig/network-scripts"); + paths.emplace_back("/etc/wpa_supplicant"); + paths.emplace_back("/etc/wifi-direct"); + + for (auto entry : paths) { + struct stat st; + std::string logStr(entry + " change"); + lstat(entry.c_str(), &st); + chmod(entry.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, logStr); + } + } + + //sethostname(74) system call positive + { + std::string hostname("localhost"); + + if (sethostname(hostname.c_str(), hostname.size()) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "sethostname(74) positive"); + } + + //setdomainname(121) system call positive + { + std::string domain("(none)"); + + if (setdomainname(domain.c_str(), domain.size()) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "setdomainname(121) positive"); + } + } +}; + +GroupBuilder networkGroup("Network"); diff --git a/tools/tests/groups/system.cpp b/tools/tests/groups/system.cpp new file mode 100644 index 0000000..93ba23e --- /dev/null +++ b/tools/tests/groups/system.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "group.h" + +#define _unused(x) ((void)(x)) + +class SystemGroup : public AbstractGroup { +public: + SystemGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "System group test start"); + changeConfigStartup(); + mountDevices(); + createNewProcessFork(); + createNewProcessVfork(); + createNewProcessClone(); + changeUmaskSettings(); + changeConfigLibs(); + changeKernelModule(); + useKernelModule(); + changeAliasePostfix(); + debugging(); + container(); + executeCommands(); + } + + virtual ~SystemGroup() + { + } + + void changeConfigStartup() { + std::vector testPath; + + testPath.emplace_back("/etc/rc.d"); + testPath.emplace_back("/etc/init.d"); + testPath.emplace_back("/etc/systemd"); + testPath.emplace_back("/usr/lib/systemd/system"); + testPath.emplace_back("/usr/lib/systemd/user"); + testPath.emplace_back("/usr/lib/systemd/network"); + + for (auto entry : testPath) { + struct stat st; + std::string logStr(entry + " access"); + lstat(entry.c_str(), &st); + chmod(entry.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, logStr); + } + } + + void mountDevices() { + std::vector mountPath; + int ret; + + mountPath.emplace_back("/tmp/audit-test-source"); + mountPath.emplace_back("/tmp/audit-test-target-1"); + mountPath.emplace_back("/tmp/audit-test-target-2"); + + for (std::string entry : mountPath) { + if (mkdir(entry.c_str(), 0644) != 0) { + Display::printError(); + Display::printResult(Display::FAIL, "mountDevices prepare"); + for (std::string iter : mountPath) { + struct stat st; + if (lstat(iter.c_str(), &st) == 0) { + rmdir(iter.c_str()); + } + } + return; + } + } + + //mount(21) system call positive + { + for (int i = 1; i <= 2; i++) { + if (mount(mountPath[0].c_str(), mountPath[i].c_str(), "ext4", MS_BIND, NULL) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + } + + Display::printResult(ret, "mount(21) positive"); + } + + //umount(22) system call positive + { + if (umount(mountPath[1].c_str()) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "umount(22) positive"); + } + + //umount2(52) system call positive + { + if (umount2(mountPath[2].c_str(), 0) != 0) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "umount2(52) positive"); + } + + for (std::string entry : mountPath) { + struct stat st; + if ((lstat(entry.c_str(), &st) == 0) && (rmdir(entry.c_str()) != 0)) + Display::printError(); + } + } + + static int childFn(void *arg) { + return 0; + } + + void createNewProcessClone() { + //clone(120) system call positive + pid_t pid; + const int stacksize = 1024 * 1024; + void *childStack = malloc(stacksize); + if (childStack == NULL) { + Display::printError(); + Display::printResult(Display::FAIL, "clone(120) positive"); + return; + } + + if ((pid = clone(childFn, (void *)((char *)childStack+ stacksize), SIGCHLD, NULL))< 0) { + Display::printError(); + Display::printResult(Display::FAIL, "clone(120) positive"); + free(childStack); + return; + } + + wait(NULL); + free(childStack); + Display::printResult(Display::SUCCESS, "clone(120) positive"); + } + + void createNewProcessFork() { + //fork(2) system call positive + pid_t pid; + + pid = fork(); + if (pid == -1) { + Display::printResult(Display::FAIL, "fork(2) positive"); + return; + } + + if (pid == 0) { + exit(0); + } else { + wait(NULL); + Display::printResult(Display::SUCCESS, "fork(2) positive"); + } + } + + void createNewProcessVfork() { + //vfork(190) system call positive + pid_t pid; + + pid = vfork(); + if (pid == -1) { + Display::printError(); + Display::printResult(Display::FAIL, "vfork(190) positive"); + return; + } else if (pid == 0) { + _exit(0); + } else { + wait(NULL); + Display::printResult(Display::SUCCESS, "vfork(190) positive"); + } + } + + void changeUmaskSettings() { + //umask(60) system call positive + mode_t origin = umask(022); + umask(origin); + Display::printResult(Display::SUCCESS, "umask(60) positive"); + } + + void changeConfigLibs() { + //path: /etc/ld.so.conf + std::string testPath("/etc/ld.so.conf"); + struct stat st; + + lstat(testPath.c_str(), &st); + chmod(testPath.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, "change /etc/ld.so.conf"); + } + + void changeKernelModule() { + //path: /etc/modules-load.d + std::string testPath("/etc/modules-load.d"); + struct stat st; + + lstat(testPath.c_str(), &st); + chmod(testPath.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, "change /etc/modules-load.d"); + } + + void useKernelModule() { + std::vector commands; + + commands.emplace_back("insmod /opt/data/audit-trail/test_module.ko"); + commands.emplace_back("rmmod test_module"); + commands.emplace_back("modprobe -c"); + + for (auto entry : commands) { + if (system(entry.c_str()) == -1) { + Display::printError(); + Display::printResult(Display::FAIL, entry); + } else { + Display::printResult(Display::SUCCESS, entry); + } + } + } + + void changeAliasePostfix() { + std::vector testPath; + struct stat st; + + testPath.emplace_back("/etc/aliases"); + testPath.emplace_back("/etc/postfix"); + + for (auto entry : testPath) { + std::string logStr(entry + " access"); + lstat(entry.c_str(), &st); + chmod(entry.c_str(), st.st_mode); + Display::printResult(Display::SUCCESS, logStr); + } + } + + void debugging() { + //ptrace(26) system call positive + pid_t pid; + + pid = syscall(__NR_fork); + if (pid == -1) { + Display::printResult(Display::FAIL, "ptrace(26) positive"); + return; + } + + if (pid == 0) { + ptrace(PTRACE_TRACEME, 0, NULL, NULL); + exit(0); + } else { + wait(NULL); + Display::printResult(Display::SUCCESS, "ptrace(26) positive"); + } + } + + void container() { + int ret; + + //unshare(337) system call positive + { + if (unshare(0) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "unshare(337) positive"); + } + + //setns(375) system call positive + { + std::string testFile = "/proc/" + std::to_string(getpid()) + "/ns/uts"; + int fd; + if ((fd = open(testFile.c_str(), O_RDONLY)) == -1) { + Display::printResult(Display::FAIL, "setns(375) positive"); + return; + } + + if (setns(fd, 0) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + + Display::printResult(ret, "setns(375) positive"); + + close(fd); + } + } + + void executeCommands() { + std::string command("/sbin/findfs"); + int ret = Display::FAIL; + + if (system(command.c_str()) == -1) + Display::printError(); + else + ret = Display::SUCCESS; + + Display::printResult(ret, "execute /sbin/findfs"); + } +}; + +GroupBuilder systemGroup("System"); diff --git a/tools/tests/groups/time.cpp b/tools/tests/groups/time.cpp new file mode 100644 index 0000000..225f002 --- /dev/null +++ b/tools/tests/groups/time.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018 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. + * + */ + +#include +#include +#include +#include + +#include "group.h" + +class TimeGroup : public AbstractGroup { +public: + TimeGroup(const std::string& name) : + AbstractGroup(name) + { + } + + void run() + { + Display::printResult(Display::NONE, "Time group test start"); + changeCurrentTime(); + } + + virtual ~TimeGroup() + { + } + + void changeCurrentTime() { + int ret; + //adjtimex(124), clock_adjtime(372) system call positive + { + struct timex time; + + time.modes = ADJ_OFFSET; + time.offset = 0; + + if (adjtimex(&time) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "adjtimex(124) positive"); + + if (clock_adjtime(CLOCK_REALTIME, &time) == -1) { + Display::printError(); + ret = Display::FAIL; + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "clock_adjtime(372) positive"); + } + + //settimeofday(79) system call positive + { + struct timeval time; + gettimeofday(&time, NULL); + + if (settimeofday(&time, NULL) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "settimeofday(79) positive"); + } + + //stime(25) system call positive + { + time_t currentTime; + + time(¤tTime); + + if (stime(¤tTime) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "stime(25) positive"); + } + + //clock_settime(262) system call positive + { + struct timespec time; + clock_gettime(CLOCK_REALTIME, &time); + + if (clock_settime(CLOCK_REALTIME, &time) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "clock_settime(262) positive"); + } + + //time config file access + { + std::string command("touch /etc/localtime"); + if (system(command.c_str()) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "/etc/localtime access"); + } + + //time config file access + { + std::string command("touch /etc/sysconfig/clock"); + if (system(command.c_str()) == -1) { + ret = Display::FAIL; + Display::printError(); + } else { + ret = Display::SUCCESS; + } + Display::printResult(ret, "/etc/sysconfig/clock access"); + } + } +}; + +GroupBuilder timeGroup("Time"); diff --git a/tools/tests/rule_verification.cpp b/tools/tests/rule_verification.cpp new file mode 100644 index 0000000..706500a --- /dev/null +++ b/tools/tests/rule_verification.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2018 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 + * @brief CLI tool to test a audit rule verification + */ + +#include +#include +#include + +#include "groups/group.h" + +int selectGroups() +{ + int groupIdx = 0; + std::string selectedGroups; + std::stringstream ss; + int n; + + std::cout << "===========================================" << std::endl; + std::cout << "<< Rule Verification Test Tool >>" << std::endl; + std::cout << "===========================================" << std::endl; + + std::cout << "[0] All" << std::endl; + for (AbstractGroup *entry : managedGroup) { + std::cout << "[" << ++groupIdx << "] " << entry->name << std::endl; + } + + std::cout << "---------------------------------------" << std::endl; + std::cout << "-1 : exit" << std::endl; + std::cout << "split by space ex) > 1 3 5 (enter)" << std::endl; + std::cout << "---------------------------------------" << std::endl; + std::cout << "> Enter group ID : "; + + std::getline(std::cin, selectedGroups); + ss.str(selectedGroups); + + while(!ss.eof()) { + ss >> n; + + if (n == -1) { + std::cout << "Exit test" << std::endl; + return 1; + } + + if (n > (int)managedGroup.size() || n < 0) { + std::cout << "Wrong option" << std::endl; + return 0; + } + + if (n == 0) { + for(AbstractGroup *selected : managedGroup) { + selected->run(); + } + + return 1; + } + + managedGroup[n - 1]->run(); + } + + return 1; +} + + int main(int argc, char* argv[]) + { + bool done = false; + + while(!done) { + if (selectGroups()) { + done = true; + } + } + + GroupCleaner::deleteGroups(); + + return 0; + }