xref: /openbmc/phosphor-net-ipmid/sessions_manager.hpp (revision ecc8efad10bc2101a434a0c1fbd253eeaa1a3a99)
1 #pragma once
2 
3 #include "session.hpp"
4 
5 #include <boost/asio/steady_timer.hpp>
6 #include <chrono>
7 #include <ipmid/api.hpp>
8 #include <ipmid/sessiondef.hpp>
9 #include <map>
10 #include <memory>
11 #include <mutex>
12 #include <string>
13 
14 namespace session
15 {
16 
17 enum class RetrieveOption
18 {
19     BMC_SESSION_ID,
20     RC_SESSION_ID,
21 };
22 
23 static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask;
24 
25 /**
26  * @class Manager
27  *
28  * Manager class acts a manager for the IPMI sessions and provides interfaces
29  * to start a session, stop a session and get reference to the session objects.
30  *
31  */
32 
33 class Manager
34 {
35   public:
36     // BMC Session ID is the key for the map
37     using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;
38 
39     Manager() = delete;
40     explicit Manager(std::shared_ptr<boost::asio::io_context>& io) :
41         io(io), timer(*io){};
42     ~Manager() = default;
43     Manager(const Manager&) = delete;
44     Manager& operator=(const Manager&) = delete;
45     Manager(Manager&&) = default;
46     Manager& operator=(Manager&&) = default;
47 
48     /**
49      * @brief Start an IPMI session
50      *
51      * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned
52      *            in the Open SessionRequest Command
53      * @param[in] priv - Privilege level requested
54      * @param[in] authAlgo - Authentication Algorithm
55      * @param[in] intAlgo - Integrity Algorithm
56      * @param[in] cryptAlgo - Confidentiality Algorithm
57      *
58      * @return session handle on success and nullptr on failure
59      *
60      */
61     std::shared_ptr<Session>
62         startSession(SessionID remoteConsoleSessID, Privilege priv,
63                      cipher::rakp_auth::Algorithms authAlgo,
64                      cipher::integrity::Algorithms intAlgo,
65                      cipher::crypt::Algorithms cryptAlgo);
66 
67     /**
68      * @brief Stop IPMI Session
69      *
70      * @param[in] bmcSessionID - BMC Session ID
71      *
72      * @return true on success and failure if session ID is invalid
73      *
74      */
75     bool stopSession(SessionID bmcSessionID);
76 
77     /**
78      * @brief Get Session Handle
79      *
80      * @param[in] sessionID - Session ID
81      * @param[in] option - Select between BMC Session ID and Remote Console
82      *            Session ID, Default option is BMC Session ID
83      *
84      * @return session handle on success and nullptr on failure
85      *
86      */
87     std::shared_ptr<Session>
88         getSession(SessionID sessionID,
89                    RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
90     uint8_t getActiveSessionCount() const;
91     uint8_t getSessionHandle(SessionID bmcSessionID) const;
92     uint8_t storeSessionHandle(SessionID bmcSessionID);
93     uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const;
94 
95     void managerInit(const std::string& channel);
96 
97     uint8_t getNetworkInstance(void);
98 
99     /**
100      * @brief Clean Session Stale Entries
101      *
102      *  Schedules cleaning the inactive sessions entries from the Session Map
103      */
104     void scheduleSessionCleaner(const std::chrono::microseconds& grace);
105 
106   private:
107     /**
108      * @brief reclaim system resources by limiting idle sessions
109      *
110      * Limits on active, authenticated sessions are calculated independently
111      * from in-setup sessions, which are not required to be authenticated. This
112      * will prevent would-be DoS attacks by calling a bunch of Open Session
113      * requests to fill up all available sessions. Too many active sessions will
114      * trigger a shorter timeout, but is unaffected by setup session counts.
115      *
116      * For active sessions, grace time is inversely proportional to (the number
117      * of active sessions beyond max sessions per channel)^3
118      *
119      * For sessions in setup, grace time is inversely proportional to (the
120      * number of total sessions beyond max sessions per channel)^3, with a max
121      * of 3 seconds
122      */
123     void cleanStaleEntries();
124 
125     std::shared_ptr<boost::asio::io_context> io;
126     boost::asio::steady_timer timer;
127 
128     std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0};
129 
130     /**
131      * @brief Session Manager keeps the session objects as a sorted
132      *        associative container with Session ID as the unique key
133      */
134     SessionMap sessionsMap;
135     std::unique_ptr<sdbusplus::server::manager::manager> objManager = nullptr;
136     std::string chName{}; // Channel Name
137     uint8_t ipmiNetworkInstance;
138     void setNetworkInstance(void);
139 };
140 
141 } // namespace session
142