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