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