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 ¶meters)
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))(¶m, 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 ¶meters, 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