1c1ed15f1Sopenharmony_ci/* 2c1ed15f1Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3c1ed15f1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4c1ed15f1Sopenharmony_ci * you may not use this file except in compliance with the License. 5c1ed15f1Sopenharmony_ci * You may obtain a copy of the License at 6c1ed15f1Sopenharmony_ci * 7c1ed15f1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8c1ed15f1Sopenharmony_ci * 9c1ed15f1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10c1ed15f1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11c1ed15f1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12c1ed15f1Sopenharmony_ci * See the License for the specific language governing permissions and 13c1ed15f1Sopenharmony_ci * limitations under the License. 14c1ed15f1Sopenharmony_ci */ 15c1ed15f1Sopenharmony_ci 16c1ed15f1Sopenharmony_ci#include <cstdlib> 17c1ed15f1Sopenharmony_ci#include <getopt.h> 18c1ed15f1Sopenharmony_ci#include <iosfwd> 19c1ed15f1Sopenharmony_ci#include <iostream> 20c1ed15f1Sopenharmony_ci#include <istream> 21c1ed15f1Sopenharmony_ci#include <memory> 22c1ed15f1Sopenharmony_ci#include <ostream> 23c1ed15f1Sopenharmony_ci#include <string> 24c1ed15f1Sopenharmony_ci#include <unistd.h> 25c1ed15f1Sopenharmony_ci 26c1ed15f1Sopenharmony_ci#include "selinux/avc.h" 27c1ed15f1Sopenharmony_ci#include "hdf_service_checker.h" 28c1ed15f1Sopenharmony_ci#include "selinux_error.h" 29c1ed15f1Sopenharmony_ci#include "service_checker.h" 30c1ed15f1Sopenharmony_ci 31c1ed15f1Sopenharmony_ciusing namespace Selinux; 32c1ed15f1Sopenharmony_ci 33c1ed15f1Sopenharmony_cistatic std::unique_ptr<ServiceChecker> g_service = nullptr; 34c1ed15f1Sopenharmony_ci 35c1ed15f1Sopenharmony_cistruct TestInput { 36c1ed15f1Sopenharmony_ci char cmd = '\0'; 37c1ed15f1Sopenharmony_ci bool isHdf = false; 38c1ed15f1Sopenharmony_ci std::string serviceName; 39c1ed15f1Sopenharmony_ci}; 40c1ed15f1Sopenharmony_ci 41c1ed15f1Sopenharmony_cistatic void PrintUsage() 42c1ed15f1Sopenharmony_ci{ 43c1ed15f1Sopenharmony_ci std::cout << "Options:" << std::endl; 44c1ed15f1Sopenharmony_ci std::cout << " -h (--help) show the help information. [eg: service_check -h]" << std::endl; 45c1ed15f1Sopenharmony_ci std::cout << "***********************optinal*************************************************" << std::endl; 46c1ed15f1Sopenharmony_ci std::cout << " -d (--isHdf) service or hdf_service. [eg: service_check -d]" << std::endl; 47c1ed15f1Sopenharmony_ci std::cout << " -n (--serviceName) serviceName. [eg: service_check -n service_name]" 48c1ed15f1Sopenharmony_ci << std::endl; 49c1ed15f1Sopenharmony_ci std::cout << "***********************requered: 1 in 4****************************************" << std::endl; 50c1ed15f1Sopenharmony_ci std::cout << " -a (--add) add service check. [eg: service_check -a]" << std::endl; 51c1ed15f1Sopenharmony_ci std::cout << " -g (--get) get service check. [eg: service_check -g]" << std::endl; 52c1ed15f1Sopenharmony_ci std::cout << " -r (--get_remote) get remote service check. [eg: service_check -r]" << std::endl; 53c1ed15f1Sopenharmony_ci std::cout << " -l (--list) list service check. [eg: service_check -l]" << std::endl; 54c1ed15f1Sopenharmony_ci std::cout << "" << std::endl; 55c1ed15f1Sopenharmony_ci std::cout << "Usage:" << std::endl; 56c1ed15f1Sopenharmony_ci std::cout << ">>>>>>> choice 1: continuous input parameters" << std::endl; 57c1ed15f1Sopenharmony_ci std::cout << "step 1:" << std::endl; 58c1ed15f1Sopenharmony_ci std::cout << "service_check (-d) -a|-g|-r|-l" << std::endl; 59c1ed15f1Sopenharmony_ci std::cout << "step 2:" << std::endl; 60c1ed15f1Sopenharmony_ci std::cout << "input service name and press 'enter' to continue, or ctrl+C to end process" << std::endl; 61c1ed15f1Sopenharmony_ci std::cout << ">>>>>>> choice 2: single input parameter" << std::endl; 62c1ed15f1Sopenharmony_ci std::cout << "service_check (-d) -a|-g|-r|-l -n service_name" << std::endl; 63c1ed15f1Sopenharmony_ci std::cout << "" << std::endl; 64c1ed15f1Sopenharmony_ci} 65c1ed15f1Sopenharmony_ci 66c1ed15f1Sopenharmony_cistatic void SetOptions(int argc, char *argv[], const option *options, TestInput &input) 67c1ed15f1Sopenharmony_ci{ 68c1ed15f1Sopenharmony_ci int index = 0; 69c1ed15f1Sopenharmony_ci const char *optStr = "dhlagrn:"; 70c1ed15f1Sopenharmony_ci int para = 0; 71c1ed15f1Sopenharmony_ci while ((para = getopt_long(argc, argv, optStr, options, &index)) != -1) { 72c1ed15f1Sopenharmony_ci switch (para) { 73c1ed15f1Sopenharmony_ci case 'h': { 74c1ed15f1Sopenharmony_ci PrintUsage(); 75c1ed15f1Sopenharmony_ci exit(0); 76c1ed15f1Sopenharmony_ci } 77c1ed15f1Sopenharmony_ci case 'n': { 78c1ed15f1Sopenharmony_ci input.serviceName = optarg; 79c1ed15f1Sopenharmony_ci break; 80c1ed15f1Sopenharmony_ci } 81c1ed15f1Sopenharmony_ci case 'd': { 82c1ed15f1Sopenharmony_ci input.isHdf = true; 83c1ed15f1Sopenharmony_ci break; 84c1ed15f1Sopenharmony_ci } 85c1ed15f1Sopenharmony_ci case 'a': { 86c1ed15f1Sopenharmony_ci input.cmd = 'a'; 87c1ed15f1Sopenharmony_ci break; 88c1ed15f1Sopenharmony_ci } 89c1ed15f1Sopenharmony_ci case 'g': { 90c1ed15f1Sopenharmony_ci input.cmd = 'g'; 91c1ed15f1Sopenharmony_ci break; 92c1ed15f1Sopenharmony_ci } 93c1ed15f1Sopenharmony_ci case 'r': { 94c1ed15f1Sopenharmony_ci input.cmd = 'r'; 95c1ed15f1Sopenharmony_ci break; 96c1ed15f1Sopenharmony_ci } 97c1ed15f1Sopenharmony_ci case 'l': { 98c1ed15f1Sopenharmony_ci input.cmd = 'l'; 99c1ed15f1Sopenharmony_ci break; 100c1ed15f1Sopenharmony_ci } 101c1ed15f1Sopenharmony_ci default: 102c1ed15f1Sopenharmony_ci std::cout << "Try 'service_check -h' for more information." << std::endl; 103c1ed15f1Sopenharmony_ci exit(-1); 104c1ed15f1Sopenharmony_ci } 105c1ed15f1Sopenharmony_ci } 106c1ed15f1Sopenharmony_ci} 107c1ed15f1Sopenharmony_ci 108c1ed15f1Sopenharmony_cistatic int GetSidForCurrentProcess(std::string &sid) 109c1ed15f1Sopenharmony_ci{ 110c1ed15f1Sopenharmony_ci char *con = nullptr; 111c1ed15f1Sopenharmony_ci if (getcon(&con) < 0) { 112c1ed15f1Sopenharmony_ci return -1; 113c1ed15f1Sopenharmony_ci } 114c1ed15f1Sopenharmony_ci sid = con; 115c1ed15f1Sopenharmony_ci freecon(con); 116c1ed15f1Sopenharmony_ci return 0; 117c1ed15f1Sopenharmony_ci} 118c1ed15f1Sopenharmony_ci 119c1ed15f1Sopenharmony_cistatic void TestAddService(bool isHdf, const std::string &serviceName) 120c1ed15f1Sopenharmony_ci{ 121c1ed15f1Sopenharmony_ci std::string sid; 122c1ed15f1Sopenharmony_ci if (GetSidForCurrentProcess(sid) < 0) { 123c1ed15f1Sopenharmony_ci return; 124c1ed15f1Sopenharmony_ci } 125c1ed15f1Sopenharmony_ci if (!serviceName.empty()) { 126c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? HdfAddServiceCheck(sid.c_str(), serviceName.c_str()) 127c1ed15f1Sopenharmony_ci : g_service->AddServiceCheck(sid, serviceName)) 128c1ed15f1Sopenharmony_ci << std::endl; 129c1ed15f1Sopenharmony_ci exit(0); 130c1ed15f1Sopenharmony_ci } 131c1ed15f1Sopenharmony_ci std::string serName; 132c1ed15f1Sopenharmony_ci while (std::cin >> serName) { 133c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? HdfAddServiceCheck(sid.c_str(), serName.c_str()) 134c1ed15f1Sopenharmony_ci : g_service->AddServiceCheck(sid, serName)) 135c1ed15f1Sopenharmony_ci << std::endl; 136c1ed15f1Sopenharmony_ci } 137c1ed15f1Sopenharmony_ci} 138c1ed15f1Sopenharmony_ci 139c1ed15f1Sopenharmony_cistatic void TestGetService(bool isHdf, const std::string &serviceName) 140c1ed15f1Sopenharmony_ci{ 141c1ed15f1Sopenharmony_ci std::string sid; 142c1ed15f1Sopenharmony_ci if (GetSidForCurrentProcess(sid) < 0) { 143c1ed15f1Sopenharmony_ci return; 144c1ed15f1Sopenharmony_ci } 145c1ed15f1Sopenharmony_ci if (!serviceName.empty()) { 146c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? HdfGetServiceCheck(sid.c_str(), serviceName.c_str()) 147c1ed15f1Sopenharmony_ci : g_service->GetServiceCheck(sid, serviceName)) 148c1ed15f1Sopenharmony_ci << std::endl; 149c1ed15f1Sopenharmony_ci exit(0); 150c1ed15f1Sopenharmony_ci } 151c1ed15f1Sopenharmony_ci std::string serName; 152c1ed15f1Sopenharmony_ci while (std::cin >> serName) { 153c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? HdfGetServiceCheck(sid.c_str(), serName.c_str()) 154c1ed15f1Sopenharmony_ci : g_service->GetServiceCheck(sid, serName)) 155c1ed15f1Sopenharmony_ci << std::endl; 156c1ed15f1Sopenharmony_ci } 157c1ed15f1Sopenharmony_ci} 158c1ed15f1Sopenharmony_ci 159c1ed15f1Sopenharmony_cistatic void TestGetRemoteService(bool isHdf, const std::string &serviceName) 160c1ed15f1Sopenharmony_ci{ 161c1ed15f1Sopenharmony_ci std::string sid; 162c1ed15f1Sopenharmony_ci if (GetSidForCurrentProcess(sid) < 0) { 163c1ed15f1Sopenharmony_ci return; 164c1ed15f1Sopenharmony_ci } 165c1ed15f1Sopenharmony_ci if (!serviceName.empty()) { 166c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? SELINUX_PERMISSION_DENY 167c1ed15f1Sopenharmony_ci : g_service->GetRemoteServiceCheck(sid, serviceName)) 168c1ed15f1Sopenharmony_ci << std::endl; 169c1ed15f1Sopenharmony_ci exit(0); 170c1ed15f1Sopenharmony_ci } 171c1ed15f1Sopenharmony_ci std::string serName; 172c1ed15f1Sopenharmony_ci while (std::cin >> serName) { 173c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? SELINUX_PERMISSION_DENY : g_service->GetRemoteServiceCheck(sid, serName)) 174c1ed15f1Sopenharmony_ci << std::endl; 175c1ed15f1Sopenharmony_ci } 176c1ed15f1Sopenharmony_ci} 177c1ed15f1Sopenharmony_ci 178c1ed15f1Sopenharmony_cistatic void TestListService(bool isHdf) 179c1ed15f1Sopenharmony_ci{ 180c1ed15f1Sopenharmony_ci std::string sid; 181c1ed15f1Sopenharmony_ci if (GetSidForCurrentProcess(sid) < 0) { 182c1ed15f1Sopenharmony_ci return; 183c1ed15f1Sopenharmony_ci } 184c1ed15f1Sopenharmony_ci std::cout << GetErrStr(isHdf ? HdfListServiceCheck(sid.c_str()) : g_service->ListServiceCheck(sid)) << std::endl; 185c1ed15f1Sopenharmony_ci} 186c1ed15f1Sopenharmony_ci 187c1ed15f1Sopenharmony_cistatic void Test(const TestInput &testCmd) 188c1ed15f1Sopenharmony_ci{ 189c1ed15f1Sopenharmony_ci switch (testCmd.cmd) { 190c1ed15f1Sopenharmony_ci case 'a': { 191c1ed15f1Sopenharmony_ci TestAddService(testCmd.isHdf, testCmd.serviceName); 192c1ed15f1Sopenharmony_ci exit(0); 193c1ed15f1Sopenharmony_ci } 194c1ed15f1Sopenharmony_ci case 'g': { 195c1ed15f1Sopenharmony_ci TestGetService(testCmd.isHdf, testCmd.serviceName); 196c1ed15f1Sopenharmony_ci exit(0); 197c1ed15f1Sopenharmony_ci } 198c1ed15f1Sopenharmony_ci case 'r': { 199c1ed15f1Sopenharmony_ci TestGetRemoteService(testCmd.isHdf, testCmd.serviceName); 200c1ed15f1Sopenharmony_ci exit(0); 201c1ed15f1Sopenharmony_ci } 202c1ed15f1Sopenharmony_ci case 'l': { 203c1ed15f1Sopenharmony_ci TestListService(testCmd.isHdf); 204c1ed15f1Sopenharmony_ci exit(0); 205c1ed15f1Sopenharmony_ci } 206c1ed15f1Sopenharmony_ci default: 207c1ed15f1Sopenharmony_ci exit(-1); 208c1ed15f1Sopenharmony_ci } 209c1ed15f1Sopenharmony_ci} 210c1ed15f1Sopenharmony_ci 211c1ed15f1Sopenharmony_ciint main(int argc, char *argv[]) 212c1ed15f1Sopenharmony_ci{ 213c1ed15f1Sopenharmony_ci struct option options[] = { 214c1ed15f1Sopenharmony_ci {"help", no_argument, nullptr, 'h'}, {"add", no_argument, nullptr, 'a'}, 215c1ed15f1Sopenharmony_ci {"get", no_argument, nullptr, 'g'}, {"get_remote", no_argument, nullptr, 'r'}, 216c1ed15f1Sopenharmony_ci {"isHdf", no_argument, nullptr, 'd'}, {"list", no_argument, nullptr, 'l'}, 217c1ed15f1Sopenharmony_ci {"serviceName", required_argument, nullptr, 'n'}, {nullptr, no_argument, nullptr, 0}, 218c1ed15f1Sopenharmony_ci }; 219c1ed15f1Sopenharmony_ci 220c1ed15f1Sopenharmony_ci if (argc == 1) { 221c1ed15f1Sopenharmony_ci PrintUsage(); 222c1ed15f1Sopenharmony_ci exit(0); 223c1ed15f1Sopenharmony_ci } 224c1ed15f1Sopenharmony_ci 225c1ed15f1Sopenharmony_ci TestInput input; 226c1ed15f1Sopenharmony_ci SetOptions(argc, argv, options, input); 227c1ed15f1Sopenharmony_ci if (!input.isHdf) { 228c1ed15f1Sopenharmony_ci g_service = std::make_unique<ServiceChecker>(false); 229c1ed15f1Sopenharmony_ci } 230c1ed15f1Sopenharmony_ci Test(input); 231c1ed15f1Sopenharmony_ci 232c1ed15f1Sopenharmony_ci exit(0); 233c1ed15f1Sopenharmony_ci} 234