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 #include "dlp_credential.h"
17 #include <thread>
18 #include <unistd.h>
19 #include <unordered_map>
20 #include "account_adapt.h"
21 #include "bundle_manager_adapter.h"
22 #include "dlp_credential_client.h"
23 #include "dlp_policy_mgr_client.h"
24 #include "dlp_permission.h"
25 #include "dlp_permission_log.h"
26 #include "dlp_permission_serializer.h"
27 #include "ipc_skeleton.h"
28 #include "ohos_account_kits.h"
29 #include "os_account_manager.h"
30 #include "parameters.h"
31 #include "permission_policy.h"
32 #include "securec.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace DlpPermission {
37 using namespace OHOS::AppExecFwk;
38 namespace {
39 const std::string LOCAL_ENCRYPTED_CERT = "encryptedPolicy";
40 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "DlpCredential"};
41 static const size_t MAX_REQUEST_NUM = 100;
42 static const uint32_t MAX_APPID_LIST_NUM = 250;
43 static const uint32_t MAX_APPID_LENGTH = 200;
44 static const uint32_t DLP_RESTORE_POLICY_DATA_LEN = 1024 * 200;
45 static const std::string POLICY_CERT = "policyCert";
46 static const std::string DLP_MANAGER_BUNDLE_NAME = "com.ohos.dlpmanager";
47 static std::unordered_map<uint64_t, RequestInfo> g_requestMap;
48 static std::unordered_map<uint64_t, DlpAccountType> g_requestAccountTypeMap;
49 static const std::string DEVELOPER_MODE = "const.security.developermode.state";
50 std::mutex g_lockRequest;
51 } // namespace
52
IsDlpCredentialHuksError(int errorCode)53 static bool IsDlpCredentialHuksError(int errorCode)
54 {
55 return ((errorCode >= DLP_ERR_GENERATE_KEY_FAILED) && (errorCode < DLP_ERR_IPC_INTERNAL_FAILED));
56 }
57
IsDlpCredentialIpcError(int errorCode)58 static bool IsDlpCredentialIpcError(int errorCode)
59 {
60 return ((errorCode >= DLP_ERR_IPC_INTERNAL_FAILED) && (errorCode < DLP_ERR_CONNECTION_TIME_OUT));
61 }
62
IsDlpCredentialServerError(int errorCode)63 static bool IsDlpCredentialServerError(int errorCode)
64 {
65 return ((errorCode >= DLP_ERR_CONNECTION_TIME_OUT) && (errorCode < DLP_ERR_FILE_PATH));
66 }
67
IsNoPermissionError(int errorCode)68 static bool IsNoPermissionError(int errorCode)
69 {
70 return ((errorCode == DLP_ERR_CONNECTION_VIP_RIGHT_EXPIRED) || (errorCode == DLP_ERR_CONNECTION_NO_PERMISSION));
71 }
72
IsNoInternetError(int errorCode)73 static bool IsNoInternetError(int errorCode)
74 {
75 return ((errorCode == DLP_ERR_CONNECTION_TIME_OUT) || (errorCode == DLP_ERR_TOKEN_CONNECTION_TIME_OUT) ||
76 (errorCode == DLP_ERR_TOKEN_CONNECTION_FAIL));
77 }
78
ConvertCredentialError(int errorCode)79 static int32_t ConvertCredentialError(int errorCode)
80 {
81 if (errorCode == DLP_SUCCESS) {
82 return DLP_OK;
83 }
84 if (errorCode == DLP_ERR_CONNECTION_POLICY_PERMISSION_EXPIRED) {
85 return DLP_CREDENTIAL_ERROR_TIME_EXPIRED;
86 }
87 if (errorCode == DLP_ERR_APPID_NOT_AUTHORIZED) {
88 return DLP_CREDENTIAL_ERROR_APPID_NOT_AUTHORIZED;
89 }
90 if (errorCode == DLP_ERR_CALLBACK_TIME_OUT) {
91 return DLP_CREDENTIAL_ERROR_SERVER_TIME_OUT_ERROR;
92 }
93 if (errorCode == DLP_ERR_ACCOUNT_NOT_LOG_IN) {
94 return DLP_CREDENTIAL_ERROR_NO_ACCOUNT_ERROR;
95 }
96 if (IsNoInternetError(errorCode)) {
97 return DLP_CREDENTIAL_ERROR_NO_INTERNET;
98 }
99 if (IsNoPermissionError(errorCode)) {
100 return DLP_CREDENTIAL_ERROR_NO_PERMISSION_ERROR;
101 }
102 if (IsDlpCredentialHuksError(errorCode)) {
103 return DLP_CREDENTIAL_ERROR_HUKS_ERROR;
104 }
105 if (IsDlpCredentialIpcError(errorCode)) {
106 return DLP_CREDENTIAL_ERROR_IPC_ERROR;
107 }
108 if (IsDlpCredentialServerError(errorCode)) {
109 return DLP_CREDENTIAL_ERROR_SERVER_ERROR;
110 }
111 return DLP_CREDENTIAL_ERROR_COMMON_ERROR;
112 }
113
GetCallbackFromRequestMap(uint64_t requestId,RequestInfo & info)114 static bool GetCallbackFromRequestMap(uint64_t requestId, RequestInfo& info)
115 {
116 DLP_LOG_INFO(LABEL, "Get callback, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
117 std::lock_guard<std::mutex> lock(g_lockRequest);
118 auto iter = g_requestMap.find(requestId);
119 if (iter != g_requestMap.end()) {
120 info = iter->second;
121 g_requestMap.erase(requestId);
122 return true;
123 }
124 DLP_LOG_ERROR(LABEL, "Callback not found");
125 return false;
126 }
127
InsertCallbackToRequestMap(uint64_t requestId,const RequestInfo & info)128 static int32_t InsertCallbackToRequestMap(uint64_t requestId, const RequestInfo& info)
129 {
130 DLP_LOG_DEBUG(LABEL, "insert request, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
131 if (g_requestMap.count(requestId) > 0) {
132 DLP_LOG_ERROR(LABEL, "Duplicate task, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
133 return DLP_SERVICE_ERROR_CREDENTIAL_TASK_DUPLICATE;
134 }
135 g_requestMap[requestId] = info;
136 return DLP_OK;
137 }
138
QueryRequestIdle()139 static int32_t QueryRequestIdle()
140 {
141 DLP_LOG_DEBUG(LABEL, "Total tasks: %{public}zu", g_requestMap.size());
142 if (g_requestMap.size() > MAX_REQUEST_NUM) {
143 DLP_LOG_ERROR(LABEL, "Task busy");
144 return DLP_SERVICE_ERROR_CREDENTIAL_BUSY;
145 }
146 return DLP_OK;
147 }
148
DlpPackPolicyCallback(uint64_t requestId,int errorCode,DLP_EncPolicyData * outParams)149 static void DlpPackPolicyCallback(uint64_t requestId, int errorCode, DLP_EncPolicyData* outParams)
150 {
151 DLP_LOG_INFO(LABEL, "Called, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
152 RequestInfo info;
153 if (!GetCallbackFromRequestMap(requestId, info)) {
154 DLP_LOG_ERROR(LABEL, "callback is null");
155 return;
156 }
157
158 if (errorCode != 0) {
159 DLP_LOG_ERROR(LABEL, "Pack Policy error, errorCode: %{public}d", errorCode);
160
161 // split DLP_CREDENTIAL error code by different situations
162 errorCode = (errorCode == DLP_ERR_TOKEN_CONNECTION_FAIL) ?
163 DLP_CREDENTIAL_ERROR_SERVER_ERROR : ConvertCredentialError(errorCode);
164 info.callback->OnGenerateDlpCertificate(errorCode, std::vector<uint8_t>());
165 return;
166 }
167
168 if (outParams == nullptr || outParams->data == nullptr || outParams->featureName == nullptr) {
169 DLP_LOG_ERROR(LABEL, "Params is null");
170 info.callback->OnGenerateDlpCertificate(DLP_SERVICE_ERROR_VALUE_INVALID, std::vector<uint8_t>());
171 return;
172 }
173 unordered_json encDataJson;
174 int32_t res = DlpPermissionSerializer::GetInstance().SerializeEncPolicyData(*outParams, encDataJson);
175 if (res != DLP_OK) {
176 DLP_LOG_ERROR(LABEL, "Serialize fail");
177 return;
178 }
179 std::string encData = encDataJson.dump();
180 std::vector<uint8_t> cert(encData.begin(), encData.end());
181 info.callback->OnGenerateDlpCertificate(errorCode, cert);
182 }
183
GetNewCert(const unordered_json & plainPolicyJson,std::vector<uint8_t> & cert,DlpAccountType ownerAccountType)184 static int32_t GetNewCert(const unordered_json& plainPolicyJson, std::vector<uint8_t>& cert,
185 DlpAccountType ownerAccountType)
186 {
187 #ifdef SUPPORT_DLP_CREDENTIAL
188 unordered_json json;
189 if (plainPolicyJson.find(POLICY_CERT) == plainPolicyJson.end() || !plainPolicyJson.at(POLICY_CERT).is_object()) {
190 DLP_LOG_ERROR(LABEL, "can not found policyCert");
191 return DLP_CREDENTIAL_ERROR_SERVER_ERROR;
192 }
193 plainPolicyJson.at(POLICY_CERT).get_to(json);
194 std::string encData = json.dump();
195 DLP_EncPolicyData params;
196 params.data = reinterpret_cast<uint8_t*>(strdup(encData.c_str()));
197 if (params.data == nullptr) {
198 DLP_LOG_ERROR(LABEL, "Strdup failed.");
199 return DLP_CREDENTIAL_ERROR_VALUE_INVALID;
200 }
201 params.dataLen = encData.length();
202 params.accountType = static_cast<AccountType>(ownerAccountType);
203 unordered_json encDataJson;
204 int32_t res = DlpPermissionSerializer::GetInstance().SerializeEncPolicyData(params, encDataJson);
205 if (res != DLP_OK) {
206 DLP_LOG_ERROR(LABEL, "Serialize fail");
207 free(params.data);
208 params.data = nullptr;
209 return res;
210 }
211 free(params.data);
212 params.data = nullptr;
213 std::string encDataStr = encDataJson.dump();
214 cert.assign(encDataStr.begin(), encDataStr.end());
215 #endif
216 return DLP_OK;
217 }
218
DlpRestorePolicyCallbackCheck(sptr<IDlpPermissionCallback> callback,DlpAccountType accountType,int errorCode,DLP_RestorePolicyData * outParams,PermissionPolicy policyInfo)219 static int32_t DlpRestorePolicyCallbackCheck(sptr<IDlpPermissionCallback> callback, DlpAccountType accountType,
220 int errorCode, DLP_RestorePolicyData* outParams, PermissionPolicy policyInfo)
221 {
222 if (callback == nullptr || accountType == INVALID_ACCOUNT) {
223 DLP_LOG_ERROR(LABEL, "callback is null or accountType is 0");
224 return DLP_SERVICE_ERROR_VALUE_INVALID;
225 }
226 if (errorCode != 0) {
227 DLP_LOG_ERROR(LABEL, "Restore Policy error, errorCode: %{public}d", errorCode);
228 callback->OnParseDlpCertificate(ConvertCredentialError(errorCode), policyInfo, {});
229 return DLP_SERVICE_ERROR_VALUE_INVALID;
230 }
231 if (outParams == nullptr || outParams->data == nullptr) {
232 DLP_LOG_ERROR(LABEL, "Params is null");
233 callback->OnParseDlpCertificate(DLP_SERVICE_ERROR_VALUE_INVALID, policyInfo, {});
234 return DLP_SERVICE_ERROR_VALUE_INVALID;
235 }
236 return DLP_OK;
237 }
238
FreeBuffer(char ** buff,uint32_t buffLen)239 static void FreeBuffer(char** buff, uint32_t buffLen)
240 {
241 if (buff == nullptr) {
242 DLP_LOG_ERROR(LABEL, "Uint8 buffer is already nullptr.");
243 return;
244 }
245 if (*buff != nullptr) {
246 memset_s(*buff, buffLen, 0, buffLen);
247 delete[] *buff;
248 *buff = nullptr;
249 }
250 }
251
SetPermissionPolicy(DLP_RestorePolicyData * outParams,sptr<IDlpPermissionCallback> callback,PermissionPolicy & policyInfo,unordered_json & jsonObj)252 static bool SetPermissionPolicy(DLP_RestorePolicyData* outParams, sptr<IDlpPermissionCallback> callback,
253 PermissionPolicy& policyInfo, unordered_json& jsonObj)
254 {
255 if (outParams->dataLen > DLP_RESTORE_POLICY_DATA_LEN) {
256 DLP_LOG_ERROR(LABEL, "outParams->dataLen is out of size.");
257 return false;
258 }
259 auto policyStr = new (std::nothrow) char[outParams->dataLen + 1];
260 if (policyStr == nullptr) {
261 DLP_LOG_ERROR(LABEL, "New memory fail");
262 callback->OnParseDlpCertificate(DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL, policyInfo, {});
263 return false;
264 }
265 if (memcpy_s(policyStr, outParams->dataLen + 1, outParams->data, outParams->dataLen) != EOK) {
266 DLP_LOG_ERROR(LABEL, "Memcpy_s fail");
267 FreeBuffer(&policyStr, outParams->dataLen + 1);
268 callback->OnParseDlpCertificate(DLP_SERVICE_ERROR_MEMORY_OPERATE_FAIL, policyInfo, {});
269 return false;
270 }
271 policyStr[outParams->dataLen] = '\0';
272 jsonObj = unordered_json::parse(policyStr, policyStr + outParams->dataLen + 1, nullptr, false);
273 if (jsonObj.is_discarded() || (!jsonObj.is_object())) {
274 DLP_LOG_ERROR(LABEL, "JsonObj is discarded");
275 FreeBuffer(&policyStr, outParams->dataLen + 1);
276 callback->OnParseDlpCertificate(DLP_SERVICE_ERROR_JSON_OPERATE_FAIL, policyInfo, {});
277 return false;
278 }
279 FreeBuffer(&policyStr, outParams->dataLen + 1);
280 auto res = DlpPermissionSerializer::GetInstance().DeserializeDlpPermission(jsonObj, policyInfo);
281 if (res != DLP_OK) {
282 callback->OnParseDlpCertificate(res, policyInfo, {});
283 return false;
284 }
285 return true;
286 }
287
CheckDebugPermission(const RequestInfo & requestInfo,PermissionPolicy & policyInfo)288 static int32_t CheckDebugPermission(const RequestInfo& requestInfo, PermissionPolicy& policyInfo)
289 {
290 bool isDebugApp = (requestInfo.appProvisionType == AppExecFwk::Constants::APP_PROVISION_TYPE_DEBUG);
291 if (!isDebugApp) {
292 return DLP_OK;
293 }
294 bool isDeveloperMode = OHOS::system::GetBoolParameter(DEVELOPER_MODE, false);
295 if (isDeveloperMode && policyInfo.debug_) {
296 return DLP_OK;
297 }
298 DLP_LOG_ERROR(LABEL, "CheckDebugPermission error, isDeveloperMode=%{public}d "
299 "isDebugApp=%{public}d isDebugFile=%{public}d.", isDeveloperMode, isDebugApp, policyInfo.debug_);
300 return DLP_SERVICE_ERROR_PERMISSION_DENY;
301 }
302
DlpRestorePolicyCallback(uint64_t requestId,int errorCode,DLP_RestorePolicyData * outParams)303 static void DlpRestorePolicyCallback(uint64_t requestId, int errorCode, DLP_RestorePolicyData* outParams)
304 {
305 DLP_LOG_INFO(LABEL, "Called, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
306 RequestInfo requestInfo;
307 if (!GetCallbackFromRequestMap(requestId, requestInfo)) {
308 DLP_LOG_ERROR(LABEL, "callback is null");
309 return;
310 }
311 PermissionPolicy policyInfo;
312 int32_t res = DlpRestorePolicyCallbackCheck(
313 requestInfo.callback, requestInfo.accountType, errorCode, outParams, policyInfo);
314 if (res != DLP_OK) {
315 return;
316 }
317 unordered_json jsonObj;
318 if (!SetPermissionPolicy(outParams, requestInfo.callback, policyInfo, jsonObj)) {
319 return;
320 }
321 policyInfo.ownerAccountType_ = requestInfo.accountType;
322 std::vector<uint8_t> cert;
323 res = GetNewCert(jsonObj, cert, requestInfo.accountType);
324 if (res != DLP_OK) {
325 requestInfo.callback->OnParseDlpCertificate(res, policyInfo, {});
326 return;
327 }
328 res = CheckDebugPermission(requestInfo, policyInfo);
329 if (res != DLP_OK) {
330 requestInfo.callback->OnParseDlpCertificate(res, policyInfo, {});
331 return;
332 }
333 requestInfo.callback->OnParseDlpCertificate(errorCode, policyInfo, cert);
334 }
335
GetInstance()336 DlpCredential& DlpCredential::GetInstance()
337 {
338 static DlpCredential instance;
339 return instance;
340 }
341
FreeDlpPackPolicyParams(DLP_PackPolicyParams & packPolicy)342 static void FreeDlpPackPolicyParams(DLP_PackPolicyParams& packPolicy)
343 {
344 if (packPolicy.featureName != nullptr) {
345 free(packPolicy.featureName);
346 packPolicy.featureName = nullptr;
347 }
348 if (packPolicy.data != nullptr) {
349 free(packPolicy.data);
350 packPolicy.data = nullptr;
351 }
352 if (packPolicy.senderAccountInfo.accountId != nullptr) {
353 free(packPolicy.senderAccountInfo.accountId);
354 packPolicy.senderAccountInfo.accountId = nullptr;
355 }
356 }
357
DlpCredential()358 DlpCredential::DlpCredential()
359 {}
360
PackPolicy(DLP_PackPolicyParams & packPolicy,DlpAccountType accountType,const sptr<IDlpPermissionCallback> & callback)361 static int32_t PackPolicy(DLP_PackPolicyParams &packPolicy, DlpAccountType accountType,
362 const sptr<IDlpPermissionCallback>& callback)
363 {
364 uint64_t requestId;
365 int32_t res = DLP_PackPolicy(GetCallingUserId(), &packPolicy, DlpPackPolicyCallback, &requestId);
366 if (res != 0) {
367 DLP_LOG_ERROR(LABEL, "Start request fail, error: %{public}d", res);
368 return ConvertCredentialError(res);
369 }
370 DLP_LOG_INFO(
371 LABEL, "Start request success, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
372 RequestInfo info = {
373 .callback = callback,
374 .accountType = accountType
375 };
376 return InsertCallbackToRequestMap(requestId, info);
377 }
378
GenerateDlpCertificate(const std::string & policy,const std::string & accountInfo,DlpAccountType accountType,const sptr<IDlpPermissionCallback> & callback)379 int32_t DlpCredential::GenerateDlpCertificate(const std::string& policy, const std::string& accountInfo,
380 DlpAccountType accountType, const sptr<IDlpPermissionCallback>& callback)
381 {
382 EncAndDecOptions encAndDecOptions = {
383 .opt = RECEIVER_DECRYPT_MUST_USE_CLOUD,
384 .extraInfo = nullptr,
385 .extraInfoLen = 0
386 };
387
388 AccountInfo accountCfg = {
389 .accountId = reinterpret_cast<uint8_t*>(strdup(accountInfo.c_str())),
390 .accountIdLen = accountInfo.size(),
391 };
392 if (accountCfg.accountId == nullptr) {
393 DLP_LOG_ERROR(LABEL, "Strdup failed.");
394 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
395 }
396
397 DLP_PackPolicyParams packPolicy = {
398 .featureName = strdup("dlp_permission_service"),
399 .data = reinterpret_cast<uint8_t*>(strdup(policy.c_str())),
400 .dataLen = policy.size(),
401 .options = encAndDecOptions,
402 .accountType = static_cast<AccountType>(accountType),
403 .senderAccountInfo = accountCfg,
404 .reserved = {0},
405 };
406 if (packPolicy.featureName == nullptr || packPolicy.data == nullptr) {
407 DLP_LOG_ERROR(LABEL, "Strdup failed.");
408 free(accountCfg.accountId);
409 accountCfg.accountId = nullptr;
410 FreeDlpPackPolicyParams(packPolicy);
411 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
412 }
413 int32_t res = 0;
414 {
415 std::lock_guard<std::mutex> lock(g_lockRequest);
416 int32_t status = QueryRequestIdle();
417 if (status != DLP_OK) {
418 FreeDlpPackPolicyParams(packPolicy);
419 return status;
420 }
421 res = PackPolicy(packPolicy, accountType, callback);
422 }
423 FreeDlpPackPolicyParams(packPolicy);
424 return res;
425 }
426
FreeDLPEncPolicyData(DLP_EncPolicyData & encPolicy)427 static void FreeDLPEncPolicyData(DLP_EncPolicyData& encPolicy)
428 {
429 if (encPolicy.featureName != nullptr) {
430 free(encPolicy.featureName);
431 encPolicy.featureName = nullptr;
432 }
433 if (encPolicy.data != nullptr) {
434 delete[] encPolicy.data;
435 encPolicy.data = nullptr;
436 }
437 if (encPolicy.options.extraInfo != nullptr) {
438 delete[] encPolicy.options.extraInfo;
439 encPolicy.options.extraInfo = nullptr;
440 }
441 if (encPolicy.receiverAccountInfo.accountId != nullptr) {
442 free(encPolicy.receiverAccountInfo.accountId);
443 encPolicy.receiverAccountInfo.accountId = nullptr;
444 }
445 }
446
GetLocalAccountName(std::string & account,const std::string & contactAccount,bool * isOwner)447 static int32_t GetLocalAccountName(std::string& account, const std::string& contactAccount, bool* isOwner)
448 {
449 std::pair<bool, AccountSA::OhosAccountInfo> accountInfo =
450 AccountSA::OhosAccountKits::GetInstance().QueryOhosAccountInfo();
451 if (accountInfo.first) {
452 account = accountInfo.second.uid_;
453 if (contactAccount.compare("") != 0 && contactAccount.compare(accountInfo.second.name_) == 0) {
454 *isOwner = true;
455 }
456 return DLP_OK;
457 }
458 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
459 }
460
GetDomainAccountName(std::string & account,const std::string & contactAccount,bool * isOwner)461 static int32_t GetDomainAccountName(std::string& account, const std::string& contactAccount, bool* isOwner)
462 {
463 int32_t userId;
464 int32_t res = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
465 if (res != 0) {
466 DLP_LOG_ERROR(LABEL, "GetForegroundOsAccountLocalId failed %{public}d", res);
467 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
468 }
469 AccountSA::OsAccountInfo osAccountInfo;
470 if (OHOS::AccountSA::OsAccountManager::QueryOsAccountById(userId, osAccountInfo) != 0) {
471 DLP_LOG_ERROR(LABEL, "GetOsAccountLocalIdFromDomain return not 0");
472 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
473 }
474 AccountSA::DomainAccountInfo domainInfo;
475 osAccountInfo.GetDomainInfo(domainInfo);
476 if (domainInfo.accountName_.empty()) {
477 DLP_LOG_ERROR(LABEL, "accountName_ empty");
478 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
479 }
480 if (contactAccount.compare("") != 0 && contactAccount.compare(domainInfo.accountName_) == 0) {
481 *isOwner = true;
482 }
483 account = domainInfo.accountId_;
484 return DLP_OK;
485 }
486
GetAccoutInfo(DlpAccountType accountType,AccountInfo & accountCfg,const std::string & contactAccount,bool * isOwner)487 static int32_t GetAccoutInfo(DlpAccountType accountType, AccountInfo& accountCfg,
488 const std::string& contactAccount, bool* isOwner)
489 {
490 std::string account;
491 if (accountType == DOMAIN_ACCOUNT) {
492 if (GetDomainAccountName(account, contactAccount, isOwner) != DLP_OK) {
493 DLP_LOG_ERROR(LABEL, "query GetDomainAccountName failed");
494 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
495 }
496 } else {
497 if (GetLocalAccountName(account, contactAccount, isOwner) != DLP_OK) {
498 DLP_LOG_ERROR(LABEL, "query GetLocalAccountName failed");
499 return DLP_PARSE_ERROR_ACCOUNT_INVALID;
500 }
501 }
502
503 accountCfg = {
504 .accountId = reinterpret_cast<uint8_t*>(strdup(account.c_str())),
505 .accountIdLen = account.size(),
506 };
507 if (accountCfg.accountId == nullptr) {
508 DLP_LOG_ERROR(LABEL, "Strdup failed.");
509 return DLP_CREDENTIAL_ERROR_VALUE_INVALID;
510 }
511 return DLP_OK;
512 }
513
AdapterData(const std::vector<uint8_t> & offlineCert,bool isOwner,unordered_json jsonObj,DLP_EncPolicyData & encPolicy)514 static int32_t AdapterData(const std::vector<uint8_t>& offlineCert, bool isOwner, unordered_json jsonObj,
515 DLP_EncPolicyData& encPolicy)
516 {
517 DLP_LOG_DEBUG(LABEL, "enter");
518 unordered_json offlineJsonObj;
519 if (!offlineCert.empty()) {
520 std::string offlineEncDataJsonStr(offlineCert.begin(), offlineCert.end());
521 offlineJsonObj = unordered_json::parse(offlineEncDataJsonStr, nullptr, false);
522 if (offlineJsonObj.is_discarded()) {
523 DLP_LOG_ERROR(LABEL, "offlineJsonObj is discarded");
524 return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
525 }
526 }
527 std::string ownerAccountId = "";
528 if (isOwner) {
529 std::string temp(reinterpret_cast<const char*>(encPolicy.receiverAccountInfo.accountId));
530 ownerAccountId = temp;
531 }
532 int32_t result = DlpPermissionSerializer::GetInstance().DeserializeEncPolicyDataByFirstVersion(jsonObj,
533 offlineJsonObj, encPolicy, ownerAccountId);
534 if (result != DLP_OK) {
535 FreeDLPEncPolicyData(encPolicy);
536 return result;
537 }
538 return DLP_OK;
539 }
540
InitEncPolicyData(EncAndDecOptions & options,DLP_EncPolicyData & encPolicy,const bool offlineAccess,const std::string & appId)541 static int32_t InitEncPolicyData(EncAndDecOptions& options, DLP_EncPolicyData& encPolicy, const bool offlineAccess,
542 const std::string& appId)
543 {
544 options = {.opt = CloudEncOption::RECEIVER_DECRYPT_MUST_USE_CLOUD, .extraInfo = nullptr};
545 if (offlineAccess) {
546 options.opt = CloudEncOption::RECEIVER_DECRYPT_MUST_USE_CLOUD_AND_RETURN_ENCRYPTION_VALUE;
547 }
548 encPolicy = {
549 .featureName = strdup(const_cast<char *>(appId.c_str())),
550 .options = options,
551 .reserved = {0},
552 };
553 if (encPolicy.featureName == nullptr) {
554 DLP_LOG_ERROR(LABEL, "Strdup failed.");
555 return DLP_CREDENTIAL_ERROR_VALUE_INVALID;
556 }
557 return DLP_OK;
558 }
559
RestorePolicy(DLP_EncPolicyData & encPolicy,AppExecFwk::ApplicationInfo & applicationInfo,const sptr<IDlpPermissionCallback> & callback,DlpAccountType accountType)560 static int32_t RestorePolicy(DLP_EncPolicyData &encPolicy, AppExecFwk::ApplicationInfo& applicationInfo,
561 const sptr<IDlpPermissionCallback>& callback, DlpAccountType accountType)
562 {
563 uint64_t requestId;
564 int32_t res = DLP_RestorePolicy(GetCallingUserId(), &encPolicy, DlpRestorePolicyCallback, &requestId);
565 if (res != 0) {
566 DLP_LOG_ERROR(LABEL, "Start request fail, error: %{public}d", res);
567 return ConvertCredentialError(res);
568 }
569 DLP_LOG_INFO(
570 LABEL, "Start request success, requestId: %{public}llu", static_cast<unsigned long long>(requestId));
571 RequestInfo info = {
572 .callback = callback,
573 .accountType = accountType,
574 .appProvisionType = applicationInfo.appProvisionType
575 };
576 return InsertCallbackToRequestMap(requestId, info);
577 }
578
ParseDlpCertificate(sptr<CertParcel> & certParcel,const sptr<IDlpPermissionCallback> & callback,const std::string & appId,const bool & offlineAccess,AppExecFwk::ApplicationInfo & applicationInfo)579 int32_t DlpCredential::ParseDlpCertificate(sptr<CertParcel>& certParcel, const sptr<IDlpPermissionCallback>& callback,
580 const std::string& appId, const bool& offlineAccess, AppExecFwk::ApplicationInfo& applicationInfo)
581 {
582 std::string encDataJsonStr(certParcel->cert.begin(), certParcel->cert.end());
583 auto jsonObj = unordered_json::parse(encDataJsonStr, nullptr, false);
584 if (jsonObj.is_discarded() || (!jsonObj.is_object())) {
585 DLP_LOG_ERROR(LABEL, "JsonObj is discarded");
586 return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
587 }
588 EncAndDecOptions options;
589 DLP_EncPolicyData encPolicy;
590 int32_t ret = InitEncPolicyData(options, encPolicy, offlineAccess, appId);
591 if (ret != DLP_OK) {
592 return ret;
593 }
594 int32_t result =
595 DlpPermissionSerializer::GetInstance().DeserializeEncPolicyData(jsonObj, encPolicy, certParcel->isNeedAdapter);
596 auto accountType = static_cast<DlpAccountType>(encPolicy.accountType);
597 if (result != DLP_OK) {
598 FreeDLPEncPolicyData(encPolicy);
599 return DLP_SERVICE_ERROR_JSON_OPERATE_FAIL;
600 }
601 bool isOwner = false;
602 int32_t infoRet = GetAccoutInfo(accountType, encPolicy.receiverAccountInfo, certParcel->contactAccount, &isOwner);
603 if (infoRet != DLP_OK) {
604 FreeDLPEncPolicyData(encPolicy);
605 return infoRet;
606 }
607 if (certParcel->isNeedAdapter) {
608 AdapterData(certParcel->offlineCert, isOwner, jsonObj, encPolicy);
609 }
610 int32_t res = 0;
611 {
612 std::lock_guard<std::mutex> lock(g_lockRequest);
613 int32_t status = QueryRequestIdle();
614 if (status != DLP_OK) {
615 FreeDLPEncPolicyData(encPolicy);
616 return status;
617 }
618 res = RestorePolicy(encPolicy, applicationInfo, callback, accountType);
619 }
620 FreeDLPEncPolicyData(encPolicy);
621 return res;
622 }
623
ParseStringVectorToUint8TypedArray(const std::vector<std::string> & appIdList,uint8_t * policy,uint32_t policySize)624 int32_t ParseStringVectorToUint8TypedArray(const std::vector<std::string>& appIdList, uint8_t *policy,
625 uint32_t policySize)
626 {
627 uint32_t count = static_cast<uint32_t>(appIdList.size());
628 if (memcpy_s(policy, policySize, &count, sizeof(uint32_t)) != EOK) {
629 DLP_LOG_ERROR(LABEL, "Memcpy policy fail");
630 return DLP_CREDENTIAL_ERROR_MEMORY_OPERATE_FAIL;
631 }
632 int32_t offset = sizeof(uint32_t);
633 for (int32_t i = 0; i < static_cast<int32_t>(appIdList.size()); i++) {
634 if (appIdList[i].empty()) {
635 DLP_LOG_ERROR(LABEL, "Empty appId");
636 return DLP_SERVICE_ERROR_VALUE_INVALID;
637 }
638 char *appId = const_cast<char *>(appIdList[i].c_str());
639 uint32_t length = static_cast<uint32_t>(strlen(appId));
640 if (length > MAX_APPID_LENGTH) {
641 DLP_LOG_ERROR(LABEL, "AppId longer than limit");
642 return DLP_SERVICE_ERROR_VALUE_INVALID;
643 }
644 if (memcpy_s(policy + offset, policySize - offset, &length, sizeof(uint32_t)) != EOK) {
645 DLP_LOG_ERROR(LABEL, "Memcpy policy fail");
646 return DLP_CREDENTIAL_ERROR_MEMORY_OPERATE_FAIL;
647 }
648 offset += sizeof(uint32_t);
649 if (memcpy_s(policy + offset, policySize - offset, appId, strlen(appId)) != EOK) {
650 DLP_LOG_ERROR(LABEL, "Memcpy policy fail");
651 return DLP_CREDENTIAL_ERROR_MEMORY_OPERATE_FAIL;
652 }
653 offset += strlen(appId);
654 }
655 return offset;
656 }
657
ParseUint8TypedArrayToStringVector(uint8_t * policy,const uint32_t * policyLen,std::vector<std::string> & appIdList)658 int32_t ParseUint8TypedArrayToStringVector(uint8_t *policy, const uint32_t *policyLen,
659 std::vector<std::string>& appIdList)
660 {
661 if (*policyLen > MAX_APPID_LIST_NUM * MAX_APPID_LENGTH) {
662 return DLP_SERVICE_ERROR_VALUE_INVALID;
663 }
664 uint32_t count = reinterpret_cast<uint32_t *>(policy)[0];
665 if (count < 0 || count > MAX_APPID_LIST_NUM) {
666 DLP_LOG_ERROR(LABEL, "get appId List too large");
667 return DLP_SERVICE_ERROR_VALUE_INVALID;
668 }
669 int32_t offset = sizeof(uint32_t);
670 for (uint32_t i = 0; i < count; i++) {
671 int32_t length = reinterpret_cast<int32_t *>(policy + offset)[0];
672 offset += sizeof(uint32_t);
673 appIdList.push_back(std::string(reinterpret_cast<char *>(policy + offset), length));
674 offset += length;
675 }
676 return DLP_OK;
677 }
678
PresetDLPPolicy(const std::vector<std::string> & srcList,std::vector<std::string> & dstList)679 int32_t PresetDLPPolicy(const std::vector<std::string>& srcList, std::vector<std::string>& dstList)
680 {
681 AppExecFwk::BundleInfo bundleInfo;
682 int32_t userId;
683 bool result = GetUserIdByForegroundAccount(&userId);
684 if (!result) {
685 DLP_LOG_ERROR(LABEL, "get userId error");
686 return DLP_SERVICE_ERROR_VALUE_INVALID;
687 }
688 if (!BundleManagerAdapter::GetInstance().GetBundleInfo(DLP_MANAGER_BUNDLE_NAME,
689 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), bundleInfo, userId)) {
690 DLP_LOG_ERROR(LABEL, "get appId error");
691 return DLP_SERVICE_ERROR_IPC_REQUEST_FAIL;
692 }
693 dstList.assign(srcList.begin(), srcList.end());
694 dstList.push_back(bundleInfo.appId);
695 return DLP_OK;
696 }
697
RemovePresetDLPPolicy(std::vector<std::string> & appIdList)698 int32_t RemovePresetDLPPolicy(std::vector<std::string>& appIdList)
699 {
700 if (appIdList.size() > 0) {
701 appIdList.pop_back();
702 }
703 return DLP_OK;
704 }
705
SetMDMPolicy(const std::vector<std::string> & appIdList)706 int32_t DlpCredential::SetMDMPolicy(const std::vector<std::string>& appIdList)
707 {
708 if (size(appIdList) > MAX_APPID_LENGTH) {
709 DLP_LOG_ERROR(LABEL, "appId List too large");
710 return DLP_SERVICE_ERROR_VALUE_INVALID;
711 }
712 uint32_t policySize = (size(appIdList) + 1) * MAX_APPID_LENGTH;
713 uint8_t *policy = new (std::nothrow)uint8_t[policySize];
714 if (policy == nullptr) {
715 DLP_LOG_WARN(LABEL, "alloc policy failed.");
716 delete[] policy;
717 return DLP_CREDENTIAL_ERROR_MEMORY_OPERATE_FAIL;
718 }
719 std::vector<std::string> presetAppIdList;
720 int32_t res = PresetDLPPolicy(appIdList, presetAppIdList);
721 if (res != DLP_OK) {
722 delete[] policy;
723 return res;
724 }
725 int32_t policyLen = ParseStringVectorToUint8TypedArray(presetAppIdList, policy, policySize);
726 if (policyLen <= 0) {
727 delete[] policy;
728 return policyLen;
729 }
730 res = DLP_AddPolicy(PolicyType::AUTHORIZED_APPLICATION_LIST, policy, policyLen);
731 if (res != DLP_OK) {
732 DLP_LOG_ERROR(LABEL, "SetMDMPolicy request fail, error: %{public}d", res);
733 }
734 delete[] policy;
735 return res;
736 }
737
GetMDMPolicy(std::vector<std::string> & appIdList)738 int32_t DlpCredential::GetMDMPolicy(std::vector<std::string>& appIdList)
739 {
740 uint32_t policyLen = MAX_APPID_LIST_NUM * MAX_APPID_LENGTH;
741 uint8_t *policy = new (std::nothrow)uint8_t[policyLen];
742 if (policy == nullptr) {
743 DLP_LOG_WARN(LABEL, "alloc policy failed.");
744 return DLP_CREDENTIAL_ERROR_MEMORY_OPERATE_FAIL;
745 }
746 int32_t res = DLP_GetPolicy(PolicyType::AUTHORIZED_APPLICATION_LIST, policy, &policyLen);
747 if (res != DLP_OK) {
748 DLP_LOG_ERROR(LABEL, "GetMDMPolicy request fail, error: %{public}d", res);
749 delete[] policy;
750 return res;
751 }
752 if (policyLen == 0) {
753 DLP_LOG_WARN(LABEL, "appIdList is empty.");
754 delete[] policy;
755 return DLP_OK;
756 }
757 res = ParseUint8TypedArrayToStringVector(policy, &policyLen, appIdList);
758 delete[] policy;
759 if (res == DLP_OK) {
760 res = RemovePresetDLPPolicy(appIdList);
761 }
762 return res;
763 }
764
RemoveMDMPolicy()765 int32_t DlpCredential::RemoveMDMPolicy()
766 {
767 int32_t res = DLP_RemovePolicy(PolicyType::AUTHORIZED_APPLICATION_LIST);
768 if (res != DLP_OK) {
769 DLP_LOG_ERROR(LABEL, "RemoveMDMPolicy request fail, error: %{public}d", res);
770 }
771 return res;
772 }
773
CheckMdmPermission(const std::string & bundleName,int32_t userId)774 int32_t DlpCredential::CheckMdmPermission(const std::string& bundleName, int32_t userId)
775 {
776 AppExecFwk::BundleInfo bundleInfo;
777 bool result = BundleManagerAdapter::GetInstance().GetBundleInfo(bundleName,
778 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), bundleInfo, userId);
779 if (!result) {
780 DLP_LOG_ERROR(LABEL, "get appId error");
781 return DLP_SERVICE_ERROR_IPC_REQUEST_FAIL;
782 }
783 PolicyHandle handle = {.id = strdup(const_cast<char *>(bundleInfo.appId.c_str()))};
784 if (handle.id == nullptr) {
785 DLP_LOG_ERROR(LABEL, "Strdup failed.");
786 return DLP_CREDENTIAL_ERROR_SERVER_ERROR;
787 }
788 int32_t res = DLP_CheckPermission(PolicyType::AUTHORIZED_APPLICATION_LIST, handle);
789 if (res != DLP_OK) {
790 DLP_LOG_ERROR(LABEL, "DLP_CheckPermission error:%{public}d", res);
791 res = DLP_CREDENTIAL_ERROR_APPID_NOT_AUTHORIZED;
792 }
793 if (handle.id != nullptr) {
794 free(handle.id);
795 handle.id = nullptr;
796 }
797 return res;
798 }
799 } // namespace DlpPermission
800 } // namespace Security
801 } // namespace OHOS
802