• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "ipc_common.h"
17 #include "ipc_skeleton.h"
18 #include "accesstoken_kit.h"
19 #include "iam_common_defines.h"
20 #include "iam_logger.h"
21 #include "tokenid_kit.h"
22 #ifdef HAS_OS_ACCOUNT_PART
23 #include "os_account_manager.h"
24 #endif // HAS_OS_ACCOUNT_PART
25 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
26 
27 namespace OHOS {
28 namespace UserIam {
29 namespace UserAuth {
30 namespace PermissionString {
31     const std::string MANAGE_USER_IDM_PERMISSION = "ohos.permission.MANAGE_USER_IDM";
32     const std::string USE_USER_IDM_PERMISSION = "ohos.permission.USE_USER_IDM";
33     const std::string ACCESS_USER_AUTH_INTERNAL_PERMISSION = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
34     const std::string ACCESS_BIOMETRIC_PERMISSION = "ohos.permission.ACCESS_BIOMETRIC";
35     const std::string ACCESS_AUTH_RESPOOL = "ohos.permission.ACCESS_AUTH_RESPOOL";
36     const std::string ENFORCE_USER_IDM = "ohos.permission.ENFORCE_USER_IDM";
37     const std::string SUPPORT_USER_AUTH = "ohos.permission.SUPPORT_USER_AUTH";
38 }
39 
40 namespace {
41     // process white list of allowing to call, <processUid, processName>
42     const std::vector<std::pair<int32_t, std::string>> whiteLists = {
43         {3058, "accountmgr"},
44     };
45 }
46 
GetCallingUserId(IPCObjectStub & stub,int32_t & userId)47 int32_t IpcCommon::GetCallingUserId(IPCObjectStub &stub, int32_t &userId)
48 {
49     if (userId != 0) {
50         return SUCCESS;
51     }
52     uint32_t tokenId = GetAccessTokenId(stub);
53     using namespace Security::AccessToken;
54     ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
55     if (callingType != TOKEN_HAP) {
56         IAM_LOGE("failed to get calling type");
57         return TYPE_NOT_SUPPORT;
58     }
59     HapTokenInfo hapTokenInfo;
60     int result = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
61     if (result != SUCCESS) {
62         IAM_LOGE("failed to get hap token info, result = %{public}d", result);
63         return TYPE_NOT_SUPPORT;
64     }
65     userId = static_cast<int32_t>(hapTokenInfo.userID);
66     IAM_LOGI("get callingUserId is %{public}d", userId);
67     return SUCCESS;
68 }
69 
GetActiveUserId(std::optional<int32_t> & userId)70 int32_t IpcCommon::GetActiveUserId(std::optional<int32_t> &userId)
71 {
72     if (userId.has_value() && userId.value() != 0) {
73         return SUCCESS;
74     }
75     std::vector<int32_t> ids;
76 #ifdef HAS_OS_ACCOUNT_PART
77     ErrCode queryRet = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
78     if (queryRet != ERR_OK || ids.empty()) {
79         IAM_LOGE("failed to query active account id");
80         return GENERAL_ERROR;
81     }
82 #else  // HAS_OS_ACCOUNT_PART
83     const int32_t DEFAULT_OS_ACCOUNT_ID = 0;
84     ids.push_back(DEFAULT_OS_ACCOUNT_ID);
85     IAM_LOGI("there is no os account part, use default id");
86 #endif // HAS_OS_ACCOUNT_PART
87     userId = ids.front();
88     return SUCCESS;
89 }
90 
CheckPermission(IPCObjectStub & stub,Permission permission)91 bool IpcCommon::CheckPermission(IPCObjectStub &stub, Permission permission)
92 {
93     switch (permission) {
94         case MANAGE_USER_IDM_PERMISSION:
95             return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::MANAGE_USER_IDM_PERMISSION) &&
96                 CheckNativeCallingProcessWhiteList(stub);
97         case USE_USER_IDM_PERMISSION:
98             return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::USE_USER_IDM_PERMISSION);
99         case ACCESS_USER_AUTH_INTERNAL_PERMISSION:
100             return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_USER_AUTH_INTERNAL_PERMISSION);
101         case ACCESS_BIOMETRIC_PERMISSION:
102             return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::ACCESS_BIOMETRIC_PERMISSION);
103         case ACCESS_AUTH_RESPOOL:
104             return CheckDirectCaller(stub, PermissionString::ACCESS_AUTH_RESPOOL);
105         case ENFORCE_USER_IDM:
106             return CheckDirectCaller(stub, PermissionString::ENFORCE_USER_IDM) &&
107                 CheckNativeCallingProcessWhiteList(stub);
108         case SUPPORT_USER_AUTH:
109             return CheckDirectCallerAndFirstCallerIfSet(stub, PermissionString::SUPPORT_USER_AUTH);
110         case IS_SYSTEM_APP:
111             return CheckCallerIsSystemApp(stub);
112         default:
113             IAM_LOGE("failed to check permission");
114             return false;
115     }
116 }
117 
GetAccessTokenId(IPCObjectStub & stub)118 uint32_t IpcCommon::GetAccessTokenId(IPCObjectStub &stub)
119 {
120     uint32_t tokenId = stub.GetFirstTokenID();
121     IAM_LOGI("get first caller tokenId: %{public}u", tokenId);
122     if (tokenId == 0) {
123         IAM_LOGI("no first caller, get direct caller tokenId: %{public}u", tokenId);
124         tokenId = stub.GetCallingTokenID();
125     }
126     return tokenId;
127 }
128 
GetTokenId(IPCObjectStub & stub)129 uint32_t IpcCommon::GetTokenId(IPCObjectStub &stub)
130 {
131     uint32_t tokenId = stub.GetCallingTokenID();
132     IAM_LOGI("get tokenId: %{public}u", tokenId);
133     return tokenId;
134 }
135 
CheckNativeCallingProcessWhiteList(IPCObjectStub & stub)136 bool IpcCommon::CheckNativeCallingProcessWhiteList(IPCObjectStub &stub)
137 {
138     uint32_t tokenId = stub.GetCallingTokenID();
139     using namespace Security::AccessToken;
140     ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(tokenId);
141     if (callingType != TOKEN_NATIVE) {
142         IAM_LOGE("failed to get calling type");
143         return false;
144     }
145     NativeTokenInfo nativeTokenInfo;
146     int result = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
147     if (result != SUCCESS) {
148         IAM_LOGE("failed to get native token info, result = %{public}d", result);
149         return false;
150     }
151 
152     std::string processName = nativeTokenInfo.processName;
153     int32_t processUid = stub.GetCallingUid();
154     for (const auto &whiteList : whiteLists) {
155         if (whiteList.first == processUid && whiteList.second == processName) {
156             return true;
157         }
158     }
159     IAM_LOGE("failed to check process white list");
160     return false;
161 }
162 
CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub & stub,const std::string & permission)163 bool IpcCommon::CheckDirectCallerAndFirstCallerIfSet(IPCObjectStub &stub, const std::string &permission)
164 {
165     uint32_t firstTokenId = stub.GetFirstTokenID();
166     uint32_t callingTokenId = stub.GetCallingTokenID();
167     using namespace Security::AccessToken;
168     if ((firstTokenId != 0 && AccessTokenKit::VerifyAccessToken(firstTokenId, permission) != RET_SUCCESS) ||
169         AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
170         IAM_LOGE("failed to check permission");
171         return false;
172     }
173     return true;
174 }
175 
CheckDirectCaller(IPCObjectStub & stub,const std::string & permission)176 bool IpcCommon::CheckDirectCaller(IPCObjectStub &stub, const std::string &permission)
177 {
178     uint32_t callingTokenId = stub.GetCallingTokenID();
179     using namespace Security::AccessToken;
180     if (AccessTokenKit::VerifyAccessToken(callingTokenId, permission) != RET_SUCCESS) {
181         IAM_LOGE("failed to check permission");
182         return false;
183     }
184     return true;
185 }
186 
CheckCallerIsSystemApp(IPCObjectStub & stub)187 bool IpcCommon::CheckCallerIsSystemApp(IPCObjectStub &stub)
188 {
189     uint32_t callingTokenId = stub.GetCallingTokenID();
190     using namespace Security::AccessToken;
191     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
192     bool checkRet = TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
193     ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(callingTokenId);
194     if (checkRet && callingType == TOKEN_HAP) {
195         IAM_LOGI("the caller is system application");
196         return true;
197     }
198     return false;
199 }
200 } // namespace UserAuth
201 } // namespace UserIam
202 } // namespace OHOS