xref: /openbmc/phosphor-net-ipmid/sessions_manager.hpp (revision 33503e2a90d5615a11ec2d27961ffdefc3a5cd10)
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