• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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