blob: 9ba00ec289ffdb086b64cf77569fef054d4da083 [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"
5#include "main.hpp"
6
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
Tom Joseph18a45e92017-04-11 11:30:44 +053014std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload,
Tom Joseph8e832ee2016-12-06 17:47:08 +053015 const message::Handler& handler)
16{
Vernon Mauery9e801a22018-10-12 13:20:49 -070017 auto request =
18 reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -070019 if (inPayload.size() != sizeof(*request))
20 {
21 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
22 return errorPayload;
23 }
24
25 std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
Tom Joseph8e832ee2016-12-06 17:47:08 +053026 auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
27
Jason M. Bills46bec0f2019-12-11 11:01:18 -080028 // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always
29 // returned
30 response->messageTag = request->messageTag;
31 response->remoteConsoleSessionID = request->remoteConsoleSessionID;
32
Tom Joseph8e832ee2016-12-06 17:47:08 +053033 // Check for valid Authentication Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080034 if (!cipher::rakp_auth::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070035 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053036 {
37 response->status_code =
38 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
39 return outPayload;
40 }
41
42 // Check for valid Integrity Algorithms
Vernon Mauery9b307be2017-11-22 09:28:16 -080043 if (!cipher::integrity::Interface::isAlgorithmSupported(
Vernon Mauery9e801a22018-10-12 13:20:49 -070044 static_cast<cipher::integrity::Algorithms>(request->intAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053045 {
46 response->status_code =
47 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
48 return outPayload;
49 }
50
Tom Joseph4021b1f2019-02-12 10:10:12 +053051 session::Privilege priv;
52
53 // 0h in the requested maximum privilege role field indicates highest level
54 // matching proposed algorithms. The maximum privilege level the session
55 // can take is set to Administrator level. In the RAKP12 command sequence
56 // the session maximum privilege role is set again based on the user's
57 // permitted privilege level.
58 if (!request->maxPrivLevel)
59 {
60 priv = session::Privilege::ADMIN;
61 }
62 else
63 {
64 priv = static_cast<session::Privilege>(request->maxPrivLevel);
65 }
66
Tom Joseph8e832ee2016-12-06 17:47:08 +053067 // Check for valid Confidentiality Algorithms
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 if (!cipher::crypt::Interface::isAlgorithmSupported(
69 static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
Tom Joseph8e832ee2016-12-06 17:47:08 +053070 {
71 response->status_code =
72 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
73 return outPayload;
74 }
75
76 std::shared_ptr<session::Session> session;
77 try
78 {
79 // Start an IPMI session
Vernon Mauery9e801a22018-10-12 13:20:49 -070080 session =
Vernon Maueryae1fda42018-10-15 12:55:34 -070081 std::get<session::Manager&>(singletonPool)
82 .startSession(
Tom Joseph4021b1f2019-02-12 10:10:12 +053083 endian::from_ipmi<>(request->remoteConsoleSessionID), priv,
Vernon Maueryae1fda42018-10-15 12:55:34 -070084 static_cast<cipher::rakp_auth::Algorithms>(
85 request->authAlgo),
86 static_cast<cipher::integrity::Algorithms>(
87 request->intAlgo),
88 static_cast<cipher::crypt::Algorithms>(request->confAlgo));
Tom Joseph8e832ee2016-12-06 17:47:08 +053089 }
90 catch (std::exception& e)
91 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070092 response->status_code =
93 static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
Vernon Maueryfc37e592018-12-19 14:55:15 -080094 log<level::ERR>("openSession : Problem opening a session",
95 entry("EXCEPTION=%s", e.what()));
Tom Joseph8e832ee2016-12-06 17:47:08 +053096 return outPayload;
97 }
98
Tom Joseph8e832ee2016-12-06 17:47:08 +053099 response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
Tom Joseph4021b1f2019-02-12 10:10:12 +0530100 response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel);
Vernon Mauery9e801a22018-10-12 13:20:49 -0700101 response->managedSystemSessionID =
102 endian::to_ipmi<>(session->getBMCSessionID());
Tom Joseph8e832ee2016-12-06 17:47:08 +0530103
Vernon Mauery9e801a22018-10-12 13:20:49 -0700104 response->authPayload = request->authPayload;
105 response->authPayloadLen = request->authPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530106 response->authAlgo = request->authAlgo;
107
Vernon Mauery9e801a22018-10-12 13:20:49 -0700108 response->intPayload = request->intPayload;
109 response->intPayloadLen = request->intPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530110 response->intAlgo = request->intAlgo;
111
Vernon Mauery9e801a22018-10-12 13:20:49 -0700112 response->confPayload = request->confPayload;
113 response->confPayloadLen = request->confPayloadLen;
Tom Joseph8e832ee2016-12-06 17:47:08 +0530114 response->confAlgo = request->confAlgo;
115
116 session->updateLastTransactionTime();
117
118 // Session state is Setup in progress
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530119 session->state(static_cast<uint8_t>(session::State::setupInProgress));
Tom Joseph8e832ee2016-12-06 17:47:08 +0530120 return outPayload;
121}
122
123} // namespace command