13e61aa0dSTom Joseph #pragma once 23e61aa0dSTom Joseph 32085ae07SVernon Mauery #include "main.hpp" 49e801a2bSVernon Mauery #include "session.hpp" 59e801a2bSVernon Mauery 6ecc8efadSVernon Mauery #include <boost/asio/steady_timer.hpp> 7f8a34fc4SSuryakanth Sekar #include <ipmid/api.hpp> 8f8a34fc4SSuryakanth Sekar #include <ipmid/sessiondef.hpp> 9bc8958feSGeorge Liu 10bc8958feSGeorge Liu #include <chrono> 113e61aa0dSTom Joseph #include <map> 123e61aa0dSTom Joseph #include <memory> 133e61aa0dSTom Joseph #include <mutex> 147408e76aSAndrew Geissler #include <string> 153e61aa0dSTom Joseph 163e61aa0dSTom Joseph namespace session 173e61aa0dSTom Joseph { 183e61aa0dSTom Joseph 193e61aa0dSTom Joseph enum class RetrieveOption 203e61aa0dSTom Joseph { 213e61aa0dSTom Joseph BMC_SESSION_ID, 223e61aa0dSTom Joseph RC_SESSION_ID, 233e61aa0dSTom Joseph }; 243e61aa0dSTom Joseph 25ecc8efadSVernon Mauery static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask; 26ecc8efadSVernon Mauery 273563f8feSTom Joseph /** 283e61aa0dSTom Joseph * @class Manager 293e61aa0dSTom Joseph * 303e61aa0dSTom Joseph * Manager class acts a manager for the IPMI sessions and provides interfaces 313e61aa0dSTom Joseph * to start a session, stop a session and get reference to the session objects. 323e61aa0dSTom Joseph * 333e61aa0dSTom Joseph */ 343e61aa0dSTom Joseph 353e61aa0dSTom Joseph class Manager 363e61aa0dSTom Joseph { 372085ae07SVernon Mauery private: 382085ae07SVernon Mauery struct Private 39bc8958feSGeorge Liu {}; 402085ae07SVernon Mauery 413e61aa0dSTom Joseph public: 423e61aa0dSTom Joseph // BMC Session ID is the key for the map 433e61aa0dSTom Joseph using SessionMap = std::map<SessionID, std::shared_ptr<Session>>; 443e61aa0dSTom Joseph 45ecc8efadSVernon Mauery Manager() = delete; Manager(std::shared_ptr<boost::asio::io_context> & io,const Private &)462085ae07SVernon Mauery Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) : 47ecc8efadSVernon Mauery io(io), timer(*io) {}; 483e61aa0dSTom Joseph ~Manager() = default; 493e61aa0dSTom Joseph Manager(const Manager&) = delete; 503e61aa0dSTom Joseph Manager& operator=(const Manager&) = delete; 513e61aa0dSTom Joseph Manager(Manager&&) = default; 523e61aa0dSTom Joseph Manager& operator=(Manager&&) = default; 533e61aa0dSTom Joseph 543563f8feSTom Joseph /** 552085ae07SVernon Mauery * @brief Get a reference to the singleton Manager 562085ae07SVernon Mauery * 572085ae07SVernon Mauery * @return Manager reference 582085ae07SVernon Mauery */ get()592085ae07SVernon Mauery static Manager& get() 602085ae07SVernon Mauery { 612085ae07SVernon Mauery static std::shared_ptr<Manager> ptr = nullptr; 622085ae07SVernon Mauery if (!ptr) 632085ae07SVernon Mauery { 642085ae07SVernon Mauery std::shared_ptr<boost::asio::io_context> io = getIo(); 652085ae07SVernon Mauery ptr = std::make_shared<Manager>(io, Private()); 662085ae07SVernon Mauery if (!ptr) 672085ae07SVernon Mauery { 682085ae07SVernon Mauery throw std::runtime_error("failed to create session manager"); 692085ae07SVernon Mauery } 702085ae07SVernon Mauery } 712085ae07SVernon Mauery return *ptr; 722085ae07SVernon Mauery } 732085ae07SVernon Mauery 742085ae07SVernon Mauery /** 753e61aa0dSTom Joseph * @brief Start an IPMI session 763e61aa0dSTom Joseph * 773e61aa0dSTom Joseph * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned 783e61aa0dSTom Joseph * in the Open SessionRequest Command 793e61aa0dSTom Joseph * @param[in] priv - Privilege level requested 803e61aa0dSTom Joseph * @param[in] authAlgo - Authentication Algorithm 81dd1be1a2STom Joseph * @param[in] intAlgo - Integrity Algorithm 82ba11f792STom Joseph * @param[in] cryptAlgo - Confidentiality Algorithm 833e61aa0dSTom Joseph * 843e61aa0dSTom Joseph * @return session handle on success and nullptr on failure 853e61aa0dSTom Joseph * 863e61aa0dSTom Joseph */ 87*33503e2aSPatrick Williams std::shared_ptr<Session> startSession( 88*33503e2aSPatrick Williams SessionID remoteConsoleSessID, Privilege priv, 899e801a2bSVernon Mauery cipher::rakp_auth::Algorithms authAlgo, 90ba11f792STom Joseph cipher::integrity::Algorithms intAlgo, 91ba11f792STom Joseph cipher::crypt::Algorithms cryptAlgo); 923e61aa0dSTom Joseph 933563f8feSTom Joseph /** 943e61aa0dSTom Joseph * @brief Stop IPMI Session 953e61aa0dSTom Joseph * 963e61aa0dSTom Joseph * @param[in] bmcSessionID - BMC Session ID 973e61aa0dSTom Joseph * 989662c3a9STom Joseph * @return true on success and failure if session ID is invalid 999662c3a9STom Joseph * 1003e61aa0dSTom Joseph */ 1019662c3a9STom Joseph bool stopSession(SessionID bmcSessionID); 1023e61aa0dSTom Joseph 1033563f8feSTom Joseph /** 1043e61aa0dSTom Joseph * @brief Get Session Handle 1053e61aa0dSTom Joseph * 1063e61aa0dSTom Joseph * @param[in] sessionID - Session ID 1073e61aa0dSTom Joseph * @param[in] option - Select between BMC Session ID and Remote Console 1083e61aa0dSTom Joseph * Session ID, Default option is BMC Session ID 1093e61aa0dSTom Joseph * 1103e61aa0dSTom Joseph * @return session handle on success and nullptr on failure 1113e61aa0dSTom Joseph * 1123e61aa0dSTom Joseph */ 113*33503e2aSPatrick Williams std::shared_ptr<Session> getSession( 114*33503e2aSPatrick Williams SessionID sessionID, 1153e61aa0dSTom Joseph RetrieveOption option = RetrieveOption::BMC_SESSION_ID); 116f8a34fc4SSuryakanth Sekar uint8_t getActiveSessionCount() const; 117f8a34fc4SSuryakanth Sekar uint8_t getSessionHandle(SessionID bmcSessionID) const; 118f8a34fc4SSuryakanth Sekar uint8_t storeSessionHandle(SessionID bmcSessionID); 119f8a34fc4SSuryakanth Sekar uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const; 120f8a34fc4SSuryakanth Sekar 121f8a34fc4SSuryakanth Sekar void managerInit(const std::string& channel); 122f8a34fc4SSuryakanth Sekar 123f8a34fc4SSuryakanth Sekar uint8_t getNetworkInstance(void); 1243e61aa0dSTom Joseph 125ecc8efadSVernon Mauery /** 126ecc8efadSVernon Mauery * @brief Clean Session Stale Entries 127ecc8efadSVernon Mauery * 128ecc8efadSVernon Mauery * Schedules cleaning the inactive sessions entries from the Session Map 129ecc8efadSVernon Mauery */ 130ecc8efadSVernon Mauery void scheduleSessionCleaner(const std::chrono::microseconds& grace); 131ecc8efadSVernon Mauery 1323e61aa0dSTom Joseph private: 133ecc8efadSVernon Mauery /** 134ecc8efadSVernon Mauery * @brief reclaim system resources by limiting idle sessions 135ecc8efadSVernon Mauery * 136ecc8efadSVernon Mauery * Limits on active, authenticated sessions are calculated independently 137ecc8efadSVernon Mauery * from in-setup sessions, which are not required to be authenticated. This 138ecc8efadSVernon Mauery * will prevent would-be DoS attacks by calling a bunch of Open Session 139ecc8efadSVernon Mauery * requests to fill up all available sessions. Too many active sessions will 140ecc8efadSVernon Mauery * trigger a shorter timeout, but is unaffected by setup session counts. 141ecc8efadSVernon Mauery * 142ecc8efadSVernon Mauery * For active sessions, grace time is inversely proportional to (the number 143ecc8efadSVernon Mauery * of active sessions beyond max sessions per channel)^3 144ecc8efadSVernon Mauery * 145ecc8efadSVernon Mauery * For sessions in setup, grace time is inversely proportional to (the 146ecc8efadSVernon Mauery * number of total sessions beyond max sessions per channel)^3, with a max 147ecc8efadSVernon Mauery * of 3 seconds 148ecc8efadSVernon Mauery */ 149ecc8efadSVernon Mauery void cleanStaleEntries(); 150ecc8efadSVernon Mauery 151ecc8efadSVernon Mauery std::shared_ptr<boost::asio::io_context> io; 152ecc8efadSVernon Mauery boost::asio::steady_timer timer; 153ecc8efadSVernon Mauery 154ecc8efadSVernon Mauery std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0}; 155f8a34fc4SSuryakanth Sekar 1563563f8feSTom Joseph /** 1573e61aa0dSTom Joseph * @brief Session Manager keeps the session objects as a sorted 1583e61aa0dSTom Joseph * associative container with Session ID as the unique key 1593e61aa0dSTom Joseph */ 1603e61aa0dSTom Joseph SessionMap sessionsMap; 1610a59062cSPatrick Williams std::unique_ptr<sdbusplus::server::manager_t> objManager = nullptr; 162f8a34fc4SSuryakanth Sekar std::string chName{}; // Channel Name 163c1c2e0a1SWilly Tu uint8_t ipmiNetworkInstance = 0; 164f8a34fc4SSuryakanth Sekar void setNetworkInstance(void); 1653e61aa0dSTom Joseph }; 1663e61aa0dSTom Joseph 1673e61aa0dSTom Joseph } // namespace session 168