1 /*
2 * Copyright (c) 2020-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 "ipc_auth.h"
17
18 #include <securec.h>
19 #include <stdbool.h>
20 #include <string.h>
21
22 #ifdef OHOS_APPFWK_ENABLE
23 #include "bundle_manager.h"
24 #endif
25 #include "log.h"
26
27 #include "ipc_auth_err.h"
28 #include "policy_preset.h"
29 #include "policy_preset_product.h"
30 #include "policy_registry.h"
31
32 static unsigned int g_systemSvcUids[] = {1, 2, 0, 6, 7, 8, 9, 10, 11, 12, 19, 20, 3046};
33
34 static unsigned int g_systemSvcUidSize = sizeof(g_systemSvcUids) / sizeof(unsigned int);
35
IsUidValid(unsigned int uid)36 static int IsUidValid(unsigned int uid)
37 {
38 for (int i = 0; i < g_systemSvcUidSize; i++) {
39 if (g_systemSvcUids[i] == uid) {
40 return AUTH_ERRORCODE_SUCCESS;
41 }
42 }
43 return AUTH_ERRORCODE_INVALID_UID;
44 }
45
46 #ifdef OHOS_APPFWK_ENABLE
GetUidByBundleName(const char * bundleName,unsigned int * uid)47 static int GetUidByBundleName(const char *bundleName, unsigned int *uid)
48 {
49 BundleInfo bundleInfo = {0};
50 if (GetBundleInfo(bundleName, 0, &bundleInfo) != 0) {
51 HILOG_ERROR(HILOG_MODULE_APP, "Invalid bundleName, [name: %s][line: %d]", bundleName, __LINE__);
52 return AUTH_ERRORCODE_INVALID_BUNDLENAME;
53 }
54 *uid = bundleInfo.uid;
55 return AUTH_ERRORCODE_SUCCESS;
56 }
57 #endif
58
StrcmpWithNull(const char * s1,const char * s2)59 static int StrcmpWithNull(const char *s1, const char *s2)
60 {
61 if ((s1 == NULL) && (s2 == NULL)) {
62 return 0;
63 }
64 if ((s1 == NULL) || (s2 == NULL)) {
65 return -1;
66 }
67 return strcmp(s1, s2);
68 }
69
SetPolicy(const IpcPolicy * policy,PolicyTrans * policyTrans)70 static void SetPolicy(const IpcPolicy *policy, PolicyTrans *policyTrans)
71 {
72 switch (policy->type) {
73 case RANGE:
74 policyTrans->type = RANGE;
75 policyTrans->uidMax = policy->uidMax;
76 policyTrans->uidMin = policy->uidMin;
77 break;
78 case FIXED:
79 policyTrans->type = FIXED;
80 for (int m = 0; m < UID_SIZE; m++) {
81 policyTrans->fixedUid[m] = policy->fixedUid[m];
82 }
83 break;
84 #ifdef OHOS_APPFWK_ENABLE
85 case BUNDLENAME: {
86 policyTrans->type = BUNDLENAME;
87 unsigned int uid = 0;
88 int ret = GetUidByBundleName(policy->bundleName, &uid);
89 if (ret != AUTH_ERRORCODE_SUCCESS) {
90 break;
91 }
92 policyTrans->fixedUid[0] = uid;
93 break;
94 }
95 #endif
96 default:
97 break;
98 }
99 }
100
IsPolicyValid(enum PolicyType type)101 static bool IsPolicyValid(enum PolicyType type)
102 {
103 if ((type == RANGE) || (type == FIXED)) {
104 return true;
105 }
106 #ifdef OHOS_APPFWK_ENABLE
107 if (type == BUNDLENAME) {
108 return true;
109 }
110 #endif
111 return false;
112 }
113
SetPolicies(const FeaturePolicy * featurePolicy,PolicyTrans ** policies,unsigned int * policyNum)114 static int SetPolicies(const FeaturePolicy *featurePolicy, PolicyTrans **policies, unsigned int *policyNum)
115 {
116 int num = 0;
117 for (int k = 0; k < POLICY_SIZE; k++) {
118 if (IsPolicyValid(featurePolicy->policies[k].type)) {
119 num++;
120 }
121 }
122 int allocSize = sizeof(PolicyTrans) * num;
123 if (allocSize == 0) {
124 return AUTH_ERRORCODE_NO_POLICY_SET;
125 }
126 *policies = (PolicyTrans *)malloc(allocSize);
127 if (*policies == NULL) {
128 HILOG_ERROR(HILOG_MODULE_APP, "Malloc failed, [line: %d]", __LINE__);
129 return AUTH_ERRORCODE_MALLOC_FAIL;
130 }
131 if (memset_s(*policies, allocSize, 0x0, allocSize) != EOK) {
132 HILOG_ERROR(HILOG_MODULE_APP, "Memset failed, [line: %d]", __LINE__);
133 free(*policies);
134 *policies = NULL;
135 return AUTH_ERRORCODE_MEMSET_FAIL;
136 }
137 int index = 0;
138 for (int k = 0; k < POLICY_SIZE; k++) {
139 IpcPolicy policy = featurePolicy->policies[k];
140 if (IsPolicyValid(policy.type)) {
141 SetPolicy(&policy, *policies + index);
142 index++;
143 }
144 }
145 *policyNum = num;
146 return AUTH_ERRORCODE_SUCCESS;
147 }
148
SetPresetPolicies(const PolicySetting presetPolicy[],int policySize,RegParams params,PolicyTrans ** policies,unsigned int * policyNum)149 static int SetPresetPolicies(const PolicySetting presetPolicy[], int policySize, RegParams params,
150 PolicyTrans **policies, unsigned int *policyNum)
151 {
152 for (int i = 0; i < policySize; i++) {
153 if (strcmp(presetPolicy[i].service, params.service) != 0) {
154 continue;
155 }
156 for (int j = 0; j < presetPolicy[i].featureNum; j++) {
157 FeaturePolicy *featurePolicy = (FeaturePolicy *) presetPolicy[i].features + j;
158 if (StrcmpWithNull(featurePolicy->feature, params.feature) != 0) {
159 continue;
160 }
161 if (SetPolicies(featurePolicy, policies, policyNum) == AUTH_ERRORCODE_SUCCESS) {
162 return AUTH_ERRORCODE_SUCCESS;
163 }
164 return AUTH_ERRORCODE_NO_POLICY_SET;
165 }
166 return AUTH_ERRORCODE_NO_POLICY_SET;
167 }
168 return AUTH_ERRORCODE_POLICY_NOT_FOUND;
169 }
170
GetCommunicationStrategy(RegParams params,PolicyTrans ** policies,unsigned int * policyNum)171 int GetCommunicationStrategy(RegParams params, PolicyTrans **policies, unsigned int *policyNum)
172 {
173 if (IsUidValid(params.uid) == AUTH_ERRORCODE_INVALID_UID) {
174 HILOG_ERROR(HILOG_MODULE_APP, "Invalid uid, [svc: %s][ft: %s][uid:%u][pid: %u][line: %d]",
175 params.service, params.feature, params.uid, params.pid, __LINE__);
176 return AUTH_ERRORCODE_INVALID_UID;
177 }
178
179 int res = SetPresetPolicies(g_presetPolicies, g_presetPolicySize, params, policies, policyNum);
180 if (res != AUTH_ERRORCODE_POLICY_NOT_FOUND) {
181 return res;
182 }
183 #if POLICY_PRODUCT
184 res = SetPresetPolicies(g_productPolicies, g_productPolicySize, params, policies, policyNum);
185 if (res != AUTH_ERRORCODE_POLICY_NOT_FOUND) {
186 return res;
187 }
188 #endif
189 res = SetPresetPolicies(g_registryPolicies, g_regPoliciesSize, params, policies, policyNum);
190 if (res != AUTH_ERRORCODE_POLICY_NOT_FOUND) {
191 return res;
192 }
193 return AUTH_ERRORCODE_NO_POLICY_SET;
194 }
195
IsUidFixed(const int fixedUid[],unsigned int consumerUid)196 static int IsUidFixed(const int fixedUid[], unsigned int consumerUid)
197 {
198 for (int m = 0; m < UID_SIZE; m++) {
199 if (fixedUid[m] == consumerUid) {
200 return AUTH_ERRORCODE_SUCCESS;
201 }
202 }
203 return AUTH_ERRORCODE_ACCESS_DENIED;
204 }
205
CheckPolicy(const IpcPolicy * policy,unsigned int consumerUid)206 static int CheckPolicy(const IpcPolicy *policy, unsigned int consumerUid)
207 {
208 switch (policy->type) {
209 case RANGE:
210 if (consumerUid >= policy->uidMin && consumerUid <= policy->uidMax) {
211 return AUTH_ERRORCODE_SUCCESS;
212 }
213 break;
214 case FIXED:
215 if (IsUidFixed(policy->fixedUid, consumerUid) == AUTH_ERRORCODE_SUCCESS) {
216 return AUTH_ERRORCODE_SUCCESS;
217 }
218 break;
219 #ifdef OHOS_APPFWK_ENABLE
220 case BUNDLENAME: {
221 unsigned int uid = 0;
222 int ret = GetUidByBundleName(policy->bundleName, &uid);
223 if (ret != AUTH_ERRORCODE_SUCCESS) {
224 return ret;
225 }
226 if (uid == consumerUid) {
227 return AUTH_ERRORCODE_SUCCESS;
228 }
229 break;
230 }
231 #endif
232 default:
233 break;
234 }
235 return AUTH_ERRORCODE_ACCESS_DENIED;
236 }
237
CheckFeaturePolicies(const FeaturePolicy * featurePolicy,unsigned int consumerUid)238 static int CheckFeaturePolicies(const FeaturePolicy *featurePolicy, unsigned int consumerUid)
239 {
240 for (int k = 0; k < POLICY_SIZE; k++) {
241 IpcPolicy policy = featurePolicy->policies[k];
242 int ret = CheckPolicy(&policy, consumerUid);
243 if (ret == AUTH_ERRORCODE_SUCCESS) {
244 return ret;
245 }
246 }
247 return AUTH_ERRORCODE_ACCESS_DENIED;
248 }
249
CheckSvcPolicies(const PolicySetting policySetting[],int policySize,const AuthParams * params)250 static int CheckSvcPolicies(const PolicySetting policySetting[], int policySize, const AuthParams *params)
251 {
252 for (int i = 0; i < policySize; i++) {
253 if (strcmp(policySetting[i].service, params->providerService) != 0) {
254 continue;
255 }
256 for (int j = 0; j < policySetting[i].featureNum; j++) {
257 FeaturePolicy *featurePolicy = (FeaturePolicy *)policySetting[i].features + j;
258 char *s1 = featurePolicy->feature;
259 char *s2 = params->providerfeature;
260 if (StrcmpWithNull(s1, s2) != 0) {
261 continue;
262 }
263 int ret = CheckFeaturePolicies(featurePolicy, params->consumerUid);
264 if (ret == AUTH_ERRORCODE_SUCCESS) {
265 return ret;
266 }
267 break;
268 }
269 break;
270 }
271 return AUTH_ERRORCODE_ACCESS_DENIED;
272 }
273
IsCommunicationAllowed(AuthParams params)274 int IsCommunicationAllowed(AuthParams params)
275 {
276 if (CheckSvcPolicies(g_presetPolicies, g_presetPolicySize, ¶ms) == AUTH_ERRORCODE_SUCCESS) {
277 return AUTH_ERRORCODE_SUCCESS;
278 }
279 #if POLICY_PRODUCT
280 if (CheckSvcPolicies(g_productPolicies, g_productPolicySize, ¶ms) == AUTH_ERRORCODE_SUCCESS) {
281 return AUTH_ERRORCODE_SUCCESS;
282 }
283 #endif
284 if (CheckSvcPolicies(g_registryPolicies, g_regPoliciesSize, ¶ms) == AUTH_ERRORCODE_SUCCESS) {
285 return AUTH_ERRORCODE_SUCCESS;
286 }
287
288 HILOG_ERROR(HILOG_MODULE_APP,
289 "Access denied, [consumerUid: %u][consumerPid: %u][providerUid:%u][providerPid: %u][line: %d]",
290 params.consumerUid, params.consumerPid, params.providerUid, params.providerPid, __LINE__);
291 return AUTH_ERRORCODE_ACCESS_DENIED;
292 }
293