1 /*
2 * Copyright (c) 2022-2024 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 "inner_domain_account_manager.h"
17 #include <dlfcn.h>
18 #include <pthread.h>
19 #include <thread>
20 #include <securec.h>
21 #include <cstring>
22 #include <vector>
23 #include "account_info_report.h"
24 #include "account_log_wrapper.h"
25 #include "bool_wrapper.h"
26 #ifdef HAS_CES_PART
27 #include "account_event_provider.h"
28 #include "common_event_support.h"
29 #endif // HAS_CES_PART
30 #include "domain_account_common.h"
31 #include "domain_account_plugin_death_recipient.h"
32 #include "domain_account_callback_service.h"
33 #include "domain_has_domain_info_callback.h"
34 #include "idomain_account_callback.h"
35 #include "iinner_os_account_manager.h"
36 #include "inner_account_iam_manager.h"
37 #include "int_wrapper.h"
38 #include "ipc_skeleton.h"
39 #include "status_listener_manager.h"
40 #include "string_wrapper.h"
41
42 namespace OHOS {
43 namespace AccountSA {
44 namespace {
45 constexpr char THREAD_AUTH[] = "auth";
46 constexpr char THREAD_INNER_AUTH[] = "innerAuth";
47 constexpr char THREAD_HAS_ACCOUNT[] = "hasAccount";
48 constexpr char THREAD_GET_ACCOUNT[] = "getAccount";
49 constexpr char THREAD_BIND_ACCOUNT[] = "bindAccount";
50 constexpr char THREAD_UNBIND_ACCOUNT[] = "unbindAccount";
51 constexpr char THREAD_GET_ACCESS_TOKEN[] = "getAccessToken";
52 constexpr char THREAD_IS_ACCOUNT_VALID[] = "isAccountTokenValid";
53 constexpr int32_t INVALID_USERID = -1;
54 constexpr int32_t SELF_UID = 3058;
55 #ifdef _ARM64_
56 static const std::string LIB_PATH = "/system/lib64/platformsdk/";
57 #else
58 static const std::string LIB_PATH = "/system/lib/platformsdk/";
59 #endif
60 static const std::string LIB_NAME = "libdomain_account_plugin.z.so";
61 }
62
InnerDomainAccountManager()63 InnerDomainAccountManager::InnerDomainAccountManager()
64 {
65 LoaderLib(LIB_PATH, LIB_NAME);
66 }
67
~InnerDomainAccountManager()68 InnerDomainAccountManager::~InnerDomainAccountManager()
69 {
70 CloseLib();
71 }
72
GetInstance()73 InnerDomainAccountManager &InnerDomainAccountManager::GetInstance()
74 {
75 static InnerDomainAccountManager *instance = new (std::nothrow) InnerDomainAccountManager();
76 return *instance;
77 }
78
InnerDomainAuthCallback(int32_t userId,const sptr<IDomainAccountCallback> & callback)79 InnerDomainAuthCallback::InnerDomainAuthCallback(int32_t userId, const sptr<IDomainAccountCallback> &callback)
80 : userId_(userId), callback_(callback)
81 {}
82
~InnerDomainAuthCallback()83 InnerDomainAuthCallback::~InnerDomainAuthCallback()
84 {}
85
OnResult(const int32_t errCode,Parcel & parcel)86 void InnerDomainAuthCallback::OnResult(const int32_t errCode, Parcel &parcel)
87 {
88 std::shared_ptr<DomainAuthResult> authResult(DomainAuthResult::Unmarshalling(parcel));
89 if (authResult == nullptr) {
90 ACCOUNT_LOGE("authResult is nullptr");
91 return;
92 }
93 if ((errCode == ERR_OK) && (userId_ != 0)) {
94 InnerDomainAccountManager::GetInstance().InsertTokenToMap(userId_, (*authResult).token);
95 DomainAccountInfo domainInfo;
96 InnerDomainAccountManager::GetInstance().GetDomainAccountInfoByUserId(userId_, domainInfo);
97 InnerDomainAccountManager::GetInstance().NotifyDomainAccountEvent(
98 userId_, DomainAccountEvent::LOG_IN, DomainAccountStatus::LOG_END, domainInfo);
99 bool isActivated = false;
100 (void)IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId_, isActivated);
101 DomainAccountStatus status = isActivated ? DomainAccountStatus::LOGIN : DomainAccountStatus::LOGIN_BACKGROUND;
102 IInnerOsAccountManager::GetInstance().UpdateAccountStatusForDomain(userId_, status);
103 }
104 (void)memset_s(authResult->token.data(), authResult->token.size(), 0, authResult->token.size());
105 authResult->token.clear();
106 Parcel resultParcel;
107 if (!(*authResult).Marshalling(resultParcel)) {
108 ACCOUNT_LOGE("authResult Marshalling failed");
109 return;
110 }
111 AccountInfoReport::ReportSecurityInfo("", userId_, ReportEvent::EVENT_LOGIN, errCode);
112 if (callback_ == nullptr) {
113 ACCOUNT_LOGI("callback_ is nullptr");
114 return;
115 }
116 return callback_->OnResult(errCode, resultParcel);
117 }
118
RegisterPlugin(const sptr<IDomainAccountPlugin> & plugin)119 ErrCode InnerDomainAccountManager::RegisterPlugin(const sptr<IDomainAccountPlugin> &plugin)
120 {
121 std::lock_guard<std::mutex> lock(mutex_);
122 if (plugin == nullptr) {
123 ACCOUNT_LOGE("the registered plugin is nullptr");
124 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
125 }
126 if (plugin_ != nullptr) {
127 ACCOUNT_LOGE("plugin already exists");
128 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_ALREADY_EXIST;
129 }
130 auto deathRecipient = GetDeathRecipient();
131 if ((plugin->AsObject()->IsProxyObject()) &&
132 ((deathRecipient == nullptr) || (!plugin->AsObject()->AddDeathRecipient(deathRecipient)))) {
133 ACCOUNT_LOGE("failed to add death recipient for plugin");
134 return ERR_ACCOUNT_COMMON_ADD_DEATH_RECIPIENT;
135 }
136 plugin_ = plugin;
137 callingUid_ = IPCSkeleton::GetCallingUid();
138 return ERR_OK;
139 }
140
UnregisterPlugin()141 void InnerDomainAccountManager::UnregisterPlugin()
142 {
143 std::lock_guard<std::mutex> lock(mutex_);
144 if ((plugin_ != nullptr) && (plugin_->AsObject() != nullptr)) {
145 plugin_->AsObject()->RemoveDeathRecipient(deathRecipient_);
146 }
147 plugin_ = nullptr;
148 callingUid_ = -1;
149 deathRecipient_ = nullptr;
150 }
151
StartAuth(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const std::vector<uint8_t> & authData,const sptr<IDomainAccountCallback> & callback,AuthMode authMode)152 ErrCode InnerDomainAccountManager::StartAuth(const sptr<IDomainAccountPlugin> &plugin, const DomainAccountInfo &info,
153 const std::vector<uint8_t> &authData, const sptr<IDomainAccountCallback> &callback, AuthMode authMode)
154 {
155 if (callback == nullptr) {
156 ACCOUNT_LOGE("invalid callback, cannot return result to client");
157 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
158 }
159 Parcel emptyParcel;
160 AccountSA::DomainAuthResult emptyResult;
161 if (!emptyResult.Marshalling(emptyParcel)) {
162 ACCOUNT_LOGE("authResult Marshalling failed");
163 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
164 }
165 if (plugin == nullptr) {
166 ACCOUNT_LOGE("plugin not exists");
167 callback->OnResult(ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST), emptyParcel);
168 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
169 }
170 ErrCode errCode = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
171 switch (authMode) {
172 case AUTH_WITH_CREDENTIAL_MODE:
173 errCode = plugin->Auth(info, authData, callback);
174 break;
175 case AUTH_WITH_POPUP_MODE:
176 errCode = plugin->AuthWithPopup(info, callback);
177 break;
178 case AUTH_WITH_TOKEN_MODE:
179 errCode = plugin->AuthWithToken(info, authData, callback);
180 break;
181 default:
182 break;
183 }
184 if (errCode != ERR_OK) {
185 ACCOUNT_LOGE("failed to auth domain account, errCode: %{public}d", errCode);
186 callback->OnResult(ConvertToJSErrCode(errCode), emptyParcel);
187 return errCode;
188 }
189 return ERR_OK;
190 }
191
GetDomainAccountInfoByUserId(int32_t userId,DomainAccountInfo & domainInfo)192 ErrCode InnerDomainAccountManager::GetDomainAccountInfoByUserId(int32_t userId, DomainAccountInfo &domainInfo)
193 {
194 OsAccountInfo accountInfo;
195 ErrCode errCode = IInnerOsAccountManager::GetInstance().QueryOsAccountById(userId, accountInfo);
196 if (errCode != ERR_OK) {
197 ACCOUNT_LOGE("get os account info failed, errCode: %{public}d", errCode);
198 return errCode;
199 }
200 accountInfo.GetDomainInfo(domainInfo);
201 if (domainInfo.accountName_.empty()) {
202 ACCOUNT_LOGE("the target user is not a domain account");
203 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
204 }
205 return ERR_OK;
206 }
207
GetMethodNameByEnum(PluginMethodEnum methondEnum)208 std::string GetMethodNameByEnum(PluginMethodEnum methondEnum)
209 {
210 switch (methondEnum) {
211 case PluginMethodEnum::ADD_SERVER_CONFIG:
212 return "AddServerConfig";
213 case PluginMethodEnum::REMOVE_SERVER_CONFIG:
214 return "RemoveServerConfig";
215 case PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG:
216 return "GetAccountServerConfig";
217 case PluginMethodEnum::AUTH:
218 return "Auth";
219 case PluginMethodEnum::AUTH_WITH_POPUP:
220 return "AuthWithPopup";
221 case PluginMethodEnum::AUTH_WITH_TOKEN:
222 return "AuthWithToken";
223 case PluginMethodEnum::GET_ACCOUNT_INFO:
224 return "GetAccountInfo";
225 case PluginMethodEnum::GET_AUTH_STATUS_INFO:
226 return "GetAuthStatusInfo";
227 case PluginMethodEnum::BIND_ACCOUNT:
228 return "BindAccount";
229 case PluginMethodEnum::UNBIND_ACCOUNT:
230 return "UnbindAccount";
231 case PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID:
232 return "IsAccountTokenValid";
233 case PluginMethodEnum::GET_ACCESS_TOKEN:
234 return "GetAccessToken";
235 case PluginMethodEnum::GET_SERVER_CONFIG:
236 return "GetServerConfig";
237 case PluginMethodEnum::UPDATE_ACCOUNT_INFO:
238 return "UpdateAccountInfo";
239 case PluginMethodEnum::IS_AUTHENTICATION_EXPIRED:
240 return "IsAuthenticationExpired";
241 case PluginMethodEnum::SET_ACCOUNT_POLICY:
242 return "SetAccountPolicy";
243 default:
244 ACCOUNT_LOGE("enum=%{public}d can not find string", methondEnum);
245 return "";
246 }
247 }
248
LoaderLib(const std::string & path,const std::string & libName)249 void InnerDomainAccountManager::LoaderLib(const std::string &path, const std::string &libName)
250 {
251 std::lock_guard<std::mutex> lock(libMutex_);
252 std::string soPath = path + libName;
253 libHandle_ = dlopen(soPath.c_str(), RTLD_LAZY);
254 if (libHandle_ == nullptr) {
255 ACCOUNT_LOGE("Call dlopen failed error=%{public}s", dlerror());
256 return;
257 }
258 for (auto i = 0; i < static_cast<int>(PluginMethodEnum::COUNT); ++i) {
259 std::string methodName = GetMethodNameByEnum(static_cast<PluginMethodEnum>(i));
260 if (methodName.empty()) {
261 ACCOUNT_LOGE("Call check methodName emtpty");
262 libHandle_ = nullptr;
263 methodMap_.clear();
264 return;
265 }
266 dlerror();
267 void *func = dlsym(libHandle_, methodName.c_str());
268 const char *dlsym_error = dlerror();
269 if (dlsym_error != nullptr) {
270 ACCOUNT_LOGE("Call check method=%{public}s error=%{public}s", methodName.c_str(), dlsym_error);
271 libHandle_ = nullptr;
272 methodMap_.clear();
273 return;
274 }
275 methodMap_.emplace(static_cast<PluginMethodEnum>(i), func);
276 }
277 }
278
CloseLib()279 void InnerDomainAccountManager::CloseLib()
280 {
281 std::lock_guard<std::mutex> lock(libMutex_);
282 if (libHandle_ == nullptr) {
283 ACCOUNT_LOGE("LibHandle_ is nullptr.");
284 return;
285 }
286 dlclose(libHandle_);
287 libHandle_ = nullptr;
288 }
289
SetPluginString(const std::string & str,PluginString & pStr)290 static void SetPluginString(const std::string &str, PluginString &pStr)
291 {
292 if (str.empty()) {
293 ACCOUNT_LOGE("Str is empty.");
294 pStr.data = nullptr;
295 pStr.length = 0;
296 return;
297 }
298 pStr.data = strdup(str.c_str());
299 if (pStr.data == nullptr) {
300 ACCOUNT_LOGE("Failed to duplicate string.");
301 pStr.length = 0;
302 return;
303 }
304 pStr.length = str.length();
305 }
306
CleanPluginString(char ** data,size_t length)307 static void CleanPluginString(char** data, size_t length)
308 {
309 if (data == nullptr || *data == nullptr) {
310 ACCOUNT_LOGE("Data is nullptr.");
311 return;
312 }
313 (void)memset_s(*data, length, 0, length);
314 free(*data);
315 *(data) = nullptr;
316 return;
317 }
318
SetPluginUint8Vector(const std::vector<uint8_t> & vector,PluginUint8Vector & pVector)319 static bool SetPluginUint8Vector(const std::vector<uint8_t> &vector, PluginUint8Vector &pVector)
320 {
321 if (vector.empty()) {
322 ACCOUNT_LOGE("Vector is empty.");
323 pVector.data = nullptr;
324 pVector.capcity = 0;
325 pVector.size = 0;
326 return true;
327 }
328 pVector.data = (uint8_t *)vector.data();
329 pVector.capcity = vector.size();
330 pVector.size = vector.size();
331 return true;
332 }
333
GetAndCleanPluginUint8Vector(PluginUint8Vector & pVector,std::vector<uint8_t> & vector)334 static ErrCode GetAndCleanPluginUint8Vector(PluginUint8Vector &pVector, std::vector<uint8_t> &vector)
335 {
336 if (pVector.data == nullptr) {
337 ACCOUNT_LOGE("PluginUint8Vector data is null.");
338 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
339 }
340 vector.assign(pVector.data, pVector.data + pVector.size);
341 (void)memset_s(pVector.data, pVector.capcity, 0, pVector.capcity);
342 free(pVector.data);
343 pVector.data = nullptr;
344 pVector.capcity = 0;
345 pVector.size = 0;
346 return ERR_OK;
347 }
348
GetAndCleanPluginBussnessError(PluginBussnessError ** error,PluginMethodEnum methodEnum)349 static ErrCode GetAndCleanPluginBussnessError(PluginBussnessError **error, PluginMethodEnum methodEnum)
350 {
351 if (error == nullptr || (*error) == nullptr) {
352 ACCOUNT_LOGE("Error is nullptr.");
353 return ERR_JS_SYSTEM_SERVICE_EXCEPTION;
354 }
355 ErrCode err = (*error)->code;
356 std::string methodName = GetMethodNameByEnum(methodEnum);
357 std::string msg;
358 if ((*error)->msg.data == nullptr) {
359 ACCOUNT_LOGW("PluginString's data is null.");
360 } else {
361 msg = std::string((*error)->msg.data);
362 (void)memset_s((*error)->msg.data, (*error)->msg.length, 0, (*error)->msg.length);
363 free((*error)->msg.data);
364 (*error)->msg.data = nullptr;
365 }
366 free((*error));
367 (*error) = nullptr;
368 if (err == ERR_OK) {
369 ACCOUNT_LOGD("Call method=%{public}s is ok msg=%{public}s.", methodName.c_str(), msg.c_str());
370 return err;
371 }
372 ACCOUNT_LOGE("Call method=%{public}s is error, errorCode=%{public}d msg=%{public}s.",
373 methodName.c_str(), err, msg.c_str());
374 return err;
375 }
376
GetAndCleanPluginString(PluginString & pStr,std::string & str)377 static ErrCode GetAndCleanPluginString(PluginString &pStr, std::string &str)
378 {
379 if (pStr.data == nullptr) {
380 ACCOUNT_LOGE("PluginString's data is null.");
381 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
382 }
383 str = std::string(pStr.data);
384 (void)memset_s(pStr.data, pStr.length, 0, pStr.length);
385 free(pStr.data);
386 pStr.data = nullptr;
387 pStr.length = 0;
388 return ERR_OK;
389 }
390
GetAndCleanPluginServerConfigInfo(PluginServerConfigInfo ** pConfigInfo,std::string & id,std::string & domain,std::string & parameters)391 static void GetAndCleanPluginServerConfigInfo(PluginServerConfigInfo **pConfigInfo,
392 std::string &id, std::string &domain, std::string ¶meters)
393 {
394 if (pConfigInfo == nullptr || *pConfigInfo == nullptr) {
395 ACCOUNT_LOGE("PluginServerConfigInfo is null");
396 return;
397 }
398 GetAndCleanPluginString((*pConfigInfo)->id, id);
399 GetAndCleanPluginString((*pConfigInfo)->domain, domain);
400 GetAndCleanPluginString((*pConfigInfo)->parameters, parameters);
401 free((*pConfigInfo));
402 (*pConfigInfo) = nullptr;
403 }
404
GetCallingUserID()405 static int32_t GetCallingUserID()
406 {
407 std::int32_t userId = IPCSkeleton::GetCallingUid() / UID_TRANSFORM_DIVISOR;
408 if (userId <= 0) {
409 std::vector<int32_t> userIds;
410 (void)IInnerOsAccountManager::GetInstance().QueryActiveOsAccountIds(userIds);
411 if (userIds.empty()) {
412 return INVALID_USERID; // invalid user id
413 }
414 userId = userIds[0];
415 }
416 return userId;
417 }
418
SetPluginDomainAccountInfo(const DomainAccountInfo & info,PluginDomainAccountInfo & pluginInfo)419 static void SetPluginDomainAccountInfo(const DomainAccountInfo &info, PluginDomainAccountInfo &pluginInfo)
420 {
421 SetPluginString(info.domain_, pluginInfo.domain);
422 SetPluginString(info.accountName_, pluginInfo.accountName);
423 SetPluginString(info.accountId_, pluginInfo.accountId);
424 if (!info.serverConfigId_.empty()) {
425 SetPluginString(info.serverConfigId_, pluginInfo.serverConfigId);
426 return;
427 }
428 int32_t userId = GetCallingUserID();
429 OsAccountInfo accountInfo;
430 ErrCode errCode = IInnerOsAccountManager::GetInstance().QueryOsAccountById(userId, accountInfo);
431 if (errCode != ERR_OK) {
432 ACCOUNT_LOGE("QueryOsAccountById fail code=%{public}d.", errCode);
433 pluginInfo.serverConfigId.data = nullptr;
434 return;
435 }
436 DomainAccountInfo savedInfo;
437 accountInfo.GetDomainInfo(savedInfo);
438 SetPluginString(savedInfo.serverConfigId_, pluginInfo.serverConfigId);
439 return;
440 }
441
GetAndCleanPluginDomainAccountInfo(DomainAccountInfo & info,PluginDomainAccountInfo ** pDomainAccountInfo)442 static void GetAndCleanPluginDomainAccountInfo(DomainAccountInfo &info, PluginDomainAccountInfo **pDomainAccountInfo)
443 {
444 if (pDomainAccountInfo == nullptr || *pDomainAccountInfo == nullptr) {
445 ACCOUNT_LOGE("PluginDomainAccountInfo is null.");
446 return;
447 }
448 GetAndCleanPluginString((*pDomainAccountInfo)->serverConfigId, info.serverConfigId_);
449 GetAndCleanPluginString((*pDomainAccountInfo)->domain, info.domain_);
450 GetAndCleanPluginString((*pDomainAccountInfo)->accountName, info.accountName_);
451 GetAndCleanPluginString((*pDomainAccountInfo)->accountId, info.accountId_);
452 info.isAuthenticated = (*pDomainAccountInfo)->isAuthenticated == 1;
453 free((*pDomainAccountInfo));
454 (*pDomainAccountInfo) = nullptr;
455 }
456
GetAndCleanPluginAuthResultInfo(PluginAuthResultInfo ** authResultInfo,std::vector<uint8_t> & token,int32_t & remainTimes,int32_t & freezingTime)457 static void GetAndCleanPluginAuthResultInfo(PluginAuthResultInfo **authResultInfo,
458 std::vector<uint8_t> &token, int32_t &remainTimes, int32_t &freezingTime)
459 {
460 if (authResultInfo == nullptr || *authResultInfo == nullptr) {
461 ACCOUNT_LOGE("PluginAuthResultInfo is null");
462 return;
463 }
464 freezingTime = (*authResultInfo)->freezingTime;
465 remainTimes = (*authResultInfo)->remainTimes;
466 GetAndCleanPluginUint8Vector((*authResultInfo)->accountToken, token);
467 free((*authResultInfo));
468 (*authResultInfo) = nullptr;
469 }
470
GetAndCleanPluginAuthStatusInfo(PluginAuthStatusInfo ** statusInfo,int32_t & remainTimes,int32_t & freezingTime)471 static void GetAndCleanPluginAuthStatusInfo(PluginAuthStatusInfo **statusInfo,
472 int32_t &remainTimes, int32_t &freezingTime)
473 {
474 if (statusInfo == nullptr || *statusInfo == nullptr) {
475 ACCOUNT_LOGE("PluginAuthStatusInfo is null.");
476 return;
477 }
478 remainTimes = (*statusInfo)->remainTimes;
479 freezingTime = (*statusInfo)->freezingTime;
480 free((*statusInfo));
481 (*statusInfo) = nullptr;
482 }
483
SetPluginGetDomainAccessTokenOptions(const GetAccessTokenOptions & option,const std::vector<uint8_t> & token,const DomainAccountInfo & info,PluginGetDomainAccessTokenOptions & pluginOptions)484 static void SetPluginGetDomainAccessTokenOptions(const GetAccessTokenOptions &option,
485 const std::vector<uint8_t> &token, const DomainAccountInfo &info, PluginGetDomainAccessTokenOptions &pluginOptions)
486 {
487 PluginDomainAccountInfo domainAccountInfo;
488 SetPluginDomainAccountInfo(info, domainAccountInfo);
489 PluginUint8Vector domainAccountToken;
490 SetPluginUint8Vector(token, domainAccountToken);
491 PluginString bussinessParams;
492 AAFwk::Want want;
493 want.SetParams(option.getTokenParams_);
494 std::string params = want.ToString();
495 SetPluginString(params, bussinessParams);
496 pluginOptions.domainAccountInfo = domainAccountInfo;
497 pluginOptions.domainAccountToken = domainAccountToken;
498 pluginOptions.bussinessParams = bussinessParams;
499 pluginOptions.callerUid = option.callingUid_;
500 }
501
AddServerConfig(const std::string & paremters,DomainServerConfig & config)502 ErrCode InnerDomainAccountManager::AddServerConfig(
503 const std::string &paremters, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
504 {
505 auto iter = methodMap_.find(PluginMethodEnum::ADD_SERVER_CONFIG);
506 if (iter == methodMap_.end() || iter->second == nullptr) {
507 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::ADD_SERVER_CONFIG);
508 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
509 }
510 int32_t localId = GetCallingUserID();
511 if (localId == INVALID_USERID) {
512 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
513 }
514 PluginString param;
515 SetPluginString(paremters, param);
516 PluginServerConfigInfo *configInfo = nullptr;
517 PluginBussnessError* error = (*reinterpret_cast<AddServerConfigFunc>(iter->second))(¶m, localId, &configInfo);
518 GetAndCleanPluginServerConfigInfo(&configInfo, config.id_, config.domain_, config.parameters_);
519 CleanPluginString(&(param.data), param.length);
520 return GetAndCleanPluginBussnessError(&error, iter->first);
521 }
522
RemoveServerConfig(const std::string & configId)523 ErrCode InnerDomainAccountManager::RemoveServerConfig(const std::string &configId) __attribute__((no_sanitize("cfi")))
524 {
525 auto iter = methodMap_.find(PluginMethodEnum::REMOVE_SERVER_CONFIG);
526 if (iter == methodMap_.end() || iter->second == nullptr) {
527 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::REMOVE_SERVER_CONFIG);
528 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
529 }
530 int32_t localId = GetCallingUserID();
531 if (localId == -1) {
532 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
533 }
534 PluginString serverConfigId;
535 SetPluginString(configId, serverConfigId);
536 PluginBussnessError* error = (*reinterpret_cast<RemoveServerConfigFunc>(iter->second))(&serverConfigId, localId);
537 CleanPluginString(&(serverConfigId.data), serverConfigId.length);
538 ErrCode errCode = GetAndCleanPluginBussnessError(&error, iter->first);
539 if (errCode == ERR_JS_INVALID_PARAMETER) {
540 return ERR_JS_SERVER_CONFIG_NOT_FOUND;
541 }
542 return errCode;
543 }
544
GetAccountServerConfig(const DomainAccountInfo & info,DomainServerConfig & config)545 ErrCode InnerDomainAccountManager::GetAccountServerConfig(
546 const DomainAccountInfo &info, DomainServerConfig &config) __attribute__((no_sanitize("cfi")))
547 {
548 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG);
549 if (iter == methodMap_.end() || iter->second == nullptr) {
550 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_SERVER_CONFIG);
551 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
552 }
553 int32_t localId = 0;
554 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, localId);
555 if (result != ERR_OK) {
556 ACCOUNT_LOGE("get os account localId from domain failed, result: %{public}d", result);
557 return result;
558 }
559 PluginDomainAccountInfo domainAccountInfo;
560 SetPluginDomainAccountInfo(info, domainAccountInfo);
561 PluginServerConfigInfo *serverConfigInfo = nullptr;
562 PluginBussnessError* error = (*reinterpret_cast<GetAccountServerConfigFunc>(iter->second))(&domainAccountInfo,
563 &serverConfigInfo);
564 GetAndCleanPluginServerConfigInfo(&serverConfigInfo, config.id_, config.domain_, config.parameters_);
565 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
566 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
567 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
568 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
569 ErrCode errCode = GetAndCleanPluginBussnessError(&error, iter->first);
570 if (errCode == ERR_JS_INVALID_PARAMETER) {
571 return ERR_JS_ACCOUNT_NOT_FOUND;
572 }
573 return errCode;
574 }
575
PluginAuth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,DomainAuthResult & resultParcel)576 ErrCode InnerDomainAccountManager::PluginAuth(const DomainAccountInfo &info,
577 const std::vector<uint8_t> &password, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
578 {
579 auto iter = methodMap_.find(PluginMethodEnum::AUTH);
580 if (iter == methodMap_.end() || iter->second == nullptr) {
581 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH);
582 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
583 }
584 int32_t localId = GetCallingUserID();
585 if (localId == -1) {
586 ACCOUNT_LOGE("fail to get activated os account ids");
587 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
588 }
589 PluginDomainAccountInfo domainAccountInfo;
590 SetPluginDomainAccountInfo(info, domainAccountInfo);
591 PluginUint8Vector credential;
592 SetPluginUint8Vector(password, credential);
593 PluginAuthResultInfo *authResultInfo = nullptr;
594 ACCOUNT_LOGD("Param localId=%{public}d.", localId);
595 PluginBussnessError* error = (*reinterpret_cast<AuthFunc>(iter->second))(&domainAccountInfo, &credential, localId,
596 &authResultInfo);
597 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
598 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
599 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
600 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
601 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
602 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
603 return GetAndCleanPluginBussnessError(&error, iter->first);
604 }
605
Auth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,const sptr<IDomainAccountCallback> & callback)606 ErrCode InnerDomainAccountManager::Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
607 const sptr<IDomainAccountCallback> &callback)
608 {
609 int32_t userId = -1;
610 sptr<IDomainAccountCallback> innerCallback = callback;
611 IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
612 if (userId >= 0) {
613 innerCallback = new (std::nothrow) InnerDomainAuthCallback(userId, callback);
614 if (innerCallback == nullptr) {
615 ACCOUNT_LOGE("failed to create innerCallback");
616 innerCallback = callback;
617 }
618 }
619 if (plugin_ == nullptr) {
620 Parcel emptyParcel;
621 AccountSA::DomainAuthResult result;
622 ErrCode err = PluginAuth(info, password, result);
623 if (!result.Marshalling(emptyParcel)) {
624 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
625 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
626 }
627 if (innerCallback != nullptr) {
628 innerCallback->OnResult(err, emptyParcel);
629 }
630 return ERR_OK;
631 }
632 auto task = [this, info, password, innerCallback] {
633 this->StartAuth(this->plugin_, info, password, innerCallback, AUTH_WITH_CREDENTIAL_MODE);
634 };
635 std::thread taskThread(task);
636 pthread_setname_np(taskThread.native_handle(), THREAD_AUTH);
637 taskThread.detach();
638 return ERR_OK;
639 }
640
PluginBindAccount(const DomainAccountInfo & info,const int32_t localId,DomainAuthResult & resultParcel)641 ErrCode InnerDomainAccountManager::PluginBindAccount(const DomainAccountInfo &info, const int32_t localId,
642 DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
643 {
644 auto iter = methodMap_.find(PluginMethodEnum::BIND_ACCOUNT);
645 if (iter == methodMap_.end() || iter->second == nullptr) {
646 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::BIND_ACCOUNT);
647 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
648 }
649 ACCOUNT_LOGD("Param localId=%{public}d.", localId);
650 int32_t callerLocalId = GetCallingUserID();
651 if (localId == -1) {
652 ACCOUNT_LOGE("fail to get activated os account ids");
653 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
654 }
655 PluginDomainAccountInfo domainAccountInfo;
656 SetPluginDomainAccountInfo(info, domainAccountInfo);
657 PluginBussnessError* error =
658 (*reinterpret_cast<BindAccountFunc>(iter->second))(&domainAccountInfo, localId, callerLocalId);
659 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
660 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
661 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
662 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
663 return GetAndCleanPluginBussnessError(&error, iter->first);
664 }
665
PluginUnBindAccount(const DomainAccountInfo & info,DomainAuthResult & resultParcel)666 ErrCode InnerDomainAccountManager::PluginUnBindAccount(
667 const DomainAccountInfo &info, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
668 {
669 auto iter = methodMap_.find(PluginMethodEnum::UNBIND_ACCOUNT);
670 if (iter == methodMap_.end() || iter->second == nullptr) {
671 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::UNBIND_ACCOUNT);
672 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
673 }
674 PluginDomainAccountInfo domainAccountInfo;
675 SetPluginDomainAccountInfo(info, domainAccountInfo);
676 PluginBussnessError* error = (*reinterpret_cast<UnbindAccountFunc>(iter->second))(&domainAccountInfo);
677 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
678 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
679 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
680 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
681 return GetAndCleanPluginBussnessError(&error, iter->first);
682 }
683
PluginIsAccountTokenValid(const DomainAccountInfo & info,const std::vector<uint8_t> & token,int32_t & isValid)684 ErrCode InnerDomainAccountManager::PluginIsAccountTokenValid(const DomainAccountInfo &info,
685 const std::vector<uint8_t> &token, int32_t &isValid) __attribute__((no_sanitize("cfi")))
686 {
687 auto iter = methodMap_.find(PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID);
688 if (iter == methodMap_.end() || iter->second == nullptr) {
689 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::IS_ACCOUNT_TOKEN_VALID);
690 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
691 }
692 PluginDomainAccountInfo domainAccountInfo;
693 SetPluginDomainAccountInfo(info, domainAccountInfo);
694 PluginUint8Vector pToken;
695 SetPluginUint8Vector(token, pToken);
696 PluginBussnessError* error =
697 (*reinterpret_cast<IsAccountTokenValidFunc>(iter->second))(&domainAccountInfo, &pToken, &isValid);
698 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
699 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
700 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
701 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
702 ACCOUNT_LOGD("return isValid=%{public}d.", isValid);
703 return GetAndCleanPluginBussnessError(&error, iter->first);
704 }
705
PluginGetAccessToken(const GetAccessTokenOptions & option,const std::vector<uint8_t> & token,const DomainAccountInfo & info,DomainAuthResult & resultParcel)706 ErrCode InnerDomainAccountManager::PluginGetAccessToken(const GetAccessTokenOptions &option,
707 const std::vector<uint8_t> &token, const DomainAccountInfo &info,
708 DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
709 {
710 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCESS_TOKEN);
711 if (iter == methodMap_.end() || iter->second == nullptr) {
712 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCESS_TOKEN);
713 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
714 }
715 PluginGetDomainAccessTokenOptions pOption;
716 SetPluginGetDomainAccessTokenOptions(option, token, info, pOption);
717 PluginUint8Vector *accessToken = nullptr;
718 ACCOUNT_LOGD("Param params=%{public}s callerUid=%{public}d.", pOption.bussinessParams.data, pOption.callerUid);
719 PluginBussnessError* error = (*reinterpret_cast<GetAccessTokenFunc>(iter->second))(&pOption, &accessToken);
720 if (accessToken != nullptr) {
721 GetAndCleanPluginUint8Vector(*accessToken, resultParcel.token);
722 free(accessToken);
723 }
724 accessToken = nullptr;
725 CleanPluginString(&(pOption.domainAccountInfo.domain.data), pOption.domainAccountInfo.domain.length);
726 CleanPluginString(&(pOption.domainAccountInfo.serverConfigId.data),
727 pOption.domainAccountInfo.serverConfigId.length);
728 CleanPluginString(&(pOption.domainAccountInfo.accountName.data),
729 pOption.domainAccountInfo.accountName.length);
730 CleanPluginString(&(pOption.domainAccountInfo.accountId.data),
731 pOption.domainAccountInfo.accountId.length);
732 CleanPluginString(&(pOption.bussinessParams.data), pOption.bussinessParams.length);
733 return GetAndCleanPluginBussnessError(&error, iter->first);
734 }
735
PluginAuthWithPopup(const DomainAccountInfo & info,DomainAuthResult & resultParcel)736 ErrCode InnerDomainAccountManager::PluginAuthWithPopup(
737 const DomainAccountInfo &info, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
738 {
739 auto iter = methodMap_.find(PluginMethodEnum::AUTH_WITH_POPUP);
740 if (iter == methodMap_.end() || iter->second == nullptr) {
741 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH_WITH_POPUP);
742 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
743 }
744 PluginDomainAccountInfo domainAccountInfo;
745 SetPluginDomainAccountInfo(info, domainAccountInfo);
746 PluginAuthResultInfo *authResultInfo = nullptr;
747 PluginBussnessError* error = (*reinterpret_cast<AuthWithPopupFunc>(iter->second))(&domainAccountInfo,
748 &authResultInfo);
749 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
750 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
751 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
752 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
753 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
754 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
755 return GetAndCleanPluginBussnessError(&error, iter->first);
756 }
757
PluginAuthToken(const DomainAccountInfo & info,const std::vector<uint8_t> & authData,DomainAuthResult & resultParcel)758 ErrCode InnerDomainAccountManager::PluginAuthToken(const DomainAccountInfo &info,
759 const std::vector<uint8_t> &authData, DomainAuthResult &resultParcel) __attribute__((no_sanitize("cfi")))
760 {
761 auto iter = methodMap_.find(PluginMethodEnum::AUTH_WITH_TOKEN);
762 if (iter == methodMap_.end() || iter->second == nullptr) {
763 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::AUTH_WITH_TOKEN);
764 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
765 }
766 PluginDomainAccountInfo domainAccountInfo;
767 SetPluginDomainAccountInfo(info, domainAccountInfo);
768 PluginUint8Vector token;
769 SetPluginUint8Vector(authData, token);
770 PluginAuthResultInfo *authResultInfo = nullptr;
771 PluginBussnessError* error = (*reinterpret_cast<AuthWithTokenFunc>(iter->second))(&domainAccountInfo, &token,
772 &authResultInfo);
773 GetAndCleanPluginAuthResultInfo(&authResultInfo, resultParcel.token,
774 resultParcel.authStatusInfo.remainingTimes, resultParcel.authStatusInfo.freezingTime);
775 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
776 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
777 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
778 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
779 return GetAndCleanPluginBussnessError(&error, iter->first);
780 }
781
PluginGetAuthStatusInfo(const DomainAccountInfo & info,AuthStatusInfo & authInfo)782 ErrCode InnerDomainAccountManager::PluginGetAuthStatusInfo(const DomainAccountInfo &info,
783 AuthStatusInfo &authInfo) __attribute__((no_sanitize("cfi")))
784 {
785 auto iter = methodMap_.find(PluginMethodEnum::GET_AUTH_STATUS_INFO);
786 if (iter == methodMap_.end() || iter->second == nullptr) {
787 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_AUTH_STATUS_INFO);
788 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
789 }
790 PluginDomainAccountInfo domainAccountInfo;
791 SetPluginDomainAccountInfo(info, domainAccountInfo);
792 PluginAuthStatusInfo *authStatusInfo = nullptr;
793 PluginBussnessError* error =
794 (*reinterpret_cast<GetAuthStatusInfoFunc>(iter->second))(&domainAccountInfo, &authStatusInfo);
795 GetAndCleanPluginAuthStatusInfo(&authStatusInfo, authInfo.remainingTimes, authInfo.freezingTime);
796 CleanPluginString(&(domainAccountInfo.domain.data), domainAccountInfo.domain.length);
797 CleanPluginString(&(domainAccountInfo.serverConfigId.data), domainAccountInfo.serverConfigId.length);
798 CleanPluginString(&(domainAccountInfo.accountName.data), domainAccountInfo.accountName.length);
799 CleanPluginString(&(domainAccountInfo.accountId.data), domainAccountInfo.accountId.length);
800 return GetAndCleanPluginBussnessError(&error, iter->first);
801 }
802
PluginUpdateAccountInfo(const DomainAccountInfo & oldAccountInfo,const DomainAccountInfo & newAccountInfo)803 ErrCode InnerDomainAccountManager::PluginUpdateAccountInfo(const DomainAccountInfo &oldAccountInfo,
804 const DomainAccountInfo &newAccountInfo) __attribute__((no_sanitize("cfi")))
805 {
806 auto iter = methodMap_.find(PluginMethodEnum::UPDATE_ACCOUNT_INFO);
807 if (iter == methodMap_.end() || iter->second == nullptr) {
808 ACCOUNT_LOGE("Caller method = %{public}d not exsit.", PluginMethodEnum::UPDATE_ACCOUNT_INFO);
809 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
810 }
811 PluginDomainAccountInfo oldDomainAccountInfo;
812 SetPluginDomainAccountInfo(oldAccountInfo, oldDomainAccountInfo);
813 PluginDomainAccountInfo newDomainAccountInfo;
814 SetPluginDomainAccountInfo(newAccountInfo, newDomainAccountInfo);
815 PluginBussnessError* error =
816 (*reinterpret_cast<UpdateAccountInfoFunc>(iter->second))(&oldDomainAccountInfo, &newDomainAccountInfo);
817 CleanPluginString(&(oldDomainAccountInfo.domain.data), oldDomainAccountInfo.domain.length);
818 CleanPluginString(&(oldDomainAccountInfo.serverConfigId.data), oldDomainAccountInfo.serverConfigId.length);
819 CleanPluginString(&(oldDomainAccountInfo.accountName.data), oldDomainAccountInfo.accountName.length);
820 CleanPluginString(&(oldDomainAccountInfo.accountId.data), oldDomainAccountInfo.accountId.length);
821 CleanPluginString(&(newDomainAccountInfo.domain.data), newDomainAccountInfo.domain.length);
822 CleanPluginString(&(newDomainAccountInfo.serverConfigId.data), newDomainAccountInfo.serverConfigId.length);
823 CleanPluginString(&(newDomainAccountInfo.accountName.data), newDomainAccountInfo.accountName.length);
824 CleanPluginString(&(newDomainAccountInfo.accountId.data), newDomainAccountInfo.accountId.length);
825 return GetAndCleanPluginBussnessError(&error, iter->first);
826 }
827
InnerAuth(int32_t userId,const std::vector<uint8_t> & authData,const sptr<IDomainAccountCallback> & callback,AuthMode authMode)828 ErrCode InnerDomainAccountManager::InnerAuth(int32_t userId, const std::vector<uint8_t> &authData,
829 const sptr<IDomainAccountCallback> &callback, AuthMode authMode)
830 {
831 DomainAccountInfo domainInfo;
832 ErrCode errCode = GetDomainAccountInfoByUserId(userId, domainInfo);
833 if (errCode != ERR_OK) {
834 return errCode;
835 }
836 sptr<InnerDomainAuthCallback> innerCallback = new (std::nothrow) InnerDomainAuthCallback(userId, callback);
837 if (innerCallback == nullptr) {
838 ACCOUNT_LOGE("failed to create innerCallback");
839 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
840 }
841 if (plugin_ == nullptr) {
842 Parcel emptyParcel;
843 AccountSA::DomainAuthResult result;
844 switch (authMode) {
845 case AUTH_WITH_CREDENTIAL_MODE:
846 errCode = PluginAuth(domainInfo, authData, result);
847 break;
848 case AUTH_WITH_POPUP_MODE:
849 errCode = PluginAuthWithPopup(domainInfo, result);
850 break;
851 case AUTH_WITH_TOKEN_MODE:
852 errCode = PluginAuthToken(domainInfo, authData, result);
853 break;
854 default:
855 ACCOUNT_LOGE("AuthMode not match.");
856 break;
857 }
858 if (!result.Marshalling(emptyParcel)) {
859 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
860 errCode = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
861 }
862 innerCallback->OnResult(errCode, emptyParcel);
863 return ERR_OK;
864 }
865 auto task = [this, domainInfo, authData, innerCallback, authMode] {
866 this->StartAuth(this->plugin_, domainInfo, authData, innerCallback, authMode);
867 };
868 std::thread taskThread(task);
869 pthread_setname_np(taskThread.native_handle(), THREAD_INNER_AUTH);
870 taskThread.detach();
871 return ERR_OK;
872 }
873
AuthUser(int32_t userId,const std::vector<uint8_t> & password,const sptr<IDomainAccountCallback> & callback)874 ErrCode InnerDomainAccountManager::AuthUser(int32_t userId, const std::vector<uint8_t> &password,
875 const sptr<IDomainAccountCallback> &callback)
876 {
877 bool isVerified = false;
878 (void) IInnerOsAccountManager::GetInstance().IsOsAccountVerified(userId, isVerified);
879 if (isVerified) {
880 return InnerAuth(userId, password, callback, AUTH_WITH_CREDENTIAL_MODE);
881 }
882
883 uint64_t credentialId = 0;
884 (void) IInnerOsAccountManager::GetInstance().GetOsAccountCredentialId(userId, credentialId);
885 if (credentialId > 0) {
886 ACCOUNT_LOGE("unsupported auth type");
887 return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
888 }
889 return InnerAuth(userId, password, callback, AUTH_WITH_CREDENTIAL_MODE);
890 }
891
AuthWithPopup(int32_t userId,const sptr<IDomainAccountCallback> & callback)892 ErrCode InnerDomainAccountManager::AuthWithPopup(int32_t userId, const sptr<IDomainAccountCallback> &callback)
893 {
894 if (userId == 0) {
895 std::vector<int32_t> userIds;
896 (void)IInnerOsAccountManager::GetInstance().QueryActiveOsAccountIds(userIds);
897 if (userIds.empty()) {
898 ACCOUNT_LOGE("fail to get activated os account ids");
899 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
900 }
901 userId = userIds[0];
902 }
903 return InnerAuth(userId, {}, callback, AUTH_WITH_POPUP_MODE);
904 }
905
AuthWithToken(int32_t userId,const std::vector<uint8_t> & token)906 ErrCode InnerDomainAccountManager::AuthWithToken(int32_t userId, const std::vector<uint8_t> &token)
907 {
908 return InnerAuth(userId, token, nullptr, AUTH_WITH_TOKEN_MODE);
909 }
910
InsertTokenToMap(int32_t userId,const std::vector<uint8_t> & token)911 void InnerDomainAccountManager::InsertTokenToMap(int32_t userId, const std::vector<uint8_t> &token)
912 {
913 std::lock_guard<std::mutex> lock(mutex_);
914 userTokenMap_[userId] = token;
915 }
916
GetTokenFromMap(int32_t userId,std::vector<uint8_t> & token)917 bool InnerDomainAccountManager::GetTokenFromMap(int32_t userId, std::vector<uint8_t> &token)
918 {
919 std::lock_guard<std::mutex> lock(mutex_);
920 auto it = userTokenMap_.find(userId);
921 if (it == userTokenMap_.end()) {
922 token.clear();
923 return false;
924 }
925 token = it->second;
926 return true;
927 }
928
RemoveTokenFromMap(int32_t userId)929 void InnerDomainAccountManager::RemoveTokenFromMap(int32_t userId)
930 {
931 std::lock_guard<std::mutex> lock(mutex_);
932 userTokenMap_.erase(userId);
933 return;
934 }
935
NotifyDomainAccountEvent(int32_t userId,DomainAccountEvent event,DomainAccountStatus status,const DomainAccountInfo & info)936 void InnerDomainAccountManager::NotifyDomainAccountEvent(
937 int32_t userId, DomainAccountEvent event, DomainAccountStatus status, const DomainAccountInfo &info)
938 {
939 if (status == DomainAccountStatus::LOG_END) {
940 bool isActivated = false;
941 (void)IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId, isActivated);
942 status = isActivated ? DomainAccountStatus::LOGIN : DomainAccountStatus::LOGIN_BACKGROUND;
943 }
944
945 // There is not need to check userid.
946 DomainAccountEventData report;
947 report.domainAccountInfo = info;
948 report.event = event;
949 report.status = status;
950 report.userId = userId;
951 StatusListenerManager::GetInstance().NotifyEventAsync(report);
952 }
953
UpdateAccountToken(const DomainAccountInfo & info,const std::vector<uint8_t> & token)954 ErrCode InnerDomainAccountManager::UpdateAccountToken(const DomainAccountInfo &info, const std::vector<uint8_t> &token)
955 {
956 int32_t callingUid = IPCSkeleton::GetCallingUid();
957 if ((callingUid != callingUid_) && (callingUid != SELF_UID)) {
958 ACCOUNT_LOGE("callingUid and register callinguid is not same!");
959 return ERR_DOMAIN_ACCOUNT_SERVICE_INVALID_CALLING_UID;
960 }
961 int32_t userId = 0;
962 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
963 if (result != ERR_OK) {
964 ACCOUNT_LOGE("get os account localId from domain failed, result: %{public}d", result);
965 return result;
966 }
967
968 if (token.empty()) {
969 RemoveTokenFromMap(userId);
970 NotifyDomainAccountEvent(userId, DomainAccountEvent::TOKEN_INVALID, DomainAccountStatus::LOGOUT, info);
971 IInnerOsAccountManager::GetInstance().UpdateAccountStatusForDomain(userId, DomainAccountStatus::LOGOUT);
972 return ERR_OK;
973 }
974 InsertTokenToMap(userId, token);
975 NotifyDomainAccountEvent(userId, DomainAccountEvent::TOKEN_UPDATED, DomainAccountStatus::LOG_END, info);
976 return ERR_OK;
977 }
978
OnResultForGetAccessToken(const ErrCode errCode,const sptr<IDomainAccountCallback> & callback)979 static void OnResultForGetAccessToken(const ErrCode errCode, const sptr<IDomainAccountCallback> &callback)
980 {
981 std::vector<uint8_t> token;
982 Parcel emptyParcel;
983 emptyParcel.WriteUInt8Vector(token);
984 callback->OnResult(errCode, emptyParcel);
985 }
986
StartGetAccessToken(const sptr<IDomainAccountPlugin> & plugin,const std::vector<uint8_t> & accountToken,const DomainAccountInfo & info,const GetAccessTokenOptions & option,const sptr<IDomainAccountCallback> & callback)987 ErrCode InnerDomainAccountManager::StartGetAccessToken(const sptr<IDomainAccountPlugin> &plugin,
988 const std::vector<uint8_t> &accountToken, const DomainAccountInfo &info, const GetAccessTokenOptions &option,
989 const sptr<IDomainAccountCallback> &callback)
990 {
991 if (callback == nullptr) {
992 ACCOUNT_LOGE("invalid callback");
993 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
994 }
995 if (plugin == nullptr) {
996 ACCOUNT_LOGE("plugin is nullptr");
997 OnResultForGetAccessToken(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
998 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
999 }
1000 DomainAccountCallbackFunc callbackFunc = [callback](const int32_t errCode, Parcel &parcel) {
1001 if (callback != nullptr) {
1002 callback->OnResult(errCode, parcel);
1003 }
1004 };
1005 sptr<DomainAccountCallbackService> callbackService =
1006 new (std::nothrow) DomainAccountCallbackService(callbackFunc);
1007 if (callbackService == nullptr) {
1008 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1009 OnResultForGetAccessToken(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1010 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1011 }
1012 ErrCode result = plugin->GetAccessToken(info, accountToken, option, callbackService);
1013 if (result != ERR_OK) {
1014 ACCOUNT_LOGE("failed to get access token, errCode: %{public}d", result);
1015 OnResultForGetAccessToken(result, callback);
1016 return result;
1017 }
1018 return ERR_OK;
1019 }
1020
QueryAccountInfo(const DomainAccountInfo & info,const int32_t & callingUid,DomainAccountInfo & targetInfo,int32_t & userId)1021 static ErrCode QueryAccountInfo(const DomainAccountInfo &info, const int32_t &callingUid,
1022 DomainAccountInfo &targetInfo, int32_t &userId)
1023 {
1024 ErrCode result = ERR_OK;
1025 if (!info.accountName_.empty()) {
1026 result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1027 if (result != ERR_OK) {
1028 ACCOUNT_LOGE("domain account not found");
1029 return result;
1030 }
1031 } else {
1032 userId = callingUid / UID_TRANSFORM_DIVISOR;
1033 OsAccountInfo osAccountInfo;
1034 (void) IInnerOsAccountManager::GetInstance().QueryOsAccountById(userId, osAccountInfo);
1035 osAccountInfo.GetDomainInfo(targetInfo);
1036 if (targetInfo.accountName_.empty()) {
1037 ACCOUNT_LOGE("domain account not found");
1038 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
1039 }
1040 }
1041 return result;
1042 }
1043
GetAccessToken(const DomainAccountInfo & info,const AAFwk::WantParams & parameters,const sptr<IDomainAccountCallback> & callback)1044 ErrCode InnerDomainAccountManager::GetAccessToken(
1045 const DomainAccountInfo &info, const AAFwk::WantParams ¶meters, const sptr<IDomainAccountCallback> &callback)
1046 {
1047 if (callback == nullptr) {
1048 ACCOUNT_LOGE("invalid callback");
1049 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1050 }
1051 int32_t callingUid = IPCSkeleton::GetCallingUid();
1052 int32_t userId = 0;
1053 DomainAccountInfo targetInfo = info;
1054 ErrCode result = QueryAccountInfo(info, callingUid, targetInfo, userId);
1055 if (result != ERR_OK) {
1056 return result;
1057 }
1058 std::vector<uint8_t> accountToken;
1059 if (!GetTokenFromMap(userId, accountToken)) {
1060 ACCOUNT_LOGE("the target domain account has not authenticated");
1061 return ERR_ACCOUNT_COMMON_NOT_AUTHENTICATED;
1062 }
1063 GetAccessTokenOptions option(callingUid, parameters);
1064 if (plugin_ == nullptr) {
1065 Parcel emptyParcel;
1066 AccountSA::DomainAuthResult authResult;
1067 ErrCode err = PluginGetAccessToken(option, accountToken, targetInfo, authResult);
1068 if (!authResult.Marshalling(emptyParcel)) {
1069 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1070 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1071 }
1072 callback->OnResult(err, emptyParcel);
1073 return ERR_OK;
1074 }
1075 auto task = [this, accountToken, targetInfo, option, callback] {
1076 this->StartGetAccessToken(this->plugin_, accountToken, targetInfo, option, callback);
1077 };
1078 std::thread taskThread(task);
1079 pthread_setname_np(taskThread.native_handle(), THREAD_GET_ACCESS_TOKEN);
1080 taskThread.detach();
1081 return ERR_OK;
1082 }
1083
IsAuthenticationExpired(const DomainAccountInfo & info,bool & isExpired)1084 ErrCode InnerDomainAccountManager::IsAuthenticationExpired(
1085 const DomainAccountInfo &info, bool &isExpired) __attribute__((no_sanitize("cfi")))
1086 {
1087 auto iter = methodMap_.find(PluginMethodEnum::IS_AUTHENTICATION_EXPIRED);
1088 if (iter == methodMap_.end() || iter->second == nullptr) {
1089 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", iter->first);
1090 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1091 }
1092 int32_t userId = 0;
1093 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1094 if (result != ERR_OK) {
1095 ACCOUNT_LOGI("The target domain account not found, isExpired=true.");
1096 isExpired = true;
1097 return ERR_DOMAIN_ACCOUNT_SERVICE_NOT_DOMAIN_ACCOUNT;
1098 }
1099 std::vector<uint8_t> accountToken;
1100 if (!GetTokenFromMap(userId, accountToken)) {
1101 ACCOUNT_LOGI("The target domain account has not authenticated, isExpired=true.");
1102 isExpired = true;
1103 return ERR_OK;
1104 }
1105
1106 PluginDomainAccountInfo domainAccountInfo;
1107 SetPluginDomainAccountInfo(info, domainAccountInfo);
1108 PluginUint8Vector pToken;
1109 SetPluginUint8Vector(accountToken, pToken);
1110 int32_t isValid = 0;
1111 PluginBussnessError* error =
1112 (*reinterpret_cast<IsAuthenticationExpiredFunc>(iter->second))(&domainAccountInfo, &pToken, &isValid);
1113 ACCOUNT_LOGI("Return isValid=%{public}d.", isValid);
1114 if (error == nullptr) {
1115 ACCOUNT_LOGE("Error is nullptr.");
1116 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1117 }
1118 isExpired = (isValid == 0);
1119 return GetAndCleanPluginBussnessError(&error, iter->first);
1120 }
1121
SetAccountPolicy(const DomainAccountPolicy & policy)1122 ErrCode InnerDomainAccountManager::SetAccountPolicy(
1123 const DomainAccountPolicy &policy) __attribute__((no_sanitize("cfi")))
1124 {
1125 auto iter = methodMap_.find(PluginMethodEnum::SET_ACCOUNT_POLICY);
1126 if (iter == methodMap_.end() || iter->second == nullptr) {
1127 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::SET_ACCOUNT_POLICY);
1128 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1129 }
1130 PluginDomainAccountPolicy domainAccountPolicy;
1131 domainAccountPolicy.authenicationValidityPeriod = policy.authenicationValidityPeriod;
1132 PluginBussnessError* error =
1133 (*reinterpret_cast<SetAccountPolicyFunc>(iter->second))(&domainAccountPolicy);
1134 if (error == nullptr) {
1135 ACCOUNT_LOGE("Error is nullptr.");
1136 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1137 }
1138 return GetAndCleanPluginBussnessError(&error, iter->first);
1139 }
1140
ErrorOnResult(const ErrCode errCode,const sptr<IDomainAccountCallback> & callback)1141 static void ErrorOnResult(const ErrCode errCode, const sptr<IDomainAccountCallback> &callback)
1142 {
1143 Parcel emptyParcel;
1144 emptyParcel.WriteBool(false);
1145 callback->OnResult(errCode, emptyParcel);
1146 }
1147
OnResult(int32_t result,Parcel & parcel)1148 void CheckUserTokenCallback::OnResult(int32_t result, Parcel &parcel)
1149 {
1150 ACCOUNT_LOGI("enter");
1151 if (result == ERR_OK) {
1152 isValid_ = parcel.ReadBool();
1153 }
1154 NotifyCallbackEnd();
1155 }
1156
GetValidity(void)1157 bool CheckUserTokenCallback::GetValidity(void)
1158 {
1159 return isValid_;
1160 }
1161
WaitForCallbackResult()1162 void CheckUserTokenCallback::WaitForCallbackResult()
1163 {
1164 std::unique_lock<std::mutex> lock(lock_);
1165 condition_.wait(lock, [this] {
1166 return threadInSleep_ == false;
1167 });
1168 ACCOUNT_LOGI("WaitForCallbackResult.");
1169 }
1170
NotifyCallbackEnd()1171 void CheckUserTokenCallback::NotifyCallbackEnd()
1172 {
1173 std::unique_lock<std::mutex> lock(lock_);
1174 if (threadInSleep_) {
1175 ACCOUNT_LOGI("threadInSleep_ set false.");
1176 threadInSleep_ = false;
1177 condition_.notify_one();
1178 }
1179 }
1180
CheckUserToken(const std::vector<uint8_t> & token,bool & isValid,const DomainAccountInfo & info)1181 ErrCode InnerDomainAccountManager::CheckUserToken(
1182 const std::vector<uint8_t> &token, bool &isValid, const DomainAccountInfo &info)
1183 {
1184 std::shared_ptr<CheckUserTokenCallback> callback = std::make_shared<CheckUserTokenCallback>();
1185 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1186 if (callbackService == nullptr) {
1187 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1188 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1189 }
1190
1191 ErrCode errCode = ERR_OK;
1192 {
1193 std::lock_guard<std::mutex> lock(mutex_);
1194 if (plugin_ == nullptr) {
1195 Parcel emptyParcel;
1196 int32_t isTokenValid = -1;
1197 ErrCode err = PluginIsAccountTokenValid(info, token, isTokenValid);
1198 if (err == ERR_OK) {
1199 isValid = (isTokenValid == 1);
1200 }
1201 return err;
1202 }
1203 errCode = plugin_->IsAccountTokenValid(info, token, callbackService);
1204 }
1205 callback->WaitForCallbackResult();
1206 isValid = callback->GetValidity();
1207 return errCode;
1208 }
1209
GetAccountStatus(const DomainAccountInfo & info,DomainAccountStatus & status)1210 ErrCode InnerDomainAccountManager::GetAccountStatus(const DomainAccountInfo &info, DomainAccountStatus &status)
1211 {
1212 status = DomainAccountStatus::LOGOUT;
1213
1214 int32_t userId = 0;
1215 ErrCode res = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(info, userId);
1216 if (res != ERR_OK) {
1217 return res;
1218 }
1219 std::vector<uint8_t> token;
1220 if (!GetTokenFromMap(userId, token)) {
1221 ACCOUNT_LOGI("the target domain account has not authenticated");
1222 return ERR_OK;
1223 }
1224
1225 bool isValid = false;
1226 res = CheckUserToken(token, isValid, info);
1227 if (!isValid) {
1228 ACCOUNT_LOGI("Token is invalid.");
1229 return res;
1230 }
1231
1232 bool isActivated = false;
1233 res = IInnerOsAccountManager::GetInstance().IsOsAccountActived(userId, isActivated);
1234 if (isActivated) {
1235 status = DomainAccountStatus::LOGIN;
1236 } else {
1237 status = DomainAccountStatus::LOGIN_BACKGROUND;
1238 }
1239 return res;
1240 }
1241
RegisterAccountStatusListener(const sptr<IDomainAccountCallback> & listener)1242 ErrCode InnerDomainAccountManager::RegisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
1243 {
1244 return StatusListenerManager::GetInstance().InsertListenerToRecords(listener->AsObject());
1245 }
1246
UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> & listener)1247 ErrCode InnerDomainAccountManager::UnregisterAccountStatusListener(const sptr<IDomainAccountCallback> &listener)
1248 {
1249 // userid may be removed already.
1250 return StatusListenerManager::GetInstance().RemoveListenerByListener(listener->AsObject());
1251 }
1252
GetAuthStatusInfo(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)1253 ErrCode InnerDomainAccountManager::GetAuthStatusInfo(
1254 const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
1255 {
1256 sptr<IDomainAccountCallback> callbackService =
1257 new (std::nothrow) DomainAccountCallbackService(callback);
1258 if (callbackService == nullptr) {
1259 ACCOUNT_LOGE("failed to create DomainAccountCallbackService");
1260 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
1261 }
1262 if (plugin_ == nullptr) {
1263 Parcel emptyParcel;
1264 AuthStatusInfo authInfo;
1265 ErrCode err = PluginGetAuthStatusInfo(info, authInfo);
1266 if (!authInfo.Marshalling(emptyParcel)) {
1267 ACCOUNT_LOGE("AuthStatusInfo marshalling failed.");
1268 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1269 }
1270 callbackService->OnResult(err, emptyParcel);
1271 return ERR_OK;
1272 }
1273 std::lock_guard<std::mutex> lock(mutex_);
1274 return plugin_->GetAuthStatusInfo(info, callbackService);
1275 }
1276
GetDeathRecipient()1277 sptr<IRemoteObject::DeathRecipient> InnerDomainAccountManager::GetDeathRecipient()
1278 {
1279 if (deathRecipient_ != nullptr) {
1280 return deathRecipient_;
1281 }
1282 deathRecipient_ = new (std::nothrow) DomainAccountPluginDeathRecipient();
1283 return deathRecipient_;
1284 }
1285
IsPluginAvailable()1286 bool InnerDomainAccountManager::IsPluginAvailable()
1287 {
1288 std::lock(mutex_, libMutex_);
1289 std::lock_guard<std::mutex> lock1(mutex_, std::adopt_lock);
1290 std::lock_guard<std::mutex> lock2(libMutex_, std::adopt_lock);
1291 return plugin_ != nullptr || libHandle_ != nullptr;
1292 }
1293
StartHasDomainAccount(const sptr<IDomainAccountPlugin> & plugin,const GetDomainAccountInfoOptions & options,const sptr<IDomainAccountCallback> & callback)1294 ErrCode InnerDomainAccountManager::StartHasDomainAccount(const sptr<IDomainAccountPlugin> &plugin,
1295 const GetDomainAccountInfoOptions &options, const sptr<IDomainAccountCallback> &callback)
1296 {
1297 if (callback == nullptr) {
1298 ACCOUNT_LOGE("invalid callback");
1299 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1300 }
1301 if (plugin == nullptr) {
1302 ACCOUNT_LOGE("plugin is nullptr");
1303 ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1304 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1305 }
1306 auto callbackWrapper = std::make_shared<DomainHasDomainInfoCallback>(
1307 callback, options.accountInfo.domain_, options.accountInfo.accountName_);
1308 if (callbackWrapper == nullptr) {
1309 ACCOUNT_LOGE("make shared DomainHasDomainInfoCallback failed");
1310 ErrorOnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, callback);
1311 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1312 }
1313 sptr<DomainAccountCallbackService> callbackService =
1314 new (std::nothrow) DomainAccountCallbackService(callbackWrapper);
1315 if (callbackService == nullptr) {
1316 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1317 ErrorOnResult(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, callback);
1318 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1319 }
1320 ErrCode result = plugin->GetDomainAccountInfo(options, callbackService);
1321 if (result != ERR_OK) {
1322 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", result);
1323 ErrorOnResult(result, callback);
1324 return result;
1325 }
1326 return ERR_OK;
1327 }
1328
HasDomainAccount(const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1329 ErrCode InnerDomainAccountManager::HasDomainAccount(
1330 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1331 {
1332 int32_t callingUid = IPCSkeleton::GetCallingUid();
1333 GetDomainAccountInfoOptions options;
1334 options.accountInfo = info;
1335 options.callingUid = callingUid;
1336 auto task = [this, options, callback] { this->StartHasDomainAccount(this->plugin_, options, callback); };
1337 std::thread taskThread(task);
1338 pthread_setname_np(taskThread.native_handle(), THREAD_HAS_ACCOUNT);
1339 taskThread.detach();
1340 return ERR_OK;
1341 }
1342
StartOnAccountBound(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const int32_t localId,const sptr<IDomainAccountCallback> & callback)1343 void InnerDomainAccountManager::StartOnAccountBound(const sptr<IDomainAccountPlugin> &plugin,
1344 const DomainAccountInfo &info, const int32_t localId, const sptr<IDomainAccountCallback> &callback)
1345 {
1346 if (plugin == nullptr) {
1347 ACCOUNT_LOGE("plugin not exists");
1348 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1349 }
1350 plugin->OnAccountBound(info, localId, callback);
1351 }
1352
OnAccountBound(const DomainAccountInfo & info,const int32_t localId,const std::shared_ptr<DomainAccountCallback> & callback)1353 ErrCode InnerDomainAccountManager::OnAccountBound(const DomainAccountInfo &info, const int32_t localId,
1354 const std::shared_ptr<DomainAccountCallback> &callback)
1355 {
1356 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1357 if (callbackService == nullptr) {
1358 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1359 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1360 }
1361 if (plugin_ == nullptr) {
1362 Parcel emptyParcel;
1363 AccountSA::DomainAuthResult result;
1364 ErrCode err = PluginBindAccount(info, localId, result);
1365 if (!result.Marshalling(emptyParcel)) {
1366 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1367 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1368 }
1369 callbackService->OnResult(err, emptyParcel);
1370 return ERR_OK;
1371 }
1372 auto task = [this, info, localId, callbackService] {
1373 this->StartOnAccountBound(this->plugin_, info, localId, callbackService);
1374 };
1375 std::thread taskThread(task);
1376 pthread_setname_np(taskThread.native_handle(), THREAD_BIND_ACCOUNT);
1377 taskThread.detach();
1378 return ERR_OK;
1379 }
1380
StartOnAccountUnBound(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1381 void InnerDomainAccountManager::StartOnAccountUnBound(const sptr<IDomainAccountPlugin> &plugin,
1382 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1383 {
1384 if (plugin == nullptr) {
1385 ACCOUNT_LOGE("plugin not exists");
1386 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1387 }
1388 plugin->OnAccountUnBound(info, callback);
1389 }
1390
OnAccountUnBound(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)1391 ErrCode InnerDomainAccountManager::OnAccountUnBound(const DomainAccountInfo &info,
1392 const std::shared_ptr<DomainAccountCallback> &callback)
1393 {
1394 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1395 if (callbackService == nullptr) {
1396 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1397 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1398 }
1399 if (plugin_ == nullptr) {
1400 Parcel emptyParcel;
1401 AccountSA::DomainAuthResult result;
1402 ErrCode err = PluginUnBindAccount(info, result);
1403 if (!result.Marshalling(emptyParcel)) {
1404 ACCOUNT_LOGE("DomainAuthResult marshalling failed.");
1405 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1406 }
1407 callbackService->OnResult(err, emptyParcel);
1408 return ERR_OK;
1409 }
1410 auto task = [this, info, callbackService] {
1411 this->StartOnAccountUnBound(this->plugin_, info, callbackService);
1412 };
1413 std::thread taskThread(task);
1414 pthread_setname_np(taskThread.native_handle(), THREAD_UNBIND_ACCOUNT);
1415 taskThread.detach();
1416 return ERR_OK;
1417 }
1418
StartGetDomainAccountInfo(const sptr<IDomainAccountPlugin> & plugin,const GetDomainAccountInfoOptions & options,const sptr<IDomainAccountCallback> & callback)1419 void InnerDomainAccountManager::StartGetDomainAccountInfo(const sptr<IDomainAccountPlugin> &plugin,
1420 const GetDomainAccountInfoOptions &options, const sptr<IDomainAccountCallback> &callback)
1421 {
1422 if (plugin == nullptr) {
1423 ACCOUNT_LOGE("plugin not exists");
1424 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1425 }
1426 ErrCode errCode = plugin->GetDomainAccountInfo(options, callback);
1427 if (errCode != ERR_OK) {
1428 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", errCode);
1429 ErrorOnResult(errCode, callback);
1430 }
1431 }
1432
PluginGetDomainAccountInfo(const GetDomainAccountInfoOptions & options,DomainAccountInfo & info)1433 ErrCode InnerDomainAccountManager::PluginGetDomainAccountInfo(const GetDomainAccountInfoOptions &options,
1434 DomainAccountInfo &info) __attribute__((no_sanitize("cfi")))
1435 {
1436 auto iter = methodMap_.find(PluginMethodEnum::GET_ACCOUNT_INFO);
1437 if (iter == methodMap_.end() || iter->second == nullptr) {
1438 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", PluginMethodEnum::GET_ACCOUNT_INFO);
1439 return ConvertToJSErrCode(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST);
1440 }
1441 PluginGetDomainAccountInfoOptions pluginOptions;
1442 SetPluginDomainAccountInfo(options.accountInfo, pluginOptions.domainAccountInfo);
1443 pluginOptions.callerUid = options.callingUid;
1444 int32_t localId = GetCallingUserID();
1445 if (localId == -1) {
1446 return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
1447 }
1448 PluginDomainAccountInfo *accountInfoResult = nullptr;
1449 PluginBussnessError* error =
1450 (*reinterpret_cast<GetAccountInfoFunc>(iter->second))(&pluginOptions, localId, &accountInfoResult);
1451 GetAndCleanPluginDomainAccountInfo(info, &accountInfoResult);
1452 CleanPluginString(&(pluginOptions.domainAccountInfo.domain.data), pluginOptions.domainAccountInfo.domain.length);
1453 CleanPluginString(&(pluginOptions.domainAccountInfo.serverConfigId.data),
1454 pluginOptions.domainAccountInfo.serverConfigId.length);
1455 CleanPluginString(&(pluginOptions.domainAccountInfo.accountName.data),
1456 pluginOptions.domainAccountInfo.accountName.length);
1457 CleanPluginString(&(pluginOptions.domainAccountInfo.accountId.data),
1458 pluginOptions.domainAccountInfo.accountId.length);
1459 return GetAndCleanPluginBussnessError(&error, iter->first);
1460 }
1461
GetDomainAccountInfo(const DomainAccountInfo & info,const sptr<IDomainAccountCallback> & callback)1462 ErrCode InnerDomainAccountManager::GetDomainAccountInfo(
1463 const DomainAccountInfo &info, const sptr<IDomainAccountCallback> &callback)
1464 {
1465 DomainAccountCallbackFunc callbackFunc = [callback](const int32_t errCode, Parcel &parcel) {
1466 if (callback != nullptr) {
1467 callback->OnResult(errCode, parcel);
1468 }
1469 };
1470 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callbackFunc);
1471 if (callbackService == nullptr) {
1472 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1473 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1474 }
1475 int32_t callingUid = IPCSkeleton::GetCallingUid();
1476 GetDomainAccountInfoOptions options;
1477 options.accountInfo = info;
1478 options.callingUid = callingUid;
1479 if (plugin_ == nullptr) {
1480 Parcel emptyParcel;
1481 DomainAccountInfo result;
1482 ErrCode err = PluginGetDomainAccountInfo(options, result);
1483 AAFwk::WantParams wParam;
1484 wParam.SetParam("domain", OHOS::AAFwk::String::Box(result.domain_));
1485 wParam.SetParam("accountName", OHOS::AAFwk::String::Box(result.accountName_));
1486 wParam.SetParam("accountId", OHOS::AAFwk::String::Box(result.accountId_));
1487 wParam.SetParam("serverConfigId", OHOS::AAFwk::String::Box(result.serverConfigId_));
1488 wParam.SetParam("isAuthenticated", OHOS::AAFwk::Boolean::Box(result.isAuthenticated));
1489 wParam.SetParam("status", OHOS::AAFwk::Integer::Box(result.status_));
1490 if (!wParam.Marshalling(emptyParcel)) {
1491 ACCOUNT_LOGE("DomainAccountInfo marshalling failed.");
1492 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1493 }
1494 callbackService->OnResult(err, emptyParcel);
1495 return ERR_OK;
1496 }
1497 auto task = [this, options, callbackService] {
1498 this->StartGetDomainAccountInfo(this->plugin_, options, callbackService);
1499 };
1500 std::thread taskThread(task);
1501 pthread_setname_np(taskThread.native_handle(), THREAD_GET_ACCOUNT);
1502 taskThread.detach();
1503 return ERR_OK;
1504 }
1505
StartIsAccountTokenValid(const sptr<IDomainAccountPlugin> & plugin,const DomainAccountInfo & info,const std::vector<uint8_t> & token,const sptr<IDomainAccountCallback> & callback)1506 void InnerDomainAccountManager::StartIsAccountTokenValid(const sptr<IDomainAccountPlugin> &plugin,
1507 const DomainAccountInfo &info, const std::vector<uint8_t> &token, const sptr<IDomainAccountCallback> &callback)
1508 {
1509 if (plugin == nullptr) {
1510 ACCOUNT_LOGE("plugin not exists");
1511 return ErrorOnResult(ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST, callback);
1512 }
1513 ErrCode errCode = plugin->IsAccountTokenValid(info, token, callback);
1514 if (errCode != ERR_OK) {
1515 ACCOUNT_LOGE("failed to get domain account, errCode: %{public}d", errCode);
1516 ErrorOnResult(errCode, callback);
1517 }
1518 }
1519
IsAccountTokenValid(const DomainAccountInfo & info,const std::vector<uint8_t> & token,const std::shared_ptr<DomainAccountCallback> & callback)1520 ErrCode InnerDomainAccountManager::IsAccountTokenValid(const DomainAccountInfo &info,
1521 const std::vector<uint8_t> &token, const std::shared_ptr<DomainAccountCallback> &callback)
1522 {
1523 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1524 if (callbackService == nullptr) {
1525 ACCOUNT_LOGE("make shared DomainAccountCallbackService failed");
1526 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1527 }
1528 if (plugin_ == nullptr) {
1529 Parcel emptyParcel;
1530 int32_t isValid = -1;
1531 ErrCode err = PluginIsAccountTokenValid(info, token, isValid);
1532 if (!emptyParcel.WriteBool(isValid == 1)) {
1533 ACCOUNT_LOGE("IsValid marshalling failed.");
1534 err = ConvertToJSErrCode(ERR_ACCOUNT_COMMON_WRITE_PARCEL_ERROR);
1535 }
1536 callbackService->OnResult(err, emptyParcel);
1537 return ERR_OK;
1538 }
1539 auto task = [this, info, token, callbackService] {
1540 this->StartIsAccountTokenValid(this->plugin_, info, token, callbackService);
1541 };
1542 std::thread taskThread(task);
1543 pthread_setname_np(taskThread.native_handle(), THREAD_IS_ACCOUNT_VALID);
1544 taskThread.detach();
1545 return ERR_OK;
1546 }
1547
OnResult(int32_t result,Parcel & parcel)1548 void UpdateAccountInfoCallback::OnResult(int32_t result, Parcel &parcel)
1549 {
1550 std::unique_lock<std::mutex> lock(lock_);
1551 if (result_ >= 0) {
1552 return;
1553 }
1554 if (result == ERR_JS_ACCOUNT_NOT_FOUND) {
1555 result_ = ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1556 } else if (result == ERR_JS_CAPABILITY_NOT_SUPPORTED) {
1557 result_ = ERR_OK;
1558 } else {
1559 result_ = result;
1560 }
1561 if (result_ == ERR_OK) {
1562 std::shared_ptr<AAFwk::WantParams> parameters(AAFwk::WantParams::Unmarshalling(parcel));
1563 if (parameters == nullptr) {
1564 ACCOUNT_LOGE("Parameters unmarshalling error");
1565 result_ = ERR_ACCOUNT_COMMON_READ_PARCEL_ERROR;
1566 } else {
1567 accountInfo_.accountName_ = parameters->GetStringParam("accountName");
1568 accountInfo_.domain_ = parameters->GetStringParam("domain");
1569 accountInfo_.accountId_ = parameters->GetStringParam("accountId");
1570 accountInfo_.serverConfigId_ = parameters->GetStringParam("serverConfigId");
1571 }
1572 }
1573 ACCOUNT_LOGI("ThreadInSleep_ set false.");
1574 threadInSleep_ = false;
1575 condition_.notify_one();
1576 }
1577
GetResult()1578 int32_t UpdateAccountInfoCallback::GetResult()
1579 {
1580 return result_;
1581 }
1582
WaitForCallbackResult()1583 void UpdateAccountInfoCallback::WaitForCallbackResult()
1584 {
1585 std::unique_lock<std::mutex> lock(lock_);
1586 condition_.wait(lock, [this] {
1587 return threadInSleep_ == false;
1588 });
1589 ACCOUNT_LOGI("WaitForCallbackResult.");
1590 }
1591
GetAccountInfo()1592 DomainAccountInfo UpdateAccountInfoCallback::GetAccountInfo()
1593 {
1594 return accountInfo_;
1595 }
1596
CheckNewDomainAccountInfo(const DomainAccountInfo & oldAccountInfo,DomainAccountInfo & newAccountInfo)1597 static ErrCode CheckNewDomainAccountInfo(const DomainAccountInfo &oldAccountInfo, DomainAccountInfo &newAccountInfo)
1598 {
1599 if (newAccountInfo.domain_ != oldAccountInfo.domain_) {
1600 ACCOUNT_LOGE("NewAccountInfo's domain is invalid");
1601 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1602 }
1603 if (!oldAccountInfo.serverConfigId_.empty()) {
1604 if (newAccountInfo.serverConfigId_.empty()) {
1605 newAccountInfo.serverConfigId_ = oldAccountInfo.serverConfigId_;
1606 }
1607 if (newAccountInfo.serverConfigId_ != oldAccountInfo.serverConfigId_) {
1608 ACCOUNT_LOGE("NewAccountInfo's serverConfigId is invalid");
1609 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
1610 }
1611 }
1612 ErrCode result = ERR_OK;
1613 if (!IInnerOsAccountManager::GetInstance().IsSameAccount(oldAccountInfo, newAccountInfo)) {
1614 int32_t userId = 0;
1615 result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(newAccountInfo, userId);
1616 if (result == ERR_OK && userId > 0) {
1617 ACCOUNT_LOGE("NewAccountInfo already exists");
1618 return ERR_OSACCOUNT_SERVICE_INNER_DOMAIN_ALREADY_BIND_ERROR;
1619 }
1620 }
1621 std::shared_ptr<UpdateAccountInfoCallback> callback = std::make_shared<UpdateAccountInfoCallback>();
1622 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
1623 if (callbackService == nullptr) {
1624 ACCOUNT_LOGE("Make shared DomainAccountCallbackService failed");
1625 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
1626 }
1627 result = InnerDomainAccountManager::GetInstance().GetDomainAccountInfo(newAccountInfo, callbackService);
1628 if (result != ERR_OK) {
1629 ACCOUNT_LOGE("GetDomainAccountInfo failed, result = %{public}d", result);
1630 return result;
1631 }
1632 callback->WaitForCallbackResult();
1633 result = callback->GetResult();
1634 if (result != ERR_OK) {
1635 ACCOUNT_LOGE("NewAccountInfo is invaild");
1636 return result;
1637 }
1638 newAccountInfo = callback->GetAccountInfo();
1639 return ERR_OK;
1640 }
1641
UpdateAccountInfo(const DomainAccountInfo & oldAccountInfo,const DomainAccountInfo & newAccountInfo)1642 ErrCode InnerDomainAccountManager::UpdateAccountInfo(
1643 const DomainAccountInfo &oldAccountInfo, const DomainAccountInfo &newAccountInfo)
1644 {
1645 if (!IsPluginAvailable()) {
1646 ACCOUNT_LOGE("Plugin is nullptr.");
1647 return ERR_DOMAIN_ACCOUNT_SERVICE_PLUGIN_NOT_EXIST;
1648 }
1649 // check old account info
1650 int32_t userId = 0;
1651 ErrCode result = IInnerOsAccountManager::GetInstance().GetOsAccountLocalIdFromDomain(oldAccountInfo, userId);
1652 if (result != ERR_OK) {
1653 ACCOUNT_LOGE("GetOsAccountLocalIdFromDomain failed, result = %{public}d", result);
1654 return result;
1655 }
1656 // check new account info
1657 DomainAccountInfo newDomainAccountInfo(newAccountInfo);
1658 result = CheckNewDomainAccountInfo(oldAccountInfo, newDomainAccountInfo);
1659 if (result != ERR_OK) {
1660 return result;
1661 }
1662 // update account info
1663 if (plugin_ == nullptr) {
1664 result = PluginUpdateAccountInfo(oldAccountInfo, newDomainAccountInfo);
1665 if (result != ERR_OK) {
1666 ACCOUNT_LOGE("PluginUpdateAccountInfo failed, errCode = %{public}d", result);
1667 return result;
1668 }
1669 }
1670 // update local info
1671 return IInnerOsAccountManager::GetInstance().UpdateAccountInfoByDomainAccountInfo(
1672 userId, newDomainAccountInfo);
1673 }
1674 } // namespace AccountSA
1675 } // namespace OHOS
1676