blob: 21e0f3fb82e67f3fb3467dfeeff31dca4a0f5ef0 [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
George Liu7b7f25f2022-07-04 17:07:32 +08007#include <phosphor-logging/lg2.hpp>
Vernon Mauery9e801a22018-10-12 13:20:49 -07008
Tom Joseph8e832ee2016-12-06 17:47:08 +05309namespace command
10{
11
George Liube1470c2022-07-04 14:33:24 +080012std::vector<uint8_t>
13 openSession(const std::vector<uint8_t>& inPayload,
14 std::shared_ptr<message::Handler>& /* handler */)
Tom Joseph8e832ee2016-12-06 17:47:08 +053015{
Vernon Mauery9e801a22018-10-12 13:20:49 -070016 auto request =
17 reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -070018 if (inPayload.size() != sizeof(*request))
19 {
20 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
21 return errorPayload;
22 }
23
24 std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
Tom Joseph8e832ee2016-12-06 17:47:08 +053025 auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
26
Jason M. Bills46bec0f2019-12-11 11:01:18 -080027 // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always
28 // returned
29 response->messageTag = request->messageTag;
30 response->remoteConsoleSessionID = request->remoteConsoleSessionID;
31
Tom Joseph8e832ee2016-12-06 17:47:08 +053032 // Check for valid Authentication Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080033 if (!cipher::rakp_auth::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070034 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053035 {
36 response->status_code =
37 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
38 return outPayload;
39 }
40
41 // Check for valid Integrity Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080042 if (!cipher::integrity::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070043 static_cast<cipher::integrity::Algorithms>(request->intAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053044 {
45 response->status_code =
46 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
47 return outPayload;
48 }
49
Tom Joseph4021b1f2019-02-12 10:10:12 +053050 session::Privilege priv;
51
52 // 0h in the requested maximum privilege role field indicates highest level
53 // matching proposed algorithms. The maximum privilege level the session
54 // can take is set to Administrator level. In the RAKP12 command sequence
55 // the session maximum privilege role is set again based on the user's
56 // permitted privilege level.
57 if (!request->maxPrivLevel)
58 {
59 priv = session::Privilege::ADMIN;
60 }
61 else
62 {
63 priv = static_cast<session::Privilege>(request->maxPrivLevel);
64 }
65
Tom Joseph8e832ee2016-12-06 17:47:08 +053066 // Check for valid Confidentiality Algorithms
Vernon Mauery9e801a22018-10-12 13:20:49 -070067 if (!cipher::crypt::Interface::isAlgorithmSupported(
68 static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053069 {
70 response->status_code =
71 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
72 return outPayload;
73 }
74
75 std::shared_ptr<session::Session> session;
76 try
77 {
78 // Start an IPMI session
Vernon Mauery2085ae02021-06-10 11:51:00 -070079 session = session::Manager::get().startSession(
80 endian::from_ipmi<>(request->remoteConsoleSessionID), priv,
81 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo),
82 static_cast<cipher::integrity::Algorithms>(request->intAlgo),
83 static_cast<cipher::crypt::Algorithms>(request->confAlgo));
Tom Joseph8e832ee2016-12-06 17:47:08 +053084 }
Patrick Williams12d199b2021-10-06 12:36:48 -050085 catch (const std::exception& e)
Tom Joseph8e832ee2016-12-06 17:47:08 +053086 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070087 response->status_code =
88 static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
George Liu7b7f25f2022-07-04 17:07:32 +080089 lg2::error("openSession : Problem opening a session: {ERROR}", "ERROR",
90 e);
Tom Joseph8e832ee2016-12-06 17:47:08 +053091 return outPayload;
92 }
93
Tom Joseph8e832ee2016-12-06 17:47:08 +053094 response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
Tom Joseph4021b1f2019-02-12 10:10:12 +053095 response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel);
Vernon Mauery9e801a22018-10-12 13:20:49 -070096 response->managedSystemSessionID =
97 endian::to_ipmi<>(session->getBMCSessionID());
Tom Joseph8e832ee2016-12-06 17:47:08 +053098
Vernon Mauery9e801a22018-10-12 13:20:49 -070099 response->authPayload = request->authPayload;
100 response->authPayloadLen = request->authPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530101 response->authAlgo = request->authAlgo;
102
Vernon Mauery9e801a22018-10-12 13:20:49 -0700103 response->intPayload = request->intPayload;
104 response->intPayloadLen = request->intPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530105 response->intAlgo = request->intAlgo;
106
Vernon Mauery9e801a22018-10-12 13:20:49 -0700107 response->confPayload = request->confPayload;
108 response->confPayloadLen = request->confPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530109 response->confAlgo = request->confAlgo;
110
111 session->updateLastTransactionTime();
112
113 // Session state is Setup in progress
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530114 session->state(static_cast<uint8_t>(session::State::setupInProgress));
Tom Joseph8e832ee2016-12-06 17:47:08 +0530115 return outPayload;
116}
117
118} // namespace command