#include "open_session.hpp" #include "comm_module.hpp" #include "endian.hpp" #include "sessions_manager.hpp" #include namespace command { std::vector openSession( const std::vector& inPayload, std::shared_ptr& /* handler */) { auto request = reinterpret_cast(inPayload.data()); if (inPayload.size() != sizeof(*request)) { std::vector errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID}; return errorPayload; } std::vector outPayload(sizeof(OpenSessionResponse)); auto response = reinterpret_cast(outPayload.data()); // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always // returned response->messageTag = request->messageTag; response->remoteConsoleSessionID = request->remoteConsoleSessionID; // Check for valid Authentication Algorithms if (!cipher::rakp_auth::Interface::isAlgorithmSupported( static_cast(request->authAlgo))) { response->status_code = static_cast(RAKP_ReturnCode::INVALID_AUTH_ALGO); return outPayload; } // Check for valid Integrity Algorithms if (!cipher::integrity::Interface::isAlgorithmSupported( static_cast(request->intAlgo))) { response->status_code = static_cast(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO); return outPayload; } session::Privilege priv; // 0h in the requested maximum privilege role field indicates highest level // matching proposed algorithms. The maximum privilege level the session // can take is set to Administrator level. In the RAKP12 command sequence // the session maximum privilege role is set again based on the user's // permitted privilege level. if (!request->maxPrivLevel) { priv = session::Privilege::ADMIN; } else { priv = static_cast(request->maxPrivLevel); } // Check for valid Confidentiality Algorithms if (!cipher::crypt::Interface::isAlgorithmSupported( static_cast(request->confAlgo))) { response->status_code = static_cast(RAKP_ReturnCode::INVALID_CONF_ALGO); return outPayload; } std::shared_ptr session; try { // Start an IPMI session session = session::Manager::get().startSession( endian::from_ipmi<>(request->remoteConsoleSessionID), priv, static_cast(request->authAlgo), static_cast(request->intAlgo), static_cast(request->confAlgo)); } catch (const std::exception& e) { response->status_code = static_cast(RAKP_ReturnCode::INSUFFICIENT_RESOURCE); lg2::error("openSession : Problem opening a session: {ERROR}", "ERROR", e); return outPayload; } response->status_code = static_cast(RAKP_ReturnCode::NO_ERROR); response->maxPrivLevel = static_cast(session->reqMaxPrivLevel); response->managedSystemSessionID = endian::to_ipmi<>(session->getBMCSessionID()); response->authPayload = request->authPayload; response->authPayloadLen = request->authPayloadLen; response->authAlgo = request->authAlgo; response->intPayload = request->intPayload; response->intPayloadLen = request->intPayloadLen; response->intAlgo = request->intAlgo; response->confPayload = request->confPayload; response->confPayloadLen = request->confPayloadLen; response->confAlgo = request->confAlgo; session->updateLastTransactionTime(); // Session state is Setup in progress session->state(static_cast(session::State::setupInProgress)); return outPayload; } } // namespace command