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 "security_mode_parser.h"
17
18 #include <algorithm>
19 #include <chrono>
20 #include <ctime>
21 #include <iomanip>
22 #include <sstream>
23
24 #include "full_ime_info_manager.h"
25 #include "ime_info_inquirer.h"
26 #include "input_method_utils.h"
27 #include "iservice_registry.h"
28 #include "serializable.h"
29 #include "settings_data_utils.h"
30 #include "sys_cfg_parser.h"
31 #include "system_ability_definition.h"
32 namespace OHOS {
33 namespace MiscServices {
34 std::mutex SecurityModeParser::instanceMutex_;
35 sptr<SecurityModeParser> SecurityModeParser::instance_ = nullptr;
36 constexpr const char *SYSTEM_SPECIAL_IME = "";
~SecurityModeParser()37 SecurityModeParser::~SecurityModeParser()
38 {
39 }
40
GetInstance()41 sptr<SecurityModeParser> SecurityModeParser::GetInstance()
42 {
43 if (instance_ == nullptr) {
44 std::lock_guard<std::mutex> autoLock(instanceMutex_);
45 if (instance_ == nullptr) {
46 IMSA_HILOGI("need to create SecurityModeParser.");
47 instance_ = new (std::nothrow) SecurityModeParser();
48 if (instance_ == nullptr) {
49 IMSA_HILOGE("instance is nullptr.");
50 return instance_;
51 }
52 }
53 }
54 return instance_;
55 }
56
Initialize(const int32_t userId)57 int32_t SecurityModeParser::Initialize(const int32_t userId)
58 {
59 return UpdateFullModeList(userId);
60 }
61
UpdateFullModeList(int32_t userId)62 int32_t SecurityModeParser::UpdateFullModeList(int32_t userId)
63 {
64 IMSA_HILOGD("key: %{public}s.", SECURITY_MODE);
65 std::string valueStr;
66 int32_t ret = SettingsDataUtils::GetInstance()->GetStringValue(SECURITY_MODE, valueStr);
67 if (ret != ErrorCode::NO_ERROR || valueStr.empty()) {
68 IMSA_HILOGW("get value failed, or valueStr is empty");
69 return ErrorCode::ERROR_ENABLE_SECURITY_MODE;
70 }
71
72 if (!ParseSecurityMode(valueStr, userId)) {
73 IMSA_HILOGE("parse %{public}s failed by %{public}d", valueStr.c_str(), userId);
74 return ErrorCode::ERROR_ENABLE_SECURITY_MODE;
75 }
76 return ErrorCode::NO_ERROR;
77 }
78
ParseSecurityMode(const std::string &valueStr, const int32_t userId)79 bool SecurityModeParser::ParseSecurityMode(const std::string &valueStr, const int32_t userId)
80 {
81 SecModeCfg secModeCfg;
82 secModeCfg.userImeCfg.userId = std::to_string(userId);
83 auto ret = secModeCfg.Unmarshall(valueStr);
84 if (!ret) {
85 IMSA_HILOGE("unmarshall failed!");
86 return ret;
87 }
88 std::lock_guard<std::mutex> autoLock(listMutex_);
89 fullModeList_ = secModeCfg.userImeCfg.identities;
90 return true;
91 }
92
GetSecurityMode(const std::string &bundleName, int32_t userId)93 SecurityMode SecurityModeParser::GetSecurityMode(const std::string &bundleName, int32_t userId)
94 {
95 if (bundleName == SYSTEM_SPECIAL_IME) {
96 return SecurityMode::FULL;
97 }
98 if (!initialized_) {
99 std::lock_guard<std::mutex> lock(initLock_);
100 if (!initialized_) {
101 UpdateFullModeList(userId);
102 initialized_ = true;
103 }
104 }
105 if (IsFullMode(bundleName)) {
106 return SecurityMode::FULL;
107 } else {
108 return SecurityMode::BASIC;
109 }
110 }
111
IsFullMode(std::string bundleName)112 bool SecurityModeParser::IsFullMode(std::string bundleName)
113 {
114 std::lock_guard<std::mutex> autoLock(listMutex_);
115 auto it = std::find_if(fullModeList_.begin(), fullModeList_.end(),
116 [&bundleName](const std::string &bundle) { return bundle == bundleName; });
117 return it != fullModeList_.end();
118 }
119
IsDefaultFullMode(const std::string &bundleName, int32_t userId)120 bool SecurityModeParser::IsDefaultFullMode(const std::string &bundleName, int32_t userId)
121 {
122 auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp();
123 if (defaultIme != nullptr && bundleName == defaultIme->name) {
124 return true;
125 }
126 std::string appId;
127 uint32_t versionCode;
128 if (!ImeInfoInquirer::GetInstance().GetImeAppId(userId, bundleName, appId)
129 || !ImeInfoInquirer::GetInstance().GetImeVersionCode(userId, bundleName, versionCode)) {
130 IMSA_HILOGE("%{public}s failed to get appId and versionCode", bundleName.c_str());
131 return false;
132 }
133 std::vector<DefaultFullImeInfo> defaultFullImeList;
134 if (!SysCfgParser::ParseDefaultFullIme(defaultFullImeList)) {
135 IMSA_HILOGE("failed to parse config");
136 return false;
137 }
138 auto ime = std::find_if(defaultFullImeList.begin(), defaultFullImeList.end(),
139 [&appId](const auto &ime) { return ime.appId == appId; });
140 if (ime == defaultFullImeList.end()) {
141 IMSA_HILOGD("not default FULL");
142 return false;
143 }
144 bool isDefaultFull = false;
145 if (ime->expirationVersionCode > 0) {
146 isDefaultFull = !IsExpired(ime->expirationTime) || versionCode < ime->expirationVersionCode;
147 } else {
148 isDefaultFull = !IsExpired(ime->expirationTime);
149 }
150 IMSA_HILOGI("ime: %{public}s, isDefaultFull: %{public}d", bundleName.c_str(), isDefaultFull);
151 return isDefaultFull;
152 }
153
IsExpired(const std::string &expirationTime)154 bool SecurityModeParser::IsExpired(const std::string &expirationTime)
155 {
156 std::istringstream expirationTimeStr(expirationTime);
157 std::tm expTime = {};
158 expirationTimeStr >> std::get_time(&expTime, "%Y-%m-%d %H:%M:%S");
159 if (expirationTimeStr.fail()) {
160 IMSA_HILOGE("get time error, expirationTime: %{public}s", expirationTime.c_str());
161 return false;
162 }
163 auto expTimePoint = std::chrono::system_clock::from_time_t(std::mktime(&expTime));
164 auto now = std::chrono::system_clock::now();
165 return expTimePoint < now;
166 }
167 } // namespace MiscServices
168 } // namespace OHOS