• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "module_file_repository.h"
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 
22 #include "directory_ex.h"
23 #include "log/log.h"
24 #include "module_constants.h"
25 #include "module_error_code.h"
26 #include "scope_guard.h"
27 #include "unique_fd.h"
28 
29 namespace OHOS {
30 namespace SysInstaller {
31 using namespace Updater;
32 using std::string;
33 
~ModuleFileRepository()34 ModuleFileRepository::~ModuleFileRepository()
35 {
36     Clear();
37 }
38 
InitRepository(const string & hmpName,const Timer & timer)39 void ModuleFileRepository::InitRepository(const string &hmpName, const Timer &timer)
40 {
41     string allPath[] = {MODULE_PREINSTALL_DIR, UPDATE_INSTALL_DIR, UPDATE_ACTIVE_DIR};
42     auto& fileMap = moduleFileMap_[hmpName];
43     for (string &path : allPath) {
44         std::vector<string> files;
45         const string checkDir = path + "/" + hmpName;
46         GetDirFiles(checkDir, files);
47         for (string &file : files) {
48             if (!CheckFileSuffix(file, MODULE_PACKAGE_SUFFIX)) {
49                 continue;
50             }
51             // verifi zip before open it.
52             if (path != MODULE_PREINSTALL_DIR && VerifyModulePackageSign(file) != 0) {
53                 LOG(ERROR) << "VerifyModulePackageSign failed of " << file;
54                 SaveInstallerResult(path, hmpName, ModuleErrorCode::ERR_VERIFY_FAIL, "verify fail", timer);
55                 continue;
56             }
57             ProcessFile(hmpName, path, file, fileMap, timer);
58         }
59     }
60     LOG(INFO) << "InitRepository all timer:" << timer;
61 }
62 
SaveInstallerResult(const std::string & path,const std::string & hmpName,int result,const std::string & resultInfo,const Timer & timer) const63 void ModuleFileRepository::SaveInstallerResult(const std::string &path, const std::string &hmpName,
64     int result, const std::string &resultInfo, const Timer &timer) const
65 {
66     if (path.find(UPDATE_INSTALL_DIR) == std::string::npos && path.find(UPDATE_ACTIVE_DIR) == std::string::npos) {
67         return;
68     }
69     if (!CheckFileSuffix(path, MODULE_PACKAGE_SUFFIX) && !CheckFileSuffix(path, MODULE_IMAGE_SUFFIX)) {
70         LOG(WARNING) << "SaveInstallerResult path:" << path << "; break;";
71         return;
72     }
73     if (!CheckPathExists(MODULE_RESULT_PATH)) {
74         LOG(ERROR) << MODULE_RESULT_PATH << " not exist";
75         return;
76     }
77     LOG(INFO) << "path:" << path << "hmp:" << hmpName << "result:" << result << "Info:" << resultInfo << "\n";
78 
79     UniqueFd fd(open(MODULE_RESULT_PATH, O_APPEND | O_RDWR | O_CLOEXEC));
80     if (fd.Get() == -1) {
81         LOG(ERROR) << "Failed to open file";
82         return;
83     }
84 
85     std::string writeInfo = hmpName + ";" + std::to_string(result) + ";" +
86         resultInfo + "|" + std::to_string(timer.duration().count()) + "\n";
87     if (CheckAndUpdateRevertResult(hmpName, writeInfo, "mount fail")) {
88         return;
89     }
90     if (write(fd, writeInfo.data(), writeInfo.length()) <= 0) {
91         LOG(WARNING) << "write result file failed, err:" << errno;
92     }
93     fsync(fd.Get());
94 }
95 
ProcessFile(const string & hmpName,const string & path,const string & file,std::unordered_map<std::string,ModuleFile> & fileMap,const Timer & timer) const96 void ModuleFileRepository::ProcessFile(const string &hmpName, const string &path, const string &file,
97     std::unordered_map<std::string, ModuleFile> &fileMap, const Timer &timer) const
98 {
99     std::unique_ptr<ModuleFile> moduleFile = ModuleFile::Open(file);
100     if (moduleFile == nullptr || moduleFile->GetVersionInfo().hmpName != hmpName) {
101         return;
102     }
103     if (!moduleFile->GetImageStat().has_value()) {
104         LOG(ERROR) << "verify failed, img is empty: " << file;
105         SaveInstallerResult(path, hmpName, ModuleErrorCode::ERR_VERIFY_FAIL, "img empty", timer);
106         return;
107     }
108     if (path != MODULE_PREINSTALL_DIR) {
109         if (!CheckFilePath(*moduleFile, path)) {
110             LOG(ERROR) << "Open " << file << " failed";
111             SaveInstallerResult(path, hmpName, ModuleErrorCode::ERR_VERIFY_FAIL, "get pub key fail", timer);
112             return;
113         }
114     }
115     LOG(INFO) << "ProcessFile " << file << " successful";
116     fileMap.insert(std::make_pair(path, std::move(*moduleFile)));
117 }
118 
GetModuleFile(const std::string & pathPrefix,const string & hmpName) const119 std::unique_ptr<ModuleFile> ModuleFileRepository::GetModuleFile(const std::string &pathPrefix,
120     const string &hmpName) const
121 {
122     auto mapIter = moduleFileMap_.find(hmpName);
123     if (mapIter == moduleFileMap_.end()) {
124         LOG(ERROR) << "Invalid path hmpName= " << hmpName;
125         return nullptr;
126     }
127     std::unordered_map<std::string, ModuleFile> fileMap = mapIter->second;
128     auto fileIter = fileMap.find(pathPrefix);
129     if (fileIter == fileMap.end()) {
130         LOG(INFO) << hmpName << " not found in " << pathPrefix;
131         return nullptr;
132     }
133     ModuleFile file = fileIter->second;
134     return std::make_unique<ModuleFile>(std::move(file));
135 }
136 
IsPreInstalledModule(const ModuleFile & moduleFile) const137 bool ModuleFileRepository::IsPreInstalledModule(const ModuleFile &moduleFile) const
138 {
139     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR,
140         moduleFile.GetVersionInfo().hmpName);
141     if (preInstalledModule == nullptr) {
142         return false;
143     }
144     return preInstalledModule->GetPath() == moduleFile.GetPath();
145 }
146 
CheckFilePath(const ModuleFile & moduleFile,const string & prefix) const147 bool ModuleFileRepository::CheckFilePath(const ModuleFile &moduleFile, const string &prefix) const
148 {
149     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR,
150         moduleFile.GetVersionInfo().hmpName);
151     if (preInstalledModule == nullptr) {
152         return false;
153     }
154     string prePath = preInstalledModule->GetPath();
155     string curPath = moduleFile.GetPath();
156     return prePath.substr(strlen(MODULE_PREINSTALL_DIR), prePath.length()) ==
157         curPath.substr(prefix.length(), curPath.length());
158 }
159 
Clear()160 void ModuleFileRepository::Clear()
161 {
162     for (auto mapIter = moduleFileMap_.begin(); mapIter != moduleFileMap_.end(); ++mapIter) {
163         std::unordered_map<std::string, ModuleFile> &fileMap = mapIter->second;
164         for (auto fileIter = fileMap.begin(); fileIter != fileMap.end(); ++fileIter) {
165             fileIter->second.ClearVerifiedData();
166         }
167         fileMap.clear();
168     }
169     moduleFileMap_.clear();
170 }
171 
GetModuleMap(void)172 const std::unordered_map<string, std::unordered_map<string, ModuleFile>> &ModuleFileRepository::GetModuleMap(void)
173 {
174     return moduleFileMap_;
175 }
176 } // SysInstaller
177 } // namespace OHOS
178