1 /*
2  * Copyright (c) 2023 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 
17 #include <pthread.h>
18 #include <unistd.h>
19 #include "stdint.h"
20 #include "account_adapt.h"
21 #include "dlp_credential_client.h"
22 #include "dlp_permission_log.h"
23 #include "mock_utils.h"
24 #include "securec.h"
25 
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #define LOG_TAG "DlpCredentialService"
29 #endif
30 
31 static uint64_t g_requestId = 0;
32 static const size_t STRING_LEN = 256;
33 static const uint32_t MAX_CERT_LEN = 1024 * 1024;
34 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
35 
36 typedef struct PackPolicyCallbackTaskPara {
37     DLP_PackPolicyCallback callback;
38     uint32_t userId;
39     uint64_t requestId;
40     int errorCode;
41     DLP_PackPolicyParams* packParams;
42 } PackPolicyCallbackTaskPara;
43 
44 typedef struct RestorePolicyCallbackTaskPara {
45     DLP_RestorePolicyCallback callback;
46     uint32_t userId;
47     uint64_t requestId;
48     int errorCode;
49     DLP_EncPolicyData* encData;
50 } RestorePolicyCallbackTaskPara;
51 
FreePackPolicyCallbackTaskPara(PackPolicyCallbackTaskPara * taskParams)52 static void FreePackPolicyCallbackTaskPara(PackPolicyCallbackTaskPara* taskParams)
53 {
54     if (taskParams == NULL) {
55         return;
56     }
57     if (taskParams->packParams == NULL) {
58         free(taskParams);
59         return;
60     }
61     if (taskParams->packParams->featureName != NULL) {
62         free(taskParams->packParams->featureName);
63         taskParams->packParams->featureName = NULL;
64     }
65     if (taskParams->packParams->data != NULL) {
66         free(taskParams->packParams->data);
67         taskParams->packParams->data = NULL;
68     }
69     free(taskParams->packParams);
70     taskParams->packParams = NULL;
71     free(taskParams);
72 }
73 
FreeRestorePolicyCallbackTaskPara(RestorePolicyCallbackTaskPara * taskParams)74 static void FreeRestorePolicyCallbackTaskPara(RestorePolicyCallbackTaskPara* taskParams)
75 {
76     if (taskParams == NULL) {
77         return;
78     }
79     if (taskParams->encData == NULL) {
80         free(taskParams);
81         return;
82     }
83     if (taskParams->encData->featureName != NULL) {
84         free(taskParams->encData->featureName);
85         taskParams->encData->featureName = NULL;
86     }
87     if (taskParams->encData->data != NULL) {
88         free(taskParams->encData->data);
89         taskParams->encData->data = NULL;
90     }
91     free(taskParams->encData);
92     taskParams->encData = NULL;
93     free(taskParams);
94 }
95 
GetAccountName(uint32_t accountType,uint32_t userId,char ** account)96 bool GetAccountName(uint32_t accountType, uint32_t userId, char** account)
97 {
98     DLP_LOG_INFO("accountName form  accountType:%{public}d DOMAIN_ACCOUNT:%{public}d", accountType, DOMAIN_ACCOUNT);
99     if (accountType != DOMAIN_ACCOUNT) {
100         if (GetLocalAccountName(account, userId) != 0) {
101             DLP_LOG_ERROR("Get local account fail");
102             return false;
103         }
104     } else {
105         if (GetDomainAccountName(account) != 0) {
106             DLP_LOG_ERROR("Get local account fail");
107             return false;
108         }
109     }
110     return true;
111 }
112 
CheckAccount(const uint8_t * data,uint32_t len,uint32_t accountType,uint32_t userId,bool isNeedCheckList)113 static int CheckAccount(const uint8_t* data, uint32_t len, uint32_t accountType, uint32_t userId, bool isNeedCheckList)
114 {
115     int res = DLP_ERROR;
116     char owner[STRING_LEN];
117     char* account = NULL;
118     char user[STRING_LEN];
119     char everyone[STRING_LEN];
120     if (len < 0) {
121         DLP_LOG_ERROR("len error");
122         return DLP_ERROR;
123     }
124     char* policy = (char*)malloc(len + 1);
125     if (policy == NULL) {
126         DLP_LOG_ERROR("policy == NULL");
127         return DLP_ERROR;
128     }
129     if (memcpy_s(policy, len + 1, data, len) != EOK) {
130         DLP_LOG_ERROR("memcpy_s error");
131         goto end;
132     }
133     policy[len] = '\0';
134     if (!GetAccountName(accountType, userId, &account)) {
135         goto end;
136     }
137     if (sprintf_s(owner, STRING_LEN, "\"ownerAccountName\":\"%s\"", account) <= 0 ||
138         sprintf_s(user, STRING_LEN, "\"%s\":{", account) <= 0 ||
139         sprintf_s(everyone, STRING_LEN, "\"%s\":{", "everyone") <= 0) {
140         DLP_LOG_ERROR("sprintf_s owner error");
141         goto end;
142     }
143     if (!isNeedCheckList) {
144         if (strstr(policy, owner) == NULL) {
145             DLP_LOG_ERROR("policy owner check error");
146         } else {
147             res = DLP_SUCCESS;
148         }
149         goto end;
150     }
151     if (strstr(policy, owner) != NULL || strstr(policy, user) != NULL || strstr(policy, everyone) != NULL) {
152         res = DLP_SUCCESS;
153     } else {
154         DLP_LOG_ERROR("No permission to parse policy");
155     }
156 end:
157     (void)memset_s(policy, len + 1, 0, len + 1);
158     free(account);
159     free(policy);
160     return res;
161 }
162 
PackPolicyCallbackTask(void * inputTaskParams)163 static void* PackPolicyCallbackTask(void* inputTaskParams)
164 {
165     if (inputTaskParams == NULL) {
166         DLP_LOG_ERROR("InputTaskParams is null");
167         return NULL;
168     }
169     PackPolicyCallbackTaskPara* taskParams = (PackPolicyCallbackTaskPara*)inputTaskParams;
170     if (taskParams->callback == NULL) {
171         DLP_LOG_ERROR("Callback is null");
172         FreePackPolicyCallbackTaskPara(taskParams);
173         return NULL;
174     }
175     if (taskParams->packParams == NULL) {
176         DLP_LOG_ERROR("packParams is null");
177         FreePackPolicyCallbackTaskPara(taskParams);
178         return NULL;
179     }
180     const char* exInfo = "DlpRestorePolicyTest_NormalInput_ExtraInfo";
181     EncAndDecOptions encAndDecOptions = {
182         .opt = ALLOW_RECEIVER_DECRYPT_WITHOUT_USE_CLOUD,
183         .extraInfo = (uint8_t*)(exInfo),
184         .extraInfoLen = strlen(exInfo)
185     };
186     DLP_EncPolicyData outParams = {
187         .featureName = taskParams->packParams->featureName,
188         .data = taskParams->packParams->data,
189         .dataLen = taskParams->packParams->dataLen,
190         .options = encAndDecOptions,
191         .accountType = taskParams->packParams->accountType,
192     };
193     if (CheckAccount(taskParams->packParams->data, taskParams->packParams->dataLen, taskParams->packParams->accountType,
194         taskParams->userId, false) != DLP_SUCCESS) {
195         taskParams->errorCode = DLP_ERR_CONNECTION_NO_PERMISSION;
196         DLP_LOG_ERROR("get ownerAccount error");
197     }
198     taskParams->callback(taskParams->requestId, taskParams->errorCode, &outParams);
199     DLP_LOG_INFO("End thread, requestId: %{public}llu", (unsigned long long)taskParams->requestId);
200     FreePackPolicyCallbackTaskPara(taskParams);
201     return NULL;
202 }
203 
RestorePolicyCallbackTask(void * inputTaskParams)204 static void* RestorePolicyCallbackTask(void* inputTaskParams)
205 {
206     if (inputTaskParams == NULL) {
207         DLP_LOG_ERROR("InputTaskParams is null");
208         return NULL;
209     }
210     RestorePolicyCallbackTaskPara* taskParams = (RestorePolicyCallbackTaskPara*)inputTaskParams;
211     if ((taskParams->callback == NULL) || (taskParams->encData == NULL)) {
212         DLP_LOG_ERROR("Callback is null");
213         FreeRestorePolicyCallbackTaskPara(taskParams);
214         return NULL;
215     }
216 
217     DLP_RestorePolicyData outParams;
218     taskParams->errorCode = DLP_SUCCESS;
219     outParams.data = NULL;
220     outParams.dataLen = 0;
221     DlpBlob accountIdBlob = { taskParams->encData->receiverAccountInfo.accountIdLen,
222                               taskParams->encData->receiverAccountInfo.accountId };
223     bool accountStatus = IsAccountLogIn(taskParams->userId, taskParams->encData->accountType, &accountIdBlob);
224     if (!accountStatus) {
225         taskParams->errorCode = DLP_ERR_ACCOUNT_NOT_LOG_IN;
226         DLP_LOG_ERROR("Check accountStatus failed.");
227         goto end;
228     }
229     if (CheckAccount(taskParams->encData->data, taskParams->encData->dataLen, taskParams->encData->accountType,
230         taskParams->userId, true) != DLP_SUCCESS) {
231         taskParams->errorCode = DLP_ERR_CONNECTION_NO_PERMISSION;
232         DLP_LOG_ERROR("get ownerAccount error");
233         goto end;
234     }
235     ModifyParseData(&outParams.data, &outParams.dataLen, taskParams->encData->data, taskParams->encData->dataLen);
236 end:
237     taskParams->callback(taskParams->requestId, taskParams->errorCode, &outParams);
238     DLP_LOG_INFO("End thread, requestId: %{public}llu", (unsigned long long)taskParams->requestId);
239     FreeRestorePolicyCallbackTaskPara(taskParams);
240     return NULL;
241 }
242 
TransPackPolicyParams(const DLP_PackPolicyParams * params,DLP_PackPolicyCallback callback,uint64_t requestId,uint32_t userId)243 static PackPolicyCallbackTaskPara* TransPackPolicyParams(const DLP_PackPolicyParams* params,
244     DLP_PackPolicyCallback callback, uint64_t requestId, uint32_t userId)
245 {
246     PackPolicyCallbackTaskPara* taskParams = (PackPolicyCallbackTaskPara*)calloc(1, sizeof(PackPolicyCallbackTaskPara));
247     if (taskParams == NULL) {
248         goto err;
249     }
250     taskParams->callback = callback;
251     taskParams->userId = userId;
252     taskParams->requestId = requestId;
253     taskParams->errorCode = 0;
254     taskParams->packParams = (DLP_PackPolicyParams*)calloc(1, sizeof(DLP_PackPolicyParams));
255     if (taskParams->packParams == NULL) {
256         goto err;
257     }
258     taskParams->packParams->featureName = (char*)strdup(params->featureName);
259     if (taskParams->packParams->featureName == NULL) {
260         goto err;
261     }
262     taskParams->packParams->data = (uint8_t*)calloc(1, params->dataLen);
263     if (taskParams->packParams->data == NULL) {
264         goto err;
265     }
266     if (memcpy_s(taskParams->packParams->data, params->dataLen, params->data, params->dataLen) != EOK) {
267         goto err;
268     }
269     taskParams->packParams->dataLen = params->dataLen;
270     taskParams->packParams->accountType = params->accountType;
271     taskParams->packParams->options = params->options;
272     taskParams->packParams->senderAccountInfo = params->senderAccountInfo;
273     return taskParams;
274 err:
275     DLP_LOG_ERROR("Memory operate fail");
276     FreePackPolicyCallbackTaskPara(taskParams);
277     return NULL;
278 }
279 
DLP_PackPolicy(uint32_t osAccountId,const DLP_PackPolicyParams * params,DLP_PackPolicyCallback callback,uint64_t * requestId)280 int DLP_PackPolicy(
281     uint32_t osAccountId, const DLP_PackPolicyParams* params, DLP_PackPolicyCallback callback, uint64_t* requestId)
282 {
283     DLP_LOG_DEBUG("enter mock");
284     (void)osAccountId;
285     if (params == NULL || params->data == NULL || params->featureName == NULL || callback == NULL ||
286         requestId == NULL || params->dataLen == 0 || params->dataLen > MAX_CERT_LEN) {
287         DLP_LOG_ERROR("Callback or params is null");
288         return DLP_ERROR;
289     }
290 
291     pthread_mutex_lock(&g_mutex);
292     uint64_t id = ++g_requestId;  // Simulation allocation requestId.
293     pthread_mutex_unlock(&g_mutex);
294     *requestId = id;
295 
296     PackPolicyCallbackTaskPara* taskParams = TransPackPolicyParams(params, callback, *requestId, osAccountId);
297     if (taskParams == NULL) {
298         return DLP_ERROR;
299     }
300 
301     pthread_t t;
302     int32_t ret = pthread_create(&t, NULL, PackPolicyCallbackTask, taskParams);
303     if (ret != 0) {
304         DLP_LOG_ERROR("pthread_create failed %d\n", ret);
305         FreePackPolicyCallbackTaskPara(taskParams);
306         return DLP_ERROR;
307     }
308     ret = pthread_detach(t);
309     if (ret != 0) {
310         DLP_LOG_ERROR("pthread_detach failed %d\n", ret);
311         FreePackPolicyCallbackTaskPara(taskParams);
312         return DLP_ERROR;
313     }
314     DLP_LOG_INFO("Start new thread, requestId: %{public}llu", (unsigned long long)*requestId);
315     return DLP_SUCCESS;
316 }
317 
TransEncPolicyData(const DLP_EncPolicyData * params,DLP_RestorePolicyCallback callback,uint64_t requestId,uint32_t userId)318 static RestorePolicyCallbackTaskPara* TransEncPolicyData(
319     const DLP_EncPolicyData* params, DLP_RestorePolicyCallback callback, uint64_t requestId, uint32_t userId)
320 {
321     RestorePolicyCallbackTaskPara* taskParams =
322         (RestorePolicyCallbackTaskPara*)calloc(1, sizeof(RestorePolicyCallbackTaskPara));
323     if (taskParams == NULL) {
324         goto err;
325     }
326     taskParams->callback = callback;
327     taskParams->userId = userId;
328     taskParams->requestId = requestId;
329     taskParams->errorCode = 0;
330     taskParams->encData = (DLP_EncPolicyData*)calloc(1, sizeof(DLP_EncPolicyData));
331     if (taskParams->encData == NULL) {
332         goto err;
333     }
334     taskParams->encData->featureName = (char*)strdup(params->featureName);
335     if (taskParams->encData->featureName == NULL) {
336         goto err;
337     }
338     taskParams->encData->data = (uint8_t*)calloc(1, params->dataLen);
339     if (taskParams->encData->data == NULL) {
340         goto err;
341     }
342     if (memcpy_s(taskParams->encData->data, params->dataLen, params->data, params->dataLen) != EOK) {
343         goto err;
344     }
345     taskParams->encData->dataLen = params->dataLen;
346     taskParams->encData->accountType = params->accountType;
347     taskParams->encData->options = params->options;
348     taskParams->encData->receiverAccountInfo = params->receiverAccountInfo;
349     return taskParams;
350 err:
351     DLP_LOG_ERROR("Memory operate fail");
352     FreeRestorePolicyCallbackTaskPara(taskParams);
353     return NULL;
354 }
355 
DLP_RestorePolicy(uint32_t osAccountId,const DLP_EncPolicyData * params,DLP_RestorePolicyCallback callback,uint64_t * requestId)356 int DLP_RestorePolicy(
357     uint32_t osAccountId, const DLP_EncPolicyData* params, DLP_RestorePolicyCallback callback, uint64_t* requestId)
358 {
359     DLP_LOG_DEBUG("DLP enter mock");
360     if (params == NULL || params->data == NULL || params->featureName == NULL || callback == NULL ||
361         requestId == NULL || params->dataLen == 0 || params->dataLen > MAX_CERT_LEN) {
362         DLP_LOG_ERROR("Callback or params is null");
363         return DLP_ERROR;
364     }
365 
366     char *tmp1 = "test_appId_passed_1";
367     char *tmp2 = "test_appId_passed_2";
368     if (strcmp(params->featureName, tmp1) || strcmp(params->featureName, tmp2)) {
369         DLP_LOG_DEBUG("appId check pass");
370     } else {
371         return DLP_ERR_APPID_NOT_AUTHORIZED;
372     }
373 
374     pthread_mutex_lock(&g_mutex);
375     uint64_t id = ++g_requestId;  // Simulation allocation requestId.
376     pthread_mutex_unlock(&g_mutex);
377     *requestId = id;
378 
379     RestorePolicyCallbackTaskPara* taskParams = TransEncPolicyData(params, callback, *requestId, osAccountId);
380     if (taskParams == NULL) {
381         return DLP_ERROR;
382     }
383 
384     pthread_t t;
385     int32_t ret = pthread_create(&t, NULL, RestorePolicyCallbackTask, taskParams);
386     if (ret != 0) {
387         DLP_LOG_ERROR("pthread_create failed %d\n", ret);
388         FreeRestorePolicyCallbackTaskPara(taskParams);
389         return DLP_ERROR;
390     }
391     ret = pthread_detach(t);
392     if (ret != 0) {
393         DLP_LOG_ERROR("pthread_detach failed %d\n", ret);
394         FreeRestorePolicyCallbackTaskPara(taskParams);
395         return DLP_ERROR;
396     }
397     DLP_LOG_INFO("Start new thread, requestId: %{public}llu", (unsigned long long)*requestId);
398     return DLP_SUCCESS;
399 }
400 
DLP_AddPolicy(PolicyType type,const uint8_t * policy,uint32_t policyLen)401 int32_t DLP_AddPolicy(PolicyType type, const uint8_t *policy, uint32_t policyLen)
402 {
403     return DLP_SUCCESS;
404 }
405 
DLP_GetPolicy(PolicyType type,uint8_t * policy,uint32_t * policyLen)406 int32_t DLP_GetPolicy(PolicyType type, uint8_t *policy, uint32_t *policyLen)
407 {
408     if (*policyLen < 0) {
409         DLP_LOG_ERROR("policyLen is null");
410         return DLP_ERROR;
411     }
412     *policyLen = 0;
413     return DLP_SUCCESS;
414 }
415 
DLP_RemovePolicy(PolicyType type)416 int32_t DLP_RemovePolicy(PolicyType type)
417 {
418     return DLP_SUCCESS;
419 }
420 
DLP_CheckPermission(PolicyType type,PolicyHandle handle)421 int32_t  DLP_CheckPermission(PolicyType type, PolicyHandle handle)
422 {
423     return DLP_SUCCESS;
424 }