• 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 "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