From f8553661ebaca7c0dad2211eedaaaf8a30c3b0fc Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Fri, 31 Jul 2026 14:36:18 +0300 Subject: [PATCH 1/3] app: thread HeapAllocator through core module Init calls Aos core library APIs (crypto provider, PKCS11 manager, cert loader, cert handler, space allocators, image manager, launcher, monitoring, network manager, node config handler, etc.) now take an allocator as part of their redesigned Init signatures, so every app entry point (cm, iam, mp, sm) gains a HeapAllocator member and passes it through. Also refactors the IAM app to move its Init/Start/Stop logic out of App into a new AosCore class, matching the pattern already used by cm and sm, which keeps App as a thin Poco::Util::ServerApplication wrapper around AosCore. Updates the affected unit tests to construct a HeapAllocator and pass it to the library calls whose signatures changed, and fixes FSPlatform::GetDirSize to call the renamed common::utils::CalculateSize helper instead of the removed aos::fs::CalculateSize. Signed-off-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Mykola Kobets Reviewed-by: Mykola Solianko --- src/cm/app/aoscore.cpp | 38 ++- src/cm/app/aoscore.hpp | 6 +- src/cm/communication/tests/communication.cpp | 24 +- src/common/utils/fsplatform.cpp | 2 +- src/iam/app/CMakeLists.txt | 2 +- src/iam/app/aoscore.cpp | 293 ++++++++++++++++++ src/iam/app/aoscore.hpp | 107 +++++++ src/iam/app/app.cpp | 253 +-------------- src/iam/app/app.hpp | 68 ++-- src/iam/iamserver/tests/iamserver.cpp | 20 +- .../visidentifier/tests/pocowsclient.cpp | 5 +- .../visidentifier/tests/visidentifier.cpp | 5 +- src/mp/app/app.cpp | 7 +- src/mp/app/app.hpp | 3 + src/sm/app/aoscore.cpp | 27 +- src/sm/app/aoscore.hpp | 3 + 16 files changed, 528 insertions(+), 335 deletions(-) create mode 100644 src/iam/app/aoscore.cpp create mode 100644 src/iam/app/aoscore.hpp diff --git a/src/cm/app/aoscore.cpp b/src/cm/app/aoscore.cpp index 1631a1561..0e09492ea 100644 --- a/src/cm/app/aoscore.cpp +++ b/src/cm/app/aoscore.cpp @@ -33,23 +33,28 @@ void AosCore::Init(const std::string& configFile) // Initialize crypto provider - err = mCryptoProvider.Init(); + err = mCryptoProvider.Init(mAllocator); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto provider"); + // Initialize PKCS11 manager + + err = mPKCS11Manager.Init(mAllocator); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize PKCS11 manager"); + // Initialize cert loader - err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager); + err = mCertLoader.Init(mAllocator, mCryptoProvider, mPKCS11Manager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert loader"); // Initialize crypto helper - err = mCryptoHelper.Init( - mIAMClient, mCryptoProvider, mCertLoader, mConfig.mServiceDiscoveryURL.c_str(), mConfig.mCACert.c_str()); + err = mCryptoHelper.Init(mAllocator, mIAMClient, mCryptoProvider, mCertLoader, mConfig.mServiceDiscoveryURL.c_str(), + mConfig.mCACert.c_str()); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto helper"); // Initialize file info provider - err = mFileInfoProvider.Init(mCryptoProvider); + err = mFileInfoProvider.Init(mAllocator, mCryptoProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize file info provider"); // Initialize TLS credentials @@ -72,13 +77,13 @@ void AosCore::Init(const std::string& configFile) InitDatabase(); InitStorageState(); - err = mAlerts.Init(mConfig.mAlerts, mCommunication, mCommunication); + err = mAlerts.Init(mAllocator, mConfig.mAlerts, mCommunication, mCommunication); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize alerts"); - err = mDownloadSpaceAllocator.Init(mConfig.mImageManager.mInstallPath, mPlatformFS, 0, &mImageManager); + err = mDownloadSpaceAllocator.Init(mAllocator, mConfig.mImageManager.mInstallPath, mPlatformFS, 0, &mImageManager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize download space allocator"); - err = mInstallSpaceAllocator.Init(mConfig.mImageManager.mInstallPath, mPlatformFS, 0, &mImageManager); + err = mInstallSpaceAllocator.Init(mAllocator, mConfig.mImageManager.mInstallPath, mPlatformFS, 0, &mImageManager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize install space allocator"); err = mDownloader.Init(&mAlerts); @@ -87,26 +92,27 @@ void AosCore::Init(const std::string& configFile) err = mFileServer.Init(mConfig.mFileServerURL, mConfig.mImageManager.mInstallPath.CStr()); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize file server"); - err = mImageManager.Init(mConfig.mImageManager, mDatabase, mCommunication, mDownloadSpaceAllocator, + err = mImageManager.Init(mAllocator, mConfig.mImageManager, mDatabase, mCommunication, mDownloadSpaceAllocator, mInstallSpaceAllocator, mDownloader, mFileServer, mCryptoHelper, mFileInfoProvider, mOCISpec); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize image manager"); - err = mNodeInfoProvider.Init(mConfig.mNodeInfoProvider, mIAMClient); + err = mNodeInfoProvider.Init(mAllocator, mConfig.mNodeInfoProvider, mIAMClient); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize node info provider"); err = mMonitoring.Init(mConfig.mMonitoring, mCommunication, mCommunication, mLauncher, mNodeInfoProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize monitoring"); - err = mUnitConfig.Init({mConfig.mUnitConfigFile.c_str()}, mNodeInfoProvider, mSMController, mJSONProvider); + err = mUnitConfig.Init( + mAllocator, {mConfig.mUnitConfigFile.c_str()}, mNodeInfoProvider, mSMController, mJSONProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize unit config"); - err = mLauncher.Init(mConfig.mLauncher, mNodeInfoProvider, mSMController, mImageManager, mOCISpec, mUnitConfig, - mStorageState, mSMController, mAlerts, mIAMClient, utils::IsUIDValid, utils::IsGIDValid, mDatabase, + err = mLauncher.Init(mAllocator, mConfig.mLauncher, mNodeInfoProvider, mSMController, mImageManager, mOCISpec, + mUnitConfig, mStorageState, mSMController, mAlerts, mIAMClient, utils::IsUIDValid, utils::IsGIDValid, mDatabase, mCommunication); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize launcher"); - err = mUpdateManager.Init({mConfig.mUnitStatusSendTimeout}, mIAMClient, mIAMClient, mUnitConfig, mNodeInfoProvider, - mImageManager, mLauncher, mCommunication, mCommunication, mDatabase); + err = mUpdateManager.Init(mAllocator, {mConfig.mUnitStatusSendTimeout}, mIAMClient, mIAMClient, mUnitConfig, + mNodeInfoProvider, mImageManager, mLauncher, mCommunication, mCommunication, mDatabase); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize update manager"); mDNSServer.Init(mConfig.mDNSStoragePath, mConfig.mDNSPidFile, mConfig.mDNSIP); @@ -275,7 +281,7 @@ void AosCore::InitStorageState() err = config.mStorageDir.Assign(mConfig.mStorageDir.c_str()); AOS_ERROR_CHECK_AND_THROW(err, "can't assign storage dir to storage state config"); - err = mStorageState.Init(config, mDatabase, mCommunication, mPlatformFS, mFSWatcher, mCryptoProvider); + err = mStorageState.Init(mAllocator, config, mDatabase, mCommunication, mPlatformFS, mFSWatcher, mCryptoProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize storage state"); } diff --git a/src/cm/app/aoscore.hpp b/src/cm/app/aoscore.hpp index e416302d2..ec08e341c 100644 --- a/src/cm/app/aoscore.hpp +++ b/src/cm/app/aoscore.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,10 @@ class AosCore { void InitStorageState(); void InitSMController(); - config::Config mConfig = {}; + aos::HeapAllocator mAllocator; + + config::Config mConfig = {}; + aos::crypto::CertLoader mCertLoader; aos::crypto::DefaultCryptoProvider mCryptoProvider; aos::crypto::CryptoHelper mCryptoHelper; diff --git a/src/cm/communication/tests/communication.cpp b/src/cm/communication/tests/communication.cpp index b59f1a106..f5d42011a 100644 --- a/src/cm/communication/tests/communication.cpp +++ b/src/cm/communication/tests/communication.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,11 @@ std::string CreateDiscoveryResponse(const std::vector& connectionIn class CMCommunicationTest : public Test { public: + CMCommunicationTest() + : mCertHandler(mAllocator) + { + } + static void SetUpTestSuite() { Poco::Net::initializeSSL(); } static void TearDownTestSuite() { Poco::Net::uninitializeSSL(); } @@ -149,15 +155,15 @@ class CMCommunicationTest : public Test { return ErrorEnum::eNone; })); - auto err = mCryptoProvider.Init(); + auto err = mCryptoProvider.Init(mAllocator); ASSERT_TRUE(err.IsNone()) << "Failed to initialize crypto provider: " << tests::utils::ErrorToStr(err); - err = mSOFTHSMEnv.Init("", "certhandler-integration-tests", SOFTHSM_BASE_CM_DIR "/softhsm2.conf", + err = mSOFTHSMEnv.Init(mAllocator, "", "certhandler-integration-tests", SOFTHSM_BASE_CM_DIR "/softhsm2.conf", SOFTHSM_BASE_CM_DIR "/tokens", SOFTHSM2_LIB); ASSERT_TRUE(err.IsNone()) << "Failed to initialize SOFTHSM environment: " << tests::utils::ErrorToStr(err); - err = mCertLoader.Init(mCryptoProvider, mSOFTHSMEnv.GetManager()); + err = mCertLoader.Init(mAllocator, mCryptoProvider, mSOFTHSMEnv.GetManager()); ASSERT_TRUE(err.IsNone()) << "Failed to initialize certificate loader: " << tests::utils::ErrorToStr(err); RegisterPKCS11Module(cCertificate); @@ -178,8 +184,8 @@ class CMCommunicationTest : public Test { auto [certPEM, err2] = common::utils::LoadPEMCertificates(certInfo.mCertURL, mCertLoader, mCryptoProvider); EXPECT_EQ(err2, ErrorEnum::eNone); - err = mCryptoHelper.Init(mCertProviderStub, mCryptoProvider, mCertLoader, mConfig.mServiceDiscoveryURL.c_str(), - mConfig.mCACert.c_str()); + err = mCryptoHelper.Init(mAllocator, mCertProviderStub, mCryptoProvider, mCertLoader, + mConfig.mServiceDiscoveryURL.c_str(), mConfig.mCACert.c_str()); ASSERT_TRUE(err.IsNone()) << "Failed to initialize crypto helper: " << tests::utils::ErrorToStr(err); StartHTTPServer(); @@ -273,9 +279,11 @@ class CMCommunicationTest : public Test { auto& pkcs11Module = mPKCS11Modules.Back(); auto& certModule = mCertModules.Back(); ASSERT_TRUE( - pkcs11Module.Init(name, GetPKCS11ModuleConfig(), mSOFTHSMEnv.GetManager(), mCryptoProvider).IsNone()); + pkcs11Module.Init(mAllocator, name, GetPKCS11ModuleConfig(), mSOFTHSMEnv.GetManager(), mCryptoProvider) + .IsNone()); ASSERT_TRUE( - certModule.Init(name, GetCertModuleConfig(keyType), mCryptoProvider, pkcs11Module, mStorage).IsNone()); + certModule.Init(mAllocator, name, GetCertModuleConfig(keyType), mCryptoProvider, pkcs11Module, mStorage) + .IsNone()); ASSERT_TRUE(mCertHandler.RegisterModule(certModule).IsNone()); } @@ -320,6 +328,8 @@ class CMCommunicationTest : public Test { static constexpr auto cServerCert = CERTIFICATES_CM_DIR "/server_int.cer"; static constexpr auto cCA = CERTIFICATES_CM_DIR "/ca.cer"; + HeapAllocator mAllocator; + MessageQueue mDiscoveryReceivedMessages; MessageQueue mDiscoverySendMessages; diff --git a/src/common/utils/fsplatform.cpp b/src/common/utils/fsplatform.cpp index 8f7f0c71f..e2169113b 100644 --- a/src/common/utils/fsplatform.cpp +++ b/src/common/utils/fsplatform.cpp @@ -42,7 +42,7 @@ RetWithError FSPlatform::GetTotalSize(const String& dir) const RetWithError FSPlatform::GetDirSize(const String& dir) const { - return fs::CalculateSize(dir); + return common::utils::CalculateSize(dir.CStr()); } RetWithError FSPlatform::GetAvailableSize(const String& dir) const diff --git a/src/iam/app/CMakeLists.txt b/src/iam/app/CMakeLists.txt index 0120641e2..307a81da9 100644 --- a/src/iam/app/CMakeLists.txt +++ b/src/iam/app/CMakeLists.txt @@ -10,7 +10,7 @@ set(TARGET_NAME app) # Sources # ###################################################################################################################### -set(SOURCES app.cpp main.cpp) +set(SOURCES aoscore.cpp app.cpp main.cpp) # ###################################################################################################################### # Libraries diff --git a/src/iam/app/aoscore.cpp b/src/iam/app/aoscore.cpp new file mode 100644 index 000000000..fdd06097d --- /dev/null +++ b/src/iam/app/aoscore.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2026 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "aoscore.hpp" + +namespace aos::iam::app { + +namespace { + +/*********************************************************************************************************************** + * Static + **********************************************************************************************************************/ + +Error ConvertCertModuleConfig(const config::ModuleConfig& config, certhandler::ModuleConfig& aosConfig) +{ + if (config.mAlgorithm == "ecc") { + aosConfig.mKeyType = crypto::KeyTypeEnum::eECDSA; + } else if (config.mAlgorithm == "rsa") { + aosConfig.mKeyType = crypto::KeyTypeEnum::eRSA; + } else { + auto err = aosConfig.mKeyType.FromString(config.mAlgorithm.c_str()); + if (!err.IsNone()) { + return err; + } + } + + aosConfig.mMaxCertificates = config.mMaxItems; + aosConfig.mSkipValidation = config.mSkipValidation; + aosConfig.mIsSelfSigned = config.mIsSelfSigned; + + for (auto const& keyUsageStr : config.mExtendedKeyUsage) { + certhandler::ExtendedKeyUsage keyUsage; + + auto err = keyUsage.FromString(keyUsageStr.c_str()); + if (!err.IsNone()) { + return err; + } + + err = aosConfig.mExtendedKeyUsage.PushBack(keyUsage); + if (!err.IsNone()) { + return err; + } + } + + for (auto const& nameStr : config.mAlternativeNames) { + auto err = aosConfig.mAlternativeNames.EmplaceBack(nameStr.c_str()); + if (!err.IsNone()) { + return err; + } + } + + return ErrorEnum::eNone; +} + +Error ConvertPKCS11ModuleParams(const config::PKCS11ModuleParams& params, certhandler::PKCS11ModuleConfig& aosParams) +{ + aosParams.mLibrary = params.mLibrary.c_str(); + + if (params.mSlotID.has_value()) { + aosParams.mSlotID.EmplaceValue(params.mSlotID.value()); + } + + if (params.mSlotIndex.has_value()) { + aosParams.mSlotIndex.EmplaceValue(params.mSlotIndex.value()); + } + + aosParams.mTokenLabel = params.mTokenLabel.c_str(); + aosParams.mUserPINPath = params.mUserPINPath.c_str(); + aosParams.mModulePathInURL = params.mModulePathInURL; + aosParams.mUID = params.mUID; + aosParams.mGID = params.mGID; + + return ErrorEnum::eNone; +} + +} // namespace + +/*********************************************************************************************************************** + * Public + **********************************************************************************************************************/ + +AosCore::AosCore() + : mCertHandler(mAllocator) +{ +} + +void AosCore::Init(const std::string& configFile, bool provisioning) +{ + mProvisioning = provisioning; + + auto err = mLogger.Init(); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize logger"); + + LOG_INF() << "Init IAM" << Log::Field("version", AOS_CORE_CPP_VERSION); + LOG_DBG() << "Aos core size" << Log::Field("size", sizeof(AosCore)); + + // Initialize Aos modules + + auto config = config::ParseConfig(configFile.empty() ? cDefaultConfigFile : configFile); + AOS_ERROR_CHECK_AND_THROW(config.mError, "can't parse config"); + + err = mDatabase.Init(config.mValue.mDatabase); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize database"); + + err = mCurrentNodeHandler.Init(config.mValue.mNodeInfo); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize current node handler"); + + err = InitIdentifierModule(config.mValue.mIdentifier); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize identifier module"); + + err = mCryptoProvider.Init(mAllocator); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto provider"); + + err = mPKCS11Manager.Init(mAllocator); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize PKCS11 manager"); + + err = mCertLoader.Init(mAllocator, mCryptoProvider, mPKCS11Manager); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert loader"); + + err = mTLSCredentials.Init(config.mValue.mIAMClient.mCACert, mCertHandler, mCertLoader, mCryptoProvider); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize TLS credentials"); + + err = InitCertModules(config.mValue); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert modules"); + + if (config.mValue.mEnablePermissionsHandler) { + mPermHandler = std::make_unique(); + + err = mPermHandler->Init(mCryptoProvider); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize permissions handler"); + } + + err = mNodeManager.Init(mAllocator, mDatabase); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize node manager"); + + err = mProvisionManager.Init(mIAMServer, mCertHandler); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize provision manager"); + + err = mIAMServer.Init(config.mValue.mIAMServer, mCertHandler, *mIdentifier, *mPermHandler, mCertLoader, + mCryptoProvider, mCurrentNodeHandler, mNodeManager, mCertHandler, mProvisionManager, mProvisioning); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize IAM server"); + + const auto& clientConfig = config.mValue.mIAMClient; + if (!clientConfig.mMainIAMPublicServerURL.empty() && !clientConfig.mMainIAMProtectedServerURL.empty()) { + mIAMClient = std::make_unique(); + + err = mIAMClient->Init(clientConfig, mIdentifier.get(), mCertHandler, mProvisionManager, mTLSCredentials, + mCurrentNodeHandler, mProvisioning); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize IAM client"); + } +} + +void AosCore::Start() +{ + LOG_INF() << "Start IAM" << Log::Field("provisioning", mProvisioning); + + if (mIdentifier) { + auto err = mIdentifier->Start(); + AOS_ERROR_CHECK_AND_THROW(err, "can't start identifier module"); + + mCleanupManager.AddCleanup([this]() { + if (auto err = mIdentifier->Stop(); !err.IsNone()) { + LOG_ERR() << "Can't stop identifier module: err=" << err; + } + }); + } + + auto err = mIAMServer.Start(); + AOS_ERROR_CHECK_AND_THROW(err, "can't start IAM server"); + + mCleanupManager.AddCleanup([this]() { + if (auto err = mIAMServer.Stop(); !err.IsNone()) { + LOG_ERR() << "Can't stop IAM server: err=" << err; + } + }); + + if (mIAMClient) { + err = mIAMClient->Start(); + AOS_ERROR_CHECK_AND_THROW(err, "can't start IAM client"); + + mCleanupManager.AddCleanup([this]() { + if (auto err = mIAMClient->Stop(); !err.IsNone()) { + LOG_ERR() << "Can't stop IAM client: err=" << err; + } + }); + } +} + +void AosCore::Stop() +{ + LOG_INF() << "Stop IAM"; + + mCleanupManager.ExecuteCleanups(); +} + +void AosCore::SetLogBackend(common::logger::Logger::Backend backend) +{ + mLogger.SetBackend(backend); +} + +void AosCore::SetLogLevel(LogLevel level) +{ + mLogger.SetLogLevel(level); +} + +/*********************************************************************************************************************** + * Private + **********************************************************************************************************************/ + +Error AosCore::InitCertModules(const config::Config& config) +{ + LOG_DBG() << "Init cert modules: " << config.mCertModules.size(); + + for (const auto& moduleConfig : config.mCertModules) { + if (moduleConfig.mPlugin != cPKCS11CertModule) { + return AOS_ERROR_WRAP(ErrorEnum::eInvalidArgument); + } + + if (moduleConfig.mDisabled) { + LOG_WRN() << "Skip disabled cert storage: storage = " << moduleConfig.mID.c_str(); + continue; + } + + auto pkcs11Params = config::ParsePKCS11ModuleParams(moduleConfig.mParams); + if (!pkcs11Params.mError.IsNone()) { + return AOS_ERROR_WRAP(pkcs11Params.mError); + } + + certhandler::ModuleConfig aosConfig {}; + + auto err = ConvertCertModuleConfig(moduleConfig, aosConfig); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + certhandler::PKCS11ModuleConfig aosParams {}; + + err = ConvertPKCS11ModuleParams(pkcs11Params.mValue, aosParams); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + auto pkcs11Module = std::make_unique(); + auto certModule = std::make_unique(); + + err = pkcs11Module->Init(mAllocator, moduleConfig.mID.c_str(), aosParams, mPKCS11Manager, mCryptoProvider); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + err = certModule->Init( + mAllocator, moduleConfig.mID.c_str(), aosConfig, mCryptoProvider, *pkcs11Module, mDatabase); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + LOG_DBG() << "Register cert module: " << certModule->GetCertType(); + + err = mCertHandler.RegisterModule(*certModule); + if (!err.IsNone()) { + return AOS_ERROR_WRAP(err); + } + + mCertModules.emplace_back(std::make_pair(std::move(pkcs11Module), std::move(certModule))); + } + + return ErrorEnum::eNone; +} + +Error AosCore::InitIdentifierModule(const config::IdentifierConfig& config) +{ + mIdentifier = identhandler::InitializeIdentModule(config, mCryptoProvider); + + if (mIdentifier) { + mIdentifier->SubscribeListener(mIAMServer); + } + + return ErrorEnum::eNone; +} + +} // namespace aos::iam::app diff --git a/src/iam/app/aoscore.hpp b/src/iam/app/aoscore.hpp new file mode 100644 index 000000000..5b4763cda --- /dev/null +++ b/src/iam/app/aoscore.hpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2026 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_IAM_APP_AOSCORE_HPP_ +#define AOS_IAM_APP_AOSCORE_HPP_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace aos::iam::app { + +/** + * Aos core instance. + */ +class AosCore { +public: + /** + * Creates a new object instance. + */ + AosCore(); + + /** + * Initializes Aos core. + * + * @param configFile config file path. + * @param provisioning provisioning mode flag. + */ + void Init(const std::string& configFile, bool provisioning); + + /** + * Starts Aos core. + */ + void Start(); + + /** + * Stops Aos core. + */ + void Stop(); + + /** + * Sets log backend. + * + * @param backend log backend. + */ + void SetLogBackend(aos::common::logger::Logger::Backend backend); + + /** + * Sets log level. + * + * @param level log level. + */ + void SetLogLevel(aos::LogLevel level); + +private: + Error InitCertModules(const config::Config& config); + Error InitIdentifierModule(const config::IdentifierConfig& config); + + static constexpr auto cDefaultConfigFile = "aos_iamanager.cfg"; + static constexpr auto cPKCS11CertModule = "pkcs11module"; + + aos::HeapAllocator mAllocator; + + crypto::DefaultCryptoProvider mCryptoProvider; + crypto::CertLoader mCertLoader; + certhandler::CertHandler mCertHandler; + pkcs11::PKCS11Manager mPKCS11Manager; + std::vector, std::unique_ptr>> mCertModules; + database::Database mDatabase; + currentnode::CurrentNodeHandler mCurrentNodeHandler; + nodemanager::NodeManager mNodeManager; + provisionmanager::ProvisionManager mProvisionManager; + iamserver::IAMServer mIAMServer; + common::iamclient::TLSCredentials mTLSCredentials; + common::logger::Logger mLogger; + std::unique_ptr mPermHandler; + std::unique_ptr mIAMClient; + std::unique_ptr mIdentifier; + aos::common::utils::CleanupManager mCleanupManager; + + bool mProvisioning = false; +}; + +} // namespace aos::iam::app + +#endif diff --git a/src/iam/app/app.cpp b/src/iam/app/app.cpp index 62721c8b5..b6ab02cf0 100644 --- a/src/iam/app/app.cpp +++ b/src/iam/app/app.cpp @@ -15,12 +15,9 @@ #include #include -#include #include #include -#include -#include #include "app.hpp" @@ -81,68 +78,6 @@ void RegisterErrorSignals() sigaction(SIGSEGV, &act, nullptr); } -Error ConvertCertModuleConfig(const config::ModuleConfig& config, certhandler::ModuleConfig& aosConfig) -{ - if (config.mAlgorithm == "ecc") { - aosConfig.mKeyType = crypto::KeyTypeEnum::eECDSA; - } else if (config.mAlgorithm == "rsa") { - aosConfig.mKeyType = crypto::KeyTypeEnum::eRSA; - } else { - auto err = aosConfig.mKeyType.FromString(config.mAlgorithm.c_str()); - if (!err.IsNone()) { - return err; - } - } - - aosConfig.mMaxCertificates = config.mMaxItems; - aosConfig.mSkipValidation = config.mSkipValidation; - aosConfig.mIsSelfSigned = config.mIsSelfSigned; - - for (auto const& keyUsageStr : config.mExtendedKeyUsage) { - certhandler::ExtendedKeyUsage keyUsage; - - auto err = keyUsage.FromString(keyUsageStr.c_str()); - if (!err.IsNone()) { - return err; - } - - err = aosConfig.mExtendedKeyUsage.PushBack(keyUsage); - if (!err.IsNone()) { - return err; - } - } - - for (auto const& nameStr : config.mAlternativeNames) { - auto err = aosConfig.mAlternativeNames.EmplaceBack(nameStr.c_str()); - if (!err.IsNone()) { - return err; - } - } - - return ErrorEnum::eNone; -} - -Error ConvertPKCS11ModuleParams(const config::PKCS11ModuleParams& params, certhandler::PKCS11ModuleConfig& aosParams) -{ - aosParams.mLibrary = params.mLibrary.c_str(); - - if (params.mSlotID.has_value()) { - aosParams.mSlotID.EmplaceValue(params.mSlotID.value()); - } - - if (params.mSlotIndex.has_value()) { - aosParams.mSlotIndex.EmplaceValue(params.mSlotIndex.value()); - } - - aosParams.mTokenLabel = params.mTokenLabel.c_str(); - aosParams.mUserPINPath = params.mUserPINPath.c_str(); - aosParams.mModulePathInURL = params.mModulePathInURL; - aosParams.mUID = params.mUID; - aosParams.mGID = params.mGID; - - return ErrorEnum::eNone; -} - } // namespace /*********************************************************************************************************************** @@ -162,8 +97,13 @@ void App::initialize(Application& self) Application::initialize(self); - Init(); - Start(); + mAosCore = std::make_unique(); + + mAosCore->Init(mConfigFile, mProvisioning); + + mInitialized = true; + + mAosCore->Start(); // Notify systemd @@ -175,9 +115,13 @@ void App::initialize(Application& self) void App::uninitialize() { - Stop(); - Application::uninitialize(); + + if (!mInitialized) { + return; + } + + mAosCore->Stop(); } void App::reinitialize(Application& self) @@ -222,107 +166,6 @@ void App::defineOptions(Poco::Util::OptionSet& options) * Private **********************************************************************************************************************/ -void App::Init() -{ - LOG_INF() << "Init IAM" << Log::Field("version", AOS_CORE_CPP_VERSION); - LOG_DBG() << "Aos core size" << Log::Field("size", sizeof(App)); - - // Initialize Aos modules - - auto config = config::ParseConfig(mConfigFile.empty() ? cDefaultConfigFile : mConfigFile); - AOS_ERROR_CHECK_AND_THROW(config.mError, "can't parse config"); - - auto err = mDatabase.Init(config.mValue.mDatabase); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize database"); - - err = mCurrentNodeHandler.Init(config.mValue.mNodeInfo); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize current node handler"); - - err = InitIdentifierModule(config.mValue.mIdentifier); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize identifier module"); - - err = mCryptoProvider.Init(); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto provider"); - - err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert loader"); - - err = mTLSCredentials.Init(config.mValue.mIAMClient.mCACert, mCertHandler, mCertLoader, mCryptoProvider); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize TLS credentials"); - - err = InitCertModules(config.mValue); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert modules"); - - if (config.mValue.mEnablePermissionsHandler) { - mPermHandler = std::make_unique(); - - err = mPermHandler->Init(mCryptoProvider); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize permissions handler"); - } - - err = mNodeManager.Init(mDatabase); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize node manager"); - - err = mProvisionManager.Init(mIAMServer, mCertHandler); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize provision manager"); - - err = mIAMServer.Init(config.mValue.mIAMServer, mCertHandler, *mIdentifier, *mPermHandler, mCertLoader, - mCryptoProvider, mCurrentNodeHandler, mNodeManager, mCertHandler, mProvisionManager, mProvisioning); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize IAM server"); - - const auto& clientConfig = config.mValue.mIAMClient; - if (!clientConfig.mMainIAMPublicServerURL.empty() && !clientConfig.mMainIAMProtectedServerURL.empty()) { - mIAMClient = std::make_unique(); - - err = mIAMClient->Init(clientConfig, mIdentifier.get(), mCertHandler, mProvisionManager, mTLSCredentials, - mCurrentNodeHandler, mProvisioning); - AOS_ERROR_CHECK_AND_THROW(err, "can't initialize IAM client"); - } -} - -void App::Start() -{ - LOG_INF() << "Start IAM" << Log::Field("provisioning", mProvisioning); - - if (mIdentifier) { - auto err = mIdentifier->Start(); - AOS_ERROR_CHECK_AND_THROW(err, "can't start identifier module"); - - mCleanupManager.AddCleanup([this]() { - if (auto err = mIdentifier->Stop(); !err.IsNone()) { - LOG_ERR() << "Can't stop identifier module: err=" << err; - } - }); - } - - auto err = mIAMServer.Start(); - AOS_ERROR_CHECK_AND_THROW(err, "can't start IAM server"); - - mCleanupManager.AddCleanup([this]() { - if (auto err = mIAMServer.Stop(); !err.IsNone()) { - LOG_ERR() << "Can't stop IAM server: err=" << err; - } - }); - - if (mIAMClient) { - err = mIAMClient->Start(); - AOS_ERROR_CHECK_AND_THROW(err, "can't start IAM client"); - - mCleanupManager.AddCleanup([this]() { - if (auto err = mIAMClient->Stop(); !err.IsNone()) { - LOG_ERR() << "Can't stop IAM client: err=" << err; - } - }); - } -} - -void App::Stop() -{ - LOG_INF() << "Stop IAM"; - - mCleanupManager.ExecuteCleanups(); -} - void App::HandleHelp(const std::string& name, const std::string& value) { (void)name; @@ -390,74 +233,4 @@ void App::HandleConfigFile(const std::string& name, const std::string& value) mConfigFile = value; } -Error App::InitCertModules(const config::Config& config) -{ - LOG_DBG() << "Init cert modules: " << config.mCertModules.size(); - - for (const auto& moduleConfig : config.mCertModules) { - if (moduleConfig.mPlugin != cPKCS11CertModule) { - return AOS_ERROR_WRAP(ErrorEnum::eInvalidArgument); - } - - if (moduleConfig.mDisabled) { - LOG_WRN() << "Skip disabled cert storage: storage = " << moduleConfig.mID.c_str(); - continue; - } - - auto pkcs11Params = config::ParsePKCS11ModuleParams(moduleConfig.mParams); - if (!pkcs11Params.mError.IsNone()) { - return AOS_ERROR_WRAP(pkcs11Params.mError); - } - - certhandler::ModuleConfig aosConfig {}; - - auto err = ConvertCertModuleConfig(moduleConfig, aosConfig); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - certhandler::PKCS11ModuleConfig aosParams {}; - - err = ConvertPKCS11ModuleParams(pkcs11Params.mValue, aosParams); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - auto pkcs11Module = std::make_unique(); - auto certModule = std::make_unique(); - - err = pkcs11Module->Init(moduleConfig.mID.c_str(), aosParams, mPKCS11Manager, mCryptoProvider); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - err = certModule->Init(moduleConfig.mID.c_str(), aosConfig, mCryptoProvider, *pkcs11Module, mDatabase); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - LOG_DBG() << "Register cert module: " << certModule->GetCertType(); - - err = mCertHandler.RegisterModule(*certModule); - if (!err.IsNone()) { - return AOS_ERROR_WRAP(err); - } - - mCertModules.emplace_back(std::make_pair(std::move(pkcs11Module), std::move(certModule))); - } - - return ErrorEnum::eNone; -} - -Error App::InitIdentifierModule(const config::IdentifierConfig& config) -{ - mIdentifier = identhandler::InitializeIdentModule(config, mCryptoProvider); - - if (mIdentifier) { - mIdentifier->SubscribeListener(mIAMServer); - } - - return ErrorEnum::eNone; -} - } // namespace aos::iam::app diff --git a/src/iam/app/app.hpp b/src/iam/app/app.hpp index 3e72b0cc4..a075f24c8 100644 --- a/src/iam/app/app.hpp +++ b/src/iam/app/app.hpp @@ -10,21 +10,7 @@ #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "aoscore.hpp" namespace aos::iam::app { @@ -32,17 +18,21 @@ namespace aos::iam::app { * Aos IAM application. */ class App : public Poco::Util::ServerApplication { +public: + /** + * Constructor. + */ + App() = default; + protected: - void initialize(Application& self); - void uninitialize(); - void reinitialize(Application& self); - int main(const ArgVec& args); - void defineOptions(Poco::Util::OptionSet& options); + void initialize(Application& self) override; + void uninitialize() override; + void reinitialize(Application& self) override; + int main(const ArgVec& args) override; + void defineOptions(Poco::Util::OptionSet& options) override; private: - static constexpr auto cSDNotifyReady = "READY=1"; - static constexpr auto cDefaultConfigFile = "aos_iamanager.cfg"; - static constexpr auto cPKCS11CertModule = "pkcs11module"; + static constexpr auto cSDNotifyReady = "READY=1"; void HandleHelp(const std::string& name, const std::string& value); void HandleVersion(const std::string& name, const std::string& value); @@ -51,32 +41,12 @@ class App : public Poco::Util::ServerApplication { void HandleLogLevel(const std::string& name, const std::string& value); void HandleConfigFile(const std::string& name, const std::string& value); - void Init(); - void Start(); - void Stop(); - Error InitCertModules(const config::Config& config); - Error InitIdentifierModule(const config::IdentifierConfig& config); - - crypto::DefaultCryptoProvider mCryptoProvider; - crypto::CertLoader mCertLoader; - certhandler::CertHandler mCertHandler; - pkcs11::PKCS11Manager mPKCS11Manager; - std::vector, std::unique_ptr>> mCertModules; - database::Database mDatabase; - currentnode::CurrentNodeHandler mCurrentNodeHandler; - nodemanager::NodeManager mNodeManager; - provisionmanager::ProvisionManager mProvisionManager; - iamserver::IAMServer mIAMServer; - common::iamclient::TLSCredentials mTLSCredentials; - common::logger::Logger mLogger; - std::unique_ptr mPermHandler; - std::unique_ptr mIAMClient; - std::unique_ptr mIdentifier; - aos::common::utils::CleanupManager mCleanupManager; - - bool mStopProcessing = false; - bool mProvisioning = false; - std::string mConfigFile; + std::unique_ptr mAosCore; + common::logger::Logger mLogger; + bool mStopProcessing = false; + bool mInitialized = false; + bool mProvisioning = false; + std::string mConfigFile; }; } // namespace aos::iam::app diff --git a/src/iam/iamserver/tests/iamserver.cpp b/src/iam/iamserver/tests/iamserver.cpp index e42f0f0fb..8f42f3227 100644 --- a/src/iam/iamserver/tests/iamserver.cpp +++ b/src/iam/iamserver/tests/iamserver.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,11 @@ class IAMServerTest : public Test { static constexpr auto cProvisioningModeOn = true; static constexpr auto cProvisioningModeOff = false; + IAMServerTest() + : mCertHandler(mAllocator) + { + } + void RegisterPKCS11Module(const String& name, crypto::KeyType keyType = crypto::KeyTypeEnum::eRSA); void SetUpCertificates(); @@ -71,6 +77,8 @@ class IAMServerTest : public Test { return T::NewStub(channel); } + HeapAllocator mAllocator; + IAMServer mServer; CertInfo mClientInfo; CertInfo mServerInfo; @@ -115,12 +123,12 @@ void IAMServerTest::SetUp() { tests::utils::InitLog(); - ASSERT_TRUE(mCryptoProvider.Init().IsNone()); + ASSERT_TRUE(mCryptoProvider.Init(mAllocator).IsNone()); ASSERT_TRUE(mSOFTHSMEnv - .Init("", "certhandler-integration-tests", SOFTHSM_BASE_IAM_DIR "/softhsm2.conf", + .Init(mAllocator, "", "certhandler-integration-tests", SOFTHSM_BASE_IAM_DIR "/softhsm2.conf", SOFTHSM_BASE_IAM_DIR "/tokens", SOFTHSM2_LIB) .IsNone()); - ASSERT_TRUE(mCertLoader.Init(mCryptoProvider, mSOFTHSMEnv.GetManager()).IsNone()); + ASSERT_TRUE(mCertLoader.Init(mAllocator, mCryptoProvider, mSOFTHSMEnv.GetManager()).IsNone()); RegisterPKCS11Module("client"); ASSERT_TRUE(mCertHandler.SetOwner("client", cPIN).IsNone()); @@ -163,8 +171,10 @@ void IAMServerTest::RegisterPKCS11Module(const String& name, crypto::KeyType key ASSERT_TRUE(mCertModules.EmplaceBack().IsNone()); auto& pkcs11Module = mPKCS11Modules.Back(); auto& certModule = mCertModules.Back(); - ASSERT_TRUE(pkcs11Module.Init(name, GetPKCS11ModuleConfig(), mSOFTHSMEnv.GetManager(), mCryptoProvider).IsNone()); - ASSERT_TRUE(certModule.Init(name, GetCertModuleConfig(keyType), mCryptoProvider, pkcs11Module, mStorage).IsNone()); + ASSERT_TRUE(pkcs11Module.Init(mAllocator, name, GetPKCS11ModuleConfig(), mSOFTHSMEnv.GetManager(), mCryptoProvider) + .IsNone()); + ASSERT_TRUE(certModule.Init(mAllocator, name, GetCertModuleConfig(keyType), mCryptoProvider, pkcs11Module, mStorage) + .IsNone()); ASSERT_TRUE(mCertHandler.RegisterModule(certModule).IsNone()); } diff --git a/src/iam/identhandler/visidentifier/tests/pocowsclient.cpp b/src/iam/identhandler/visidentifier/tests/pocowsclient.cpp index b3e7430ca..b54140d50 100644 --- a/src/iam/identhandler/visidentifier/tests/pocowsclient.cpp +++ b/src/iam/identhandler/visidentifier/tests/pocowsclient.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ class PocoWSClientTests : public Test { void SetUp() override { mCryptoProvider = std::make_unique(); - ASSERT_TRUE(mCryptoProvider->Init().IsNone()) << "Failed to initialize crypto provider"; + ASSERT_TRUE(mCryptoProvider->Init(mAllocator).IsNone()) << "Failed to initialize crypto provider"; ASSERT_NO_THROW(mWsClientPtr = std::make_shared(cConfig, *mCryptoProvider, WSClientItf::MessageHandlerFunc())); @@ -86,6 +87,8 @@ class PocoWSClientTests : public Test { Poco::Net::uninitializeSSL(); } + HeapAllocator mAllocator; + std::unique_ptr mCryptoProvider; std::shared_ptr mWsClientPtr; }; diff --git a/src/iam/identhandler/visidentifier/tests/visidentifier.cpp b/src/iam/identhandler/visidentifier/tests/visidentifier.cpp index 20087ceca..42ac866d7 100644 --- a/src/iam/identhandler/visidentifier/tests/visidentifier.cpp +++ b/src/iam/identhandler/visidentifier/tests/visidentifier.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,8 @@ class VisidentifierTest : public testing::Test { const std::string cTestSubscriptionId {"1234-4321"}; const config::VISIdentifierModuleParams cVISConfig {"vis-service", "ca-path", 1}; + HeapAllocator mAllocator; + WSClientEvent mWSClientEvent; iamclient::SubjectsListenerMock mVISSubjectsListenerMock; std::unique_ptr mCryptoProvider; @@ -78,7 +81,7 @@ class VisidentifierTest : public testing::Test { mVisIdentifier.SubscribeListener(mVISSubjectsListenerMock); mCryptoProvider = std::make_unique(); - ASSERT_TRUE(mCryptoProvider->Init().IsNone()) << "Failed to initialize crypto provider"; + ASSERT_TRUE(mCryptoProvider->Init(mAllocator).IsNone()) << "Failed to initialize crypto provider"; } void ExpectStopSucceeded() diff --git a/src/mp/app/app.cpp b/src/mp/app/app.cpp index 7578eedf5..1cd2f499d 100644 --- a/src/mp/app/app.cpp +++ b/src/mp/app/app.cpp @@ -95,10 +95,13 @@ void App::Init() mCleanupManager.AddCleanup([this]() { curl_global_cleanup(); }); - err = mCryptoProvider.Init(); + err = mCryptoProvider.Init(mAllocator); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto provider"); - err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager); + err = mPKCS11Manager.Init(mAllocator); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize PKCS11 manager"); + + err = mCertLoader.Init(mAllocator, mCryptoProvider, mPKCS11Manager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert loader"); auto retConfig = config::ParseConfig(mConfigFile); diff --git a/src/mp/app/app.hpp b/src/mp/app/app.hpp index 15ed33696..80649dd81 100644 --- a/src/mp/app/app.hpp +++ b/src/mp/app/app.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -67,6 +68,8 @@ class App : public Poco::Util::ServerApplication { void Init(); void Start(); + aos::HeapAllocator mAllocator; + common::logger::Logger mLogger; bool mStopProcessing = false; bool mProvisioning = false; diff --git a/src/sm/app/aoscore.cpp b/src/sm/app/aoscore.cpp index 998059bf0..f26754280 100644 --- a/src/sm/app/aoscore.cpp +++ b/src/sm/app/aoscore.cpp @@ -33,12 +33,17 @@ void AosCore::Init(const std::string& configFile) // Initialize crypto provider - err = mCryptoProvider.Init(); + err = mCryptoProvider.Init(mAllocator); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize crypto provider"); + // Initialize PKCS11 manager + + err = mPKCS11Manager.Init(mAllocator); + AOS_ERROR_CHECK_AND_THROW(err, "can't initialize PKCS11 manager"); + // Initialize cert loader - err = mCertLoader.Init(mCryptoProvider, mPKCS11Manager); + err = mCertLoader.Init(mAllocator, mCryptoProvider, mPKCS11Manager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize cert loader"); // Initialize TLS credentials @@ -91,7 +96,7 @@ void AosCore::Init(const std::string& configFile) err = mTrafficMonitor.Init(mDatabase, mNFTables); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize traffic monitor"); - err = mNetworkManager.Init(mDatabase, mBridgeNetwork, mFirewall, mBandwidth, mDNSName, mTrafficMonitor, + err = mNetworkManager.Init(mAllocator, mDatabase, mBridgeNetwork, mFirewall, mBandwidth, mDNSName, mTrafficMonitor, mNamespaceManager, mNetworkInterfaceManager, mCryptoProvider, mNetworkInterfaceManager, mSMClient, nodeInfo->mNodeID.CStr()); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize network manager"); @@ -114,7 +119,7 @@ void AosCore::Init(const std::string& configFile) // Initialize images space allocator - err = mImagesSpaceAllocator.Init(mConfig.mImageManager.mImagePath, mPlatformFS, 0, &mImageManager); + err = mImagesSpaceAllocator.Init(mAllocator, mConfig.mImageManager.mImagePath, mPlatformFS, 0, &mImageManager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize images space allocator"); // Initialize downloader @@ -124,7 +129,7 @@ void AosCore::Init(const std::string& configFile) // Initialize file info provider - err = mFileInfoProvider.Init(mCryptoProvider); + err = mFileInfoProvider.Init(mAllocator, mCryptoProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize file info provider"); // Initialize image handler @@ -133,25 +138,25 @@ void AosCore::Init(const std::string& configFile) // Initialize image manager - err = mImageManager.Init(mConfig.mImageManager, mSMClient, mImagesSpaceAllocator, mDownloader, mFileInfoProvider, - mOCISpec, mImageHandler, mDatabase); + err = mImageManager.Init(mAllocator, mConfig.mImageManager, mSMClient, mImagesSpaceAllocator, mDownloader, + mFileInfoProvider, mOCISpec, mImageHandler, mDatabase); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize image manager"); // Initialize launcher - err = mLauncher.Init(*runtimes, mImageManager, mSMClient, mDatabase, mOCISpec, mImageManager, mSMClient, + err = mLauncher.Init(mAllocator, *runtimes, mImageManager, mSMClient, mDatabase, mOCISpec, mImageManager, mSMClient, mNetworkManager, mInstanceIDProvider, mResourceManager); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize launcher"); // Initialize node config handler - err = mNodeConfigHandler.Init({mConfig.mNodeConfigFile.c_str()}, mJSONProvider); + err = mNodeConfigHandler.Init(mAllocator, {mConfig.mNodeConfigFile.c_str()}, mJSONProvider); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize node config handler"); // Initialize monitoring - err = mMonitoring.Init( - mConfig.mMonitoring, mNodeConfigHandler, mIAMClient, mSMClient, mSMClient, mNodeMonitoringProvider, &mLauncher); + err = mMonitoring.Init(mAllocator, mConfig.mMonitoring, mNodeConfigHandler, mIAMClient, mSMClient, mSMClient, + mNodeMonitoringProvider, &mLauncher); AOS_ERROR_CHECK_AND_THROW(err, "can't initialize monitoring"); // Initialize logprovider diff --git a/src/sm/app/aoscore.hpp b/src/sm/app/aoscore.hpp index b57f08548..af509dc34 100644 --- a/src/sm/app/aoscore.hpp +++ b/src/sm/app/aoscore.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,8 @@ class AosCore { void SetLogLevel(aos::LogLevel level); private: + aos::HeapAllocator mAllocator; + config::Config mConfig = {}; aos::crypto::CertLoader mCertLoader; From 5b7d366d98f81f1b114d2c5e7996b291b4b8a38a Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 3 Aug 2026 19:05:22 +0300 Subject: [PATCH 2/3] common: utils: fix int overflow in CalculateSize std::accumulate was seeded with an int literal 0, so the running total was accumulated as int and only converted to uintmax_t on return. Directories whose aggregate size exceeds INT_MAX (~2 GiB) overflowed before conversion, which can make SpaceAllocator receive a bogus size and make incorrect allocation or cleanup decisions. Seed the accumulator with uintmax_t{0} instead, and add a regression test that sums two sub-INT_MAX sparse files whose total crosses INT_MAX. Signed-off-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Mykola Kobets Reviewed-by: Mykola Solianko --- src/common/utils/filesystem.cpp | 4 ++-- src/common/utils/tests/filesystem.cpp | 30 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/common/utils/filesystem.cpp b/src/common/utils/filesystem.cpp index 12bc31301..c51ed57d0 100644 --- a/src/common/utils/filesystem.cpp +++ b/src/common/utils/filesystem.cpp @@ -69,8 +69,8 @@ RetWithError CalculateSize(const std::string& path) } if (fs::is_directory(path)) { - return std::accumulate(fs::recursive_directory_iterator(path), fs::recursive_directory_iterator(), 0, - [](uintmax_t total, const auto& entry) { + return std::accumulate(fs::recursive_directory_iterator(path), fs::recursive_directory_iterator(), + uintmax_t {0}, [](uintmax_t total, const auto& entry) { return (fs::is_regular_file(entry)) ? (total + fs::file_size(entry)) : total; }); } diff --git a/src/common/utils/tests/filesystem.cpp b/src/common/utils/tests/filesystem.cpp index 1bc998865..30c5dfd59 100644 --- a/src/common/utils/tests/filesystem.cpp +++ b/src/common/utils/tests/filesystem.cpp @@ -7,6 +7,7 @@ #include #include +#include #include @@ -152,4 +153,33 @@ TEST_F(FSTest, CalculateSize) EXPECT_EQ(size, 4 * buffer.size()); } +TEST_F(FSTest, CalculateSizeOverflow) +{ + // Each file is below INT_MAX, but their sum is above it. This catches accumulators that start + // from an `int` zero and overflow before the result is converted to uintmax_t. + + constexpr uintmax_t cFileSize = 1500000000ULL; + + const auto root = std::filesystem::path(cTestDir) / "size-overflow-test"; + const auto f1 = root / "f1"; + const auto f2 = root / "f2"; + + std::filesystem::create_directories(f1); + std::filesystem::create_directories(f2); + + for (const auto& file : {f1 / "f1.bin", f2 / "f2.bin"}) { + std::ofstream stream(file, std::ios::binary); + ASSERT_TRUE(stream.good()); + + stream.seekp(static_cast(cFileSize) - 1); + stream.put('\0'); + } + + auto [size, err] = CalculateSize(root.string()); + + ASSERT_EQ(err, aos::ErrorEnum::eNone); + EXPECT_EQ(size, 2 * cFileSize); + EXPECT_GT(size, static_cast(std::numeric_limits::max())); +} + } // namespace aos::common::utils From cb449888408c33571136a59c9ec4197dbe28a2df Mon Sep 17 00:00:00 2001 From: Oleksandr Grytsov Date: Mon, 3 Aug 2026 19:26:26 +0300 Subject: [PATCH 3/3] cm: communication: tests: drop stale cppcheck suppressions The templateRecursion suppressions are no longer needed for these two make_unique calls. Signed-off-by: Oleksandr Grytsov Reviewed-by: Mykhailo Lohvynenko Reviewed-by: Mykola Kobets Reviewed-by: Mykola Solianko --- src/cm/communication/tests/communication.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cm/communication/tests/communication.cpp b/src/cm/communication/tests/communication.cpp index f5d42011a..78aa49159 100644 --- a/src/cm/communication/tests/communication.cpp +++ b/src/cm/communication/tests/communication.cpp @@ -441,7 +441,6 @@ TEST_F(CMCommunicationTest, MessageIsRecentIfAckNotReceived) mUUIDProvider.SetUUID("fb6e8461-2601-4f9a-8957-7ab4e52f304c"); - // cppcheck-suppress templateRecursion auto alerts = std::make_unique(); alerts->mCorrelationID = "id"; @@ -473,7 +472,6 @@ TEST_F(CMCommunicationTest, SendAlerts) mUUIDProvider.SetUUID("fb6e8461-2601-4f9a-8957-7ab4e52f304c"); - // cppcheck-suppress templateRecursion auto alerts = std::make_unique(); alerts->mCorrelationID = "id";