1 #include "open_session.hpp" 2 3 #include "comm_module.hpp" 4 #include "endian.hpp" 5 #include "main.hpp" 6 7 #include <phosphor-logging/log.hpp> 8 9 using namespace phosphor::logging; 10 11 namespace command 12 { 13 14 std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, 15 const message::Handler& handler) 16 { 17 18 std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse)); 19 auto request = 20 reinterpret_cast<const OpenSessionRequest*>(inPayload.data()); 21 auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data()); 22 23 // Per the IPMI Spec, messageTag and remoteConsoleSessionID are always 24 // returned 25 response->messageTag = request->messageTag; 26 response->remoteConsoleSessionID = request->remoteConsoleSessionID; 27 28 // Check for valid Authentication Algorithms 29 if (!cipher::rakp_auth::Interface::isAlgorithmSupported( 30 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo))) 31 { 32 response->status_code = 33 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO); 34 return outPayload; 35 } 36 37 // Check for valid Integrity Algorithms 38 if (!cipher::integrity::Interface::isAlgorithmSupported( 39 static_cast<cipher::integrity::Algorithms>(request->intAlgo))) 40 { 41 response->status_code = 42 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO); 43 return outPayload; 44 } 45 46 session::Privilege priv; 47 48 // 0h in the requested maximum privilege role field indicates highest level 49 // matching proposed algorithms. The maximum privilege level the session 50 // can take is set to Administrator level. In the RAKP12 command sequence 51 // the session maximum privilege role is set again based on the user's 52 // permitted privilege level. 53 if (!request->maxPrivLevel) 54 { 55 priv = session::Privilege::ADMIN; 56 } 57 else 58 { 59 priv = static_cast<session::Privilege>(request->maxPrivLevel); 60 } 61 62 // Check for valid Confidentiality Algorithms 63 if (!cipher::crypt::Interface::isAlgorithmSupported( 64 static_cast<cipher::crypt::Algorithms>(request->confAlgo))) 65 { 66 response->status_code = 67 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO); 68 return outPayload; 69 } 70 71 std::shared_ptr<session::Session> session; 72 try 73 { 74 // Start an IPMI session 75 session = 76 std::get<session::Manager&>(singletonPool) 77 .startSession( 78 endian::from_ipmi<>(request->remoteConsoleSessionID), priv, 79 static_cast<cipher::rakp_auth::Algorithms>( 80 request->authAlgo), 81 static_cast<cipher::integrity::Algorithms>( 82 request->intAlgo), 83 static_cast<cipher::crypt::Algorithms>(request->confAlgo)); 84 } 85 catch (std::exception& e) 86 { 87 response->status_code = 88 static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE); 89 log<level::ERR>("openSession : Problem opening a session", 90 entry("EXCEPTION=%s", e.what())); 91 return outPayload; 92 } 93 94 response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR); 95 response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel); 96 response->managedSystemSessionID = 97 endian::to_ipmi<>(session->getBMCSessionID()); 98 99 response->authPayload = request->authPayload; 100 response->authPayloadLen = request->authPayloadLen; 101 response->authAlgo = request->authAlgo; 102 103 response->intPayload = request->intPayload; 104 response->intPayloadLen = request->intPayloadLen; 105 response->intAlgo = request->intAlgo; 106 107 response->confPayload = request->confPayload; 108 response->confPayloadLen = request->confPayloadLen; 109 response->confAlgo = request->confAlgo; 110 111 session->updateLastTransactionTime(); 112 113 // Session state is Setup in progress 114 session->state(static_cast<uint8_t>(session::State::setupInProgress)); 115 return outPayload; 116 } 117 118 } // namespace command 119