1 /*
2  * Copyright (c) 2022 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 "risk_analysis_manager_service.h"
17 
18 #include <thread>
19 
20 #include "accesstoken_kit.h"
21 #include "tokenid_kit.h"
22 #include "ipc_skeleton.h"
23 
24 #include "bigdata.h"
25 #include "database_manager.h"
26 #include "errors.h"
27 #include "model_manager.h"
28 #include "risk_analysis_define.h"
29 #include "risk_analysis_manager_callback_proxy.h"
30 #include "security_guard_define.h"
31 #include "security_guard_log.h"
32 #include "security_guard_utils.h"
33 #include "system_ability_definition.h"
34 #include "task_handler.h"
35 #include "model_manager.h"
36 #include "config_manager.h"
37 #include "store_define.h"
38 
39 namespace OHOS::Security::SecurityGuard {
40 REGISTER_SYSTEM_ABILITY_BY_ID(RiskAnalysisManagerService, RISK_ANALYSIS_MANAGER_SA_ID, true);
41 
42 namespace {
43     constexpr int32_t TIMEOUT_REPLY = 500;
44     constexpr const char* REQUEST_PERMISSION = "ohos.permission.securityguard.REQUEST_SECURITY_MODEL_RESULT";
45     constexpr const char* QUERY_SECURITY_MODEL_RESULT_PERMISSION = "ohos.permission.QUERY_SECURITY_MODEL_RESULT";
46     const std::vector<uint32_t> MODELIDS = { 3001000000, 3001000001, 3001000002, 3001000005, 3001000006, 3001000007 };
47     const std::unordered_map<std::string, std::vector<std::string>> g_apiPermissionsMap {
48         {"RequestSecurityModelResult", {REQUEST_PERMISSION, QUERY_SECURITY_MODEL_RESULT_PERMISSION}},
49     };
50 }
51 
RiskAnalysisManagerService(int32_t saId,bool runOnCreate)52 RiskAnalysisManagerService::RiskAnalysisManagerService(int32_t saId, bool runOnCreate)
53     : SystemAbility(saId, runOnCreate)
54 {
55     SGLOGW("%{public}s", __func__);
56 }
57 
OnStart()58 void RiskAnalysisManagerService::OnStart()
59 {
60     SGLOGI("RiskAnalysisManagerService %{public}s", __func__);
61     if (!Publish(this)) {
62         SGLOGE("Publish error");
63     }
64     bool success = ConfigManager::InitConfig<EventConfig>();
65     if (!success) {
66         SGLOGE("init event config error");
67     }
68     success = ConfigManager::InitConfig<ModelConfig>();
69     if (!success) {
70         SGLOGE("init model config error");
71     }
72 
73     TaskHandler::Task task = [] {
74         ModelManager::GetInstance().Init();
75     };
76     TaskHandler::GetInstance()->AddTask(task);
77 
78     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
79 }
80 
OnStop()81 void RiskAnalysisManagerService::OnStop()
82 {
83 }
84 
IsApiHasPermission(const std::string & api)85 int32_t RiskAnalysisManagerService::IsApiHasPermission(const std::string &api)
86 {
87     if (g_apiPermissionsMap.count(api) == 0) {
88         SGLOGE("api not in map");
89         return FAILED;
90     }
91     AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
92     if (std::none_of(g_apiPermissionsMap.at(api).cbegin(), g_apiPermissionsMap.at(api).cend(),
93         [callerToken](const std::string &per) {
94         int code = AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, per);
95         return code == AccessToken::PermissionState::PERMISSION_GRANTED;
96     })) {
97         SGLOGE("caller no permission");
98         return NO_PERMISSION;
99     }
100 
101     AccessToken::ATokenTypeEnum tokenType = AccessToken::AccessTokenKit::GetTokenType(callerToken);
102     if (tokenType != AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
103         uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
104         if (!AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
105             SGLOGE("not system app no permission");
106             return NO_SYSTEMCALL;
107         }
108     }
109     return SUCCESS;
110 }
111 
RequestSecurityModelResult(const std::string & devId,uint32_t modelId,const std::string & param,const sptr<IRemoteObject> & callback)112 int32_t RiskAnalysisManagerService::RequestSecurityModelResult(const std::string &devId, uint32_t modelId,
113     const std::string &param, const sptr<IRemoteObject> &callback)
114 {
115     SGLOGD("%{public}s", __func__);
116     int32_t ret = IsApiHasPermission("RequestSecurityModelResult");
117     if (ret != SUCCESS) {
118         return ret;
119     }
120     ClassifyEvent event;
121     event.pid = IPCSkeleton::GetCallingPid();
122     event.time = SecurityGuardUtils::GetDate();
123     auto promise = std::make_shared<std::promise<std::string>>();
124     auto future = promise->get_future();
125     PushRiskAnalysisTask(modelId, param, promise);
126     std::chrono::milliseconds span(TIMEOUT_REPLY);
127     std::string result{};
128     if (future.wait_for(span) == std::future_status::timeout) {
129         SGLOGE("wait for result timeout");
130         ret = TIME_OUT;
131     } else {
132         result = future.get();
133         ret =  SUCCESS;
134     }
135     SGLOGI("ReportClassifyEvent");
136     event.status = result;
137     BigData::ReportClassifyEvent(event);
138     auto proxy = iface_cast<RiskAnalysisManagerCallbackProxy>(callback);
139     if (proxy == nullptr) {
140         return NULL_OBJECT;
141     }
142     proxy->ResponseSecurityModelResult(devId, modelId, result);
143     SGLOGI("get analysis result=%{public}s", result.c_str());
144     return ret;
145 }
146 
PushRiskAnalysisTask(uint32_t modelId,std::string param,std::shared_ptr<std::promise<std::string>> promise)147 void RiskAnalysisManagerService::PushRiskAnalysisTask(uint32_t modelId, std::string param,
148     std::shared_ptr<std::promise<std::string>> promise)
149 {
150     TaskHandler::Task task = [modelId, param, promise] {
151         SGLOGD("modelId=%{public}u", modelId);
152         if (std::count(MODELIDS.begin(), MODELIDS.end(), modelId) == 0) {
153             SGLOGE("model not support, no need to analyse, modelId=%{public}u", modelId);
154             promise->set_value(UNKNOWN_STATUS);
155             return;
156         }
157         std::string result = ModelManager::GetInstance().GetResult(modelId, param);
158         SGLOGI("result is %{public}s", result.c_str());
159         promise->set_value(result);
160     };
161     TaskHandler::GetInstance()->AddTask(task);
162 }
163 
SetModelState(uint32_t modelId,bool enable)164 int32_t RiskAnalysisManagerService::SetModelState(uint32_t modelId, bool enable)
165 {
166     return SUCCESS;
167 }
168 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)169 void RiskAnalysisManagerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
170 {
171     SGLOGI("OnAddSystemAbility, systemAbilityId=%{public}d", systemAbilityId);
172     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
173         ConfigManager::GetInstance().StartUpdate();
174     }
175 }
176 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)177 void RiskAnalysisManagerService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
178 {
179     SGLOGW("OnRemoveSystemAbility, systemAbilityId=%{public}d", systemAbilityId);
180 }
181 }
182