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 <accesstoken_kit.h>
17 #include <app_mgr_client.h>
18 #include <app_mgr_interface.h>
19 #include <bundle_constants.h>
20 #include <ipc_skeleton.h>
21 #include <bundle_mgr_proxy.h>
22 #include <bundle_mgr_interface.h>
23 #include <system_ability_definition.h>
24 #include <iservice_registry.h>
25 #include <tokenid_kit.h>
26 #include <input_method_controller.h>
27 #include <singleton.h>
28 #include <singleton_container.h>
29 #include <pwd.h>
30 #include "common/include/session_permission.h"
31 #include "parameters.h"
32 #include "window_manager_hilog.h"
33 
34 namespace OHOS {
35 namespace Rosen {
36 namespace {
37 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionPermission"};
38 constexpr int32_t FOUNDATION_UID = 5523;
39 
GetBundleManagerProxy()40 sptr<AppExecFwk::IBundleMgr> GetBundleManagerProxy()
41 {
42     sptr<ISystemAbilityManager> systemAbilityManager =
43         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
44     if (!systemAbilityManager) {
45         WLOGFE("Failed to get system ability mgr.");
46         return nullptr;
47     }
48     sptr<IRemoteObject> remoteObject
49         = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
50     if (!remoteObject) {
51         WLOGFE("Failed to get bundle manager service.");
52         return nullptr;
53     }
54     auto bundleManagerServiceProxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
55     if (!bundleManagerServiceProxy || !bundleManagerServiceProxy->AsObject()) {
56         WLOGFE("Failed to get bundle manager proxy.");
57         return nullptr;
58     }
59     return bundleManagerServiceProxy;
60 }
61 }
62 
IsSystemServiceCalling(bool needPrintLog)63 bool SessionPermission::IsSystemServiceCalling(bool needPrintLog)
64 {
65     const auto tokenId = IPCSkeleton::GetCallingTokenID();
66     const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
67     if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
68         flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
69         TLOGD(WmsLogTag::DEFAULT, "system service calling, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
70         return true;
71     }
72     if (needPrintLog) {
73         TLOGE(WmsLogTag::DEFAULT, "Not system service calling, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
74     }
75     return false;
76 }
77 
IsSystemCalling()78 bool SessionPermission::IsSystemCalling()
79 {
80     const auto tokenId = IPCSkeleton::GetCallingTokenID();
81     const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
82     TLOGD(WmsLogTag::DEFAULT, "tokenId:%{private}u, flag:%{public}u", tokenId, flag);
83     if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
84         flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
85         return true;
86     }
87     return IsSystemAppCall();
88 }
89 
IsSystemAppCall()90 bool SessionPermission::IsSystemAppCall()
91 {
92     uint64_t callingTokenId = IPCSkeleton::GetCallingFullTokenID();
93     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callingTokenId);
94 }
95 
IsSACalling()96 bool SessionPermission::IsSACalling()
97 {
98     const auto tokenId = IPCSkeleton::GetCallingTokenID();
99     const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
100     if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
101         TLOGD(WmsLogTag::DEFAULT, "SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
102         return true;
103     }
104     TLOGI(WmsLogTag::DEFAULT, "Not SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
105     return false;
106 }
107 
VerifyCallingPermission(const std::string& permissionName)108 bool SessionPermission::VerifyCallingPermission(const std::string& permissionName)
109 {
110     auto callerToken = IPCSkeleton::GetCallingTokenID();
111     TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u",
112         permissionName.c_str(), callerToken);
113     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
114     if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
115         TLOGE(WmsLogTag::DEFAULT,
116             "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d",
117             permissionName.c_str(), callerToken, ret);
118         return false;
119     }
120     TLOGI(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u",
121         permissionName.c_str(), callerToken);
122     return true;
123 }
124 
VerifyPermissionByCallerToken(const uint32_t callerToken, const std::string& permissionName)125 bool SessionPermission::VerifyPermissionByCallerToken(const uint32_t callerToken, const std::string& permissionName)
126 {
127     TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u",
128         permissionName.c_str(), callerToken);
129     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
130     if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
131         TLOGE(WmsLogTag::DEFAULT,
132             "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d",
133             permissionName.c_str(), callerToken, ret);
134         return false;
135     }
136     TLOGI(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u",
137         permissionName.c_str(), callerToken);
138     return true;
139 }
140 
VerifySessionPermission()141 bool SessionPermission::VerifySessionPermission()
142 {
143     if (IsSACalling()) {
144         WLOGFI("Is SA Call, Permission verified success.");
145         return true;
146     }
147     if (VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
148         WLOGFI("MANAGE permission verified success.");
149         return true;
150     }
151     WLOGFW("Permission verified failed.");
152     return false;
153 }
154 
JudgeCallerIsAllowedToUseSystemAPI()155 bool SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()
156 {
157     if (IsSACalling() || IsShellCall()) {
158         return true;
159     }
160     return IsSystemAppCall();
161 }
162 
IsShellCall()163 bool SessionPermission::IsShellCall()
164 {
165     auto callerToken = IPCSkeleton::GetCallingTokenID();
166     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
167     if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
168         WLOGFI("TokenType is Shell, verify success");
169         return true;
170     }
171     TLOGI(WmsLogTag::DEFAULT, "Not Shell called. tokenId:%{private}u, type:%{public}u", callerToken, tokenType);
172     return false;
173 }
174 
IsStartByHdcd()175 bool SessionPermission::IsStartByHdcd()
176 {
177     OHOS::Security::AccessToken::NativeTokenInfo info;
178     if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(IPCSkeleton::GetCallingTokenID(), info) != 0) {
179         return false;
180     }
181     if (info.processName.compare("hdcd") == 0) {
182         return true;
183     }
184     return false;
185 }
186 
IsStartedByInputMethod()187 bool SessionPermission::IsStartedByInputMethod()
188 {
189     auto imc = MiscServices::InputMethodController::GetInstance();
190     if (!imc) {
191         TLOGE(WmsLogTag::DEFAULT, "InputMethodController is nullptr");
192         return false;
193     }
194     int pid = IPCSkeleton::GetCallingPid();
195     return imc->IsCurrentImeByPid(pid);
196 }
197 
IsSameBundleNameAsCalling(const std::string& bundleName)198 bool SessionPermission::IsSameBundleNameAsCalling(const std::string& bundleName)
199 {
200     if (bundleName == "") {
201         return false;
202     }
203     auto bundleManagerServiceProxy_ = GetBundleManagerProxy();
204     if (!bundleManagerServiceProxy_) {
205         WLOGFE("failed to get BundleManagerServiceProxy");
206         return false;
207     }
208     int uid = IPCSkeleton::GetCallingUid();
209     // reset ipc identity
210     std::string identity = IPCSkeleton::ResetCallingIdentity();
211     std::string callingBundleName;
212     bundleManagerServiceProxy_->GetNameForUid(uid, callingBundleName);
213     IPCSkeleton::SetCallingIdentity(identity);
214     if (callingBundleName == bundleName) {
215         WLOGFD("verify bundle name success");
216         return true;
217     } else {
218         WLOGFE("verify bundle name failed, calling bundle name %{public}s, but window bundle name %{public}s.",
219             callingBundleName.c_str(), bundleName.c_str());
220         return false;
221     }
222 }
223 
IsSameAppAsCalling(const std::string& bundleName, const std::string& appIdentifier)224 bool SessionPermission::IsSameAppAsCalling(const std::string& bundleName, const std::string& appIdentifier)
225 {
226     if (bundleName == "" || appIdentifier == "") {
227         return false;
228     }
229     auto bundleManagerServiceProxy = GetBundleManagerProxy();
230     if (!bundleManagerServiceProxy) {
231         TLOGE(WmsLogTag::DEFAULT, "failed to get BundleManagerServiceProxy");
232         return false;
233     }
234     int uid = IPCSkeleton::GetCallingUid();
235     // reset ipc identity
236     std::string identity = IPCSkeleton::ResetCallingIdentity();
237     std::string callingBundleName;
238     bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName);
239     if (callingBundleName != bundleName) {
240         TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.",
241               callingBundleName.c_str(), bundleName.c_str());
242         IPCSkeleton::SetCallingIdentity(identity);
243         return false;
244     }
245     AppExecFwk::BundleInfo bundleInfo;
246     int userId = uid / 200000; // 200000 use uid to caculate userId
247     bool ret = bundleManagerServiceProxy->GetBundleInfoV9(
248         callingBundleName, static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO),
249         bundleInfo, userId);
250     IPCSkeleton::SetCallingIdentity(identity);
251 
252     if (ret != ERR_OK) {
253         TLOGE(WmsLogTag::DEFAULT, "failed to query app info, callingBundleName:%{public}s, userId:%{public}d",
254               callingBundleName.c_str(), userId);
255         return false;
256     }
257 
258     if (bundleInfo.signatureInfo.appIdentifier == appIdentifier) {
259         TLOGI(WmsLogTag::DEFAULT, "verify app success");
260         return true;
261     }
262 
263     TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.",
264           callingBundleName.c_str(), bundleName.c_str());
265     return false;
266 }
267 
IsStartedByUIExtension()268 bool SessionPermission::IsStartedByUIExtension()
269 {
270     auto bundleManagerServiceProxy = GetBundleManagerProxy();
271     if (!bundleManagerServiceProxy) {
272         WLOGFE("failed to get BundleManagerServiceProxy");
273         return false;
274     }
275 
276     int uid = IPCSkeleton::GetCallingUid();
277     // reset ipc identity
278     std::string identity = IPCSkeleton::ResetCallingIdentity();
279     std::string bundleName;
280     bundleManagerServiceProxy->GetNameForUid(uid, bundleName);
281     AppExecFwk::BundleInfo bundleInfo;
282     int userId = uid / 200000; // 200000 use uid to caculate userId
283     bool result = bundleManagerServiceProxy->GetBundleInfo(bundleName,
284         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
285     // set ipc identity to raw
286     IPCSkeleton::SetCallingIdentity(identity);
287     if (!result) {
288         WLOGFE("failed to query extension ability info, bundleName:%{public}s, userId:%{public}d",
289                bundleName.c_str(), userId);
290         return false;
291     }
292 
293     auto extensionInfo = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(),
294         [](AppExecFwk::ExtensionAbilityInfo extensionInfo) {
295             return (extensionInfo.type == AppExecFwk::ExtensionAbilityType::SYS_COMMON_UI);
296         });
297     return extensionInfo != bundleInfo.extensionInfos.end();
298 }
299 
CheckCallingIsUserTestMode(pid_t pid)300 bool SessionPermission::CheckCallingIsUserTestMode(pid_t pid)
301 {
302     TLOGI(WmsLogTag::DEFAULT, "Calling proxy func");
303     bool isUserTestMode = false;
304     auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
305     if (appMgrClient == nullptr) {
306         TLOGE(WmsLogTag::DEFAULT, "AppMgeClient is null!");
307         return false;
308     }
309     // reset ipc identity
310     std::string identity = IPCSkeleton::ResetCallingIdentity();
311     int32_t ret = appMgrClient->CheckCallingIsUserTestMode(pid, isUserTestMode);
312     // set ipc identity to raw
313     IPCSkeleton::SetCallingIdentity(identity);
314     if (ret != ERR_OK) {
315         TLOGE(WmsLogTag::DEFAULT, "Permission denied! ret=%{public}d", ret);
316         return false;
317     }
318     return isUserTestMode;
319 }
320 
IsBetaVersion()321 bool SessionPermission::IsBetaVersion()
322 {
323     std::string betaName = OHOS::system::GetParameter("const.logsystem.versiontype", "");
324     return betaName.find("beta") != std::string::npos;
325 }
326 
IsFoundationCall()327 bool SessionPermission::IsFoundationCall()
328 {
329     return IPCSkeleton::GetCallingUid() == FOUNDATION_UID;
330 }
331 
GetCallingBundleName()332 std::string SessionPermission::GetCallingBundleName()
333 {
334     auto bundleManagerServiceProxy = GetBundleManagerProxy();
335     if (!bundleManagerServiceProxy) {
336         WLOGFE("failed to get BundleManagerServiceProxy");
337         return "";
338     }
339     int uid = IPCSkeleton::GetCallingUid();
340     // reset ipc identity
341     std::string identity = IPCSkeleton::ResetCallingIdentity();
342     std::string callingBundleName;
343     bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName);
344     // if bundlename is empty, fill in pw_name
345     if (callingBundleName.empty()) {
346         if (struct passwd* user = getpwuid(uid)) {
347             callingBundleName = user->pw_name;
348         }
349     }
350     IPCSkeleton::SetCallingIdentity(identity);
351     return callingBundleName;
352 }
353 } // namespace Rosen
354 } // namespace OHOS