1 /*
2 * Copyright (c) 2022 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 "account_log_wrapper.h"
19 #include "account_permission_manager.h"
20 #include "domain_auth_callback_proxy.h"
21 #include "ipc_skeleton.h"
22
23 namespace OHOS {
24 namespace AccountSA {
25 namespace {
26 const size_t MAX_PASSWORD_SIZE = 4096;
27 }
28
DomainAccountStub()29 DomainAccountStub::DomainAccountStub()
30 {}
31
~DomainAccountStub()32 DomainAccountStub::~DomainAccountStub()
33 {}
34
35 const std::map<uint32_t, DomainAccountStub::DomainAccountStubFunc> DomainAccountStub::stubFuncMap_ = {
36 {
37 IDomainAccount::Message::REGISTER_PLUGIN,
38 &DomainAccountStub::ProcRegisterPlugin
39 },
40 {
41 IDomainAccount::Message::UNREGISTER_PLUGIN,
42 &DomainAccountStub::ProcUnregisterPlugin
43 },
44 {
45 IDomainAccount::Message::DOMAIN_AUTH,
46 &DomainAccountStub::ProcAuth
47 },
48 {
49 IDomainAccount::Message::DOMAIN_AUTH_USER,
50 &DomainAccountStub::ProcAuthUser
51 }
52 };
53
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)54 int32_t DomainAccountStub::OnRemoteRequest(
55 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
56 {
57 int32_t uid = IPCSkeleton::GetCallingUid();
58 ACCOUNT_LOGD("Received stub message: %{public}d, callingUid: %{public}d", code, uid);
59 ErrCode errCode = CheckPermission(code, uid);
60 if (errCode != ERR_OK) {
61 ACCOUNT_LOGE("check permission failed");
62 return errCode;
63 }
64 if (data.ReadInterfaceToken() != GetDescriptor()) {
65 ACCOUNT_LOGE("check descriptor failed! code %{public}u.", code);
66 return ERR_ACCOUNT_COMMON_CHECK_DESCRIPTOR_ERROR;
67 }
68 const auto &itFunc = stubFuncMap_.find(code);
69 if (itFunc != stubFuncMap_.end()) {
70 return (this->*(itFunc->second))(data, reply);
71 }
72 ACCOUNT_LOGW("remote request unhandled: %{public}d", code);
73 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
74 }
75
ProcRegisterPlugin(MessageParcel & data,MessageParcel & reply)76 ErrCode DomainAccountStub::ProcRegisterPlugin(MessageParcel &data, MessageParcel &reply)
77 {
78 auto plugin = iface_cast<IDomainAccountPlugin>(data.ReadRemoteObject());
79 ErrCode result = RegisterPlugin(plugin);
80 if (!reply.WriteInt32(result)) {
81 ACCOUNT_LOGE("failed to write result");
82 return IPC_STUB_WRITE_PARCEL_ERR;
83 }
84 return ERR_NONE;
85 }
86
ProcUnregisterPlugin(MessageParcel & data,MessageParcel & reply)87 ErrCode DomainAccountStub::ProcUnregisterPlugin(MessageParcel &data, MessageParcel &reply)
88 {
89 ErrCode result = UnregisterPlugin();
90 if (!reply.WriteInt32(result)) {
91 ACCOUNT_LOGE("fail to write result");
92 return IPC_STUB_WRITE_PARCEL_ERR;
93 }
94 return ERR_NONE;
95 }
96
ProcAuth(MessageParcel & data,MessageParcel & reply)97 ErrCode DomainAccountStub::ProcAuth(MessageParcel &data, MessageParcel &reply)
98 {
99 DomainAccountInfo info;
100 if (!data.ReadString(info.accountName_)) {
101 ACCOUNT_LOGE("fail to read name");
102 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
103 }
104 if (!data.ReadString(info.domain_)) {
105 ACCOUNT_LOGE("fail to read domain");
106 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
107 }
108 std::vector<uint8_t> password;
109 if (!data.ReadUInt8Vector(&password)) {
110 ACCOUNT_LOGE("fail to read password");
111 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
112 }
113 auto callback = iface_cast<IDomainAuthCallback>(data.ReadRemoteObject());
114 size_t passwordSize = password.size();
115 ErrCode result = ERR_ACCOUNT_COMMON_INVALID_PARAMTER;
116 if (passwordSize > MAX_PASSWORD_SIZE) {
117 ACCOUNT_LOGE("password is too large");
118 } else if (callback == nullptr) {
119 ACCOUNT_LOGE("callback is nullptr");
120 } else {
121 result = Auth(info, password, callback);
122 }
123 for (size_t i = 0; i < passwordSize; ++i) {
124 password[i] = 0;
125 }
126 if (!reply.WriteInt32(result)) {
127 ACCOUNT_LOGE("failed to write auth result");
128 return IPC_STUB_WRITE_PARCEL_ERR;
129 }
130 return ERR_NONE;
131 }
132
ProcAuthUser(MessageParcel & data,MessageParcel & reply)133 ErrCode DomainAccountStub::ProcAuthUser(MessageParcel &data, MessageParcel &reply)
134 {
135 int32_t userId = 0;
136 if (!data.ReadInt32(userId)) {
137 ACCOUNT_LOGE("fail to read userId");
138 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
139 }
140 std::vector<uint8_t> password;
141 if (!data.ReadUInt8Vector(&password)) {
142 ACCOUNT_LOGE("fail to read password");
143 return ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
144 }
145 auto callback = iface_cast<IDomainAuthCallback>(data.ReadRemoteObject());
146 size_t passwordSize = password.size();
147 ErrCode result = ERR_ACCOUNT_COMMON_INVALID_PARAMTER;
148 if (passwordSize > MAX_PASSWORD_SIZE) {
149 ACCOUNT_LOGE("password is too large");
150 } else if (callback == nullptr) {
151 ACCOUNT_LOGE("callback is nullptr");
152 } else {
153 result = AuthUser(userId, password, callback);
154 }
155 for (size_t i = 0; i < passwordSize; ++i) {
156 password[i] = 0;
157 }
158 if (!reply.WriteInt32(result)) {
159 ACCOUNT_LOGE("failed to write authUser result");
160 return IPC_STUB_WRITE_PARCEL_ERR;
161 }
162 return ERR_NONE;
163 }
164
CheckPermission(uint32_t code,int32_t uid)165 ErrCode DomainAccountStub::CheckPermission(uint32_t code, int32_t uid)
166 {
167 if (uid == 0) {
168 return ERR_OK;
169 }
170 std::string permissionName;
171 switch (code) {
172 case IDomainAccount::Message::REGISTER_PLUGIN:
173 case IDomainAccount::Message::UNREGISTER_PLUGIN:
174 permissionName = AccountPermissionManager::MANAGE_LOCAL_ACCOUNTS;
175 break;
176 case IDomainAccount::Message::DOMAIN_AUTH:
177 case IDomainAccount::Message::DOMAIN_AUTH_USER:
178 permissionName = AccountPermissionManager::ACCESS_USER_AUTH_INTERNAL;
179 break;
180 default:
181 break;
182 }
183 if (permissionName.empty()) {
184 return ERR_OK;
185 }
186 return AccountPermissionManager::GetInstance()->VerifyPermission(permissionName);
187 }
188 } // namespace AccountSA
189 } // namespace OHOS
190