blob: 0d82a067e7ea054a7f0dbfbb3a953ccc033634a8 [file] [log] [blame]
Tom Joseph8e832ee2016-12-06 17:47:08 +05301#include "open_session.hpp"
2
Tom Joseph8e832ee2016-12-06 17:47:08 +05303#include "comm_module.hpp"
4#include "endian.hpp"
Vernon Mauery2085ae02021-06-10 11:51:00 -07005#include "sessions_manager.hpp"
Tom Joseph8e832ee2016-12-06 17:47:08 +05306
Vernon Maueryfc37e592018-12-19 14:55:15 -08007#include <phosphor-logging/log.hpp>
8
9using namespace phosphor::logging;
Vernon Mauery9e801a22018-10-12 13:20:49 -070010
Tom Joseph8e832ee2016-12-06 17:47:08 +053011namespace command
12{
13
George Liube1470c2022-07-04 14:33:24 +080014std::vector<uint8_t>
15 openSession(const std::vector<uint8_t>& inPayload,
16 std::shared_ptr<message::Handler>& /* handler */)
Tom Joseph8e832ee2016-12-06 17:47:08 +053017{
Vernon Mauery9e801a22018-10-12 13:20:49 -070018 auto request =
19 reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -070020 if (inPayload.size() != sizeof(*request))
21 {
22 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
23 return errorPayload;
24 }
25
26 std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
Tom Joseph8e832ee2016-12-06 17:47:08 +053027 auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
28
Jason M. Bills46bec0f2019-12-11 11:01:18 -080029 // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always
30 // returned
31 response->messageTag = request->messageTag;
32 response->remoteConsoleSessionID = request->remoteConsoleSessionID;
33
Tom Joseph8e832ee2016-12-06 17:47:08 +053034 // Check for valid Authentication Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080035 if (!cipher::rakp_auth::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070036 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053037 {
38 response->status_code =
39 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
40 return outPayload;
41 }
42
43 // Check for valid Integrity Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080044 if (!cipher::integrity::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070045 static_cast<cipher::integrity::Algorithms>(request->intAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053046 {
47 response->status_code =
48 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
49 return outPayload;
50 }
51
Tom Joseph4021b1f2019-02-12 10:10:12 +053052 session::Privilege priv;
53
54 // 0h in the requested maximum privilege role field indicates highest level
55 // matching proposed algorithms. The maximum privilege level the session
56 // can take is set to Administrator level. In the RAKP12 command sequence
57 // the session maximum privilege role is set again based on the user's
58 // permitted privilege level.
59 if (!request->maxPrivLevel)
60 {
61 priv = session::Privilege::ADMIN;
62 }
63 else
64 {
65 priv = static_cast<session::Privilege>(request->maxPrivLevel);
66 }
67
Tom Joseph8e832ee2016-12-06 17:47:08 +053068 // Check for valid Confidentiality Algorithms
Vernon Mauery9e801a22018-10-12 13:20:49 -070069 if (!cipher::crypt::Interface::isAlgorithmSupported(
70 static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053071 {
72 response->status_code =
73 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
74 return outPayload;
75 }
76
77 std::shared_ptr<session::Session> session;
78 try
79 {
80 // Start an IPMI session
Vernon Mauery2085ae02021-06-10 11:51:00 -070081 session = session::Manager::get().startSession(
82 endian::from_ipmi<>(request->remoteConsoleSessionID), priv,
83 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo),
84 static_cast<cipher::integrity::Algorithms>(request->intAlgo),
85 static_cast<cipher::crypt::Algorithms>(request->confAlgo));
Tom Joseph8e832ee2016-12-06 17:47:08 +053086 }
Patrick Williams12d199b2021-10-06 12:36:48 -050087 catch (const std::exception& e)
Tom Joseph8e832ee2016-12-06 17:47:08 +053088 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070089 response->status_code =
90 static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
Vernon Maueryfc37e592018-12-19 14:55:15 -080091 log<level::ERR>("openSession : Problem opening a session",
92 entry("EXCEPTION=%s", e.what()));
Tom Joseph8e832ee2016-12-06 17:47:08 +053093 return outPayload;
94 }
95
Tom Joseph8e832ee2016-12-06 17:47:08 +053096 response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
Tom Joseph4021b1f2019-02-12 10:10:12 +053097 response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel);
Vernon Mauery9e801a22018-10-12 13:20:49 -070098 response->managedSystemSessionID =
99 endian::to_ipmi<>(session->getBMCSessionID());
Tom Joseph8e832ee2016-12-06 17:47:08 +0530100
Vernon Mauery9e801a22018-10-12 13:20:49 -0700101 response->authPayload = request->authPayload;
102 response->authPayloadLen = request->authPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530103 response->authAlgo = request->authAlgo;
104
Vernon Mauery9e801a22018-10-12 13:20:49 -0700105 response->intPayload = request->intPayload;
106 response->intPayloadLen = request->intPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530107 response->intAlgo = request->intAlgo;
108
Vernon Mauery9e801a22018-10-12 13:20:49 -0700109 response->confPayload = request->confPayload;
110 response->confPayloadLen = request->confPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530111 response->confAlgo = request->confAlgo;
112
113 session->updateLastTransactionTime();
114
115 // Session state is Setup in progress
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530116 session->state(static_cast<uint8_t>(session::State::setupInProgress));
Tom Joseph8e832ee2016-12-06 17:47:08 +0530117 return outPayload;
118}
119
120} // namespace command