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