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 <cstdio> 17c1ed15f1Sopenharmony_ci#include <cstdlib> 18c1ed15f1Sopenharmony_ci#include <getopt.h> 19c1ed15f1Sopenharmony_ci#include <iosfwd> 20c1ed15f1Sopenharmony_ci#include <iostream> 21c1ed15f1Sopenharmony_ci#include <istream> 22c1ed15f1Sopenharmony_ci#include <memory> 23c1ed15f1Sopenharmony_ci#include <ostream> 24c1ed15f1Sopenharmony_ci#include <string> 25c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 26c1ed15f1Sopenharmony_ci#include <sys/time.h> 27c1ed15f1Sopenharmony_ci#endif 28c1ed15f1Sopenharmony_ci#include <unistd.h> 29c1ed15f1Sopenharmony_ci#include <sys/socket.h> 30c1ed15f1Sopenharmony_ci#include <selinux/selinux.h> 31c1ed15f1Sopenharmony_ci 32c1ed15f1Sopenharmony_ci#include "selinux_error.h" 33c1ed15f1Sopenharmony_ci#include "selinux_parameter.h" 34c1ed15f1Sopenharmony_ci#include "param_checker.h" 35c1ed15f1Sopenharmony_ci 36c1ed15f1Sopenharmony_ciusing namespace Selinux; 37c1ed15f1Sopenharmony_ci 38c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 39c1ed15f1Sopenharmony_ciconst static long USEC_PER_SEC = 1000000L; 40c1ed15f1Sopenharmony_ci#endif 41c1ed15f1Sopenharmony_ci 42c1ed15f1Sopenharmony_cistruct TestInput { 43c1ed15f1Sopenharmony_ci std::string paraName; 44c1ed15f1Sopenharmony_ci char cmd = '\0'; 45c1ed15f1Sopenharmony_ci}; 46c1ed15f1Sopenharmony_ci 47c1ed15f1Sopenharmony_cistatic void TestLoadList() 48c1ed15f1Sopenharmony_ci{ 49c1ed15f1Sopenharmony_ci ParamContextsList *buff = nullptr; 50c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 51c1ed15f1Sopenharmony_ci struct timeval start, end, diff; 52c1ed15f1Sopenharmony_ci gettimeofday(&start, nullptr); 53c1ed15f1Sopenharmony_ci#endif 54c1ed15f1Sopenharmony_ci buff = GetParamList(); 55c1ed15f1Sopenharmony_ci if (buff == nullptr) { 56c1ed15f1Sopenharmony_ci std::cout << "buff empty" << std::endl; 57c1ed15f1Sopenharmony_ci return; 58c1ed15f1Sopenharmony_ci } 59c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 60c1ed15f1Sopenharmony_ci gettimeofday(&end, nullptr); 61c1ed15f1Sopenharmony_ci timersub(&end, &start, &diff); 62c1ed15f1Sopenharmony_ci int runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 63c1ed15f1Sopenharmony_ci std::cout << "GetParamList time use: " << runtime_us << std::endl; 64c1ed15f1Sopenharmony_ci#endif 65c1ed15f1Sopenharmony_ci 66c1ed15f1Sopenharmony_ci ParamContextsList *head = buff; 67c1ed15f1Sopenharmony_ci while (buff != nullptr) { 68c1ed15f1Sopenharmony_ci if (security_check_context(buff->info.paraContext) < 0) { 69c1ed15f1Sopenharmony_ci std::cout << "failed check context: " << buff->info.paraContext << " " << strlen(buff->info.paraContext) 70c1ed15f1Sopenharmony_ci << std::endl; 71c1ed15f1Sopenharmony_ci buff = buff->next; 72c1ed15f1Sopenharmony_ci continue; 73c1ed15f1Sopenharmony_ci } 74c1ed15f1Sopenharmony_ci std::cout << "param: " << buff->info.paraName << ", contexts: " << buff->info.paraContext 75c1ed15f1Sopenharmony_ci << ", index: " << buff->info.index << std::endl; 76c1ed15f1Sopenharmony_ci buff = buff->next; 77c1ed15f1Sopenharmony_ci } 78c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 79c1ed15f1Sopenharmony_ci gettimeofday(&start, nullptr); 80c1ed15f1Sopenharmony_ci#endif 81c1ed15f1Sopenharmony_ci DestroyParamList(&head); 82c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 83c1ed15f1Sopenharmony_ci gettimeofday(&end, nullptr); 84c1ed15f1Sopenharmony_ci timersub(&end, &start, &diff); 85c1ed15f1Sopenharmony_ci runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 86c1ed15f1Sopenharmony_ci std::cout << "DestroyParamList time use: " << runtime_us << std::endl; 87c1ed15f1Sopenharmony_ci#endif 88c1ed15f1Sopenharmony_ci} 89c1ed15f1Sopenharmony_ci 90c1ed15f1Sopenharmony_cistatic void TestGetContext(std::string ¶Name) 91c1ed15f1Sopenharmony_ci{ 92c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 93c1ed15f1Sopenharmony_ci struct timeval start, end, diff; 94c1ed15f1Sopenharmony_ci gettimeofday(&start, nullptr); 95c1ed15f1Sopenharmony_ci#endif 96c1ed15f1Sopenharmony_ci const char *context = GetParamLabel(paraName.c_str()); 97c1ed15f1Sopenharmony_ci int index = GetParamLabelIndex(paraName.c_str()); 98c1ed15f1Sopenharmony_ci std::cout << "paraName: " << paraName << "context: " << context << " index: " << index << std::endl; 99c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 100c1ed15f1Sopenharmony_ci gettimeofday(&end, nullptr); 101c1ed15f1Sopenharmony_ci timersub(&end, &start, &diff); 102c1ed15f1Sopenharmony_ci int runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 103c1ed15f1Sopenharmony_ci std::cout << "time use: " << runtime_us << std::endl; 104c1ed15f1Sopenharmony_ci#endif 105c1ed15f1Sopenharmony_ci std::cout << "para " << paraName.c_str() << "'s context is " << context << std::endl; 106c1ed15f1Sopenharmony_ci} 107c1ed15f1Sopenharmony_ci 108c1ed15f1Sopenharmony_cistatic void TestReadPara(std::string ¶Name) 109c1ed15f1Sopenharmony_ci{ 110c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 111c1ed15f1Sopenharmony_ci struct timeval start, end, diff; 112c1ed15f1Sopenharmony_ci gettimeofday(&start, nullptr); 113c1ed15f1Sopenharmony_ci#endif 114c1ed15f1Sopenharmony_ci const char *contexts = GetParamLabel(paraName.c_str()); 115c1ed15f1Sopenharmony_ci std::string path = "/dev/__parameters__/" + std::string(contexts); 116c1ed15f1Sopenharmony_ci if (access(path.c_str(), F_OK) != 0) { 117c1ed15f1Sopenharmony_ci std::cout << "read param: " << paraName << " fail" << std::endl; 118c1ed15f1Sopenharmony_ci } else { 119c1ed15f1Sopenharmony_ci std::cout << "read param: " << paraName << " succ" << std::endl; 120c1ed15f1Sopenharmony_ci } 121c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 122c1ed15f1Sopenharmony_ci gettimeofday(&end, nullptr); 123c1ed15f1Sopenharmony_ci timersub(&end, &start, &diff); 124c1ed15f1Sopenharmony_ci int runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 125c1ed15f1Sopenharmony_ci std::cout << "time use: " << runtime_us << std::endl; 126c1ed15f1Sopenharmony_ci#endif 127c1ed15f1Sopenharmony_ci} 128c1ed15f1Sopenharmony_ci 129c1ed15f1Sopenharmony_cistatic void TestSetPara(std::string ¶Name, SrcInfo *info) 130c1ed15f1Sopenharmony_ci{ 131c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 132c1ed15f1Sopenharmony_ci struct timeval start, end, diff; 133c1ed15f1Sopenharmony_ci gettimeofday(&start, nullptr); 134c1ed15f1Sopenharmony_ci#endif 135c1ed15f1Sopenharmony_ci std::cout << GetErrStr(SetParamCheck(paraName.c_str(), GetParamLabel(paraName.c_str()), info)) << std::endl; 136c1ed15f1Sopenharmony_ci#ifdef TIME_DISPLAY 137c1ed15f1Sopenharmony_ci gettimeofday(&end, nullptr); 138c1ed15f1Sopenharmony_ci timersub(&end, &start, &diff); 139c1ed15f1Sopenharmony_ci int runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; 140c1ed15f1Sopenharmony_ci std::cout << "time use: " << runtime_us << std::endl; 141c1ed15f1Sopenharmony_ci#endif 142c1ed15f1Sopenharmony_ci} 143c1ed15f1Sopenharmony_ci 144c1ed15f1Sopenharmony_cistatic void PrintUsage() 145c1ed15f1Sopenharmony_ci{ 146c1ed15f1Sopenharmony_ci std::cout << "Options:" << std::endl; 147c1ed15f1Sopenharmony_ci std::cout << " -h (--help) show the help information. [eg: param_check -h]" << std::endl; 148c1ed15f1Sopenharmony_ci std::cout << " -g (--getContext) get context for paraName. [eg: param_check -g]" << std::endl; 149c1ed15f1Sopenharmony_ci std::cout << " -r (--read) read para perm. [eg: param_check -r]" << std::endl; 150c1ed15f1Sopenharmony_ci std::cout << " -w (--write) write para perm. [eg: param_check -w]" << std::endl; 151c1ed15f1Sopenharmony_ci std::cout << " -l (--list) load para list. [eg: param_check -l]" << std::endl; 152c1ed15f1Sopenharmony_ci std::cout << " -n (--paraName) paraName. [eg: param_check -r|-w|-g -n para_name]" 153c1ed15f1Sopenharmony_ci << std::endl; 154c1ed15f1Sopenharmony_ci std::cout << "" << std::endl; 155c1ed15f1Sopenharmony_ci std::cout << "Usage:" << std::endl; 156c1ed15f1Sopenharmony_ci std::cout << ">>>>>>> choice 1: continuous input parameters" << std::endl; 157c1ed15f1Sopenharmony_ci std::cout << "step 1:" << std::endl; 158c1ed15f1Sopenharmony_ci std::cout << "param_check -r|-w|-g|-l" << std::endl; 159c1ed15f1Sopenharmony_ci std::cout << "step 2:" << std::endl; 160c1ed15f1Sopenharmony_ci std::cout << "input param name and press 'enter' to continue, or ctrl+C to end process" << std::endl; 161c1ed15f1Sopenharmony_ci std::cout << "" << std::endl; 162c1ed15f1Sopenharmony_ci std::cout << ">>>>>>> choice 2: single input parameter" << std::endl; 163c1ed15f1Sopenharmony_ci std::cout << "param_check -r|-w|-g -n para_name" << std::endl; 164c1ed15f1Sopenharmony_ci std::cout << "" << std::endl; 165c1ed15f1Sopenharmony_ci} 166c1ed15f1Sopenharmony_ci 167c1ed15f1Sopenharmony_cistatic void SetOptions(int argc, char *argv[], const option *options, TestInput &input) 168c1ed15f1Sopenharmony_ci{ 169c1ed15f1Sopenharmony_ci int index = 0; 170c1ed15f1Sopenharmony_ci const char *optStr = "hgrwln:"; 171c1ed15f1Sopenharmony_ci int para = 0; 172c1ed15f1Sopenharmony_ci while ((para = getopt_long(argc, argv, optStr, options, &index)) != -1) { 173c1ed15f1Sopenharmony_ci switch (para) { 174c1ed15f1Sopenharmony_ci case 'h': { 175c1ed15f1Sopenharmony_ci PrintUsage(); 176c1ed15f1Sopenharmony_ci exit(0); 177c1ed15f1Sopenharmony_ci } 178c1ed15f1Sopenharmony_ci case 'n': { 179c1ed15f1Sopenharmony_ci input.paraName = optarg; 180c1ed15f1Sopenharmony_ci break; 181c1ed15f1Sopenharmony_ci } 182c1ed15f1Sopenharmony_ci case 'g': { 183c1ed15f1Sopenharmony_ci input.cmd = 'g'; 184c1ed15f1Sopenharmony_ci break; 185c1ed15f1Sopenharmony_ci } 186c1ed15f1Sopenharmony_ci case 'r': { 187c1ed15f1Sopenharmony_ci input.cmd = 'r'; 188c1ed15f1Sopenharmony_ci break; 189c1ed15f1Sopenharmony_ci } 190c1ed15f1Sopenharmony_ci case 'w': { 191c1ed15f1Sopenharmony_ci input.cmd = 'w'; 192c1ed15f1Sopenharmony_ci break; 193c1ed15f1Sopenharmony_ci } 194c1ed15f1Sopenharmony_ci case 'l': { 195c1ed15f1Sopenharmony_ci TestLoadList(); 196c1ed15f1Sopenharmony_ci exit(0); 197c1ed15f1Sopenharmony_ci } 198c1ed15f1Sopenharmony_ci default: 199c1ed15f1Sopenharmony_ci std::cout << "Try 'param_check -h' for more information." << std::endl; 200c1ed15f1Sopenharmony_ci exit(-1); 201c1ed15f1Sopenharmony_ci } 202c1ed15f1Sopenharmony_ci } 203c1ed15f1Sopenharmony_ci} 204c1ed15f1Sopenharmony_ci 205c1ed15f1Sopenharmony_cistatic void TestWriteParameters(TestInput &testCmd) 206c1ed15f1Sopenharmony_ci{ 207c1ed15f1Sopenharmony_ci int fd[2]; 208c1ed15f1Sopenharmony_ci if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) { 209c1ed15f1Sopenharmony_ci perror("socketpair"); 210c1ed15f1Sopenharmony_ci exit(EXIT_FAILURE); 211c1ed15f1Sopenharmony_ci } 212c1ed15f1Sopenharmony_ci 213c1ed15f1Sopenharmony_ci SrcInfo info; 214c1ed15f1Sopenharmony_ci info.uc.pid = getpid(); 215c1ed15f1Sopenharmony_ci info.uc.uid = getuid(); 216c1ed15f1Sopenharmony_ci info.uc.gid = getgid(); 217c1ed15f1Sopenharmony_ci info.sockFd = fd[0]; 218c1ed15f1Sopenharmony_ci if (!testCmd.paraName.empty()) { 219c1ed15f1Sopenharmony_ci TestSetPara(testCmd.paraName, &info); 220c1ed15f1Sopenharmony_ci close(fd[0]); 221c1ed15f1Sopenharmony_ci close(fd[1]); 222c1ed15f1Sopenharmony_ci exit(0); 223c1ed15f1Sopenharmony_ci } 224c1ed15f1Sopenharmony_ci std::string paraName; 225c1ed15f1Sopenharmony_ci while (std::cin >> paraName) { 226c1ed15f1Sopenharmony_ci TestSetPara(paraName, &info); 227c1ed15f1Sopenharmony_ci } 228c1ed15f1Sopenharmony_ci close(fd[0]); 229c1ed15f1Sopenharmony_ci close(fd[1]); 230c1ed15f1Sopenharmony_ci exit(0); 231c1ed15f1Sopenharmony_ci} 232c1ed15f1Sopenharmony_ci 233c1ed15f1Sopenharmony_cistatic void Test(TestInput &testCmd) 234c1ed15f1Sopenharmony_ci{ 235c1ed15f1Sopenharmony_ci std::string paraName; 236c1ed15f1Sopenharmony_ci switch (testCmd.cmd) { 237c1ed15f1Sopenharmony_ci case 'g': { 238c1ed15f1Sopenharmony_ci if (!testCmd.paraName.empty()) { 239c1ed15f1Sopenharmony_ci TestGetContext(testCmd.paraName); 240c1ed15f1Sopenharmony_ci exit(0); 241c1ed15f1Sopenharmony_ci } 242c1ed15f1Sopenharmony_ci while (std::cin >> paraName) { 243c1ed15f1Sopenharmony_ci TestGetContext(paraName); 244c1ed15f1Sopenharmony_ci } 245c1ed15f1Sopenharmony_ci exit(0); 246c1ed15f1Sopenharmony_ci } 247c1ed15f1Sopenharmony_ci case 'r': { 248c1ed15f1Sopenharmony_ci if (!testCmd.paraName.empty()) { 249c1ed15f1Sopenharmony_ci TestReadPara(testCmd.paraName); 250c1ed15f1Sopenharmony_ci exit(0); 251c1ed15f1Sopenharmony_ci } 252c1ed15f1Sopenharmony_ci while (std::cin >> paraName) { 253c1ed15f1Sopenharmony_ci TestReadPara(paraName); 254c1ed15f1Sopenharmony_ci } 255c1ed15f1Sopenharmony_ci exit(0); 256c1ed15f1Sopenharmony_ci } 257c1ed15f1Sopenharmony_ci case 'w': { 258c1ed15f1Sopenharmony_ci TestWriteParameters(testCmd); 259c1ed15f1Sopenharmony_ci break; 260c1ed15f1Sopenharmony_ci } 261c1ed15f1Sopenharmony_ci default: 262c1ed15f1Sopenharmony_ci PrintUsage(); 263c1ed15f1Sopenharmony_ci exit(-1); 264c1ed15f1Sopenharmony_ci } 265c1ed15f1Sopenharmony_ci} 266c1ed15f1Sopenharmony_ci 267c1ed15f1Sopenharmony_ciint main(int argc, char *argv[]) 268c1ed15f1Sopenharmony_ci{ 269c1ed15f1Sopenharmony_ci struct option options[] = { 270c1ed15f1Sopenharmony_ci {"help", no_argument, nullptr, 'h'}, {"paraName", required_argument, nullptr, 'n'}, 271c1ed15f1Sopenharmony_ci {"read", no_argument, nullptr, 'r'}, {"write", no_argument, nullptr, 'w'}, 272c1ed15f1Sopenharmony_ci {"list", no_argument, nullptr, 'l'}, {"getContext", no_argument, nullptr, 'g'}, 273c1ed15f1Sopenharmony_ci {nullptr, no_argument, nullptr, 0}, 274c1ed15f1Sopenharmony_ci }; 275c1ed15f1Sopenharmony_ci 276c1ed15f1Sopenharmony_ci if (argc == 1) { 277c1ed15f1Sopenharmony_ci PrintUsage(); 278c1ed15f1Sopenharmony_ci exit(0); 279c1ed15f1Sopenharmony_ci } 280c1ed15f1Sopenharmony_ci InitParamSelinux(0); 281c1ed15f1Sopenharmony_ci TestInput testCmd; 282c1ed15f1Sopenharmony_ci SetOptions(argc, argv, options, testCmd); 283c1ed15f1Sopenharmony_ci Test(testCmd); 284c1ed15f1Sopenharmony_ci exit(0); 285c1ed15f1Sopenharmony_ci} 286