1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <unistd.h>
18
19 #include <gtest/gtest.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/ProcessState.h>
22 #include <utils/threads.h>
23 #include <utils/KeyedVector.h>
24 #include <utils/String8.h>
25 #include <utils/SystemClock.h>
26 #include <VehiclePropertyAccessControlForTesting.h>
27
28 namespace android {
29
30 class VehiclePropertyAccessControlTest : public testing::Test {
31 public:
VehiclePropertyAccessControlTest()32 VehiclePropertyAccessControlTest() {}
~VehiclePropertyAccessControlTest()33 ~VehiclePropertyAccessControlTest() {}
34
35 public:
36 static std::string xmlData;
37 static std::string xmlData2;
38 static const int32_t prop1;
39 static const int32_t prop2;
40 static const int32_t prop3;
41 static const int32_t uid1;
42 static const int32_t uid2;
43 static const int32_t uid3;
44
45 protected:
SetUp()46 void SetUp() {}
47
48 protected:
49 xmlDoc* doc;
50 VehiclePropertyAccessControlForTesting mVehiclePropertyAccessControl;
51 };
52
53 std::string VehiclePropertyAccessControlTest::xmlData =
54 "<ALLOW>"
55 "<PROPERTY name=\"PROP1\" value=\"0xA\">"
56 "<UID name=\"UID1\" access=\"r\" value=\"1000\"/>"
57 "</PROPERTY>"
58 "<PROPERTY name=\"PROP2\" value=\"0xB\">"
59 "<UID name=\"UID2\" access=\"w\" value=\"2000\"/>"
60 "</PROPERTY>"
61 "<PROPERTY name=\"PROP3\" value=\"0xC\">"
62 "<UID name=\"UID3\" access=\"rw\" value=\"3000\"/>"
63 "</PROPERTY>"
64 "</ALLOW>";
65
66 const int32_t VehiclePropertyAccessControlTest::prop1 = 0xa;
67 const int32_t VehiclePropertyAccessControlTest::prop2 = 0xb;
68 const int32_t VehiclePropertyAccessControlTest::prop3 = 0xc;
69 const int32_t VehiclePropertyAccessControlTest::uid1 = 1000;
70 const int32_t VehiclePropertyAccessControlTest::uid2 = 2000;
71 const int32_t VehiclePropertyAccessControlTest::uid3 = 3000;
72
TEST_F(VehiclePropertyAccessControlTest,isHexNotation)73 TEST_F(VehiclePropertyAccessControlTest, isHexNotation) {
74 static const std::string shouldPass[] =
75 {"0x01234567",
76 "0x01abcdef",
77 "0x01ABCDEF",
78 "0x0"};
79
80 static const std::string shouldFail[] =
81 {"0",
82 "0x",
83 "01234567",
84 "ABCDEF01",
85 "0xabi"};
86
87 for(auto& h : shouldPass) {
88 ASSERT_TRUE(mVehiclePropertyAccessControl.isHexNotation(h));
89 }
90
91 for(auto& h : shouldFail) {
92 ASSERT_FALSE(mVehiclePropertyAccessControl.isHexNotation(h));
93 }
94 }
95
TEST_F(VehiclePropertyAccessControlTest,accessToInt)96 TEST_F(VehiclePropertyAccessControlTest, accessToInt) {
97 static const char* property = "property";
98 static const char* uid = "uid";
99 struct ShouldPassType {std::string str; int32_t value;};
100 static const struct ShouldPassType shouldPass[] = {
101 {"r", VEHICLE_PROP_ACCESS_READ},
102 {"w", VEHICLE_PROP_ACCESS_WRITE},
103 {"rw", VEHICLE_PROP_ACCESS_READ_WRITE},
104 {"wr", VEHICLE_PROP_ACCESS_READ_WRITE}
105 };
106 static const char* shouldFail[] = {"rr", "ww", "rww", "rwr", "", "k"};
107 int32_t value;
108
109 for(auto& h : shouldPass) {
110 ASSERT_TRUE(mVehiclePropertyAccessControl.accessToInt(&value,
111 (const xmlChar*)property, (const xmlChar*)uid,
112 (const xmlChar*)h.str.c_str()));
113 ASSERT_EQ(h.value, value);
114 }
115
116 for(auto& h : shouldFail) {
117 ASSERT_FALSE(mVehiclePropertyAccessControl.accessToInt(&value,
118 (const xmlChar*)property, (const xmlChar*)uid, (const xmlChar*)h));
119 }
120 }
121
TEST_F(VehiclePropertyAccessControlTest,updateOrCreate)122 TEST_F(VehiclePropertyAccessControlTest, updateOrCreate) {
123 std::map<int32_t, int32_t> *accessMap;
124
125 // Empty the map
126 mVehiclePropertyAccessControl.emptyAccessControlMap();
127
128 // Make sure the property does not exist
129 ASSERT_FALSE(mVehiclePropertyAccessControl.getAccessToProperty(prop1,
130 &accessMap));
131
132 // Create the property and give uid read access
133 ASSERT_FALSE(mVehiclePropertyAccessControl.updateOrCreate(uid1, prop1,
134 VEHICLE_PROP_ACCESS_READ));
135
136 // Make sure the property was created
137 ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1,
138 &accessMap));
139
140 // Make sure uid has read access to the property
141 ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ);
142
143 // Give uid2 read/write access to the property
144 ASSERT_FALSE(mVehiclePropertyAccessControl.updateOrCreate(uid2, prop1,
145 VEHICLE_PROP_ACCESS_READ_WRITE));
146
147 // Get the accessMap
148 ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1,
149 &accessMap));
150 // Make sure uid2 has read/write access to the property
151 ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_READ_WRITE);
152
153 // Make sure uid still has read access to the property
154 ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ);
155
156 // Change uid access to write for property
157 ASSERT_TRUE(mVehiclePropertyAccessControl.updateOrCreate(uid1, prop1,
158 VEHICLE_PROP_ACCESS_WRITE));
159
160 // Get the accessMap
161 ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1,
162 &accessMap));
163
164 // Make sure uid has write access to property
165 ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_WRITE);
166
167 // Make sure uid2 has read write access to property
168 ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_READ_WRITE);
169 }
170
TEST_F(VehiclePropertyAccessControlTest,populate)171 TEST_F(VehiclePropertyAccessControlTest, populate) {
172 xmlNode* root_element;
173 std::map<int32_t, int32_t> *accessMap;
174
175 // Empty the map
176 mVehiclePropertyAccessControl.emptyAccessControlMap();
177
178 doc = xmlReadMemory(xmlData.c_str(), xmlData.length(), NULL, NULL, 0);
179 ASSERT_TRUE(doc != NULL);
180 root_element = xmlDocGetRootElement(doc);
181 ASSERT_TRUE(root_element != NULL);
182
183 bool result = mVehiclePropertyAccessControl.populate(root_element->children);
184
185 ASSERT_TRUE(result);
186
187 // Get the accessMap
188 ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop1,
189 &accessMap));
190
191 // Make sure uid still has read access to the property
192 ASSERT_EQ((*accessMap)[uid1], VEHICLE_PROP_ACCESS_READ);
193
194 // Get the accessMap
195 ASSERT_TRUE(mVehiclePropertyAccessControl.getAccessToProperty(prop2,
196 &accessMap));
197
198 // Make sure uid still has write access to the property
199 ASSERT_EQ((*accessMap)[uid2], VEHICLE_PROP_ACCESS_WRITE);
200
201 ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop1, uid1, 0));
202 ASSERT_FALSE(mVehiclePropertyAccessControl.testAccess(prop1, uid1, 1));
203 ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop2, uid2, 1));
204 ASSERT_FALSE(mVehiclePropertyAccessControl.testAccess(prop2, uid2, 0));
205 ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop3, uid3, 1));
206 ASSERT_TRUE(mVehiclePropertyAccessControl.testAccess(prop3, uid3, 0));
207
208 static const std::string dump_msg =
209 "UID 1000: property 0x0000000a, access read\n"
210 "UID 2000: property 0x0000000b, access write\n"
211 "UID 3000: property 0x0000000c, access read/write\n";
212
213 String8 msg;
214 mVehiclePropertyAccessControl.dump(msg);
215
216 ASSERT_EQ(dump_msg.compare(msg.string()), 0);
217
218 }
219
TEST_F(VehiclePropertyAccessControlTest,init)220 TEST_F(VehiclePropertyAccessControlTest, init) {
221 xmlFreeDoc(doc);
222 xmlCleanupParser();
223 // Empty the map
224 mVehiclePropertyAccessControl.emptyAccessControlMap();
225 ASSERT_TRUE(mVehiclePropertyAccessControl.init());
226 }
227 }; // namespace android
228