• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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