• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params) == AUTH_ERRORCODE_SUCCESS) {
282         return AUTH_ERRORCODE_SUCCESS;
283     }
284 #if  POLICY_PRODUCT
285     if (CheckSvcPolicies(g_productPolicies, g_productPolicySize, &params) == AUTH_ERRORCODE_SUCCESS) {
286         return AUTH_ERRORCODE_SUCCESS;
287     }
288 #endif
289     if (CheckSvcPolicies(g_registryPolicies, g_regPoliciesSize, &params) == 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