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(SETTING_URI_PROXY, 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(), [&bundleName](const std::string& bundle) {
116 return bundle == bundleName;
117 });
118 return it != fullModeList_.end();
119 }
120
IsDefaultFullMode(const std::string & bundleName,int32_t userId)121 bool SecurityModeParser::IsDefaultFullMode(const std::string &bundleName, int32_t userId)
122 {
123 auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp();
124 if (defaultIme != nullptr && bundleName == defaultIme->name) {
125 return true;
126 }
127 std::string appId;
128 uint32_t versionCode;
129 if (!ImeInfoInquirer::GetInstance().GetImeAppId(userId, bundleName, appId)
130 || !ImeInfoInquirer::GetInstance().GetImeVersionCode(userId, bundleName, versionCode)) {
131 IMSA_HILOGE("%{public}s failed to get appId and versionCode", bundleName.c_str());
132 return false;
133 }
134 std::vector<DefaultFullImeInfo> defaultFullImeList;
135 if (!SysCfgParser::ParseDefaultFullIme(defaultFullImeList)) {
136 IMSA_HILOGE("failed to parse config");
137 return false;
138 }
139 auto ime = std::find_if(defaultFullImeList.begin(), defaultFullImeList.end(),
140 [&appId](const auto &ime) { return ime.appId == appId; });
141 if (ime == defaultFullImeList.end()) {
142 IMSA_HILOGD("not default FULL");
143 return false;
144 }
145 bool isDefaultFull = false;
146 if (ime->expirationVersionCode > 0) {
147 isDefaultFull = !IsExpired(ime->expirationTime) || versionCode < ime->expirationVersionCode;
148 } else {
149 isDefaultFull = !IsExpired(ime->expirationTime);
150 }
151 IMSA_HILOGI("ime: %{public}s, isDefaultFull: %{public}d", bundleName.c_str(), isDefaultFull);
152 return isDefaultFull;
153 }
154
IsExpired(const std::string & expirationTime)155 bool SecurityModeParser::IsExpired(const std::string &expirationTime)
156 {
157 std::istringstream expirationTimeStr(expirationTime);
158 std::tm expTime = {};
159 expirationTimeStr >> std::get_time(&expTime, "%Y-%m-%d %H:%M:%S");
160 if (expirationTimeStr.fail()) {
161 IMSA_HILOGE("get time error, expirationTime: %{public}s", expirationTime.c_str());
162 return false;
163 }
164 auto expTimePoint = std::chrono::system_clock::from_time_t(std::mktime(&expTime));
165 auto now = std::chrono::system_clock::now();
166 return expTimePoint < now;
167 }
168 } // namespace MiscServices
169 } // namespace OHOS