13ceed64fSopenharmony_ci/* 23ceed64fSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 33ceed64fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43ceed64fSopenharmony_ci * you may not use this file except in compliance with the License. 53ceed64fSopenharmony_ci * You may obtain a copy of the License at 63ceed64fSopenharmony_ci * 73ceed64fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83ceed64fSopenharmony_ci * 93ceed64fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103ceed64fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113ceed64fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123ceed64fSopenharmony_ci * See the License for the specific language governing permissions and 133ceed64fSopenharmony_ci * limitations under the License. 143ceed64fSopenharmony_ci */ 153ceed64fSopenharmony_ci 163ceed64fSopenharmony_ci#include "form_util.h" 173ceed64fSopenharmony_ci 183ceed64fSopenharmony_ci#include <set> 193ceed64fSopenharmony_ci#include <thread> 203ceed64fSopenharmony_ci#include <chrono> 213ceed64fSopenharmony_ci#include <cinttypes> 223ceed64fSopenharmony_ci#include <regex> 233ceed64fSopenharmony_ci 243ceed64fSopenharmony_ci#include "accesstoken_kit.h" 253ceed64fSopenharmony_ci#include "bundle_constants.h" 263ceed64fSopenharmony_ci#include "fms_log_wrapper.h" 273ceed64fSopenharmony_ci#include "form_constants.h" 283ceed64fSopenharmony_ci#include "ipc_skeleton.h" 293ceed64fSopenharmony_ci#include "os_account_manager_wrapper.h" 303ceed64fSopenharmony_ci 313ceed64fSopenharmony_cinamespace OHOS { 323ceed64fSopenharmony_cinamespace AppExecFwk { 333ceed64fSopenharmony_cinamespace { 343ceed64fSopenharmony_ciconstexpr int64_t SEC_TO_NANOSEC = 1000000000; 353ceed64fSopenharmony_ciconstexpr int64_t SEC_TO_MILLISEC = 1000; 363ceed64fSopenharmony_ciconstexpr int64_t MILLISEC_TO_NANOSEC = 1000000; 373ceed64fSopenharmony_ciconstexpr int64_t INVALID_UDID_HASH = 0; 383ceed64fSopenharmony_ciconstexpr int32_t SYSTEM_UID = 1000; 393ceed64fSopenharmony_ciconstexpr int INT_64_LENGTH = 19; 403ceed64fSopenharmony_ciconstexpr int ZERO_VALUE = 0; 413ceed64fSopenharmony_ciconstexpr int BASE_NUMBER = 9; 423ceed64fSopenharmony_ciconstexpr int64_t HEAD_BIT_NUM = 9000000000000000000; 433ceed64fSopenharmony_ci} // namespace 443ceed64fSopenharmony_ci 453ceed64fSopenharmony_ciusing namespace std; 463ceed64fSopenharmony_ciusing namespace std::chrono; 473ceed64fSopenharmony_ci 483ceed64fSopenharmony_cistatic std::set<uint64_t> s_memFormIds; 493ceed64fSopenharmony_cistatic std::mutex s_memFormIdsMutex; 503ceed64fSopenharmony_ci 513ceed64fSopenharmony_ci/** 523ceed64fSopenharmony_ci * @brief create form id for form. 533ceed64fSopenharmony_ci * @param udidHash udid hash 543ceed64fSopenharmony_ci * @return new form id. 553ceed64fSopenharmony_ci */ 563ceed64fSopenharmony_ciint64_t FormUtil::GenerateFormId(int64_t udidHash) 573ceed64fSopenharmony_ci{ 583ceed64fSopenharmony_ci set<uint64_t>::iterator it; 593ceed64fSopenharmony_ci const int retryTimes = 5; 603ceed64fSopenharmony_ci const int delayMs = 1; 613ceed64fSopenharmony_ci int64_t elapsedTime = 0; 623ceed64fSopenharmony_ci size_t elapsedHash = 0; 633ceed64fSopenharmony_ci uint64_t unsignedUdidHash = 0; 643ceed64fSopenharmony_ci uint64_t formId = 0; 653ceed64fSopenharmony_ci int64_t ret = -1; 663ceed64fSopenharmony_ci struct timespec t; 673ceed64fSopenharmony_ci t.tv_sec = 0; 683ceed64fSopenharmony_ci t.tv_nsec = 0; 693ceed64fSopenharmony_ci for (int i = 0; i < retryTimes; i++) { 703ceed64fSopenharmony_ci clock_gettime(CLOCK_REALTIME, &t); 713ceed64fSopenharmony_ci elapsedTime = (t.tv_sec) * SEC_TO_NANOSEC + t.tv_nsec; 723ceed64fSopenharmony_ci elapsedHash = std::hash<std::string>()(std::to_string(elapsedTime)); 733ceed64fSopenharmony_ci unsignedUdidHash = static_cast<uint64_t>(udidHash); 743ceed64fSopenharmony_ci formId = unsignedUdidHash | (uint32_t)(elapsedHash & 0x000000007fffffffL); 753ceed64fSopenharmony_ci ret = static_cast<int64_t>(formId); 763ceed64fSopenharmony_ci it = s_memFormIds.find(formId); 773ceed64fSopenharmony_ci if (it != s_memFormIds.end()) { 783ceed64fSopenharmony_ci HILOG_INFO("repeated formId:%{public}" PRId64, ret); 793ceed64fSopenharmony_ci std::this_thread::sleep_for(std::chrono::milliseconds(delayMs)); 803ceed64fSopenharmony_ci } else { 813ceed64fSopenharmony_ci std::lock_guard<std::mutex> lock(s_memFormIdsMutex); 823ceed64fSopenharmony_ci s_memFormIds.insert(formId); 833ceed64fSopenharmony_ci break; 843ceed64fSopenharmony_ci } 853ceed64fSopenharmony_ci } 863ceed64fSopenharmony_ci HILOG_INFO("generate elapsed hash %{public}zu, formId:%{public}" PRId64, elapsedHash, ret); 873ceed64fSopenharmony_ci return ret; 883ceed64fSopenharmony_ci} 893ceed64fSopenharmony_ci 903ceed64fSopenharmony_ci/** 913ceed64fSopenharmony_ci@brief delete form id for form. 923ceed64fSopenharmony_ci@param formId The id of the form. 933ceed64fSopenharmony_ci*/ 943ceed64fSopenharmony_civoid FormUtil::DeleteFormId(int64_t formId) 953ceed64fSopenharmony_ci{ 963ceed64fSopenharmony_ci std::lock_guard<std::mutex> lock(s_memFormIdsMutex); 973ceed64fSopenharmony_ci s_memFormIds.erase(static_cast<uint64_t>(formId)); 983ceed64fSopenharmony_ci} 993ceed64fSopenharmony_ci 1003ceed64fSopenharmony_ci/** 1013ceed64fSopenharmony_ci * @brief padding form id. 1023ceed64fSopenharmony_ci * @param formId The id of the form. 1033ceed64fSopenharmony_ci * @param udidHash udid hash 1043ceed64fSopenharmony_ci * @return new form id. 1053ceed64fSopenharmony_ci */ 1063ceed64fSopenharmony_ciint64_t FormUtil::PaddingUdidHash(uint64_t formId, uint64_t udidHash) 1073ceed64fSopenharmony_ci{ 1083ceed64fSopenharmony_ci // Compatible with int form id. 1093ceed64fSopenharmony_ci if ((formId & 0xffffffff00000000L) == 0) { 1103ceed64fSopenharmony_ci return udidHash | formId; 1113ceed64fSopenharmony_ci } 1123ceed64fSopenharmony_ci 1133ceed64fSopenharmony_ci return formId; 1143ceed64fSopenharmony_ci} 1153ceed64fSopenharmony_ci/** 1163ceed64fSopenharmony_ci * @brief create udid hash. 1173ceed64fSopenharmony_ci * @param udidHash udid hash. 1183ceed64fSopenharmony_ci * @return Returns true on success, false on failure. 1193ceed64fSopenharmony_ci */ 1203ceed64fSopenharmony_cibool FormUtil::GenerateUdidHash(int64_t &udidHash) 1213ceed64fSopenharmony_ci{ 1223ceed64fSopenharmony_ci HILOG_INFO("udidHash:%{private}s", std::to_string(udidHash).c_str()); 1233ceed64fSopenharmony_ci if (udidHash != INVALID_UDID_HASH) { 1243ceed64fSopenharmony_ci return true; 1253ceed64fSopenharmony_ci } 1263ceed64fSopenharmony_ci 1273ceed64fSopenharmony_ci u_int64_t hashId = 0L; 1283ceed64fSopenharmony_ci const int32_t thirtyTwo = 32; 1293ceed64fSopenharmony_ci udidHash = (hashId & 0x0000000000ffffffL) << thirtyTwo; 1303ceed64fSopenharmony_ci if (udidHash < 0) { 1313ceed64fSopenharmony_ci udidHash = 0L; 1323ceed64fSopenharmony_ci } 1333ceed64fSopenharmony_ci HILOG_INFO("generate hash %{private}s", std::to_string(udidHash).c_str()); 1343ceed64fSopenharmony_ci return true; 1353ceed64fSopenharmony_ci} 1363ceed64fSopenharmony_ci/** 1373ceed64fSopenharmony_ci * @brief Get current system nanosecond. 1383ceed64fSopenharmony_ci * @return Current system nanosecond. 1393ceed64fSopenharmony_ci */ 1403ceed64fSopenharmony_ciint64_t FormUtil::GetCurrentNanosecond() 1413ceed64fSopenharmony_ci{ 1423ceed64fSopenharmony_ci struct timespec ts; 1433ceed64fSopenharmony_ci ts.tv_sec = 0; 1443ceed64fSopenharmony_ci ts.tv_nsec = 0; 1453ceed64fSopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 1463ceed64fSopenharmony_ci return (ts.tv_sec * SEC_TO_NANOSEC + ts.tv_nsec); 1473ceed64fSopenharmony_ci} 1483ceed64fSopenharmony_ci/** 1493ceed64fSopenharmony_ci * @brief Get current system millisecond. 1503ceed64fSopenharmony_ci * @return Current system millisecond. 1513ceed64fSopenharmony_ci */ 1523ceed64fSopenharmony_ciint64_t FormUtil::GetCurrentMillisecond() 1533ceed64fSopenharmony_ci{ 1543ceed64fSopenharmony_ci struct timespec ts; 1553ceed64fSopenharmony_ci clock_gettime(CLOCK_REALTIME, &ts); 1563ceed64fSopenharmony_ci return (ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC); 1573ceed64fSopenharmony_ci} 1583ceed64fSopenharmony_ci 1593ceed64fSopenharmony_ciint64_t FormUtil::GetCurrentSteadyClockMillseconds() 1603ceed64fSopenharmony_ci{ 1613ceed64fSopenharmony_ci return std::chrono::duration_cast<std::chrono::milliseconds>( 1623ceed64fSopenharmony_ci std::chrono::steady_clock::now().time_since_epoch()).count(); 1633ceed64fSopenharmony_ci} 1643ceed64fSopenharmony_ci 1653ceed64fSopenharmony_ciint64_t FormUtil::GetNowMillisecond() 1663ceed64fSopenharmony_ci{ 1673ceed64fSopenharmony_ci system_clock::time_point pointTime = system_clock::now(); 1683ceed64fSopenharmony_ci auto timeMilliseconds = chrono::duration_cast<chrono::milliseconds>(pointTime.time_since_epoch()); 1693ceed64fSopenharmony_ci return timeMilliseconds.count(); 1703ceed64fSopenharmony_ci} 1713ceed64fSopenharmony_ci 1723ceed64fSopenharmony_ci/** 1733ceed64fSopenharmony_ci * @brief Get millisecond from tm. 1743ceed64fSopenharmony_ci * @param tmAtTime tm time. 1753ceed64fSopenharmony_ci * @return Millisecond. 1763ceed64fSopenharmony_ci */ 1773ceed64fSopenharmony_ciint64_t FormUtil::GetMillisecondFromTm(struct tm &tmAtTime) 1783ceed64fSopenharmony_ci{ 1793ceed64fSopenharmony_ci time_t inputTime = mktime(&tmAtTime); 1803ceed64fSopenharmony_ci if (inputTime == -1) { 1813ceed64fSopenharmony_ci HILOG_ERROR("mktime failed"); 1823ceed64fSopenharmony_ci return -1; 1833ceed64fSopenharmony_ci } 1843ceed64fSopenharmony_ci system_clock::time_point pointTime = system_clock::from_time_t(inputTime); 1853ceed64fSopenharmony_ci auto timeMilliseconds = chrono::duration_cast<chrono::milliseconds>(pointTime.time_since_epoch()); 1863ceed64fSopenharmony_ci return timeMilliseconds.count(); 1873ceed64fSopenharmony_ci} 1883ceed64fSopenharmony_ci 1893ceed64fSopenharmony_ci/** 1903ceed64fSopenharmony_ci* @brief split string. 1913ceed64fSopenharmony_ci * @param in string. 1923ceed64fSopenharmony_ci * @param delim delimiter. 1933ceed64fSopenharmony_ci * @return string list. 1943ceed64fSopenharmony_ci */ 1953ceed64fSopenharmony_cistd::vector<std::string> FormUtil::StringSplit(const std::string &in, const std::string &delim) 1963ceed64fSopenharmony_ci{ 1973ceed64fSopenharmony_ci std::regex reg { delim }; 1983ceed64fSopenharmony_ci return std::vector<std::string> { 1993ceed64fSopenharmony_ci std::sregex_token_iterator(in.begin(), in.end(), reg, -1), 2003ceed64fSopenharmony_ci std::sregex_token_iterator() 2013ceed64fSopenharmony_ci }; 2023ceed64fSopenharmony_ci} 2033ceed64fSopenharmony_ci 2043ceed64fSopenharmony_ci/** 2053ceed64fSopenharmony_ci * @brief get current active account id. 2063ceed64fSopenharmony_ci * @return int current active account id. 2073ceed64fSopenharmony_ci */ 2083ceed64fSopenharmony_ciint FormUtil::GetCurrentAccountId() 2093ceed64fSopenharmony_ci{ 2103ceed64fSopenharmony_ci std::vector<int32_t> activeList; 2113ceed64fSopenharmony_ci ErrCode errCode = DelayedSingleton<OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList); 2123ceed64fSopenharmony_ci if (errCode != ERR_OK) { 2133ceed64fSopenharmony_ci HILOG_ERROR("QueryActiveOsAccountIds failed"); 2143ceed64fSopenharmony_ci return Constants::ANY_USERID; 2153ceed64fSopenharmony_ci } 2163ceed64fSopenharmony_ci if (activeList.empty()) { 2173ceed64fSopenharmony_ci HILOG_ERROR("empty QueryActiveOsAccountIds,no accounts"); 2183ceed64fSopenharmony_ci return Constants::ANY_USERID; 2193ceed64fSopenharmony_ci } 2203ceed64fSopenharmony_ci 2213ceed64fSopenharmony_ci return activeList.front(); 2223ceed64fSopenharmony_ci} 2233ceed64fSopenharmony_ci 2243ceed64fSopenharmony_cibool FormUtil::IsSACall() 2253ceed64fSopenharmony_ci{ 2263ceed64fSopenharmony_ci auto callerToken = IPCSkeleton::GetCallingTokenID(); 2273ceed64fSopenharmony_ci HILOG_DEBUG("callerToken : %{private}u", callerToken); 2283ceed64fSopenharmony_ci 2293ceed64fSopenharmony_ci auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken); 2303ceed64fSopenharmony_ci if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) { 2313ceed64fSopenharmony_ci HILOG_DEBUG("caller tokenType is native, verify success"); 2323ceed64fSopenharmony_ci return true; 2333ceed64fSopenharmony_ci } 2343ceed64fSopenharmony_ci 2353ceed64fSopenharmony_ci if (IPCSkeleton::GetCallingUid() == SYSTEM_UID) { 2363ceed64fSopenharmony_ci HILOG_DEBUG("callingUid is native,verify success"); 2373ceed64fSopenharmony_ci return true; 2383ceed64fSopenharmony_ci } 2393ceed64fSopenharmony_ci 2403ceed64fSopenharmony_ci HILOG_DEBUG("call"); 2413ceed64fSopenharmony_ci return false; 2423ceed64fSopenharmony_ci} 2433ceed64fSopenharmony_ci 2443ceed64fSopenharmony_cibool FormUtil::VerifyCallingPermission(const std::string &permissionName) 2453ceed64fSopenharmony_ci{ 2463ceed64fSopenharmony_ci HILOG_DEBUG("call.permission name is:%{public}s", permissionName.c_str()); 2473ceed64fSopenharmony_ci auto callerToken = IPCSkeleton::GetCallingTokenID(); 2483ceed64fSopenharmony_ci int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); 2493ceed64fSopenharmony_ci if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) { 2503ceed64fSopenharmony_ci HILOG_ERROR("permission %{public}s: PERMISSION_DENIED", permissionName.c_str()); 2513ceed64fSopenharmony_ci return false; 2523ceed64fSopenharmony_ci } 2533ceed64fSopenharmony_ci HILOG_DEBUG("Verify calling permission success"); 2543ceed64fSopenharmony_ci return true; 2553ceed64fSopenharmony_ci} 2563ceed64fSopenharmony_ci 2573ceed64fSopenharmony_cibool FormUtil::ConvertStringToInt64(const std::string &strInfo, int64_t &int64Value) 2583ceed64fSopenharmony_ci{ 2593ceed64fSopenharmony_ci size_t strLength = strInfo.size(); 2603ceed64fSopenharmony_ci if (strLength == ZERO_VALUE) { 2613ceed64fSopenharmony_ci int64Value = ZERO_VALUE; 2623ceed64fSopenharmony_ci return true; 2633ceed64fSopenharmony_ci } 2643ceed64fSopenharmony_ci std::regex pattern("^0|-?[1-9][0-9]{0,18}$"); // "^-?[0-9]{1,19}$" 2653ceed64fSopenharmony_ci std::smatch match; 2663ceed64fSopenharmony_ci if (regex_match(strInfo, match, pattern)) { 2673ceed64fSopenharmony_ci HILOG_DEBUG("regex_match successed"); 2683ceed64fSopenharmony_ci if (strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1) != "-") { // maximum: 9223372036854775807 2693ceed64fSopenharmony_ci if (strLength < INT_64_LENGTH) { 2703ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 2713ceed64fSopenharmony_ci return true; 2723ceed64fSopenharmony_ci } 2733ceed64fSopenharmony_ci int maxSubValue = std::stoi(strInfo.substr(ZERO_VALUE, ZERO_VALUE + 1)); 2743ceed64fSopenharmony_ci if (strLength == INT_64_LENGTH && maxSubValue < BASE_NUMBER) { 2753ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 2763ceed64fSopenharmony_ci return true; 2773ceed64fSopenharmony_ci } 2783ceed64fSopenharmony_ci // Means 0x7FFFFFFFFFFFFFFF remove the first number:(2^63 - 1 - 9 * 10 ^ 19) 2793ceed64fSopenharmony_ci int64_t subValue = std::stoll(strInfo.substr(ZERO_VALUE + 1, INT_64_LENGTH - 1)); 2803ceed64fSopenharmony_ci if (strLength == INT_64_LENGTH && subValue <= (INT64_MAX - HEAD_BIT_NUM)) { 2813ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 2823ceed64fSopenharmony_ci return true; 2833ceed64fSopenharmony_ci } 2843ceed64fSopenharmony_ci return false; 2853ceed64fSopenharmony_ci } 2863ceed64fSopenharmony_ci if (strLength < INT_64_LENGTH + 1) { // The minimum value: -9223372036854775808 2873ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 2883ceed64fSopenharmony_ci return true; 2893ceed64fSopenharmony_ci } 2903ceed64fSopenharmony_ci if (strLength == INT_64_LENGTH + 1) { 2913ceed64fSopenharmony_ci int minSubValue = std::stoi(strInfo.substr(1, 1)); 2923ceed64fSopenharmony_ci if (minSubValue < BASE_NUMBER) { 2933ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 2943ceed64fSopenharmony_ci return true; 2953ceed64fSopenharmony_ci } 2963ceed64fSopenharmony_ci 2973ceed64fSopenharmony_ci // Means 0x8000000000000000 remove the first number:-(2^63 - 9 * 10 ^ 19) 2983ceed64fSopenharmony_ci int64_t subValue = std::stoll(strInfo.substr(ZERO_VALUE + 2, INT_64_LENGTH - 1)); 2993ceed64fSopenharmony_ci if (subValue <= (INT64_MAX - HEAD_BIT_NUM + 1)) { 3003ceed64fSopenharmony_ci int64Value = std::stoll(strInfo); 3013ceed64fSopenharmony_ci return true; 3023ceed64fSopenharmony_ci } 3033ceed64fSopenharmony_ci } 3043ceed64fSopenharmony_ci } 3053ceed64fSopenharmony_ci HILOG_DEBUG("regex_match failed"); 3063ceed64fSopenharmony_ci return false; 3073ceed64fSopenharmony_ci} 3083ceed64fSopenharmony_ci} // namespace AppExecFwk 3093ceed64fSopenharmony_ci} // namespace OHOS