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
17 #include <accesstoken_kit.h>
18 #include <bundle_constants.h>
19 #include <ipc_skeleton.h>
20 #include <bundle_mgr_proxy.h>
21 #include <bundle_mgr_interface.h>
22 #include <system_ability_definition.h>
23 #include <iservice_registry.h>
24 #include <tokenid_kit.h>
25 #include <input_method_controller.h>
26 #include "common/include/session_permission.h"
27 #include "window_manager_hilog.h"
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionPermission"};
33
GetBundleManagerProxy()34 sptr<AppExecFwk::IBundleMgr> GetBundleManagerProxy()
35 {
36 sptr<ISystemAbilityManager> systemAbilityManager =
37 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
38 if (!systemAbilityManager) {
39 WLOGFE("Failed to get system ability mgr.");
40 return nullptr;
41 }
42 sptr<IRemoteObject> remoteObject
43 = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
44 if (!remoteObject) {
45 WLOGFE("Failed to get bundle manager service.");
46 return nullptr;
47 }
48 auto bundleManagerServiceProxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
49 if (!bundleManagerServiceProxy || !bundleManagerServiceProxy->AsObject()) {
50 WLOGFE("Failed to get bundle manager proxy.");
51 return nullptr;
52 }
53 return bundleManagerServiceProxy;
54 }
55
GetInputMethodBundleName(std::string & name)56 bool GetInputMethodBundleName(std::string &name)
57 {
58 auto imc = MiscServices::InputMethodController::GetInstance();
59 if (!imc) {
60 WLOGFE("InputMethodController is nullptr");
61 return false;
62 }
63 auto imProp = imc->GetCurrentInputMethod();
64 if (!imProp) {
65 WLOGFE("CurrentInputMethod is nullptr");
66 return false;
67 }
68 name = imProp->name;
69 return true;
70 }
71 }
72
IsSystemServiceCalling(bool needPrintLog)73 bool SessionPermission::IsSystemServiceCalling(bool needPrintLog)
74 {
75 const auto tokenId = IPCSkeleton::GetCallingTokenID();
76 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
77 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
78 flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
79 WLOGFD("system service calling, tokenId: %{public}u, flag: %{public}u", tokenId, flag);
80 return true;
81 }
82 if (needPrintLog) {
83 WLOGFE("not system service calling, tokenId: %{public}u, flag: %{public}u", tokenId, flag);
84 }
85 return false;
86 }
87
IsSystemCalling()88 bool SessionPermission::IsSystemCalling()
89 {
90 const auto& tokenId = IPCSkeleton::GetCallingTokenID();
91 const auto& flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
92 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
93 flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
94 WLOGFD("tokenId: %{public}u, flag: %{public}u", tokenId, flag);
95 return true;
96 }
97 WLOGFD("tokenId: %{public}u, flag: %{public}u", tokenId, flag);
98 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
99 bool isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
100 return isSystemApp;
101 }
102
IsSACalling()103 bool SessionPermission::IsSACalling()
104 {
105 const auto& tokenId = IPCSkeleton::GetCallingTokenID();
106 const auto& flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
107 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
108 WLOGFW("SA Called, tokenId: %{public}u, flag: %{public}u", tokenId, flag);
109 return true;
110 }
111 WLOGFD("Not SA called");
112 return false;
113 }
114
VerifyCallingPermission(const std::string & permissionName)115 bool SessionPermission::VerifyCallingPermission(const std::string& permissionName)
116 {
117 WLOGFI("VerifyCallingPermission permission %{public}s", permissionName.c_str());
118 auto callerToken = IPCSkeleton::GetCallingTokenID();
119 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
120 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
121 WLOGFE("permission %{public}s: PERMISSION_DENIED", permissionName.c_str());
122 return false;
123 }
124 WLOGFI("verify AccessToken success");
125 return true;
126 }
127
VerifySessionPermission()128 bool SessionPermission::VerifySessionPermission()
129 {
130 if (IsSACalling()) {
131 WLOGFI("this is SA Calling, Permission verification succeeded.");
132 return true;
133 }
134 if (VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
135 WLOGFI("Permission verification succeeded.");
136 return true;
137 }
138 WLOGFE("Permission verification failed");
139 return false;
140 }
141
JudgeCallerIsAllowedToUseSystemAPI()142 bool SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()
143 {
144 if (IsSACalling() || IsShellCall()) {
145 return true;
146 }
147 auto callerToken = IPCSkeleton::GetCallingFullTokenID();
148 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callerToken);
149 }
150
IsShellCall()151 bool SessionPermission::IsShellCall()
152 {
153 auto callerToken = IPCSkeleton::GetCallingTokenID();
154 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
155 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
156 WLOGFI("caller tokenType is shell, verify success");
157 return true;
158 }
159 WLOGFI("Not shell called.");
160 return false;
161 }
162
IsStartByHdcd()163 bool SessionPermission::IsStartByHdcd()
164 {
165 OHOS::Security::AccessToken::NativeTokenInfo info;
166 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(IPCSkeleton::GetCallingTokenID(), info) != 0) {
167 return false;
168 }
169 if (info.processName.compare("hdcd") == 0) {
170 return true;
171 }
172 return false;
173 }
174
IsStartedByInputMethod()175 bool SessionPermission::IsStartedByInputMethod()
176 {
177 auto bundleManagerServiceProxy_ = GetBundleManagerProxy();
178 if (!bundleManagerServiceProxy_) {
179 WLOGFE("failed to get BundleManagerServiceProxy");
180 return false;
181 }
182 std::string inputMethodBundleName;
183 if (!GetInputMethodBundleName(inputMethodBundleName)) {
184 WLOGFE("failed to get input method bundle name");
185 return false;
186 }
187
188 int uid = IPCSkeleton::GetCallingUid();
189 // reset ipc identity
190 std::string identity = IPCSkeleton::ResetCallingIdentity();
191 std::string bundleName;
192 bundleManagerServiceProxy_->GetNameForUid(uid, bundleName);
193 AppExecFwk::BundleInfo bundleInfo;
194 // 200000 use uid to caculate userId
195 int userId = uid / 200000;
196 bool result = bundleManagerServiceProxy_->GetBundleInfo(bundleName,
197 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
198 // set ipc identity to raw
199 IPCSkeleton::SetCallingIdentity(identity);
200 if (!result) {
201 WLOGFE("failed to query extension ability info, bundleName:%{public}s, userId:%{public}d",
202 bundleName.c_str(), userId);
203 return false;
204 }
205
206 auto extensionInfo = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(),
207 [](AppExecFwk::ExtensionAbilityInfo extensionInfo) {
208 return (extensionInfo.type == AppExecFwk::ExtensionAbilityType::INPUTMETHOD);
209 });
210 return extensionInfo != bundleInfo.extensionInfos.end() && extensionInfo->bundleName == inputMethodBundleName;
211 }
212
IsSameBundleNameAsCalling(const std::string & bundleName)213 bool SessionPermission::IsSameBundleNameAsCalling(const std::string& bundleName)
214 {
215 if (bundleName == "") {
216 return false;
217 }
218 auto bundleManagerServiceProxy_ = GetBundleManagerProxy();
219 if (!bundleManagerServiceProxy_) {
220 WLOGFE("failed to get BundleManagerServiceProxy");
221 return false;
222 }
223 int uid = IPCSkeleton::GetCallingUid();
224 // reset ipc identity
225 std::string identity = IPCSkeleton::ResetCallingIdentity();
226 std::string callingBundleName;
227 bundleManagerServiceProxy_->GetNameForUid(uid, callingBundleName);
228 if (callingBundleName == bundleName) {
229 WLOGFI("verify bundle name success");
230 return true;
231 } else {
232 WLOGFE("verify bundle name failed, calling bundle name is %{public}s, but window bundle name is %{public}s",
233 callingBundleName.c_str(), bundleName.c_str());
234 return false;
235 }
236 }
237 } // namespace Rosen
238 } // namespace OHOS