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 "domain_account_stub.h"
17
18 #include <securec.h>
19 #include "account_log_wrapper.h"
20 #include "account_permission_manager.h"
21 #include "domain_account_callback_proxy.h"
22 #include "domain_auth_callback_proxy.h"
23 #include "ipc_skeleton.h"
24 #include "memory_guard.h"
25
26 namespace OHOS {
27 namespace AccountSA {
28 namespace {
29 const std::string MANAGE_LOCAL_ACCOUNTS = "ohos.permission.MANAGE_LOCAL_ACCOUNTS";
30 const std::string GET_LOCAL_ACCOUNTS = "ohos.permission.GET_LOCAL_ACCOUNTS";
31 const std::string ACCESS_USER_AUTH_INTERNAL = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
32 const std::string GET_DOMAIN_ACCOUNTS = "ohos.permission.GET_DOMAIN_ACCOUNTS";
33 }
34
35 const std::map<DomainAccountInterfaceCode, DomainAccountStub::DomainAccountStubFunc> stubFuncMap = {
36 {
37 DomainAccountInterfaceCode::REGISTER_PLUGIN,
38 &DomainAccountStub::ProcRegisterPlugin
39 },
40 {
41 DomainAccountInterfaceCode::UNREGISTER_PLUGIN,
42 &DomainAccountStub::ProcUnregisterPlugin
43 },
44 {
45 DomainAccountInterfaceCode::DOMAIN_AUTH,
46 &DomainAccountStub::ProcAuth
47 },
48 {
49 DomainAccountInterfaceCode::DOMAIN_AUTH_USER,
50 &DomainAccountStub::ProcAuthUser
51 },
52 {
53 DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_ENQUIRY,
54 &DomainAccountStub::ProcGetAccountStatus
55 },
56 {
57 DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER,
58 &DomainAccountStub::ProcRegisterAccountStatusListener
59 },
60 {
61 DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER,
62 &DomainAccountStub::ProcUnregisterAccountStatusListener
63 },
64 {
65 DomainAccountInterfaceCode::DOMAIN_AUTH_WITH_POPUP,
66 &DomainAccountStub::ProcAuthWithPopup
67 },
68 {
69 DomainAccountInterfaceCode::DOMAIN_HAS_DOMAIN_ACCOUNT,
70 &DomainAccountStub::ProcHasDomainAccount
71 },
72 {
73 DomainAccountInterfaceCode::DOMAIN_UPDATE_ACCOUNT_TOKEN,
74 &DomainAccountStub::ProcUpdateAccountToken
75 },
76 {
77 DomainAccountInterfaceCode::DOMAIN_GET_ACCESS_TOKEN,
78 &DomainAccountStub::ProcGetDomainAccessToken
79 },
80 {
81 DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO,
82 &DomainAccountStub::ProcUnregisterAccountStatusListenerByInfo
83 },
84 {
85 DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO,
86 &DomainAccountStub::ProcRegisterAccountStatusListenerByInfo
87 },
88 {
89 DomainAccountInterfaceCode::DOMAIN_GET_ACCOUNT_INFO,
90 &DomainAccountStub::ProcGetDomainAccountInfo
91 },
92 };
93
DomainAccountStub()94 DomainAccountStub::DomainAccountStub()
95 {
96 stubFuncMap_ = stubFuncMap;
97 }
98
~DomainAccountStub()99 DomainAccountStub::~DomainAccountStub()
100 {}
101
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)102 int32_t DomainAccountStub::OnRemoteRequest(
103 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
104 {
105 MemoryGuard cacheGuard;
106 int32_t uid = IPCSkeleton::GetCallingUid();
107 ACCOUNT_LOGD("Received stub message: %{public}d, callingUid: %{public}d", code, uid);
108 ErrCode errCode = CheckPermission(static_cast<DomainAccountInterfaceCode>(code), uid);
109 if (errCode != ERR_OK) {
110 ACCOUNT_LOGE("check permission failed");
111 return errCode;
112 }
113 if (data.ReadInterfaceToken() != GetDescriptor()) {
114 ACCOUNT_LOGE("check descriptor failed! code %{public}u.", code);
115 return ERR_ACCOUNT_COMMON_CHECK_DESCRIPTOR_ERROR;
116 }
117 const auto &itFunc = stubFuncMap_.find(static_cast<DomainAccountInterfaceCode>(code));
118 if (itFunc != stubFuncMap_.end()) {
119 return (this->*(itFunc->second))(data, reply);
120 }
121 ACCOUNT_LOGW("remote request unhandled: %{public}d", code);
122 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
123 }
124
ProcHasDomainAccount(MessageParcel & data,MessageParcel & reply)125 ErrCode DomainAccountStub::ProcHasDomainAccount(MessageParcel &data, MessageParcel &reply)
126 {
127 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
128 if (info == nullptr) {
129 ACCOUNT_LOGE("failed to read domain account info");
130 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
131 }
132 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
133 if (callback == nullptr) {
134 ACCOUNT_LOGE("failed to read domain callback");
135 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
136 }
137 ErrCode result = HasDomainAccount(*info, callback);
138 if (!reply.WriteInt32(result)) {
139 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
140 return IPC_STUB_WRITE_PARCEL_ERR;
141 }
142 return ERR_NONE;
143 }
144
ProcUpdateAccountToken(MessageParcel & data,MessageParcel & reply)145 ErrCode DomainAccountStub::ProcUpdateAccountToken(MessageParcel &data, MessageParcel &reply)
146 {
147 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
148 if (info == nullptr) {
149 ACCOUNT_LOGE("failed to read domain account info");
150 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
151 }
152 std::vector<uint8_t> token;
153 if (!data.ReadUInt8Vector(&token)) {
154 ACCOUNT_LOGE("fail to read token");
155 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
156 }
157 ErrCode result = UpdateAccountToken(*info, token);
158 if (!reply.WriteInt32(result)) {
159 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
160 return IPC_STUB_WRITE_PARCEL_ERR;
161 }
162 return ERR_NONE;
163 }
164
ProcRegisterPlugin(MessageParcel & data,MessageParcel & reply)165 ErrCode DomainAccountStub::ProcRegisterPlugin(MessageParcel &data, MessageParcel &reply)
166 {
167 auto plugin = iface_cast<IDomainAccountPlugin>(data.ReadRemoteObject());
168 ErrCode result = RegisterPlugin(plugin);
169 if (!reply.WriteInt32(result)) {
170 ACCOUNT_LOGE("failed to write result");
171 return IPC_STUB_WRITE_PARCEL_ERR;
172 }
173 return ERR_NONE;
174 }
175
ProcUnregisterPlugin(MessageParcel & data,MessageParcel & reply)176 ErrCode DomainAccountStub::ProcUnregisterPlugin(MessageParcel &data, MessageParcel &reply)
177 {
178 ErrCode result = UnregisterPlugin();
179 if (!reply.WriteInt32(result)) {
180 ACCOUNT_LOGE("fail to write result");
181 return IPC_STUB_WRITE_PARCEL_ERR;
182 }
183 return ERR_NONE;
184 }
185
ProcAuth(MessageParcel & data,MessageParcel & reply)186 ErrCode DomainAccountStub::ProcAuth(MessageParcel &data, MessageParcel &reply)
187 {
188 DomainAccountInfo info;
189 if (!data.ReadString(info.accountName_)) {
190 ACCOUNT_LOGE("fail to read name");
191 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
192 }
193 if (!data.ReadString(info.domain_)) {
194 ACCOUNT_LOGE("fail to read domain");
195 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
196 }
197 std::vector<uint8_t> password;
198 if (!data.ReadUInt8Vector(&password)) {
199 ACCOUNT_LOGE("fail to read password");
200 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
201 }
202 auto callback = iface_cast<IDomainAuthCallback>(data.ReadRemoteObject());
203 ErrCode result = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
204 if (callback == nullptr) {
205 ACCOUNT_LOGE("callback is nullptr");
206 } else {
207 result = Auth(info, password, callback);
208 }
209 (void)memset_s(password.data(), password.size(), 0, password.size());
210 if (!reply.WriteInt32(result)) {
211 ACCOUNT_LOGE("failed to write auth result");
212 return IPC_STUB_WRITE_PARCEL_ERR;
213 }
214 return ERR_NONE;
215 }
216
ProcGetAccountStatus(MessageParcel & data,MessageParcel & reply)217 ErrCode DomainAccountStub::ProcGetAccountStatus(MessageParcel &data, MessageParcel &reply)
218 {
219 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
220 if (info == nullptr) {
221 ACCOUNT_LOGE("failed to read domain account info");
222 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
223 }
224 DomainAccountStatus status;
225 ErrCode result = GetAccountStatus(*info, status);
226 if (!reply.WriteInt32(result)) {
227 ACCOUNT_LOGE("failed to write result");
228 return IPC_STUB_WRITE_PARCEL_ERR;
229 }
230 if (!reply.WriteInt32(status)) {
231 ACCOUNT_LOGE("failed to write status");
232 return IPC_STUB_WRITE_PARCEL_ERR;
233 }
234 return ERR_NONE;
235 }
236
ProcGetDomainAccountInfo(MessageParcel & data,MessageParcel & reply)237 ErrCode DomainAccountStub::ProcGetDomainAccountInfo(MessageParcel &data, MessageParcel &reply)
238 {
239 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
240 if (info == nullptr) {
241 ACCOUNT_LOGE("failed to read domain account info");
242 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
243 }
244 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
245 if (callback == nullptr) {
246 ACCOUNT_LOGE("failed to read domain callback");
247 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
248 }
249 ErrCode result = GetDomainAccountInfo(*info, callback);
250 if (!reply.WriteInt32(result)) {
251 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
252 return IPC_STUB_WRITE_PARCEL_ERR;
253 }
254 return ERR_NONE;
255 }
256
ProcRegisterAccountStatusListener(MessageParcel & data,MessageParcel & reply)257 ErrCode DomainAccountStub::ProcRegisterAccountStatusListener(MessageParcel &data, MessageParcel &reply)
258 {
259 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
260 if (callback == nullptr) {
261 ACCOUNT_LOGE("failed to read domain callback");
262 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
263 }
264 ErrCode result = RegisterAccountStatusListener(callback);
265 if (!reply.WriteInt32(result)) {
266 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
267 return IPC_STUB_WRITE_PARCEL_ERR;
268 }
269
270 return ERR_OK;
271 }
272
ProcRegisterAccountStatusListenerByInfo(MessageParcel & data,MessageParcel & reply)273 ErrCode DomainAccountStub::ProcRegisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply)
274 {
275 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
276 if (info == nullptr) {
277 ACCOUNT_LOGE("failed to read domain account info");
278 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
279 }
280 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
281 if (callback == nullptr) {
282 ACCOUNT_LOGE("failed to read domain callback");
283 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
284 }
285 ErrCode result = RegisterAccountStatusListener(*info, callback);
286 if (!reply.WriteInt32(result)) {
287 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
288 return IPC_STUB_WRITE_PARCEL_ERR;
289 }
290
291 return ERR_OK;
292 }
293
ProcUnregisterAccountStatusListenerByInfo(MessageParcel & data,MessageParcel & reply)294 ErrCode DomainAccountStub::ProcUnregisterAccountStatusListenerByInfo(MessageParcel &data, MessageParcel &reply)
295 {
296 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
297 if (info == nullptr) {
298 ACCOUNT_LOGE("failed to read domain account info");
299 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
300 }
301 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
302 if (callback == nullptr) {
303 ACCOUNT_LOGE("failed to read domain callback");
304 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
305 }
306 ErrCode result = UnregisterAccountStatusListener(*info, callback);
307 if (!reply.WriteInt32(result)) {
308 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
309 return IPC_STUB_WRITE_PARCEL_ERR;
310 }
311 return ERR_OK;
312 }
313
ProcUnregisterAccountStatusListener(MessageParcel & data,MessageParcel & reply)314 ErrCode DomainAccountStub::ProcUnregisterAccountStatusListener(MessageParcel &data, MessageParcel &reply)
315 {
316 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
317 if (callback == nullptr) {
318 ACCOUNT_LOGE("failed to read domain callback");
319 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
320 }
321 ErrCode result = UnregisterAccountStatusListener(callback);
322 if (!reply.WriteInt32(result)) {
323 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
324 return IPC_STUB_WRITE_PARCEL_ERR;
325 }
326 return ERR_OK;
327 }
328
ProcAuthUser(MessageParcel & data,MessageParcel & reply)329 ErrCode DomainAccountStub::ProcAuthUser(MessageParcel &data, MessageParcel &reply)
330 {
331 int32_t userId = 0;
332 if (!data.ReadInt32(userId)) {
333 ACCOUNT_LOGE("fail to read userId");
334 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
335 }
336 std::vector<uint8_t> password;
337 if (!data.ReadUInt8Vector(&password)) {
338 ACCOUNT_LOGE("fail to read password");
339 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
340 }
341 auto callback = iface_cast<IDomainAuthCallback>(data.ReadRemoteObject());
342 ErrCode result = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
343 if (callback == nullptr) {
344 ACCOUNT_LOGE("callback is nullptr");
345 } else {
346 result = AuthUser(userId, password, callback);
347 }
348 (void)memset_s(password.data(), password.size(), 0, password.size());
349 if (!reply.WriteInt32(result)) {
350 ACCOUNT_LOGE("failed to write authUser result");
351 return IPC_STUB_WRITE_PARCEL_ERR;
352 }
353 return ERR_NONE;
354 }
355
ProcAuthWithPopup(MessageParcel & data,MessageParcel & reply)356 ErrCode DomainAccountStub::ProcAuthWithPopup(MessageParcel &data, MessageParcel &reply)
357 {
358 int32_t userId = 0;
359 if (!data.ReadInt32(userId)) {
360 ACCOUNT_LOGE("fail to read userId");
361 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
362 }
363 auto callback = iface_cast<IDomainAuthCallback>(data.ReadRemoteObject());
364 ErrCode result = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
365 if (callback == nullptr) {
366 ACCOUNT_LOGE("callback is nullptr");
367 } else {
368 result = AuthWithPopup(userId, callback);
369 }
370 if (!reply.WriteInt32(result)) {
371 ACCOUNT_LOGE("failed to write authUser result");
372 return IPC_STUB_WRITE_PARCEL_ERR;
373 }
374 return ERR_NONE;
375 }
376
ProcGetDomainAccessToken(MessageParcel & data,MessageParcel & reply)377 ErrCode DomainAccountStub::ProcGetDomainAccessToken(MessageParcel &data, MessageParcel &reply)
378 {
379 std::shared_ptr<DomainAccountInfo> info(data.ReadParcelable<DomainAccountInfo>());
380 if (info == nullptr) {
381 ACCOUNT_LOGE("failed to read domain account info");
382 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
383 }
384 std::shared_ptr<AAFwk::WantParams> parameters(data.ReadParcelable<AAFwk::WantParams>());
385 if (parameters == nullptr) {
386 ACCOUNT_LOGE("failed to read domain parameters");
387 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
388 }
389 auto callback = iface_cast<IDomainAccountCallback>(data.ReadRemoteObject());
390 if (callback == nullptr) {
391 ACCOUNT_LOGE("failed to read domain callback");
392 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
393 }
394 ErrCode result = GetAccessToken(*info, *parameters, callback);
395 if (!reply.WriteInt32(result)) {
396 ACCOUNT_LOGE("failed to write reply, result %{public}d.", result);
397 return IPC_STUB_WRITE_PARCEL_ERR;
398 }
399 return ERR_NONE;
400 }
401
CheckPermission(DomainAccountInterfaceCode code,int32_t uid)402 ErrCode DomainAccountStub::CheckPermission(DomainAccountInterfaceCode code, int32_t uid)
403 {
404 ErrCode errCode = AccountPermissionManager::CheckSystemApp();
405 if (errCode != ERR_OK) {
406 ACCOUNT_LOGE("the caller is not system application, errCode = %{public}d.", errCode);
407 return errCode;
408 }
409 if (uid == 0) {
410 return ERR_OK;
411 }
412 std::string permissionName;
413 switch (code) {
414 case DomainAccountInterfaceCode::REGISTER_PLUGIN:
415 case DomainAccountInterfaceCode::UNREGISTER_PLUGIN:
416 case DomainAccountInterfaceCode::DOMAIN_HAS_DOMAIN_ACCOUNT:
417 case DomainAccountInterfaceCode::DOMAIN_UPDATE_ACCOUNT_TOKEN:
418 permissionName = MANAGE_LOCAL_ACCOUNTS;
419 break;
420 case DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_ENQUIRY:
421 case DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER:
422 case DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER:
423 case DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_UNREGISTER_BY_INFO:
424 case DomainAccountInterfaceCode::DOMAIN_ACCOUNT_STATUS_LISTENER_REGISTER_BY_INFO:
425 permissionName = GET_LOCAL_ACCOUNTS;
426 break;
427 case DomainAccountInterfaceCode::DOMAIN_AUTH:
428 case DomainAccountInterfaceCode::DOMAIN_AUTH_USER:
429 case DomainAccountInterfaceCode::DOMAIN_AUTH_WITH_POPUP:
430 permissionName = ACCESS_USER_AUTH_INTERNAL;
431 break;
432 case DomainAccountInterfaceCode::DOMAIN_GET_ACCOUNT_INFO:
433 permissionName = GET_DOMAIN_ACCOUNTS;
434 break;
435 default:
436 break;
437 }
438 if (code == DomainAccountInterfaceCode::DOMAIN_GET_ACCESS_TOKEN) {
439 errCode = AccountPermissionManager::VerifyPermission(MANAGE_LOCAL_ACCOUNTS);
440 if (errCode != ERR_OK) {
441 return AccountPermissionManager::VerifyPermission(GET_LOCAL_ACCOUNTS);
442 }
443 return ERR_OK;
444 }
445 if (permissionName.empty()) {
446 return ERR_OK;
447 }
448 return AccountPermissionManager::VerifyPermission(permissionName);
449 }
450 } // namespace AccountSA
451 } // namespace OHOS
452