Open Session Request/Response Implementation
Change-Id: I2726f52c8eb331575677fb0e6a52943a2c5f5865
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/command/open_session.cpp b/command/open_session.cpp
new file mode 100644
index 0000000..0c17d3d
--- /dev/null
+++ b/command/open_session.cpp
@@ -0,0 +1,93 @@
+#include "open_session.hpp"
+
+#include <iostream>
+
+#include "comm_module.hpp"
+#include "endian.hpp"
+#include "main.hpp"
+
+namespace command
+{
+
+std::vector<uint8_t> openSession(std::vector<uint8_t>& inPayload,
+ const message::Handler& handler)
+{
+ std::cout << ">> openSession\n";
+
+ std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
+ auto request = reinterpret_cast<OpenSessionRequest*>(inPayload.data());
+ auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
+
+ // Check for valid Authentication Algorithms
+ if (request->authAlgo != static_cast<uint8_t>
+ (cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA1))
+ {
+ response->status_code =
+ static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
+ return outPayload;
+ }
+
+ // Check for valid Integrity Algorithms
+ if (request->intAlgo != 0)
+ {
+ response->status_code =
+ static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
+ return outPayload;
+ }
+
+ // Check for valid Confidentiality Algorithms
+ if (request->confAlgo != 0)
+ {
+ response->status_code =
+ static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
+ return outPayload;
+ }
+
+ std::shared_ptr<session::Session> session;
+ try
+ {
+ // Start an IPMI session
+ session = (std::get<session::Manager&>(singletonPool).startSession(
+ endian::from_ipmi<>(request->remoteConsoleSessionID),
+ static_cast<session::Privilege>(request->maxPrivLevel),
+ static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)
+ )).lock();
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << e.what() << "\n";
+ response->status_code = static_cast<uint8_t>
+ (RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
+ std::cerr << "openSession : Problem opening a session\n";
+ return outPayload;
+ }
+
+ response->messageTag = request->messageTag;
+ response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
+ response->maxPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
+ response->remoteConsoleSessionID = request->remoteConsoleSessionID;
+ 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 = session::State::SETUP_IN_PROGRESS;
+
+ std::cout << "<< openSession\n";
+ return outPayload;
+}
+
+} // namespace command
diff --git a/command/open_session.hpp b/command/open_session.hpp
new file mode 100644
index 0000000..f5111d2
--- /dev/null
+++ b/command/open_session.hpp
@@ -0,0 +1,180 @@
+#pragma once
+
+#include <vector>
+
+#include "message_handler.hpp"
+
+namespace command
+{
+
+/*
+ * @ struct OpenSessionRequest
+ *
+ * IPMI Payload for RMCP+ Open Session Request
+ */
+struct OpenSessionRequest
+{
+ uint8_t messageTag; // Message tag from request buffer
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t maxPrivLevel : 4 ;// Requested maximum privilege level
+ uint8_t reserved1 : 4; // Reserved for future definition
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved1 : 4; // Reserved for future definition
+ uint8_t maxPrivLevel : 4 ;// Requested maximum privilege level
+
+#endif
+
+ uint16_t reserved2;
+ uint32_t remoteConsoleSessionID ;
+
+ uint8_t authPayload ;
+ uint16_t reserved3;
+ uint8_t authPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t authAlgo : 6;
+ uint8_t reserved4 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved4 : 2;
+ uint8_t authAlgo : 6;
+#endif
+
+ uint8_t reserved5;
+ uint16_t reserved6;
+
+ uint8_t intPayload;
+ uint16_t reserved7;
+ uint8_t intPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t intAlgo : 6;
+ uint8_t reserved8 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved8 : 2;
+ uint8_t intAlgo : 6;
+#endif
+
+ uint8_t reserved9;
+ uint16_t reserved10;
+
+ uint8_t confPayload;
+ uint16_t reserved11;
+ uint8_t confPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t confAlgo : 6;
+ uint8_t reserved12 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved12 : 2;
+ uint8_t confAlgo : 6;
+#endif
+
+ uint8_t reserved13;
+ uint16_t reserved14;
+} __attribute__((packed));
+
+/*
+ * @ struct OpenSessionResponse
+ *
+ * IPMI Payload for RMCP+ Open Session Response
+ */
+struct OpenSessionResponse
+{
+ uint8_t messageTag;
+ uint8_t status_code;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t maxPrivLevel : 4;
+ uint8_t reserved1 : 4;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved1 : 4;
+ uint8_t maxPrivLevel : 4;
+#endif
+
+ uint8_t reserved2;
+ uint32_t remoteConsoleSessionID;
+ uint32_t managedSystemSessionID;
+
+ uint8_t authPayload;
+ uint16_t reserved3;
+ uint8_t authPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t authAlgo : 6;
+ uint8_t reserved4 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved4 : 2;
+ uint8_t authAlgo : 6;
+#endif
+
+ uint8_t reserved5;
+ uint16_t reserved6;
+
+ uint8_t intPayload;
+ uint16_t reserved7;
+ uint8_t intPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t intAlgo : 6;
+ uint8_t reserved8 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved8 : 2;
+ uint8_t intAlgo : 6;
+
+#endif
+
+ uint8_t reserved9;
+ uint16_t reserved10;
+
+ uint8_t confPayload;
+ uint16_t reserved11;
+ uint8_t confPayloadLen;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t confAlgo : 6;
+ uint8_t reserved12 : 2;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved12 : 2;
+ uint8_t confAlgo : 6;
+#endif
+
+ uint8_t reserved13;
+ uint16_t reserved14;
+} __attribute__((packed));
+
+/*
+ * @brief RMCP+ Open Session Request, RMCP+ Open Session Response
+ *
+ * The RMCP+ Open Session request and response messages are used to enable a
+ * remote console to discover what Cipher Suite(s) can be used for establishing
+ * a session at a requested maximum privilege level. These messages are also
+ * used for transferring the sessions IDs that the remote console and BMC wish
+ * to for the session once it’s been activated, and to track each party during
+ * the exchange of messages used for establishing the session.
+ *
+ * @param[in] inPayload - Request Data for the command
+ * @param[in] handler - Reference to the Message Handler
+ *
+ * @return Response data for the command
+ */
+std::vector<uint8_t> openSession(std::vector<uint8_t>& inPayload,
+ const message::Handler& handler);
+
+} // namespace command