1/* 2 * Copyright (c) 2024 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 <stdio.h> 17#include <stdlib.h> 18#include <string.h> 19#include <dirent.h> 20#include <unistd.h> 21#include <sys/stat.h> 22#include <ctype.h> 23#include <errno.h> 24#include <getopt.h> 25 26#include "policycoreutils.h" 27#ifdef CODE_SIGNATURE_ENABLE 28#include "code_sign_utils_in_c.h" 29#endif 30#include "hnp_installer.h" 31 32#ifdef __cplusplus 33extern "C" { 34#endif 35 36static int HnpInstallerUidGet(const char *uidIn, int *uidOut) 37{ 38 int index; 39 40 for (index = 0; uidIn[index] != '\0'; index++) { 41 if (!isdigit(uidIn[index])) { 42 return HNP_ERRNO_INSTALLER_ARGV_UID_INVALID; 43 } 44 } 45 46 *uidOut = atoi(uidIn); // 转化为10进制 47 return 0; 48} 49 50static int HnpGenerateSoftLinkAllByJson(const char *installPath, const char *dstPath, HnpCfgInfo *hnpCfg) 51{ 52 char srcFile[MAX_FILE_PATH_LEN]; 53 char dstFile[MAX_FILE_PATH_LEN]; 54 NativeBinLink *currentLink = hnpCfg->links; 55 char *fileNameTmp; 56 57 if (access(dstPath, F_OK) != 0) { 58 int ret = mkdir(dstPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 59 if ((ret != 0) && (errno != EEXIST)) { 60 HNP_LOGE("mkdir [%{public}s] unsuccess, ret=%{public}d, errno:%{public}d", dstPath, ret, errno); 61 return HNP_ERRNO_BASE_MKDIR_PATH_FAILED; 62 } 63 } 64 65 for (unsigned int i = 0; i < hnpCfg->linkNum; i++) { 66 if (strstr(currentLink->source, "../") || strstr(currentLink->target, "../")) { 67 HNP_LOGE("hnp json link source[%{public}s],target[%{public}s],does not allow the use of ../", 68 currentLink->source, currentLink->target); 69 return HNP_ERRNO_INSTALLER_GET_HNP_PATH_FAILED; 70 } 71 int ret = sprintf_s(srcFile, MAX_FILE_PATH_LEN, "%s/%s", installPath, currentLink->source); 72 char *fileName; 73 if (ret < 0) { 74 HNP_LOGE("sprintf install bin src file unsuccess."); 75 return HNP_ERRNO_BASE_SPRINTF_FAILED; 76 } 77 /* 如果target为空则使用源二进制名称 */ 78 if (strcmp(currentLink->target, "") == 0) { 79 fileNameTmp = currentLink->source; 80 } else { 81 fileNameTmp = currentLink->target; 82 } 83 fileName = strrchr(fileNameTmp, DIR_SPLIT_SYMBOL); 84 if (fileName == NULL) { 85 fileName = fileNameTmp; 86 } else { 87 fileName++; 88 } 89 ret = sprintf_s(dstFile, MAX_FILE_PATH_LEN, "%s/%s", dstPath, fileName); 90 if (ret < 0) { 91 HNP_LOGE("sprintf install bin dst file unsuccess."); 92 return HNP_ERRNO_BASE_SPRINTF_FAILED; 93 } 94 /* 生成软链接 */ 95 ret = HnpSymlink(srcFile, dstFile); 96 if (ret != 0) { 97 return ret; 98 } 99 100 currentLink++; 101 } 102 103 return 0; 104} 105 106static int HnpGenerateSoftLinkAll(const char *installPath, const char *dstPath) 107{ 108 char srcPath[MAX_FILE_PATH_LEN]; 109 char srcFile[MAX_FILE_PATH_LEN]; 110 char dstFile[MAX_FILE_PATH_LEN]; 111 int ret; 112 DIR *dir; 113 struct dirent *entry; 114 115 ret = sprintf_s(srcPath, MAX_FILE_PATH_LEN, "%s/bin", installPath); 116 if (ret < 0) { 117 HNP_LOGE("sprintf install bin path unsuccess."); 118 return HNP_ERRNO_BASE_SPRINTF_FAILED; 119 } 120 121 if ((dir = opendir(srcPath)) == NULL) { 122 HNP_LOGI("soft link bin file:%{public}s not exist", srcPath); 123 return 0; 124 } 125 126 if (access(dstPath, F_OK) != 0) { 127 ret = mkdir(dstPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 128 if ((ret != 0) && (errno != EEXIST)) { 129 closedir(dir); 130 HNP_LOGE("mkdir [%{public}s] unsuccess, ret=%{public}d, errno:%{public}d", dstPath, ret, errno); 131 return HNP_ERRNO_BASE_MKDIR_PATH_FAILED; 132 } 133 } 134 135 while (((entry = readdir(dir)) != NULL)) { 136 /* 非二进制文件跳过 */ 137 if (entry->d_type != DT_REG) { 138 continue; 139 } 140 ret = sprintf_s(srcFile, MAX_FILE_PATH_LEN, "%s/%s", srcPath, entry->d_name); 141 if (ret < 0) { 142 closedir(dir); 143 HNP_LOGE("sprintf install bin src file unsuccess."); 144 return HNP_ERRNO_BASE_SPRINTF_FAILED; 145 } 146 147 ret = sprintf_s(dstFile, MAX_FILE_PATH_LEN, "%s/%s", dstPath, entry->d_name); 148 if (ret < 0) { 149 closedir(dir); 150 HNP_LOGE("sprintf install bin dst file unsuccess."); 151 return HNP_ERRNO_BASE_SPRINTF_FAILED; 152 } 153 /* 生成软链接 */ 154 ret = HnpSymlink(srcFile, dstFile); 155 if (ret != 0) { 156 closedir(dir); 157 return ret; 158 } 159 } 160 161 closedir(dir); 162 return 0; 163} 164 165static int HnpGenerateSoftLink(const char *installPath, const char *hnpBasePath, HnpCfgInfo *hnpCfg) 166{ 167 int ret = 0; 168 char binPath[MAX_FILE_PATH_LEN]; 169 170 ret = sprintf_s(binPath, MAX_FILE_PATH_LEN, "%s/bin", hnpBasePath); 171 if (ret < 0) { 172 HNP_LOGE("sprintf install bin path unsuccess."); 173 return HNP_ERRNO_BASE_SPRINTF_FAILED; 174 } 175 176 if (hnpCfg->linkNum == 0) { 177 ret = HnpGenerateSoftLinkAll(installPath, binPath); 178 } else { 179 ret = HnpGenerateSoftLinkAllByJson(installPath, binPath, hnpCfg); 180 } 181 182 return ret; 183} 184 185static int HnpInstall(const char *hnpFile, HnpInstallInfo *hnpInfo, HnpCfgInfo *hnpCfg, 186 HnpSignMapInfo *hnpSignMapInfos, int *count) 187{ 188 int ret; 189 190 /* 解压hnp文件 */ 191 ret = HnpUnZip(hnpFile, hnpInfo->hnpVersionPath, hnpInfo->hnpSignKeyPrefix, hnpSignMapInfos, count); 192 if (ret != 0) { 193 return ret; /* 内部已打印日志 */ 194 } 195 196 /* 生成软链 */ 197 return HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, hnpCfg); 198} 199 200/** 201 * 卸载公共hnp. 202 * 203 * @param packageName hap名称. 204 * @param name hnp名称 205 * @param version 版本号. 206 * @param uid 用户id. 207 * @param isInstallVersion 是否卸载安装版本. 208 * 209 * @return 0:success;other means failure. 210 */ 211static int HnpUnInstallPublicHnp(const char* packageName, const char *name, const char *version, int uid, 212 bool isInstallVersion) 213{ 214 int ret; 215 char hnpNamePath[MAX_FILE_PATH_LEN]; 216 char hnpVersionPath[MAX_FILE_PATH_LEN]; 217 char sandboxPath[MAX_FILE_PATH_LEN]; 218 219 if (sprintf_s(hnpNamePath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnppublic/%s.org", uid, name) < 0) { 220 HNP_LOGE("hnp uninstall name path sprintf unsuccess,uid:%{public}d,name:%{public}s", uid, name); 221 return HNP_ERRNO_BASE_SPRINTF_FAILED; 222 } 223 224 if (sprintf_s(hnpVersionPath, MAX_FILE_PATH_LEN, "%s/%s_%s", hnpNamePath, name, version) < 0) { 225 HNP_LOGE("hnp uninstall sprintf version path unsuccess."); 226 return HNP_ERRNO_BASE_SPRINTF_FAILED; 227 } 228 229 if (sprintf_s(sandboxPath, MAX_FILE_PATH_LEN, HNP_SANDBOX_BASE_PATH"/%s.org", name) < 0) { 230 HNP_LOGE("sprintf unstall base path unsuccess."); 231 return HNP_ERRNO_BASE_SPRINTF_FAILED; 232 } 233 234 ret = HnpProcessRunCheck(sandboxPath); 235 if (ret != 0) { 236 return ret; 237 } 238 239 if (!isInstallVersion) { 240 ret = HnpPackageInfoHnpDelete(packageName, name, version); 241 if (ret != 0) { 242 return ret; 243 } 244 } 245 246 ret = HnpDeleteFolder(hnpVersionPath); 247 if (ret != 0) { 248 return ret; 249 } 250 251 if (HnpPathFileCount(hnpNamePath) == 0) { 252 return HnpDeleteFolder(hnpNamePath); 253 } 254 255 return 0; 256} 257 258static int HnpNativeUnInstall(HnpPackageInfo *packageInfo, int uid, const char *packageName) 259{ 260 int ret = 0; 261 262 HNP_LOGI("hnp uninstall start now! name=%{public}s,version=[%{public}s,%{public}s],uid=%{public}d," 263 "package=%{public}s", packageInfo->name, packageInfo->currentVersion, packageInfo->installVersion, uid, 264 packageName); 265 266 if (!packageInfo->hnpExist) { 267 ret = HnpUnInstallPublicHnp(packageName, packageInfo->name, packageInfo->currentVersion, uid, false); 268 if (ret != 0) { 269 return ret; 270 } 271 } 272 273 if (strcmp(packageInfo->installVersion, "none") != 0 && 274 strcmp(packageInfo->currentVersion, packageInfo->installVersion) != 0) { 275 ret = HnpUnInstallPublicHnp(packageName, packageInfo->name, packageInfo->installVersion, uid, true); 276 if (ret != 0) { 277 return ret; 278 } 279 } 280 HNP_LOGI("hnp uninstall end! ret=%{public}d", ret); 281 282 return 0; 283} 284 285static int HnpUnInstall(int uid, const char *packageName) 286{ 287 HnpPackageInfo *packageInfo = NULL; 288 int count = 0; 289 char privatePath[MAX_FILE_PATH_LEN]; 290 char dstPath[MAX_FILE_PATH_LEN]; 291 292 /* 拼接卸载路径 */ 293 if (sprintf_s(dstPath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d", uid) < 0) { 294 HNP_LOGE("hnp install sprintf unsuccess, uid:%{public}d", uid); 295 return HNP_ERRNO_BASE_SPRINTF_FAILED; 296 } 297 298 /* 验证卸载路径是否存在 */ 299 if (access(dstPath, F_OK) != 0) { 300 HNP_LOGE("hnp uninstall uid path[%{public}s] is not exist", dstPath); 301 return HNP_ERRNO_UNINSTALLER_HNP_PATH_NOT_EXIST; 302 } 303 304 int ret = HnpPackageInfoGet(packageName, &packageInfo, &count); 305 if (ret != 0) { 306 return ret; 307 } 308 309 /* 卸载公有native */ 310 for (int i = 0; i < count; i++) { 311 ret = HnpNativeUnInstall(&packageInfo[i], uid, packageName); 312 if (ret != 0) { 313 free(packageInfo); 314 return ret; 315 } 316 } 317 free(packageInfo); 318 319 ret = HnpPackageInfoDelete(packageName); 320 if (ret != 0) { 321 return ret; 322 } 323 324 if (sprintf_s(privatePath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnp/%s", uid, packageName) < 0) { 325 HNP_LOGE("hnp uninstall private path sprintf unsuccess, uid:%{public}d,package name[%{public}s]", uid, 326 packageName); 327 return HNP_ERRNO_BASE_SPRINTF_FAILED; 328 } 329 330 (void)HnpDeleteFolder(privatePath); 331 332 return 0; 333} 334 335static int HnpInstallForceCheck(HnpCfgInfo *hnpCfgInfo, HnpInstallInfo *hnpInfo) 336{ 337 int ret = 0; 338 339 /* 判断安装目录是否存在,存在判断是否是强制安装,如果是则走卸载流程,否则返回错误 */ 340 if (access(hnpInfo->hnpSoftwarePath, F_OK) == 0) { 341 if (hnpInfo->hapInstallInfo->isForce == false) { 342 HNP_LOGE("hnp install path[%{public}s] exist, but force is false", hnpInfo->hnpSoftwarePath); 343 return HNP_ERRNO_INSTALLER_PATH_IS_EXIST; 344 } 345 if (hnpInfo->isPublic == false) { 346 if (HnpDeleteFolder(hnpInfo->hnpSoftwarePath) != 0) { 347 return ret; 348 } 349 } 350 } 351 352 ret = HnpCreateFolder(hnpInfo->hnpVersionPath); 353 if (ret != 0) { 354 return HnpDeleteFolder(hnpInfo->hnpVersionPath); 355 } 356 return ret; 357} 358 359static int HnpInstallPathGet(HnpCfgInfo *hnpCfgInfo, HnpInstallInfo *hnpInfo) 360{ 361 int ret; 362 363 /* 拼接安装路径 */ 364 ret = sprintf_s(hnpInfo->hnpSoftwarePath, MAX_FILE_PATH_LEN, "%s/%s.org", hnpInfo->hnpBasePath, 365 hnpCfgInfo->name); 366 if (ret < 0) { 367 HNP_LOGE("hnp install sprintf hnp base path unsuccess."); 368 return HNP_ERRNO_BASE_SPRINTF_FAILED; 369 } 370 371 /* 拼接安装路径 */ 372 ret = sprintf_s(hnpInfo->hnpVersionPath, MAX_FILE_PATH_LEN, "%s/%s_%s", hnpInfo->hnpSoftwarePath, 373 hnpCfgInfo->name, hnpCfgInfo->version); 374 if (ret < 0) { 375 HNP_LOGE("hnp install sprintf install path unsuccess."); 376 return HNP_ERRNO_BASE_SPRINTF_FAILED; 377 } 378 379 return 0; 380} 381 382static int HnpPublicDealAfterInstall(HnpInstallInfo *hnpInfo, HnpCfgInfo *hnpCfg) 383{ 384 char *version = HnpCurrentVersionUninstallCheck(hnpCfg->name); 385 if (version == NULL) { 386 version = HnpCurrentVersionGet(hnpCfg->name); 387 if (version != NULL) { 388 HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg->name, version, 389 hnpInfo->hapInstallInfo->uid, true); 390 } 391 } 392 if (version != NULL) { 393 free(version); 394 } 395 hnpCfg->isInstall = true; 396 397 return HnpInstallInfoJsonWrite(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg); 398} 399 400static int HnpReadAndInstall(char *srcFile, HnpInstallInfo *hnpInfo, HnpSignMapInfo *hnpSignMapInfos, int *count) 401{ 402 int ret; 403 HnpCfgInfo hnpCfg = {0}; 404 405 HNP_LOGI("hnp install start now! src file=%{public}s, dst path=%{public}s", srcFile, hnpInfo->hnpBasePath); 406 /* 从hnp zip获取cfg信息 */ 407 ret = HnpCfgGetFromZip(srcFile, &hnpCfg); 408 if (ret != 0) { 409 return ret; 410 } 411 412 ret = HnpInstallPathGet(&hnpCfg, hnpInfo); 413 if (ret != 0) { 414 // 释放软链接占用的内存 415 if (hnpCfg.links != NULL) { 416 free(hnpCfg.links); 417 } 418 return ret; 419 } 420 421 /* 存在对应版本的公有hnp包跳过安装 */ 422 if (access(hnpInfo->hnpVersionPath, F_OK) == 0 && hnpInfo->isPublic) { 423 /* 刷新软链 */ 424 ret = HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, &hnpCfg); 425 if (ret != 0) { 426 return ret; 427 } 428 // 释放软链接占用的内存 429 if (hnpCfg.links != NULL) { 430 free(hnpCfg.links); 431 } 432 return HnpPublicDealAfterInstall(hnpInfo, &hnpCfg); 433 } 434 435 ret = HnpInstallForceCheck(&hnpCfg, hnpInfo); 436 if (ret != 0) { 437 // 释放软链接占用的内存 438 if (hnpCfg.links != NULL) { 439 free(hnpCfg.links); 440 } 441 return ret; 442 } 443 444 /* hnp安装 */ 445 ret = HnpInstall(srcFile, hnpInfo, &hnpCfg, hnpSignMapInfos, count); 446 // 释放软链接占用的内存 447 if (hnpCfg.links != NULL) { 448 free(hnpCfg.links); 449 } 450 if (ret != 0) { 451 HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg.name, hnpCfg.version, 452 hnpInfo->hapInstallInfo->uid, false); 453 return ret; 454 } 455 456 if (hnpInfo->isPublic) { 457 ret = HnpPublicDealAfterInstall(hnpInfo, &hnpCfg); 458 if (ret != 0) { 459 HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg.name, hnpCfg.version, 460 hnpInfo->hapInstallInfo->uid, false); 461 } 462 } 463 464 return ret; 465} 466 467static bool HnpFileCheck(const char *file) 468{ 469 const char suffix[] = ".hnp"; 470 int len = strlen(file); 471 int suffixLen = strlen(suffix); 472 if ((len >= suffixLen) && (strcmp(file + len - suffixLen, suffix) == 0)) { 473 return true; 474 } 475 476 return false; 477} 478 479static int HnpPackageGetAndInstall(const char *dirPath, HnpInstallInfo *hnpInfo, char *sunDir, 480 HnpSignMapInfo *hnpSignMapInfos, int *count) 481{ 482 DIR *dir; 483 struct dirent *entry; 484 char path[MAX_FILE_PATH_LEN]; 485 char sunDirNew[MAX_FILE_PATH_LEN]; 486 487 if ((dir = opendir(dirPath)) == NULL) { 488 HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", dirPath, errno); 489 return HNP_ERRNO_BASE_DIR_OPEN_FAILED; 490 } 491 492 while ((entry = readdir(dir)) != NULL) { 493 if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { 494 continue; 495 } 496 if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", dirPath, entry->d_name) < 0) { 497 HNP_LOGE("hnp install sprintf unsuccess, dir[%{public}s], path[%{public}s]", dirPath, entry->d_name); 498 closedir(dir); 499 return HNP_ERRNO_BASE_SPRINTF_FAILED; 500 } 501 502 if (entry->d_type == DT_DIR) { 503 if (sprintf_s(sunDirNew, MAX_FILE_PATH_LEN, "%s%s/", sunDir, entry->d_name) < 0) { 504 HNP_LOGE("hnp install sprintf sub dir unsuccess"); 505 closedir(dir); 506 return HNP_ERRNO_BASE_SPRINTF_FAILED; 507 } 508 int ret = HnpPackageGetAndInstall(path, hnpInfo, sunDirNew, hnpSignMapInfos, count); 509 if (ret != 0) { 510 closedir(dir); 511 return ret; 512 } 513 } else { 514 if (HnpFileCheck(path) == false) { 515 continue; 516 } 517 if (sprintf_s(hnpInfo->hnpSignKeyPrefix, MAX_FILE_PATH_LEN, "hnp/%s/%s%s", hnpInfo->hapInstallInfo->abi, 518 sunDir, entry->d_name) < 0) { 519 HNP_LOGE("hnp install sprintf unsuccess,sub[%{public}s],path[%{public}s]", sunDir, entry->d_name); 520 closedir(dir); 521 return HNP_ERRNO_BASE_SPRINTF_FAILED; 522 } 523 int ret = HnpReadAndInstall(path, hnpInfo, hnpSignMapInfos, count); 524 HNP_LOGI("hnp install end, ret=%{public}d", ret); 525 if (ret != 0) { 526 closedir(dir); 527 return ret; 528 } 529 } 530 } 531 closedir(dir); 532 return 0; 533} 534 535static int HapReadAndInstall(const char *dstPath, HapInstallInfo *installInfo, HnpSignMapInfo *hnpSignMapInfos, 536 int *count) 537{ 538 struct dirent *entry; 539 char hnpPath[MAX_FILE_PATH_LEN]; 540 HnpInstallInfo hnpInfo = {0}; 541 int ret; 542 543 DIR *dir = opendir(installInfo->hnpRootPath); 544 if (dir == NULL) { 545 HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", installInfo->hnpRootPath, errno); 546 return HNP_ERRNO_BASE_DIR_OPEN_FAILED; 547 } 548 549 hnpInfo.hapInstallInfo = installInfo; 550 /* 遍历src目录 */ 551 while ((entry = readdir(dir)) != NULL) { 552 if (strcmp(entry->d_name, "public") == 0) { 553 hnpInfo.isPublic = true; 554 if ((sprintf_s(hnpInfo.hnpBasePath, MAX_FILE_PATH_LEN, "%s/hnppublic", dstPath) < 0) || 555 (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/public", installInfo->hnpRootPath) < 0)) { 556 HNP_LOGE("hnp install public base path sprintf unsuccess."); 557 closedir(dir); 558 return HNP_ERRNO_BASE_SPRINTF_FAILED; 559 } 560 } else if (strcmp(entry->d_name, "private") == 0) { 561 hnpInfo.isPublic = false; 562 if ((sprintf_s(hnpInfo.hnpBasePath, MAX_FILE_PATH_LEN, "%s/hnp/%s", dstPath, 563 installInfo->hapPackageName) < 0) || (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/private", 564 installInfo->hnpRootPath) < 0)) { 565 HNP_LOGE("hnp install private base path sprintf unsuccess."); 566 closedir(dir); 567 return HNP_ERRNO_BASE_SPRINTF_FAILED; 568 } 569 } else { 570 continue; 571 } 572 573 ret = HnpPackageGetAndInstall(hnpPath, &hnpInfo, "", hnpSignMapInfos, count); 574 if (ret != 0) { 575 closedir(dir); 576 return ret; 577 } 578 } 579 580 closedir(dir); 581 return 0; 582} 583 584static int HnpInstallHnpFileCountGet(char *hnpPath, int *count) 585{ 586 DIR *dir; 587 struct dirent *entry; 588 char path[MAX_FILE_PATH_LEN]; 589 int ret; 590 591 if ((dir = opendir(hnpPath)) == NULL) { 592 HNP_LOGE("hnp install count get opendir:%{public}s unsuccess, errno=%{public}d", hnpPath, errno); 593 return HNP_ERRNO_BASE_DIR_OPEN_FAILED; 594 } 595 596 while ((entry = readdir(dir)) != NULL) { 597 if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { 598 continue; 599 } 600 601 if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", hnpPath, entry->d_name) < 0) { 602 HNP_LOGE("hnp install count get sprintf unsuccess, dir[%{public}s], path[%{public}s]", hnpPath, 603 entry->d_name); 604 closedir(dir); 605 return HNP_ERRNO_BASE_SPRINTF_FAILED; 606 } 607 608 if (entry->d_type == DT_DIR) { 609 if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", hnpPath, entry->d_name) < 0) { 610 HNP_LOGE("hnp install sprintf sub dir unsuccess"); 611 closedir(dir); 612 return HNP_ERRNO_BASE_SPRINTF_FAILED; 613 } 614 ret = HnpInstallHnpFileCountGet(path, count); 615 if (ret != 0) { 616 closedir(dir); 617 return ret; 618 } 619 } else { 620 if (HnpFileCheck(path) == false) { 621 continue; 622 } 623 ret = HnpFileCountGet(path, count); 624 if (ret != 0) { 625 closedir(dir); 626 return ret; 627 } 628 } 629 } 630 631 closedir(dir); 632 return 0; 633} 634 635static int HnpInstallHapFileCountGet(const char *root, int *count) 636{ 637 struct dirent *entry; 638 char hnpPath[MAX_FILE_PATH_LEN]; 639 640 DIR *dir = opendir(root); 641 if (dir == NULL) { 642 HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", root, errno); 643 return HNP_ERRNO_BASE_DIR_OPEN_FAILED; 644 } 645 646 while ((entry = readdir(dir)) != NULL) { 647 if ((strcmp(entry->d_name, "public") != 0) && (strcmp(entry->d_name, "private") != 0)) { 648 continue; 649 } 650 if (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/%s", root, entry->d_name) < 0) { 651 HNP_LOGE("hnp install private base path sprintf unsuccess."); 652 closedir(dir); 653 return HNP_ERRNO_BASE_SPRINTF_FAILED; 654 } 655 656 int ret = HnpInstallHnpFileCountGet(hnpPath, count); 657 if (ret != 0) { 658 closedir(dir); 659 return ret; 660 } 661 } 662 663 closedir(dir); 664 return 0; 665} 666 667static int SetHnpRestorecon(char *path) 668{ 669 int ret; 670 char publicPath[MAX_FILE_PATH_LEN] = {0}; 671 if (sprintf_s(publicPath, MAX_FILE_PATH_LEN, "%s/hnppublic", path) < 0) { 672 HNP_LOGE("sprintf fail, get hnp restorecon path fail"); 673 return HNP_ERRNO_INSTALLER_RESTORECON_HNP_PATH_FAIL; 674 } 675 676 if (access(publicPath, F_OK) != 0) { 677 ret = mkdir(publicPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 678 if ((ret != 0) && (errno != EEXIST)) { 679 HNP_LOGE("mkdir public path fail"); 680 return HNP_ERRNO_BASE_MKDIR_PATH_FAILED; 681 } 682 } 683 684 if (RestoreconRecurse(publicPath)) { 685 HNP_LOGE("restorecon hnp path fail"); 686 return HNP_ERRNO_INSTALLER_RESTORECON_HNP_PATH_FAIL; 687 } 688 689 return 0; 690} 691 692static int CheckInstallPath(char *dstPath, HapInstallInfo *installInfo) 693{ 694 /* 拼接安装路径 */ 695 if (sprintf_s(dstPath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d", installInfo->uid) < 0) { 696 HNP_LOGE("hnp install sprintf unsuccess, uid:%{public}d", installInfo->uid); 697 return HNP_ERRNO_INSTALLER_GET_HNP_PATH_FAILED; 698 } 699 700 /* 验证安装路径是否存在 */ 701 if (access(dstPath, F_OK) != 0) { 702 HNP_LOGE("hnp install uid path[%{public}s] is not exist", dstPath); 703 return HNP_ERRNO_INSTALLER_GET_REALPATH_FAILED; 704 } 705 706 /* restorecon hnp 安装目录 */ 707 return SetHnpRestorecon(dstPath); 708} 709 710static int HnpInsatllPre(HapInstallInfo *installInfo) 711{ 712 char dstPath[MAX_FILE_PATH_LEN]; 713 int count = 0; 714 HnpSignMapInfo *hnpSignMapInfos = NULL; 715#ifdef CODE_SIGNATURE_ENABLE 716 struct EntryMapEntryData data = {0}; 717 int i; 718#endif 719 int ret; 720 721 if ((ret = CheckInstallPath(dstPath, installInfo)) != 0 || 722 (ret = HnpInstallHapFileCountGet(installInfo->hnpRootPath, &count)) != 0) { 723 return ret; 724 } 725 726 if (count > 0) { 727 hnpSignMapInfos = (HnpSignMapInfo *)malloc(sizeof(HnpSignMapInfo) * count); 728 if (hnpSignMapInfos == NULL) { 729 return HNP_ERRNO_NOMEM; 730 } 731 } 732 733 count = 0; 734 ret = HapReadAndInstall(dstPath, installInfo, hnpSignMapInfos, &count); 735 HNP_LOGI("sign start hap path[%{public}s],abi[%{public}s],count=%{public}d", installInfo->hapPath, installInfo->abi, 736 count); 737#ifdef CODE_SIGNATURE_ENABLE 738 if ((ret == 0) && (count > 0)) { 739 data.entries = malloc(sizeof(struct EntryMapEntry) * count); 740 if (data.entries == NULL) { 741 return HNP_ERRNO_NOMEM; 742 } 743 for (i = 0; i < count; i++) { 744 data.entries[i].key = hnpSignMapInfos[i].key; 745 data.entries[i].value = hnpSignMapInfos[i].value; 746 } 747 data.count = count; 748 ret = EnforceCodeSignForApp(installInfo->hapPath, &data, FILE_ENTRY_ONLY); 749 HNP_LOGI("sign end ret=%{public}d,last key[%{public}s],value[%{public}s]", ret, data.entries[i - 1].key, 750 data.entries[i - 1].value); 751 free(data.entries); 752 if (ret != 0) { 753 HnpUnInstall(installInfo->uid, installInfo->hapPackageName); 754 ret = HNP_ERRNO_INSTALLER_CODE_SIGN_APP_FAILED; 755 } 756 } 757#endif 758 free(hnpSignMapInfos); 759 return ret; 760} 761 762static int ParseInstallArgs(int argc, char *argv[], HapInstallInfo *installInfo) 763{ 764 int ret; 765 int ch; 766 767 optind = 1; // 从头开始遍历参数 768 while ((ch = getopt_long(argc, argv, "hu:p:i:s:a:f", NULL, NULL)) != -1) { 769 switch (ch) { 770 case 'h' : 771 return HNP_ERRNO_OPERATOR_ARGV_MISS; 772 case 'u': // 用户id 773 ret = HnpInstallerUidGet(optarg, &installInfo->uid); 774 if (ret != 0) { 775 HNP_LOGE("hnp install argv uid[%{public}s] invalid", optarg); 776 return ret; 777 } 778 break; 779 case 'p': // app名称 780 installInfo->hapPackageName = (char *)optarg; 781 break; 782 case 'i': // hnp安装目录 783 installInfo->hnpRootPath = (char *)optarg; 784 break; 785 case 's': // hap目录 786 installInfo->hapPath = (char *)optarg; 787 break; 788 case 'a': // 系统abi路径 789 installInfo->abi = (char *)optarg; 790 break; 791 case 'f': // is force 792 installInfo->isForce = true; 793 break; 794 default: 795 break; 796 } 797 } 798 799 if ((installInfo->uid == -1) || (installInfo->hnpRootPath == NULL) || (installInfo->hapPath == NULL) || 800 (installInfo->abi == NULL) || (installInfo->hapPackageName == NULL)) { 801 HNP_LOGE("argv params is missing."); 802 return HNP_ERRNO_OPERATOR_ARGV_MISS; 803 } 804 805 return 0; 806} 807 808int HnpCmdInstall(int argc, char *argv[]) 809{ 810 HapInstallInfo installInfo = {0}; 811 812 installInfo.uid = -1; // 预设值,判断简单 813 // 解析参数并生成安装信息 814 int ret = ParseInstallArgs(argc, argv, &installInfo); 815 if (ret != 0) { 816 return ret; 817 } 818 819 return HnpInsatllPre(&installInfo); 820} 821 822int HnpCmdUnInstall(int argc, char *argv[]) 823{ 824 int uid; 825 char *uidArg = NULL; 826 char *packageName = NULL; 827 int ret; 828 int ch; 829 830 optind = 1; // 从头开始遍历参数 831 while ((ch = getopt_long(argc, argv, "hu:p:", NULL, NULL)) != -1) { 832 switch (ch) { 833 case 'h' : 834 return HNP_ERRNO_OPERATOR_ARGV_MISS; 835 case 'u': // uid 836 uidArg = optarg; 837 ret = HnpInstallerUidGet(uidArg, &uid); 838 if (ret != 0) { 839 HNP_LOGE("hnp install arg uid[%{public}s] invalid", uidArg); 840 return ret; 841 } 842 break; 843 case 'p': // hnp package name 844 packageName = (char *)optarg; 845 break; 846 default: 847 break; 848 } 849 } 850 851 if ((uidArg == NULL) || (packageName == NULL)) { 852 HNP_LOGE("hnp uninstall params invalid uid[%{public}s], package name[%{public}s]", uidArg, packageName); 853 return HNP_ERRNO_OPERATOR_ARGV_MISS; 854 } 855 856 return HnpUnInstall(uid, packageName); 857} 858 859#ifdef __cplusplus 860} 861#endif 862