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