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