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 "ipc_security/rs_ipc_interface_code_access_verifier_base.h"
17
18 namespace OHOS {
19 namespace Rosen {
20
21 const std::unordered_map<PermissionType, std::string> PERMISSION_MAP {
22 { PermissionType::CAPTURE_SCREEN, "ohos.permission.CAPTURE_SCREEN" },
23 { PermissionType::UPDATE_CONFIGURATION, "ohos.permission.UPDATE_CONFIGURATION" },
24 { PermissionType::GET_RUNNING_INFO, "ohos.permission.GET_RUNNING_INFO" },
25 };
26
IsInterfaceCodeAccessible(CodeUnderlyingType code)27 bool RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible(CodeUnderlyingType code)
28 {
29 #ifdef ENABLE_IPC_SECURITY
30 if (!IsCommonVerificationPassed(code)) {
31 RS_LOGE("RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible common verification not passed.");
32 return false;
33 }
34 if (!IsExclusiveVerificationPassed(code)) {
35 RS_LOGE("RSInterfaceCodeAccessVerifierBase::IsInterfaceCodeAccessible exclusive verification not passed.");
36 return false;
37 }
38 #endif
39 return true;
40 }
41 #ifdef ENABLE_IPC_SECURITY
GetTokenType()42 Security::AccessToken::ATokenTypeEnum RSInterfaceCodeAccessVerifierBase::GetTokenType()
43 {
44 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
45 return Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
46 }
47
GetTokenID() const48 Security::AccessToken::AccessTokenID RSInterfaceCodeAccessVerifierBase::GetTokenID() const
49 {
50 return IPCSkeleton::GetCallingTokenID();
51 }
52
CheckNativePermission(const Security::AccessToken::AccessTokenID tokenID,const std::string & permission) const53 bool RSInterfaceCodeAccessVerifierBase::CheckNativePermission(
54 const Security::AccessToken::AccessTokenID tokenID, const std::string& permission) const
55 {
56 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission, false);
57 if (result != Security::AccessToken::PERMISSION_GRANTED) {
58 return false;
59 }
60 return true;
61 }
62
CheckHapPermission(const Security::AccessToken::AccessTokenID tokenID,const std::string & permission) const63 bool RSInterfaceCodeAccessVerifierBase::CheckHapPermission(
64 const Security::AccessToken::AccessTokenID tokenID, const std::string& permission) const
65 {
66 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenID, permission, false);
67 if (result != Security::AccessToken::PERMISSION_GRANTED) {
68 return false;
69 }
70 return true;
71 }
72
CheckPermission(CodeUnderlyingType code) const73 bool RSInterfaceCodeAccessVerifierBase::CheckPermission(CodeUnderlyingType code) const
74 {
75 std::vector<std::string> permissions = GetPermissions(code);
76 bool hasPermission = true;
77 auto tokenType = GetTokenType();
78 auto tokenID = GetTokenID();
79 for (auto& permission : permissions) {
80 switch (tokenType) {
81 case Security::AccessToken::ATokenTypeEnum::TOKEN_HAP:
82 hasPermission = CheckHapPermission(tokenID, permission);
83 break;
84 case Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE:
85 hasPermission = CheckNativePermission(tokenID, permission);
86 break;
87 case Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL:
88 hasPermission = CheckNativePermission(tokenID, permission);
89 break;
90 default:
91 break;
92 }
93 if (!hasPermission) {
94 RS_LOGD("%{public}d ipc interface code access denied: HAS NO PERMISSION", code);
95 return false; // will return hasPermission after defining Permissions for APIs
96 }
97 }
98 return hasPermission;
99 }
100
PermissionEnumToString(PermissionType permission) const101 std::string RSInterfaceCodeAccessVerifierBase::PermissionEnumToString(PermissionType permission) const
102 {
103 if (PERMISSION_MAP.count(permission) > 0) {
104 return PERMISSION_MAP.at(permission);
105 } else {
106 return "unknown";
107 }
108 }
109
AddPermission(CodeUnderlyingType interfaceName,const std::string & newPermission)110 bool RSInterfaceCodeAccessVerifierBase::AddPermission(
111 CodeUnderlyingType interfaceName, const std::string& newPermission)
112 {
113 if (interfacePermissions_.count(interfaceName) > 0) {
114 auto& permissions = interfacePermissions_[interfaceName];
115 auto iter = std::find_if(permissions.cbegin(), permissions.cend(),
116 [newPermission](const auto& permission) { return newPermission == permission; });
117 if (iter == permissions.cend()) {
118 permissions.push_back(newPermission);
119 return true;
120 } else {
121 return false;
122 }
123 } else {
124 interfacePermissions_[interfaceName].push_back(newPermission);
125 }
126 return true;
127 }
128
GetPermissions(CodeUnderlyingType interfaceName) const129 std::vector<std::string> RSInterfaceCodeAccessVerifierBase::GetPermissions(CodeUnderlyingType interfaceName) const
130 {
131 if (interfacePermissions_.count(interfaceName) == 0) {
132 return {};
133 } else {
134 return interfacePermissions_.at(interfaceName);
135 }
136 }
137
GetInterfacePermissionSize() const138 int RSInterfaceCodeAccessVerifierBase::GetInterfacePermissionSize() const
139 {
140 uint32_t countSz = 0;
141 for (auto& [permissionKey, permissionVal] : interfacePermissions_) {
142 countSz += permissionVal.size();
143 }
144 return countSz;
145 }
146
IsSystemApp()147 bool RSInterfaceCodeAccessVerifierBase::IsSystemApp()
148 {
149 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
150 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
151 }
152
IsSystemCalling(const std::string & callingCode)153 bool RSInterfaceCodeAccessVerifierBase::IsSystemCalling(const std::string& callingCode)
154 {
155 bool isSystemCalling = false;
156 auto tokenType = GetTokenType();
157 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
158 isSystemCalling = IsSystemApp();
159 } else if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
160 isSystemCalling = true;
161 } else if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
162 isSystemCalling = true;
163 }
164 if (!isSystemCalling) {
165 RS_LOGE("%{public}s ipc interface code access denied: not system calling", callingCode.c_str());
166 }
167 return isSystemCalling;
168 }
169
IsAncoCalling(const std::string & callingCode) const170 bool RSInterfaceCodeAccessVerifierBase::IsAncoCalling(const std::string& callingCode) const
171 {
172 static constexpr uint32_t ANCO_UID = 5557;
173 bool isAncoCalling = (OHOS::IPCSkeleton::GetCallingUid() == ANCO_UID);
174 if (!isAncoCalling) {
175 RS_LOGE("%{public}s ipc interface code access denied: not anco calling", callingCode.c_str());
176 }
177 return isAncoCalling;
178 }
179
IsFoundationCalling(const std::string & callingCode) const180 bool RSInterfaceCodeAccessVerifierBase::IsFoundationCalling(const std::string& callingCode) const
181 {
182 static constexpr uint32_t FOUNDATION_UID = 5523;
183 bool isFoundationCalling = (OHOS::IPCSkeleton::GetCallingUid() == FOUNDATION_UID);
184 if (!isFoundationCalling) {
185 RS_LOGE("%{public}s ipc interface code access denied: not foundation calling", callingCode.c_str());
186 }
187 return isFoundationCalling;
188 }
189
GetAccessType(bool & isTokenTypeValid,bool & isNonSystemAppCalling)190 void RSInterfaceCodeAccessVerifierBase::GetAccessType(bool& isTokenTypeValid, bool& isNonSystemAppCalling)
191 {
192 switch (GetTokenType()) {
193 case (Security::AccessToken::ATokenTypeEnum::TOKEN_HAP): {
194 isTokenTypeValid = true;
195 isNonSystemAppCalling = !IsSystemApp();
196 break;
197 }
198 case (Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE): {
199 isTokenTypeValid = true;
200 isNonSystemAppCalling = false;
201 break;
202 }
203 case (Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL): {
204 isTokenTypeValid = true;
205 isNonSystemAppCalling = false;
206 break;
207 }
208 default: { // TOKEN_INVALID and TOKEN_TYPE_BUTT
209 isTokenTypeValid = false;
210 isNonSystemAppCalling = false;
211 break;
212 }
213 }
214 }
215
IsStylusServiceCalling(const std::string & callingCode) const216 bool RSInterfaceCodeAccessVerifierBase::IsStylusServiceCalling(const std::string& callingCode) const
217 {
218 // Stylus service calls only
219 static constexpr uint32_t STYLUS_SERVICE_UID = 7555;
220 static const std::string STYLUS_SERVICE_PROCESS_NAME = "stylus_service";
221 Security::AccessToken::NativeTokenInfo tokenInfo;
222 int32_t ret = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(GetTokenID(), tokenInfo);
223 if (ret == ERR_OK) {
224 bool isStylusServiceProcessName = (tokenInfo.processName == STYLUS_SERVICE_PROCESS_NAME);
225 bool isNativeCalling = (GetTokenType() == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE);
226 bool isStylusServiceUid = (OHOS::IPCSkeleton::GetCallingUid() == STYLUS_SERVICE_UID);
227 bool isStylusServiceCalling = isNativeCalling && isStylusServiceUid && isStylusServiceProcessName;
228 if (!isStylusServiceCalling) {
229 RS_LOGE("%{public}s ipc interface code access denied: not stylus service calling", callingCode.c_str());
230 }
231 return isStylusServiceCalling;
232 }
233 RS_LOGE("%{public}s ipc interface code access denied: GetNativeTokenInfo error", callingCode.c_str());
234 return false;
235 }
236 #else
IsSystemCalling(const std::string &)237 bool RSInterfaceCodeAccessVerifierBase::IsSystemCalling(const std::string& /* callingCode */)
238 {
239 return true;
240 }
241
CheckPermission(CodeUnderlyingType code) const242 bool RSInterfaceCodeAccessVerifierBase::CheckPermission(CodeUnderlyingType code) const
243 {
244 return true;
245 }
246
IsAncoCalling(const std::string & callingCode) const247 bool RSInterfaceCodeAccessVerifierBase::IsAncoCalling(const std::string& callingCode) const
248 {
249 return true;
250 }
251
GetAccessType(bool & isTokenTypeValid,bool & isNonSystemAppCalling)252 void RSInterfaceCodeAccessVerifierBase::GetAccessType(bool& isTokenTypeValid, bool& isNonSystemAppCalling)
253 {
254 isTokenTypeValid = true;
255 isNonSystemAppCalling = false;
256 }
257
IsStylusServiceCalling(const std::string & callingCode) const258 bool RSInterfaceCodeAccessVerifierBase::IsStylusServiceCalling(const std::string& callingCode) const
259 {
260 return true;
261 }
262 #endif
263
IsCommonVerificationPassed(CodeUnderlyingType)264 bool RSInterfaceCodeAccessVerifierBase::IsCommonVerificationPassed(CodeUnderlyingType /* code */)
265 {
266 // Since no common verification rule is temporarily required, directly return true.
267 // If any common rule is required in the future, overwrite this function.
268 return true;
269 }
270
IsAccessTimesVerificationPassed(CodeUnderlyingType code,uint32_t times) const271 bool RSInterfaceCodeAccessVerifierBase::IsAccessTimesVerificationPassed(CodeUnderlyingType code, uint32_t times) const
272 {
273 return true;
274 }
275
276 } // namespace Rosen
277 } // namespace OHOS
278