1 /*
2 * Copyright (c) 2022-2025 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 "app_account_authenticator_session.h"
17
18 #include <pthread.h>
19 #include <thread>
20 #include "ability_manager_adapter.h"
21 #include "account_info.h"
22 #include "account_log_wrapper.h"
23 #include "app_account_authenticator_callback.h"
24 #include "app_account_authenticator_manager.h"
25 #include "app_account_common.h"
26 #include "bundle_manager_adapter.h"
27 #include "iservice_registry.h"
28
29 namespace OHOS {
30 namespace AccountSA {
31 namespace {
32 const char THREAD_AUTH_SESSION[] = "authSession";
ConvertToAccountErrCode(ErrCode idlErrCode,int32_t funcResult)33 ErrCode ConvertToAccountErrCode(ErrCode idlErrCode, int32_t funcResult)
34 {
35 if (idlErrCode == ERR_OK) {
36 return funcResult;
37 }
38 if (idlErrCode == ERR_INVALID_VALUE) {
39 return ERR_ACCOUNT_COMMON_WRITE_DESCRIPTOR_ERROR;
40 } else if (idlErrCode == ERR_INVALID_DATA) {
41 return ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR;
42 } else {
43 return ERR_APPACCOUNT_KIT_SEND_REQUEST;
44 }
45 }
46 }
47
SessionClientDeathRecipient(const std::string & sessionId)48 SessionClientDeathRecipient::SessionClientDeathRecipient(const std::string &sessionId) : sessionId_(sessionId)
49 {}
50
OnRemoteDied(const wptr<IRemoteObject> & remote)51 void SessionClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
52 {
53 (void)remote;
54 AppAccountAuthenticatorSessionManager::GetInstance().CloseSession(sessionId_);
55 }
56
SessionServerDeathRecipient(const std::string & sessionId)57 SessionServerDeathRecipient::SessionServerDeathRecipient(const std::string &sessionId) : sessionId_(sessionId)
58 {}
59
OnRemoteDied(const wptr<IRemoteObject> & remote)60 void SessionServerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
61 {
62 (void)remote;
63 AppAccountAuthenticatorSessionManager::GetInstance().OnSessionServerDied(sessionId_);
64 }
65
SessionConnection(const std::string & sessionId)66 SessionConnection::SessionConnection(const std::string &sessionId) : sessionId_(sessionId)
67 {}
68
~SessionConnection()69 SessionConnection::~SessionConnection()
70 {}
71
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)72 void SessionConnection::OnAbilityConnectDone(
73 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
74 {
75 AppAccountAuthenticatorSessionManager::GetInstance().OnSessionAbilityConnectDone(
76 sessionId_, element, remoteObject, resultCode);
77 }
78
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)79 void SessionConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
80 {
81 AppAccountAuthenticatorSessionManager::GetInstance().OnSessionAbilityDisconnectDone(
82 sessionId_, element, resultCode);
83 }
84
AppAccountAuthenticatorSession(AuthenticatorAction action,const AuthenticatorSessionRequest & request)85 AppAccountAuthenticatorSession::AppAccountAuthenticatorSession(
86 AuthenticatorAction action, const AuthenticatorSessionRequest &request)
87 : action_(action), request_(request)
88 {
89 Init();
90 }
91
~AppAccountAuthenticatorSession()92 AppAccountAuthenticatorSession::~AppAccountAuthenticatorSession()
93 {
94 if (isOpened_) {
95 Close();
96 }
97 }
98
Init()99 void AppAccountAuthenticatorSession::Init()
100 {
101 if (isInitialized_) {
102 ACCOUNT_LOGE("session has been initialized");
103 return;
104 }
105
106 sessionId_ = std::to_string(reinterpret_cast<int64_t>(this));
107 conn_ = new (std::nothrow) SessionConnection(sessionId_);
108 clientDeathRecipient_ = new (std::nothrow) SessionClientDeathRecipient(sessionId_);
109 serverDeathRecipient_ = new (std::nothrow) SessionServerDeathRecipient(sessionId_);
110 authenticatorCb_ = new (std::nothrow) AppAccountAuthenticatorCallback(sessionId_);
111 if ((conn_ == nullptr) || (clientDeathRecipient_ == nullptr)
112 || (serverDeathRecipient_ == nullptr) || (authenticatorCb_ == nullptr)) {
113 conn_ = nullptr;
114 clientDeathRecipient_ = nullptr;
115 serverDeathRecipient_ = nullptr;
116 authenticatorCb_ = nullptr;
117 return;
118 }
119 userId_ = request_.callerUid / UID_TRANSFORM_DIVISOR;
120 ownerUid_ = BundleManagerAdapter::GetInstance()->GetUidByBundleName(request_.owner, userId_);
121 isInitialized_ = true;
122 }
123
Open()124 ErrCode AppAccountAuthenticatorSession::Open()
125 {
126 if (isOpened_) {
127 ACCOUNT_LOGD("session has been opened");
128 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
129 }
130 if (!isInitialized_) {
131 ACCOUNT_LOGD("session has not been initialized");
132 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
133 }
134 AuthenticatorInfo info;
135 ErrCode errCode = AppAccountAuthenticatorManager::GetAuthenticatorInfo(request_.owner, userId_, info);
136 if (errCode != ERR_OK) {
137 ACCOUNT_LOGE("authenticator not exist, owner: %{public}s, errCode: %{public}d.",
138 request_.owner.c_str(), errCode);
139 return errCode;
140 }
141 AAFwk::Want want;
142 want.SetElementName(request_.owner, info.abilityName);
143 auto task = [want, this] {
144 AbilityManagerAdapter::GetInstance()->ConnectAbility(want, this->conn_, nullptr, this->userId_);
145 };
146 std::thread taskThread(task);
147 pthread_setname_np(taskThread.native_handle(), THREAD_AUTH_SESSION);
148 taskThread.detach();
149 isOpened_ = true;
150 return ERR_OK;
151 }
152
Close()153 void AppAccountAuthenticatorSession::Close()
154 {
155 std::lock_guard<std::mutex> lock(mutex_);
156 if ((authenticatorProxy_ != nullptr) && (authenticatorProxy_->AsObject() != nullptr)) {
157 authenticatorProxy_->AsObject()->RemoveDeathRecipient(serverDeathRecipient_);
158 }
159 if ((request_.callback != nullptr) && (request_.callback->AsObject() != nullptr)) {
160 request_.callback->AsObject()->RemoveDeathRecipient(clientDeathRecipient_);
161 }
162 if (isConnected_) {
163 AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
164 }
165 isOpened_ = false;
166 }
167
CloseSelf() const168 void AppAccountAuthenticatorSession::CloseSelf() const
169 {
170 AppAccountAuthenticatorSessionManager::GetInstance().CloseSession(sessionId_);
171 }
172
AddClientDeathRecipient()173 ErrCode AppAccountAuthenticatorSession::AddClientDeathRecipient()
174 {
175 if (!isOpened_) {
176 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
177 }
178 if ((request_.callback == nullptr) || (request_.callback->AsObject() == nullptr)) {
179 return ERR_OK;
180 }
181 bool result = request_.callback->AsObject()->AddDeathRecipient(clientDeathRecipient_);
182 if (!result) {
183 return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
184 }
185 return ERR_OK;
186 }
187
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)188 void AppAccountAuthenticatorSession::OnAbilityConnectDone(
189 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
190 {
191 std::lock_guard<std::mutex> lock(mutex_);
192 isConnected_ = true;
193 AAFwk::Want errResult;
194 authenticatorProxy_ = iface_cast<IAppAccountAuthenticator>(remoteObject);
195 if ((!authenticatorProxy_) || (!authenticatorProxy_->AsObject())) {
196 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult);
197 return;
198 }
199 authenticatorProxy_->AsObject()->AddDeathRecipient(serverDeathRecipient_);
200 AppAccountAuthenticatorStringInfo stringInfo(request_.name, request_.authType, request_.callerBundleName);
201 OnAbilityConnectInner(stringInfo, resultCode, errResult);
202 if (resultCode != ERR_OK) {
203 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult);
204 }
205 }
206
OnAbilityConnectInner(const AppAccountAuthenticatorStringInfo & stringInfo,int32_t & resultCode,AAFwk::Want & errResult)207 void AppAccountAuthenticatorSession::OnAbilityConnectInner(const AppAccountAuthenticatorStringInfo &stringInfo,
208 int32_t &resultCode, AAFwk::Want &errResult)
209 {
210 int32_t funcResult = 0;
211 switch (action_) {
212 case ADD_ACCOUNT_IMPLICITLY:
213 resultCode = authenticatorProxy_->AddAccountImplicitly(request_.authType, request_.callerBundleName,
214 request_.options.GetParams(), authenticatorCb_->AsObject(), funcResult);
215 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
216 break;
217 case AUTHENTICATE:
218 resultCode = authenticatorProxy_->Authenticate(stringInfo, request_.options.GetParams(),
219 authenticatorCb_->AsObject(), funcResult);
220 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
221 break;
222 case CREATE_ACCOUNT_IMPLICITLY:
223 resultCode = authenticatorProxy_->CreateAccountImplicitly(request_.createOptions,
224 authenticatorCb_->AsObject(), funcResult);
225 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
226 break;
227 case AUTH:
228 resultCode = authenticatorProxy_->Auth(
229 request_.name, request_.authType, request_.options.GetParams(), authenticatorCb_->AsObject(),
230 funcResult);
231 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
232 break;
233 case VERIFY_CREDENTIAL:
234 resultCode = authenticatorProxy_->VerifyCredential(
235 request_.name, request_.verifyCredOptions, authenticatorCb_->AsObject(), funcResult);
236 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
237 break;
238 case CHECK_ACCOUNT_LABELS:
239 resultCode = authenticatorProxy_->CheckAccountLabels(
240 request_.name, request_.labels, authenticatorCb_->AsObject(), funcResult);
241 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
242 break;
243 case SET_AUTHENTICATOR_PROPERTIES:
244 resultCode = authenticatorProxy_->SetProperties(request_.setPropOptions, authenticatorCb_->AsObject(),
245 funcResult);
246 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
247 break;
248 case IS_ACCOUNT_REMOVABLE:
249 resultCode = authenticatorProxy_->IsAccountRemovable(request_.name, authenticatorCb_->AsObject(),
250 funcResult);
251 resultCode = ConvertToAccountErrCode(resultCode, funcResult);
252 break;
253 default:
254 ACCOUNT_LOGE("unsupported action: %{public}d", action_);
255 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult);
256 return;
257 }
258 }
259
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)260 void AppAccountAuthenticatorSession::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
261 {
262 isConnected_ = false;
263 }
264
OnServerDied()265 void AppAccountAuthenticatorSession::OnServerDied()
266 {
267 AAFwk::Want result;
268 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, result);
269 }
270
OnResult(int32_t resultCode,const AAFwk::Want & result) const271 int32_t AppAccountAuthenticatorSession::OnResult(int32_t resultCode, const AAFwk::Want &result) const
272 {
273 if (resultCode == ERR_JS_SUCCESS) {
274 switch (action_) {
275 case ADD_ACCOUNT_IMPLICITLY:
276 resultCode = OnAddAccountImplicitlyDone(result);
277 break;
278 case AUTHENTICATE:
279 resultCode = OnAuthenticateDone(result);
280 break;
281 default:
282 break;
283 }
284 }
285 if ((request_.callback != nullptr) && (request_.callback->AsObject() != nullptr)) {
286 request_.callback->OnResult(resultCode, result);
287 }
288 if (isConnected_) {
289 AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
290 }
291 CloseSelf();
292 return resultCode;
293 }
294
OnRequestRedirected(AAFwk::Want & newRequest) const295 int32_t AppAccountAuthenticatorSession::OnRequestRedirected(AAFwk::Want &newRequest) const
296 {
297 AAFwk::Want errResult;
298 AppExecFwk::ElementName element = newRequest.GetElement();
299 if (element.GetBundleName() != request_.owner) {
300 ACCOUNT_LOGD("invalid response");
301 OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult);
302 return ERR_JS_SUCCESS;
303 }
304 if ((!request_.callback) || (!request_.callback->AsObject())) {
305 ACCOUNT_LOGD("app account callback is nullptr");
306 if (isConnected_) {
307 AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
308 }
309 CloseSelf();
310 return ERR_JS_SUCCESS;
311 }
312 newRequest.SetParam(Constants::KEY_ACTION, action_);
313 newRequest.SetParam(Constants::KEY_NAME, request_.name);
314 newRequest.SetParam(Constants::KEY_SESSION_ID, sessionId_);
315 newRequest.SetParam(Constants::KEY_CALLER_BUNDLE_NAME, request_.callerBundleName);
316 newRequest.SetParam(Constants::KEY_CALLER_PID, request_.callerPid);
317 newRequest.SetParam(Constants::KEY_CALLER_UID, request_.callerUid);
318 if (action_ == AUTHENTICATE || action_ == ADD_ACCOUNT_IMPLICITLY) {
319 newRequest.SetParam(Constants::KEY_AUTH_TYPE, request_.authType);
320 }
321 request_.callback->OnRequestRedirected(newRequest);
322 return ERR_JS_SUCCESS;
323 }
324
OnRequestContinued() const325 int32_t AppAccountAuthenticatorSession::OnRequestContinued() const
326 {
327 if ((!request_.callback) || (!request_.callback->AsObject())) {
328 ACCOUNT_LOGD("app account callback is nullptr");
329 if (isConnected_) {
330 AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
331 }
332 CloseSelf();
333 return ERR_JS_SUCCESS;
334 }
335 request_.callback->OnRequestContinued();
336 return ERR_JS_SUCCESS;
337 }
338
OnAuthenticateDone(const AAFwk::Want & result) const339 int32_t AppAccountAuthenticatorSession::OnAuthenticateDone(const AAFwk::Want &result) const
340 {
341 std::string name = result.GetStringParam(Constants::KEY_NAME);
342 if (name != request_.name) {
343 return ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION;
344 }
345 return ERR_OK;
346 }
347
OnAddAccountImplicitlyDone(const AAFwk::Want & result) const348 int32_t AppAccountAuthenticatorSession::OnAddAccountImplicitlyDone(const AAFwk::Want &result) const
349 {
350 std::string name = result.GetStringParam(Constants::KEY_NAME);
351 if (name.empty()) {
352 return ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION;
353 }
354 AppAccountInfo info(name, request_.owner);
355 info.SetAppIndex(0);
356 AppAccountControlManager::GetInstance().AddAccount(name, "", ownerUid_, request_.owner, info);
357 return ERR_OK;
358 }
359
GetRequest(AuthenticatorSessionRequest & request) const360 void AppAccountAuthenticatorSession::GetRequest(AuthenticatorSessionRequest &request) const
361 {
362 request = request_;
363 }
364
GetAuthenticatorCallback(const AuthenticatorSessionRequest & request,sptr<IRemoteObject> & callback) const365 ErrCode AppAccountAuthenticatorSession::GetAuthenticatorCallback(
366 const AuthenticatorSessionRequest &request, sptr<IRemoteObject> &callback) const
367 {
368 callback = nullptr;
369 if ((request.callerUid != ownerUid_) || (request.callerBundleName != request_.owner)) {
370 ACCOUNT_LOGE("fail to get authenticator callback for permission denied");
371 return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
372 }
373 if (!authenticatorCb_) {
374 ACCOUNT_LOGE("session has not been initialized");
375 return ERR_APPACCOUNT_SERVICE_OAUTH_AUTHENTICATOR_CALLBACK_NOT_EXIST;
376 }
377 callback = authenticatorCb_->AsObject();
378 return ERR_OK;
379 }
380
GetSessionId() const381 std::string AppAccountAuthenticatorSession::GetSessionId() const
382 {
383 return sessionId_;
384 }
385 } // namespace AccountSA
386 } // namespace OHOS
387