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