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