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