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