• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "privacy_manager_stub.h"
17 
18 #include "accesstoken_kit.h"
19 #include "accesstoken_log.h"
20 #include "ipc_skeleton.h"
21 #include "memory_guard.h"
22 #include "privacy_error.h"
23 #include "string_ex.h"
24 
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
30     LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacyManagerStub"
31 };
32 static const uint32_t PERM_LIST_SIZE_MAX = 1024;
33 static const int32_t ERROR = -1;
34 static const std::string PERMISSION_USED_STATS = "ohos.permission.PERMISSION_USED_STATS";
35 }
36 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)37 int32_t PrivacyManagerStub::OnRemoteRequest(
38     uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
39 {
40     MemoryGuard cacheGuard;
41     std::u16string descriptor = data.ReadInterfaceToken();
42     if (descriptor != IPrivacyManager::GetDescriptor()) {
43         ACCESSTOKEN_LOG_ERROR(LABEL, "get unexpect descriptor: %{public}s", Str16ToStr8(descriptor).c_str());
44         return ERROR;
45     }
46     switch (code) {
47         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::ADD_PERMISSION_USED_RECORD):
48             AddPermissionUsedRecordInner(data, reply);
49             break;
50         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::START_USING_PERMISSION):
51             StartUsingPermissionInner(data, reply);
52             break;
53         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::START_USING_PERMISSION_CALLBACK):
54             StartUsingPermissionCallbackInner(data, reply);
55             break;
56         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::STOP_USING_PERMISSION):
57             StopUsingPermissionInner(data, reply);
58             break;
59         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::DELETE_PERMISSION_USED_RECORDS):
60             RemovePermissionUsedRecordsInner(data, reply);
61             break;
62         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::GET_PERMISSION_USED_RECORDS):
63             GetPermissionUsedRecordsInner(data, reply);
64             break;
65         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::GET_PERMISSION_USED_RECORDS_ASYNC):
66             GetPermissionUsedRecordsAsyncInner(data, reply);
67             break;
68         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::REGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK):
69             RegisterPermActiveStatusCallbackInner(data, reply);
70             break;
71         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::UNREGISTER_PERM_ACTIVE_STATUS_CHANGE_CALLBACK):
72             UnRegisterPermActiveStatusCallbackInner(data, reply);
73             break;
74         case static_cast<uint32_t>(IPrivacyManager::InterfaceCode::IS_ALLOWED_USING_PERMISSION):
75             IsAllowedUsingPermissionInner(data, reply);
76             break;
77         default:
78             return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
79     }
80     return NO_ERROR;
81 }
82 
AddPermissionUsedRecordInner(MessageParcel & data,MessageParcel & reply)83 void PrivacyManagerStub::AddPermissionUsedRecordInner(MessageParcel& data, MessageParcel& reply)
84 {
85     if (!VerifyPermission(PERMISSION_USED_STATS)) {
86         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
87         return;
88     }
89     AccessTokenID tokenId = data.ReadUint32();
90     std::string permissionName = data.ReadString();
91     int32_t successCount = data.ReadInt32();
92     int32_t failCount = data.ReadInt32();
93     int32_t result = this->AddPermissionUsedRecord(tokenId, permissionName, successCount, failCount);
94     reply.WriteInt32(result);
95 }
96 
StartUsingPermissionInner(MessageParcel & data,MessageParcel & reply)97 void PrivacyManagerStub::StartUsingPermissionInner(MessageParcel& data, MessageParcel& reply)
98 {
99     if (!VerifyPermission(PERMISSION_USED_STATS)) {
100         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
101         return;
102     }
103     AccessTokenID tokenId = data.ReadUint32();
104     std::string permissionName = data.ReadString();
105     int32_t result = this->StartUsingPermission(tokenId, permissionName);
106     reply.WriteInt32(result);
107 }
108 
StartUsingPermissionCallbackInner(MessageParcel & data,MessageParcel & reply)109 void PrivacyManagerStub::StartUsingPermissionCallbackInner(MessageParcel& data, MessageParcel& reply)
110 {
111     if (!VerifyPermission(PERMISSION_USED_STATS)) {
112         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
113         return;
114     }
115     AccessTokenID tokenId = data.ReadUint32();
116     std::string permissionName = data.ReadString();
117     sptr<IRemoteObject> callback = data.ReadRemoteObject();
118     if (callback == nullptr) {
119         ACCESSTOKEN_LOG_ERROR(LABEL, "read ReadRemoteObject fail");
120         reply.WriteInt32(PrivacyError::ERR_READ_PARCEL_FAILED);
121         return;
122     }
123     int32_t result = this->StartUsingPermission(tokenId, permissionName, callback);
124     reply.WriteInt32(result);
125 }
126 
StopUsingPermissionInner(MessageParcel & data,MessageParcel & reply)127 void PrivacyManagerStub::StopUsingPermissionInner(MessageParcel& data, MessageParcel& reply)
128 {
129     if (!VerifyPermission(PERMISSION_USED_STATS)) {
130         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
131         return;
132     }
133     AccessTokenID tokenId = data.ReadUint32();
134     std::string permissionName = data.ReadString();
135     int32_t result = this->StopUsingPermission(tokenId, permissionName);
136     reply.WriteInt32(result);
137 }
138 
RemovePermissionUsedRecordsInner(MessageParcel & data,MessageParcel & reply)139 void PrivacyManagerStub::RemovePermissionUsedRecordsInner(MessageParcel& data, MessageParcel& reply)
140 {
141     if (!IsAccessTokenCalling() && !VerifyPermission(PERMISSION_USED_STATS)) {
142         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
143         return;
144     }
145 
146     AccessTokenID tokenId = data.ReadUint32();
147     std::string deviceID = data.ReadString();
148     int32_t result = this->RemovePermissionUsedRecords(tokenId, deviceID);
149     reply.WriteInt32(result);
150 }
151 
GetPermissionUsedRecordsInner(MessageParcel & data,MessageParcel & reply)152 void PrivacyManagerStub::GetPermissionUsedRecordsInner(MessageParcel& data, MessageParcel& reply)
153 {
154     PermissionUsedResultParcel responseParcel;
155     if (!VerifyPermission(PERMISSION_USED_STATS)) {
156         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
157         return;
158     }
159     sptr<PermissionUsedRequestParcel> requestParcel = data.ReadParcelable<PermissionUsedRequestParcel>();
160     if (requestParcel == nullptr) {
161         ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable faild");
162         reply.WriteInt32(PrivacyError::ERR_READ_PARCEL_FAILED);
163         return;
164     }
165     int32_t result = this->GetPermissionUsedRecords(*requestParcel, responseParcel);
166     reply.WriteInt32(result);
167     reply.WriteParcelable(&responseParcel);
168 }
169 
GetPermissionUsedRecordsAsyncInner(MessageParcel & data,MessageParcel & reply)170 void PrivacyManagerStub::GetPermissionUsedRecordsAsyncInner(MessageParcel& data, MessageParcel& reply)
171 {
172     if (!VerifyPermission(PERMISSION_USED_STATS)) {
173         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
174         return;
175     }
176     sptr<PermissionUsedRequestParcel> requestParcel = data.ReadParcelable<PermissionUsedRequestParcel>();
177     if (requestParcel == nullptr) {
178         ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable faild");
179         reply.WriteInt32(PrivacyError::ERR_READ_PARCEL_FAILED);
180         return;
181     }
182     sptr<OnPermissionUsedRecordCallback> callback = iface_cast<OnPermissionUsedRecordCallback>(data.ReadRemoteObject());
183     int32_t result = this->GetPermissionUsedRecords(*requestParcel, callback);
184     reply.WriteInt32(result);
185 }
186 
RegisterPermActiveStatusCallbackInner(MessageParcel & data,MessageParcel & reply)187 void PrivacyManagerStub::RegisterPermActiveStatusCallbackInner(MessageParcel& data, MessageParcel& reply)
188 {
189     if (!VerifyPermission(PERMISSION_USED_STATS)) {
190         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
191         return;
192     }
193     uint32_t permListSize = data.ReadUint32();
194     if (permListSize > PERM_LIST_SIZE_MAX) {
195         ACCESSTOKEN_LOG_ERROR(LABEL, "read permListSize fail");
196         reply.WriteInt32(PrivacyError::ERR_OVERSIZE);
197         return;
198     }
199     std::vector<std::string> permList;
200     for (uint32_t i = 0; i < permListSize; i++) {
201         std::string perm = data.ReadString();
202         permList.emplace_back(perm);
203     }
204     sptr<IRemoteObject> callback = data.ReadRemoteObject();
205     if (callback == nullptr) {
206         ACCESSTOKEN_LOG_ERROR(LABEL, "read ReadRemoteObject fail");
207         reply.WriteInt32(PrivacyError::ERR_READ_PARCEL_FAILED);
208         return;
209     }
210     int32_t result = this->RegisterPermActiveStatusCallback(permList, callback);
211     reply.WriteInt32(result);
212 }
213 
UnRegisterPermActiveStatusCallbackInner(MessageParcel & data,MessageParcel & reply)214 void PrivacyManagerStub::UnRegisterPermActiveStatusCallbackInner(MessageParcel& data, MessageParcel& reply)
215 {
216     if (!VerifyPermission(PERMISSION_USED_STATS)) {
217         reply.WriteInt32(PrivacyError::ERR_PERMISSION_DENIED);
218         return;
219     }
220     sptr<IRemoteObject> callback = data.ReadRemoteObject();
221     if (callback == nullptr) {
222         ACCESSTOKEN_LOG_ERROR(LABEL, "read scopeParcel fail");
223         reply.WriteInt32(PrivacyError::ERR_READ_PARCEL_FAILED);
224         return;
225     }
226 
227     int32_t result = this->UnRegisterPermActiveStatusCallback(callback);
228     reply.WriteInt32(result);
229 }
230 
IsAllowedUsingPermissionInner(MessageParcel & data,MessageParcel & reply)231 void PrivacyManagerStub::IsAllowedUsingPermissionInner(MessageParcel& data, MessageParcel& reply)
232 {
233     if (!VerifyPermission(PERMISSION_USED_STATS)) {
234         reply.WriteBool(false);
235         return;
236     }
237     AccessTokenID tokenId = data.ReadUint32();
238 
239     std::string permissionName = data.ReadString();
240     bool result = this->IsAllowedUsingPermission(tokenId, permissionName);
241     if (!reply.WriteBool(result)) {
242         ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteBool(%{public}s)", permissionName.c_str());
243         return;
244     }
245 }
246 
IsAccessTokenCalling() const247 bool PrivacyManagerStub::IsAccessTokenCalling() const
248 {
249     int32_t callingUid = IPCSkeleton::GetCallingUid();
250     return callingUid == ACCESSTOKEN_UID;
251 }
252 
VerifyPermission(const std::string & permission) const253 bool PrivacyManagerStub::VerifyPermission(const std::string& permission) const
254 {
255     uint32_t callingTokenID = IPCSkeleton::GetCallingTokenID();
256     if (AccessTokenKit::VerifyAccessToken(callingTokenID, permission) == PERMISSION_DENIED) {
257         ACCESSTOKEN_LOG_ERROR(LABEL, "permission denied(callingTokenID=%{public}d)", callingTokenID);
258         return false;
259     }
260     return true;
261 }
262 } // namespace AccessToken
263 } // namespace Security
264 } // namespace OHOS
265