1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "unit_test.h"
17#include "selinux_error.h"
18#include "service_checker.h"
19#include "hdf_service_checker.h"
20#include "test_common.h"
21
22namespace OHOS {
23namespace Security {
24namespace SelinuxUnitTest {
25using namespace testing::ext;
26using namespace Selinux;
27const static std::string TEST_SERVICE_NAME = "test_service";
28const static std::string DEFAULT_SERVICE = "default_service";
29const static std::string DEFAULT_HDF_SERVICE = "default_hdf_service";
30const static std::string invalidSid = "invalid_sid";
31
32void SelinuxUnitTest::SetUpTestCase()
33{
34    // make test case clean
35}
36
37void SelinuxUnitTest::TearDownTestCase() {}
38
39void SelinuxUnitTest::SetUp() {}
40
41void SelinuxUnitTest::TearDown() {}
42
43void SelinuxUnitTest::CreateDataFile() const {}
44
45int GetSidForCurrentProcess(std::string &sid)
46{
47    char *con = nullptr;
48    if (getcon(&con) < 0) {
49        return -1;
50    }
51    sid = con;
52    freecon(con);
53    return 0;
54}
55
56/**
57 * @tc.name: HdfListServiceCheck001
58 * @tc.desc: HdfListServiceCheck test.
59 * @tc.type: FUNC
60 * @tc.require:AR000GJSDS
61 */
62HWTEST_F(SelinuxUnitTest, HdfListServiceCheck001, TestSize.Level1)
63{
64    std::string sid;
65    if (GetSidForCurrentProcess(sid) < 0) {
66        return;
67    }
68    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, HdfListServiceCheck(invalidSid.c_str()));
69    ASSERT_EQ(SELINUX_SUCC, HdfListServiceCheck(sid.c_str()));
70    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { list } for service=hdf_devmgr_class sid=" +
71                      sid + "' | grep 'tclass=hdf_devmgr_class'";
72    std::string cmdRes = RunCommand(cmd);
73    ASSERT_TRUE(cmdRes.find("hdf_devmgr_class") != std::string::npos);
74}
75
76/**
77 * @tc.name: HdfGetServiceCheck001
78 * @tc.desc: HdfGetServiceCheck test.
79 * @tc.type: FUNC
80 * @tc.require:AR000GJSDS
81 */
82HWTEST_F(SelinuxUnitTest, HdfGetServiceCheck001, TestSize.Level1)
83{
84    std::string sid;
85    if (GetSidForCurrentProcess(sid) < 0) {
86        return;
87    }
88    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, HdfGetServiceCheck(invalidSid.c_str(), TEST_SERVICE_NAME.c_str()));
89    ASSERT_EQ(-SELINUX_PTR_NULL, HdfGetServiceCheck(sid.c_str(), nullptr));
90    ASSERT_EQ(SELINUX_SUCC, HdfGetServiceCheck(sid.c_str(), TEST_SERVICE_NAME.c_str()));
91    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { get } for service=" + TEST_SERVICE_NAME +
92                      " sid=" + sid + "' | grep 'tclass=hdf_devmgr_class'";
93    std::string cmdRes = RunCommand(cmd);
94    ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos);
95}
96
97/**
98 * @tc.name: HdfAddServiceCheck001
99 * @tc.desc: HdfAddServiceCheck test.
100 * @tc.type: FUNC
101 * @tc.require:AR000GJSDS
102 */
103HWTEST_F(SelinuxUnitTest, HdfAddServiceCheck001, TestSize.Level1)
104{
105    std::string sid;
106    if (GetSidForCurrentProcess(sid) < 0) {
107        return;
108    }
109    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, HdfAddServiceCheck(invalidSid.c_str(), TEST_SERVICE_NAME.c_str()));
110    ASSERT_EQ(-SELINUX_PTR_NULL, HdfAddServiceCheck(sid.c_str(), nullptr));
111    ASSERT_EQ(SELINUX_SUCC, HdfAddServiceCheck(sid.c_str(), TEST_SERVICE_NAME.c_str()));
112    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { add } for service=" + TEST_SERVICE_NAME +
113                      " sid=" + sid + "' | grep 'tclass=hdf_devmgr_class'";
114    std::string cmdRes = RunCommand(cmd);
115    ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos);
116}
117
118/**
119 * @tc.name: ListServiceCheck001
120 * @tc.desc: ListServiceCheck test.
121 * @tc.type: FUNC
122 * @tc.require:AR000GJSDS
123 */
124HWTEST_F(SelinuxUnitTest, ListServiceCheck001, TestSize.Level1)
125{
126    std::string sid;
127    if (GetSidForCurrentProcess(sid) < 0) {
128        return;
129    }
130    ServiceChecker service(false);
131    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, service.ListServiceCheck(invalidSid));
132    ASSERT_EQ(SELINUX_SUCC, service.ListServiceCheck(sid));
133    std::string cmd =
134        "hilog -T Selinux -x | grep 'avc:  denied  { list } for service=samgr_class sid=" + sid +
135        "' | grep 'tclass=samgr_class'";
136    std::string cmdRes = RunCommand(cmd);
137    ASSERT_TRUE(cmdRes.find("samgr_class") != std::string::npos);
138}
139
140/**
141 * @tc.name: GetServiceCheck001
142 * @tc.desc: GetServiceCheck test.
143 * @tc.type: FUNC
144 * @tc.require:AR000GJSDS
145 */
146HWTEST_F(SelinuxUnitTest, GetServiceCheck001, TestSize.Level1)
147{
148    std::string sid;
149    if (GetSidForCurrentProcess(sid) < 0) {
150        return;
151    }
152    ServiceChecker service(false);
153    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, service.GetServiceCheck(invalidSid, TEST_SERVICE_NAME));
154    ASSERT_EQ(-SELINUX_ARG_INVALID, service.GetServiceCheck(sid, ""));
155    ASSERT_EQ(SELINUX_SUCC, service.GetServiceCheck(sid, TEST_SERVICE_NAME));
156    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { get } for service=" + TEST_SERVICE_NAME +
157                      " sid=" + sid + "' | grep 'tclass=samgr_class'";
158    std::string cmdRes = RunCommand(cmd);
159    ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos);
160}
161
162/**
163 * @tc.name: GetRemoteServiceCheck001
164 * @tc.desc: GetRemoteServiceCheck test.
165 * @tc.type: FUNC
166 * @tc.require:AR000GJSDS
167 */
168HWTEST_F(SelinuxUnitTest, GetRemoteServiceCheck001, TestSize.Level1)
169{
170    std::string sid;
171    if (GetSidForCurrentProcess(sid) < 0) {
172        return;
173    }
174    ServiceChecker service(false);
175    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, service.GetRemoteServiceCheck(invalidSid, TEST_SERVICE_NAME));
176    ASSERT_EQ(-SELINUX_ARG_INVALID, service.GetRemoteServiceCheck(sid, ""));
177    ASSERT_EQ(SELINUX_SUCC, service.GetRemoteServiceCheck(sid, TEST_SERVICE_NAME));
178    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { get_remote } for service=" + TEST_SERVICE_NAME +
179                      " sid=" + sid + "' | grep 'tclass=samgr_class'";
180    std::string cmdRes = RunCommand(cmd);
181    ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos);
182}
183
184/**
185 * @tc.name: AddServiceCheck001
186 * @tc.desc: AddServiceCheck test.
187 * @tc.type: FUNC
188 * @tc.require:AR000GJSDS
189 */
190HWTEST_F(SelinuxUnitTest, AddServiceCheck001, TestSize.Level1)
191{
192    std::string sid;
193    if (GetSidForCurrentProcess(sid) < 0) {
194        return;
195    }
196    ServiceChecker service(false);
197    ASSERT_EQ(-SELINUX_CHECK_CONTEXT_ERROR, service.AddServiceCheck(invalidSid, TEST_SERVICE_NAME));
198    ASSERT_EQ(-SELINUX_ARG_INVALID, service.AddServiceCheck(sid, ""));
199    ASSERT_EQ(SELINUX_SUCC, service.AddServiceCheck(sid, TEST_SERVICE_NAME));
200    std::string cmd = "hilog -T Selinux -x | grep 'avc:  denied  { add } for service=" + TEST_SERVICE_NAME +
201                      " sid=" + sid + "' | grep 'tclass=samgr_class'";
202    std::string cmdRes = RunCommand(cmd);
203    ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos);
204}
205} // namespace SelinuxUnitTest
206} // namespace Security
207} // namespace OHOS
208