* Copyright (C) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "permission_manager.h"
#include "accesstoken_kit.h"
#include "iservice_registry.h"
#include "os_account_manager.h"
#include "tokenid_kit.h"
#include "location_log.h"
#include "constant_definition.h"
namespace OHOS {
namespace Location {
bool PermissionManager::CheckLocationPermission(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(ACCESS_LOCATION, tokenId, firstTokenId);
}
bool PermissionManager::CheckPermission(const std::string &permission, uint32_t callerToken, uint32_t tokenFirstCaller)
{
auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
int result = Security::AccessToken::PERMISSION_DENIED;
if (tokenFirstCaller == 0) {
if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_INVALID) {
LBSLOGD(LOCATOR, "id = %{public}d has no permission.permission name=%{public}s",
callerToken, permission.c_str());
return false;
} else {
result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permission);
}
} else {
result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, tokenFirstCaller, permission);
}
if (result == Security::AccessToken::PERMISSION_GRANTED) {
return true;
} else {
LBSLOGD(LOCATOR, "id = %{public}d has no permission.permission name=%{public}s",
callerToken, permission.c_str());
return false;
}
}
bool PermissionManager::CheckRssProcessName(uint32_t tokenId)
{
Security::AccessToken::NativeTokenInfo callingTokenInfo;
Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, callingTokenInfo);
if (callingTokenInfo.processName != RSS_PROCESS_NAME) {
LBSLOGE(LOCATOR, "CheckProcess failed, processName=%{public}s", callingTokenInfo.processName.c_str());
return false;
}
return true;
}
bool PermissionManager::CheckBackgroundPermission(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(ACCESS_BACKGROUND_LOCATION, tokenId, firstTokenId);
}
bool PermissionManager::CheckMockLocationPermission(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(ACCESS_MOCK_LOCATION, tokenId, firstTokenId);
}
bool PermissionManager::CheckApproximatelyPermission(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(ACCESS_APPROXIMATELY_LOCATION, tokenId, firstTokenId);
}
bool PermissionManager::CheckSecureSettings(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(MANAGE_SECURE_SETTINGS, tokenId, firstTokenId);
}
bool PermissionManager::CheckCallingPermission(pid_t callingUid, pid_t callingPid, MessageParcel &reply)
{
if (callingUid != static_cast<pid_t>(getuid()) || callingPid != getpid()) {
LBSLOGE(LOCATOR, "uid pid not match locationhub process.");
reply.WriteInt32(LOCATION_ERRCODE_PERMISSION_DENIED);
return false;
}
return true;
}
int PermissionManager::GetPermissionLevel(uint32_t tokenId, uint32_t firstTokenId)
{
int ret = PERMISSION_INVALID;
if (CheckPermission(ACCESS_APPROXIMATELY_LOCATION, tokenId, firstTokenId) &&
CheckPermission(ACCESS_LOCATION, tokenId, firstTokenId)) {
ret = PERMISSION_ACCURATE;
} else if (CheckPermission(ACCESS_APPROXIMATELY_LOCATION, tokenId, firstTokenId) &&
!CheckPermission(ACCESS_LOCATION, tokenId, firstTokenId)) {
ret = PERMISSION_APPROXIMATELY;
} else if (!CheckPermission(ACCESS_APPROXIMATELY_LOCATION, tokenId, firstTokenId) &&
CheckPermission(ACCESS_LOCATION, tokenId, firstTokenId)) {
ret = PERMISSION_ACCURATE;
} else {
ret = PERMISSION_INVALID;
}
return ret;
}
bool PermissionManager::CheckSystemPermission(uint32_t callerTokenId, uint64_t callerTokenIdEx)
{
auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerTokenId);
if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
Security::AccessToken::AccessTokenKit::IsCliToolToken(callerTokenId)) {
return true;
}
if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL ||
tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_INVALID) {
return false;
}
bool isSysApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callerTokenIdEx);
return isSysApp;
}
bool PermissionManager::CheckIsSystemSa(uint32_t tokenId)
{
auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
return true;
}
return false;
}
bool PermissionManager::CheckLocationSwitchIgnoredPermission(uint32_t tokenId, uint32_t firstTokenId)
{
return CheckPermission(ACCESS_LOCATION_SWITCH_IGNORED, tokenId, firstTokenId);
}
}
}