1 /*
2 * Copyright (c) 2020 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 "gt_bundle_installer.h"
17 #include "app_verify_pub.h"
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 #ifdef __cplusplus
23 }
24 #endif
25 #include "appexecfwk_errors.h"
26 #include "bundle_util.h"
27 #include "bundlems_log.h"
28 #include "dirent.h"
29 #include "fcntl.h"
30 #include "global.h"
31 #include "gt_bundle_extractor.h"
32 #include "gt_bundle_manager_service.h"
33 #include "gt_bundle_parser.h"
34 #include "stdio.h"
35 #include "sys/stat.h"
36 #include "unistd.h"
37 #include "utils.h"
38
39 namespace OHOS {
40 const char MATCHED_ALL_STR[] = ".*";
41 const uint8_t OPERATION_DOING = 200;
42 const uint8_t BMS_FIRST_FINISHED_PROCESS = 10;
43 const uint8_t BMS_SECOND_FINISHED_PROCESS = 50;
44 const uint8_t BMS_THIRD_FINISHED_PROCESS = 60;
45 const uint8_t BMS_FOURTH_FINISHED_PROCESS = 70;
46 const uint8_t BMS_FIFTH_FINISHED_PROCESS = 80;
47 const uint8_t BMS_SIXTH_FINISHED_PROCESS = 90;
48 const uint8_t RADN_NUM = 16;
49
PreCheckBundle(const char * path,int32_t & fp,SignatureInfo & signatureInfo,uint32_t & fileSize,uint8_t bundleStyle)50 uint8_t GtBundleInstaller::PreCheckBundle(const char *path, int32_t &fp, SignatureInfo &signatureInfo,
51 uint32_t &fileSize, uint8_t bundleStyle)
52 {
53 // check install file path and file whether is valid
54 if (!BundleUtil::IsFile(path)) {
55 return ERR_APPEXECFWK_INSTALL_FAILED_FILE_NOT_EXISTS;
56 }
57
58 uint32_t size = BundleUtil::GetFileSize(path);
59 if (size == 0) {
60 return ERR_APPEXECFWK_INSTALL_FAILED_BAD_FILE;
61 }
62
63 // get fp and bundleName from install file
64 char *bundleName = nullptr;
65 uint8_t errorCode = GtBundleExtractor::ExtractBundleParam(path, fp, &bundleName);
66 if (errorCode != ERR_OK) {
67 UI_Free(bundleName);
68 return errorCode;
69 }
70
71 errorCode = VerifySignature(path, signatureInfo, fileSize, bundleStyle);
72 if (errorCode != ERR_OK) {
73 UI_Free(bundleName);
74 return errorCode;
75 }
76 // reshape appId
77 if ((signatureInfo.appId != nullptr) && strstr(signatureInfo.appId, MATCHED_ALL_STR) == nullptr) {
78 if (!BundleUtil::StartWith(signatureInfo.appId, bundleName)) {
79 HILOG_ERROR(HILOG_MODULE_AAFWK, "bundleName does not match the appId!");
80 UI_Free(bundleName);
81 return ERR_APPEXECFWK_INSTALL_FAILED_INVALID_PROVISIONINFO;
82 }
83 }
84 if ((signatureInfo.appId != nullptr) && strstr(signatureInfo.appId, bundleName) == nullptr) {
85 signatureInfo.appId = ReshapeAppId(bundleName, signatureInfo.appId);
86 if (signatureInfo.appId == nullptr) {
87 UI_Free(bundleName);
88 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
89 }
90 }
91
92 // check number of current installed third bundles whether is to MAX_THIRD_BUNDLE_NUMBER
93 if (bundleStyle == THIRD_APP_FLAG) {
94 uint32_t numOfBundles = GtManagerService::GetInstance().GetNumOfThirdBundles();
95 if (GtManagerService::GetInstance().QueryBundleInfo(bundleName) == nullptr &&
96 numOfBundles >= MAX_THIRD_BUNDLE_NUMBER) {
97 UI_Free(bundleName);
98 return ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_BUNDLE_NUMBER;
99 }
100 }
101 UI_Free(bundleName);
102 return ERR_OK;
103 }
104
VerifySignature(const char * path,SignatureInfo & signatureInfo,uint32_t & fileSize,uint8_t bundleStyle)105 uint8_t GtBundleInstaller::VerifySignature(const char *path, SignatureInfo &signatureInfo, uint32_t &fileSize,
106 uint8_t bundleStyle)
107 {
108 #ifndef __LITEOS_M__
109 VerifyResult verifyResult;
110 // verify signature
111 (void) APPVERI_SetDebugMode(true);
112 int32_t ret = (bundleStyle == THIRD_APP_FLAG) ? APPVERI_AppVerify(path, &verifyResult) :
113 APPVERI_AppVerify(path, &verifyResult);
114 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] APPVERI_AppVerify is %d", ret);
115 uint8_t errorCode = SwitchErrorCode(ret);
116 if (errorCode != ERR_OK) {
117 return errorCode;
118 }
119 fileSize = APPVERI_GetUnsignedFileLength(path);
120 signatureInfo.appId = Utils::Strdup(verifyResult.profile.appid);
121 signatureInfo.bundleName = Utils::Strdup(verifyResult.profile.bundleInfo.bundleName);
122 if (signatureInfo.appId == nullptr || signatureInfo.bundleName == nullptr) {
123 APPVERI_FreeVerifyRst(&verifyResult);
124 FREE_SIGNATUREINFO(signatureInfo);
125 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
126 }
127 signatureInfo.restricNum = verifyResult.profile.permission.restricNum;
128 if (signatureInfo.restricNum == 0) {
129 APPVERI_FreeVerifyRst(&verifyResult);
130 return ERR_OK;
131 }
132 char **restricPermission = verifyResult.profile.permission.restricPermission;
133 signatureInfo.restricPermission = reinterpret_cast<char **>(AdapterMalloc(sizeof(char *) *
134 signatureInfo.restricNum));
135 if (signatureInfo.restricPermission == nullptr) {
136 APPVERI_FreeVerifyRst(&verifyResult);
137 FREE_SIGNATUREINFO(signatureInfo);
138 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
139 }
140 for (int i = 0; i < signatureInfo.restricNum; i++) {
141 *(signatureInfo.restricPermission + i) = Utils::Strdup(*(restricPermission + i));
142 if (*(signatureInfo.restricPermission + i) == nullptr) {
143 APPVERI_FreeVerifyRst(&verifyResult);
144 FREE_SIGNATUREINFO(signatureInfo);
145 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
146 }
147 }
148 APPVERI_FreeVerifyRst(&verifyResult);
149 #endif
150 return ERR_OK;
151 }
152
SwitchErrorCode(int32_t errorCode)153 uint8_t GtBundleInstaller::SwitchErrorCode(int32_t errorCode)
154 {
155 if (errorCode >= V_ERR_GET_CERT_INFO && errorCode <= V_ERR_GET_CERT_TYPE) {
156 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_APP_SIGNATURE_ERROR;
157 } else if (errorCode >= V_ERR_GET_PROFILE_DATA && errorCode <= V_ERR_INVALID_DEVID) {
158 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PROFILE_SIGNATURE_ERROR;
159 } else if (errorCode >= V_ERR_FILE_OPEN && errorCode <= V_ERR_FILE_LENGTH) {
160 return ERR_APPEXECFWK_INSTALL_FAILED_OPERATE_SIGNED_FILE_ERROR;
161 } else if ((errorCode >= V_ERR_MEMSET && errorCode <= V_ERR_MALLOC) || errorCode == V_ERR) {
162 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_SIGNATURE_ERROR;
163 } else {
164 return ERR_OK;
165 }
166 }
167
Install(const char * path,InstallerCallback installerCallback)168 uint8_t GtBundleInstaller::Install(const char *path, InstallerCallback installerCallback)
169 {
170 if (path == nullptr) {
171 return ERR_APPEXECFWK_INSTALL_FAILED_PARAM_ERROR;
172 }
173
174 InstallRecord installRecord = {
175 .bundleName = nullptr,
176 .codePath = nullptr,
177 .appId = nullptr,
178 #ifdef BC_TRANS_ENABLE
179 .jsEngineVersion = nullptr,
180 .transformResult = -1,
181 #endif
182 .versionCode = -1
183 };
184 // process bundle install
185 uint8_t bundleStyle = 0;
186 if (BundleUtil::StartWith(path, SYSTEM_BUNDLE_PATH)) {
187 bundleStyle = SYSTEM_APP_FLAG;
188 } else if (BundleUtil::StartWith(path, THIRD_SYSTEM_BUNDLE_PATH)) {
189 bundleStyle = THIRD_SYSTEM_APP_FLAG;
190 } else {
191 bundleStyle = THIRD_APP_FLAG;
192 }
193 char randStr[RADN_NUM] = { 0 };
194 BundleUtil::CreateRandStr(randStr, RADN_NUM);
195 if (strlen(randStr) == 0) {
196 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] create random str fail!");
197 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
198 }
199
200 uint8_t errorCode = ProcessBundleInstall(path, randStr, installRecord, bundleStyle, installerCallback);
201 if (errorCode != ERR_OK) {
202 return errorCode;
203 }
204 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_SIXTH_FINISHED_PROCESS, installerCallback);
205
206 // rename bundle.json
207 if (!RenameJsonFile(installRecord.bundleName, randStr)) {
208 BundleInfo *bundleInfo = GtManagerService::GetInstance().QueryBundleInfo(installRecord.bundleName);
209 CLEAR_INSTALL_ENV(bundleInfo);
210 return ERR_APPEXECFWK_INSTALL_FAILED_RENAME_FILE_ERROR;
211 }
212 // if third system bundle, it need to record bundleName in THIRD_SYSTEM_BUNDLE_JSON
213 if (bundleStyle == THIRD_SYSTEM_APP_FLAG && !CheckIsThirdSystemBundle(installRecord.bundleName)) {
214 RecordThirdSystemBundle(installRecord.bundleName, THIRD_SYSTEM_BUNDLE_JSON);
215 }
216
217 if (bundleStyle == THIRD_APP_FLAG) {
218 GtManagerService::GetInstance().AddNumOfThirdBundles();
219 }
220 // record app info event when install app
221 return ERR_OK;
222 }
223
ProcessBundleInstall(const char * path,const char * randStr,InstallRecord & installRecord,uint8_t bundleStyle,InstallerCallback installerCallback)224 uint8_t GtBundleInstaller::ProcessBundleInstall(const char *path, const char *randStr, InstallRecord &installRecord,
225 uint8_t bundleStyle, InstallerCallback installerCallback)
226 {
227 SignatureInfo signatureInfo;
228 signatureInfo = {.bundleName = nullptr, .appId = nullptr, .restricPermission = nullptr, .restricNum = 0};
229 int32_t fp = -1;
230 uint32_t fileSize = 0;
231 // check bundle whether is valid
232 Permissions permissions = {.permNum = 0, .permissionTrans = nullptr};
233 BundleRes bundleRes = {
234 .bundleName = nullptr, .moduleDescriptionId = 0, .abilityRes = nullptr, .totalNumOfAbilityRes = 0
235 };
236 BundleInfo *bundleInfo = nullptr;
237 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_FIRST_FINISHED_PROCESS, installerCallback);
238 uint8_t errorCode = PreCheckBundle(path, fp, signatureInfo, fileSize, bundleStyle);
239 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
240 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_SECOND_FINISHED_PROCESS, installerCallback);
241 #ifdef __LITEOS_M__
242 fp = open(path, O_RDONLY, S_IREAD);
243 if (fp < 0) {
244 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] process bundle install fp open fail");
245 errorCode = ERR_APPEXECFWK_INSTALL_FAILED_FILE_NOT_EXISTS;
246 }
247 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
248 #endif
249 // parse HarmoyProfile.json, get permissions and bundleInfo
250 errorCode = GtBundleParser::ParseHapProfile(fp, fileSize, permissions, bundleRes, &bundleInfo);
251 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
252 SetCurrentBundle(bundleInfo->bundleName);
253 // terminate current runing app
254 uint32_t labelId = (bundleRes.abilityRes != nullptr) ? bundleRes.abilityRes->labelId : 0;
255 uint32_t iconId = (bundleRes.abilityRes != nullptr) ? bundleRes.abilityRes->iconId : 0;
256 AdapterFree(bundleRes.abilityRes);
257 // check signatureInfo
258 errorCode = CheckProvisionInfoIsValid(signatureInfo, permissions, bundleInfo->bundleName);
259 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
260 installRecord.codePath = bundleInfo->codePath;
261 installRecord.bundleName = bundleInfo->bundleName;
262 installRecord.appId = signatureInfo.appId;
263 installRecord.versionCode = bundleInfo->versionCode;
264 bundleInfo->appId = Utils::Strdup(signatureInfo.appId);
265 // check version when in update status
266 errorCode = CheckVersionAndSignature(installRecord.bundleName, installRecord.appId, bundleInfo);
267 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
268 // restore bin data to file
269 char *tmpCodePathComp[] = {installRecord.codePath, const_cast<char *>(randStr)};
270 char *tmpCodePath = BundleUtil::Strscat(tmpCodePathComp, sizeof(tmpCodePathComp) / sizeof(char *));
271 errorCode = (tmpCodePath == nullptr) ? ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR : ERR_OK;
272 CHECK_PRO_RESULT(errorCode, fp, permissions, bundleInfo, signatureInfo);
273 errorCode = GtBundleExtractor::ExtractHap(tmpCodePath, installRecord.bundleName, fp, fileSize, bundleStyle);
274 close(fp);
275 CHECK_PRO_PART_ROLLBACK(errorCode, tmpCodePath, permissions, bundleInfo, signatureInfo);
276 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_THIRD_FINISHED_PROCESS, installerCallback);
277 // get js engine version
278 #ifdef BC_TRANS_ENABLE
279 char *jsEngineVersion = get_jerry_version_no();
280 errorCode = (jsEngineVersion != nullptr) ? ERR_OK : ERR_APPEXECFWK_INSTALL_FAILED_GET_JS_ENGINE_VERSION_ERROR;
281 CHECK_PRO_PART_ROLLBACK(errorCode, tmpCodePath, permissions, bundleInfo, signatureInfo);
282 installRecord.jsEngineVersion = jsEngineVersion;
283 // try to transform js file to bc file
284 errorCode = TransformJsToBc(tmpCodePath, installRecord);
285 CHECK_PRO_PART_ROLLBACK(errorCode, tmpCodePath, permissions, bundleInfo, signatureInfo);
286 #endif
287 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_FOURTH_FINISHED_PROCESS, installerCallback);
288 // rename install path and record install infomation
289 bool isUpdate = GtManagerService::GetInstance().QueryBundleInfo(installRecord.bundleName) != nullptr;
290 errorCode = HandleFileAndBackUpRecord(installRecord, tmpCodePath, randStr, bundleInfo->dataPath, isUpdate);
291 AdapterFree(tmpCodePath);
292 CHECK_PRO_ROLLBACK(errorCode, permissions, bundleInfo, signatureInfo, randStr);
293
294 // move rawfile to data path when rawfile is exists
295 errorCode = MoveRawFileToDataPath(bundleInfo);
296 CHECK_PRO_ROLLBACK(errorCode, permissions, bundleInfo, signatureInfo, randStr);
297 (void) GtManagerService::GetInstance().ReportInstallCallback(OPERATION_DOING, 0, BMS_FIFTH_FINISHED_PROCESS, installerCallback);
298 // store permissions
299 errorCode = StorePermissions(installRecord.bundleName, permissions.permissionTrans, permissions.permNum,
300 isUpdate);
301 CHECK_PRO_ROLLBACK(errorCode, permissions, bundleInfo, signatureInfo, randStr);
302 // update bundle Info
303 errorCode = UpdateBundleInfo(bundleStyle, labelId, iconId, bundleInfo, isUpdate);
304 CHECK_PRO_ROLLBACK(errorCode, permissions, bundleInfo, signatureInfo, randStr);
305 // free memory
306 UI_Free(permissions.permissionTrans);
307 FREE_SIGNATUREINFO(signatureInfo);
308 return ERR_OK;
309 }
310
MoveRawFileToDataPath(const BundleInfo * bundleInfo)311 uint8_t GtBundleInstaller::MoveRawFileToDataPath(const BundleInfo *bundleInfo)
312 {
313 if (bundleInfo == nullptr) {
314 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
315 }
316
317 char *srcRawFilePathComp[] = {
318 const_cast<char *>(bundleInfo->codePath), const_cast<char *>(ASSETS),
319 const_cast<char *>(bundleInfo->moduleInfos[0].moduleName), const_cast<char *>(RESOURCES_RAW_FILE)
320 };
321 char *srcRawFilePath = BundleUtil::Strscat(srcRawFilePathComp, sizeof(srcRawFilePathComp) / sizeof(char *));
322 if (srcRawFilePath == nullptr) {
323 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] srcRawFilePath is nullptr");
324 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
325 }
326
327 if (!BundleUtil::IsDir(srcRawFilePath)) {
328 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] rawfile is not exists!");
329 AdapterFree(srcRawFilePath);
330 return ERR_OK;
331 }
332
333 char *dstRawFilePathComp[] = {const_cast<char *>(bundleInfo->dataPath), const_cast<char *>(RAW_FILE)};
334 char *dstRawFilePath = BundleUtil::Strscat(dstRawFilePathComp, sizeof(dstRawFilePathComp) / sizeof(char *));
335 if (dstRawFilePath == nullptr) {
336 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] dstRawFilePath is nullptr");
337 AdapterFree(srcRawFilePath);
338 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
339 }
340
341 if (!BundleUtil::RenameDir(srcRawFilePath, dstRawFilePath)) {
342 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] frename rawfile fail!");
343 AdapterFree(srcRawFilePath);
344 AdapterFree(dstRawFilePath);
345 return ERR_APPEXECFWK_INSTALL_FAILED_RENAME_DIR_ERROR;
346 }
347 AdapterFree(srcRawFilePath);
348 AdapterFree(dstRawFilePath);
349 return ERR_OK;
350 }
351
ReshapeAppId(const char * bundleName,char * appId)352 char *GtBundleInstaller::ReshapeAppId(const char *bundleName, char *appId)
353 {
354 if (appId == nullptr || bundleName == nullptr) {
355 return nullptr;
356 }
357
358 char *pos = appId;
359 for (int32_t i = 0; appId[i] != '\0'; i++) {
360 if (appId[i] == '_') {
361 break;
362 }
363 pos++;
364 }
365
366 char *appIdComp[] = {const_cast<char *>(bundleName), pos};
367 char *newAppid = BundleUtil::Strscat(appIdComp, sizeof(appIdComp) / sizeof(char *));
368 AdapterFree(appId);
369 return newAppid;
370 }
371
CheckProvisionInfoIsValid(const SignatureInfo & signatureInfo,const Permissions & permissions,const char * bundleName)372 uint8_t GtBundleInstaller::CheckProvisionInfoIsValid(const SignatureInfo &signatureInfo, const Permissions &permissions,
373 const char *bundleName)
374 {
375 if (bundleName == nullptr) {
376 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
377 }
378
379 if (!MatchBundleName(bundleName, signatureInfo.bundleName)) {
380 return ERR_APPEXECFWK_INSTALL_FAILED_INVALID_PROVISIONINFO;
381 }
382 return ERR_OK;
383 }
384
385
MatchBundleName(const char * bundleName,const char * matchedBundleName)386 bool GtBundleInstaller::MatchBundleName(const char *bundleName, const char *matchedBundleName)
387 {
388 if (bundleName == nullptr || matchedBundleName == nullptr) {
389 return false;
390 }
391
392 if (strcmp(matchedBundleName, MATCHED_ALL_STR) == 0 || strcmp(bundleName, matchedBundleName) == 0) {
393 return true;
394 }
395
396 char *pos = const_cast<char *>(matchedBundleName);
397 for (uint32_t i = 0; matchedBundleName[i] != '\0' && bundleName[i] != '\0'; i++, pos++) {
398 if (bundleName[i] != matchedBundleName[i]) {
399 if (strcmp(pos, MATCHED_ALL_STR) == 0) {
400 return true;
401 }
402 return false;
403 } else if (strcmp(pos, MATCHED_ALL_STR) == 0) {
404 return true;
405 }
406 }
407 return false;
408 }
409
MatchPermissions(char ** restrictedPermissions,uint32_t restricNum,PermissionTrans * permissionsTrans,int32_t permTransNum)410 bool GtBundleInstaller::MatchPermissions(char ** restrictedPermissions, uint32_t restricNum,
411 PermissionTrans *permissionsTrans, int32_t permTransNum)
412 {
413 if (permTransNum == 0) {
414 return true;
415 }
416
417 if (permissionsTrans == nullptr || restrictedPermissions == nullptr) {
418 return false;
419 }
420
421 PermissionTrans *perm = permissionsTrans;
422 for (int32_t i = 0; i < permTransNum; i++) {
423 bool isMatched = false;
424 for (int32_t j = 0; j < restricNum; j++) {
425 if (((perm + i)->name != nullptr) && strcmp(*(restrictedPermissions + j), (perm + i)->name) == 0) {
426 isMatched = true;
427 break;
428 }
429 }
430 if (!isMatched) {
431 return false;
432 }
433 }
434 return true;
435 }
436
HandleFileAndBackUpRecord(const InstallRecord & record,const char * tmpPath,const char * randStr,const char * dataPath,bool isUpdate)437 uint8_t GtBundleInstaller::HandleFileAndBackUpRecord(const InstallRecord &record, const char *tmpPath,
438 const char *randStr, const char *dataPath, bool isUpdate)
439 {
440 if (tmpPath == nullptr || dataPath == nullptr) {
441 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
442 }
443 // delete old bundleRes
444 GtManagerService::GetInstance().RemoveBundleResList(record.bundleName);
445
446 if (!BundleUtil::RenameDir(tmpPath, record.codePath)) {
447 BundleUtil::RemoveDir(tmpPath);
448 return ERR_APPEXECFWK_INSTALL_FAILED_RENAME_DIR_ERROR;
449 }
450
451 char *bundleTmpJsonPathComp[] = {
452 const_cast<char *>(JSON_PATH), const_cast<char *>(record.bundleName), const_cast<char *>(randStr),
453 const_cast<char *>(JSON_SUFFIX)
454 };
455 char *bundleTmpJsonPath = BundleUtil::Strscat(bundleTmpJsonPathComp,
456 sizeof(bundleTmpJsonPathComp) / sizeof(char *));
457 if (bundleTmpJsonPath == nullptr) {
458 return ERR_APPEXECFWK_INSTALL_FAILED_RECORD_INFO_ERROR;
459 }
460
461 if (!BackUpInstallRecord(record, bundleTmpJsonPath)) {
462 unlink(bundleTmpJsonPath);
463 AdapterFree(bundleTmpJsonPath);
464 return ERR_APPEXECFWK_INSTALL_FAILED_RECORD_INFO_ERROR;
465 }
466 AdapterFree(bundleTmpJsonPath);
467
468 if (!isUpdate) {
469 (void) BundleUtil::RemoveDir(dataPath);
470 if (!BundleUtil::MkDirs(dataPath)) {
471 return ERR_APPEXECFWK_INSTALL_FAILED_CREATE_DATA_DIR_ERROR;
472 }
473 }
474 return ERR_OK;
475 }
476
477 #ifdef BC_TRANS_ENABLE
TransformJsToBc(const char * codePath,InstallRecord & record)478 uint8_t GtBundleInstaller::TransformJsToBc(const char *codePath, InstallRecord &record)
479 {
480 if (codePath == nullptr) {
481 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
482 }
483
484 char *jsPathComp[] = {const_cast<char *>(codePath), const_cast<char *>(ASSET_JS_PATH)};
485 char *jsPath = BundleUtil::Strscat(jsPathComp, sizeof(jsPathComp) / sizeof(char *));
486 if (jsPath == nullptr) {
487 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
488 }
489 EXECRES result = walk_directory(jsPath);
490 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] transform js to bc when install, result is %d", result);
491 if (result != EXCE_ACE_JERRY_EXEC_OK) {
492 AdapterFree(jsPath);
493 return ERR_APPEXECFWK_INSTALL_FAILED_TRANSFORM_BC_FILE_ERROR;
494 }
495 AdapterFree(jsPath);
496 record.transformResult = 0;
497 return ERR_OK;
498 }
499 #endif
500
UpdateBundleInfo(uint8_t bundleStyle,uint32_t labelId,uint32_t iconId,BundleInfo * bundleInfo,bool isUpdate)501 uint8_t GtBundleInstaller::UpdateBundleInfo(uint8_t bundleStyle, uint32_t labelId, uint32_t iconId,
502 BundleInfo *bundleInfo, bool isUpdate)
503 {
504 if (bundleInfo == nullptr || bundleInfo->abilityInfo == nullptr) {
505 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
506 }
507
508 if (!BundleUtil::IsDir(bundleInfo->abilityInfo->srcPath)) {
509 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_JS_DIR_ERROR;
510 }
511
512 uint8_t errorCode = GtBundleParser::ConvertResInfoToBundleInfo(bundleInfo->codePath, labelId, iconId, bundleInfo);
513 if (errorCode != ERR_OK) {
514 return errorCode;
515 }
516 if (!isUpdate) {
517 if (bundleStyle == SYSTEM_APP_FLAG) {
518 bundleInfo->isSystemApp = true;
519 GtManagerService::GetInstance().AddBundleInfo(bundleInfo);
520 } else if (bundleStyle == THIRD_SYSTEM_APP_FLAG) {
521 bundleInfo->isSystemApp = false;
522 GtManagerService::GetInstance().AddBundleInfo(bundleInfo);
523 } else {
524 bundleInfo->isSystemApp = false;
525 GtManagerService::GetInstance().AddBundleInfo(bundleInfo);
526 }
527 } else {
528 BundleInfo *oldBundleInfo = GtManagerService::GetInstance().QueryBundleInfo(bundleInfo->bundleName);
529 if (oldBundleInfo == nullptr) {
530 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
531 }
532 bundleInfo->isSystemApp = oldBundleInfo->isSystemApp;
533
534 if (!GtManagerService::GetInstance().UpdateBundleInfo(bundleInfo)) {
535 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
536 }
537 }
538 // update bundle res list
539 return AddBundleResList(bundleInfo->bundleName, labelId, iconId);
540 }
541
AddBundleResList(const char * bundleName,uint32_t labelId,uint32_t iconId)542 uint8_t GtBundleInstaller::AddBundleResList(const char *bundleName, uint32_t labelId, uint32_t iconId)
543 {
544 if (labelId == 0 && iconId == 0) {
545 return ERR_OK;
546 }
547
548 if (bundleName == nullptr) {
549 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
550 }
551
552 BundleRes *bundleRes = reinterpret_cast<BundleRes *>(AdapterMalloc(sizeof(BundleRes)));
553 if (bundleRes == nullptr) {
554 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
555 }
556
557 bundleRes->abilityRes = reinterpret_cast<AbilityRes *>(AdapterMalloc(sizeof(AbilityRes)));
558 if (bundleRes->abilityRes == nullptr) {
559 AdapterFree(bundleRes);
560 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
561 }
562 bundleRes->bundleName = const_cast<char *>(bundleName);
563 bundleRes->abilityRes->labelId = labelId;
564 bundleRes->abilityRes->iconId = iconId;
565
566 GtManagerService::GetInstance().AddBundleResList(bundleRes);
567 return ERR_OK;
568 }
569
Uninstall(const char * bundleName)570 uint8_t GtBundleInstaller::Uninstall(const char *bundleName)
571 {
572 if (bundleName == nullptr) {
573 return ERR_APPEXECFWK_UNINSTALL_FAILED_PARAM_ERROR;
574 }
575
576 BundleInfo *bundleInfo = GtManagerService::GetInstance().QueryBundleInfo(bundleName);
577 if (bundleInfo == nullptr) {
578 return ERR_APPEXECFWK_UNINSTALL_FAILED_BUNDLE_NOT_EXISTS;
579 }
580
581 if (bundleInfo->isSystemApp) {
582 return ERR_APPEXECFWK_UNINSTALL_FAILED_BUNDLE_NOT_UNINSTALLABLE;
583 }
584
585 char bundleJsonPath[PATH_LENGTH] = { 0 };
586 if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
587 return ERR_APPEXECFWK_UNINSTALL_FAILED_INTERNAL_ERROR;
588 }
589 #ifndef __LITEOS_M__
590 if (DeletePermissions(const_cast<char *>(bundleName)) < 0) {
591 return ERR_APPEXECFWK_UNINSTALL_FAILED_DELETE_PERMISSIONS_ERROR;
592 }
593 #endif
594 bool res = CheckIsThirdSystemBundle(bundleName);
595 if (!(BundleUtil::RemoveDir(bundleInfo->codePath) && BundleUtil::RemoveDir(bundleInfo->dataPath))) {
596 GtManagerService::GetInstance().RemoveBundleInfo(bundleName);
597 GtManagerService::GetInstance().RemoveBundleResList(bundleName);
598 if (!res) {
599 GtManagerService::GetInstance().ReduceNumOfThirdBundles();
600 }
601 return ERR_APPEXECFWK_UNINSTALL_FAILED_DELETE_DIRS_ERROR;
602 }
603
604 GtManagerService::GetInstance().RemoveBundleInfo(bundleName);
605 GtManagerService::GetInstance().RemoveBundleResList(bundleName);
606 if (!res) {
607 GtManagerService::GetInstance().ReduceNumOfThirdBundles();
608 }
609 if (unlink(bundleJsonPath) < 0) {
610 return ERR_APPEXECFWK_UNINSTALL_FAILED_DELETE_RECORD_INFO_ERROR;
611 }
612
613 if (res) {
614 RecordThirdSystemBundle(bundleName, UNINSTALL_THIRD_SYSTEM_BUNDLE_JSON);
615 }
616
617 return ERR_OK;
618 }
619
CheckIsThirdSystemBundle(const char * bundleName)620 bool GtBundleInstaller::CheckIsThirdSystemBundle(const char *bundleName)
621 {
622 if (bundleName == nullptr) {
623 return false;
624 }
625 cJSON *root = BundleUtil::GetJsonStream(THIRD_SYSTEM_BUNDLE_JSON);
626 if (root == nullptr) {
627 return false;
628 }
629
630 cJSON *son = cJSON_GetObjectItem(root, JSON_MAIN_KEY);
631 if (!cJSON_IsArray(son)) {
632 (void) unlink(THIRD_SYSTEM_BUNDLE_JSON);
633 cJSON_Delete(root);
634 return false;
635 }
636
637 cJSON *item = nullptr;
638 cJSON_ArrayForEach(item, son) {
639 if (!cJSON_IsString(item)) {
640 cJSON_Delete(root);
641 return false;
642 }
643 if ((item->valuestring != nullptr) && strcmp(bundleName, item->valuestring) == 0) {
644 cJSON_Delete(root);
645 return true;
646 }
647 }
648 cJSON_Delete(root);
649 return false;
650 }
651
RecordThirdSystemBundle(const char * bundleName,const char * path)652 void GtBundleInstaller::RecordThirdSystemBundle(const char *bundleName, const char *path)
653 {
654 if (bundleName == nullptr || path == nullptr) {
655 return;
656 }
657 if (BundleUtil::IsFile(path)) {
658 cJSON *root = BundleUtil::GetJsonStream(path);
659 if (root == nullptr) {
660 return;
661 }
662
663 cJSON *son = cJSON_GetObjectItem(root, JSON_MAIN_KEY);
664 if (!cJSON_IsArray(son)) {
665 unlink(path);
666 cJSON_Delete(root);
667 InitThirdSystemBundleRecord(bundleName, path);
668 return;
669 }
670
671 cJSON *str = cJSON_CreateString(bundleName);
672 if (str == nullptr) {
673 cJSON_Delete(root);
674 return;
675 }
676 cJSON_AddItemToArray(son, str);
677
678 (void) BundleUtil::StoreJsonContentToFile(path, root);
679 cJSON_Delete(root);
680 } else {
681 InitThirdSystemBundleRecord(bundleName, path);
682 }
683 }
684
InitThirdSystemBundleRecord(const char * bundleName,const char * path)685 void GtBundleInstaller::InitThirdSystemBundleRecord(const char *bundleName, const char *path)
686 {
687 if (bundleName == nullptr || path == nullptr) {
688 return;
689 }
690 cJSON *root = cJSON_CreateObject();
691 if (root == nullptr) {
692 return;
693 }
694
695 cJSON *son = cJSON_CreateArray();
696 if (son == nullptr) {
697 cJSON_Delete(root);
698 return;
699 }
700
701 if (!cJSON_AddItemToObject(root, JSON_MAIN_KEY, son)) {
702 cJSON_Delete(son);
703 cJSON_Delete(root);
704 return;
705 }
706
707 cJSON *str = cJSON_CreateString(bundleName);
708 if (str == nullptr) {
709 cJSON_Delete(root);
710 return;
711 }
712
713 if (!cJSON_AddItemToArray(son, str)) {
714 cJSON_Delete(str);
715 cJSON_Delete(root);
716 return;
717 }
718
719 BundleUtil::StoreJsonContentToFile(path, root);
720 cJSON_Delete(root);
721 }
722
BackUpInstallRecord(const InstallRecord & record,const char * jsonPath)723 bool GtBundleInstaller::BackUpInstallRecord(const InstallRecord &record, const char *jsonPath)
724 {
725 if (jsonPath == nullptr) {
726 return false;
727 }
728
729 cJSON *object = BundleUtil::ConvertInstallRecordToJson(record);
730 if (object == nullptr) {
731 return false;
732 }
733
734 if (!BundleUtil::StoreJsonContentToFile(jsonPath, object)) {
735 cJSON_Delete(object);
736 return false;
737 }
738 cJSON_Delete(object);
739 return true;
740 }
741
StorePermissions(const char * bundleName,PermissionTrans * permissions,int32_t permNum,bool isUpdate)742 uint8_t GtBundleInstaller::StorePermissions(const char *bundleName, PermissionTrans *permissions, int32_t permNum,
743 bool isUpdate)
744 {
745 if (permNum == 0) {
746 #ifndef __LITEOS_M__
747 if (isUpdate) {
748 int32_t ret = DeletePermissions(bundleName);
749 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] delete permissions, result is %d", ret);
750 }
751 #endif
752 return ERR_OK;
753 }
754
755 if (bundleName == nullptr || permissions == nullptr) {
756 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
757 }
758
759 if (!BundleUtil::IsDir(PERMISSIONS_PATH)) {
760 BundleUtil::MkDirs(PERMISSIONS_PATH);
761 }
762 #ifndef __LITEOS_M__
763 if (SaveOrUpdatePermissions(const_cast<char *>(bundleName), permissions, permNum,
764 static_cast<IsUpdate>(isUpdate)) != 0) {
765 return ERR_APPEXECFWK_INSTALL_FAILED_STORE_PERMISSIONS_ERROR;
766 }
767 #endif
768 return ERR_OK;
769 }
770
CheckVersionAndSignature(const char * bundleName,const char * appId,BundleInfo * bundleInfo)771 uint8_t GtBundleInstaller::CheckVersionAndSignature(const char *bundleName, const char *appId, BundleInfo *bundleInfo)
772 {
773 if (bundleName == nullptr || appId == nullptr || bundleInfo == nullptr) {
774 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
775 }
776 BundleInfo *oldBundleInfo = GtManagerService::GetInstance().QueryBundleInfo(bundleName);
777 if (oldBundleInfo != nullptr) {
778 if (oldBundleInfo->versionCode > bundleInfo->versionCode) {
779 return ERR_APPEXECFWK_INSTALL_FAILED_VERSION_DOWNGRADE;
780 }
781 char *oldAppId = BundleUtil::GetValueFromBundleJson(bundleName, JSON_SUB_KEY_APPID);
782 if (oldAppId == nullptr) {
783 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
784 }
785 if (strcmp(oldAppId, appId) != 0) {
786 AdapterFree(oldAppId);
787 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
788 }
789 AdapterFree(oldAppId);
790 }
791 return ERR_OK;
792 }
793
RenameJsonFile(const char * fileName,const char * randStr)794 bool GtBundleInstaller::RenameJsonFile(const char *fileName, const char *randStr)
795 {
796 if (fileName == nullptr || randStr == nullptr) {
797 return false;
798 }
799
800 char *tmpJsonPathComp[] = {
801 const_cast<char *>(JSON_PATH), const_cast<char *>(fileName), const_cast<char *>(randStr),
802 const_cast<char *>(JSON_SUFFIX)
803 };
804 char *tmpJsonPath = BundleUtil::Strscat(tmpJsonPathComp, sizeof(tmpJsonPathComp) / sizeof(char *));
805 if (tmpJsonPath == nullptr) {
806 return false;
807 }
808
809 if (!BundleUtil::IsFile(tmpJsonPath)) {
810 AdapterFree(tmpJsonPath);
811 return false;
812 }
813
814 char *jsonPathComp[] = {
815 const_cast<char *>(JSON_PATH), const_cast<char *>(fileName), const_cast<char *>(JSON_SUFFIX)
816 };
817 char *jsonPath = BundleUtil::Strscat(jsonPathComp, sizeof(jsonPathComp) / sizeof(char *));
818 if (jsonPath == nullptr) {
819 AdapterFree(tmpJsonPath);
820 return false;
821 }
822
823 if (!BundleUtil::RenameFile(tmpJsonPath, jsonPath)) {
824 AdapterFree(jsonPath);
825 AdapterFree(tmpJsonPath);
826 return false;
827 }
828
829 AdapterFree(jsonPath);
830 AdapterFree(tmpJsonPath);
831 return true;
832 }
833 } // namespace OHOS