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