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 // Check for valid Authentication Algorithms 24 if (!cipher::rakp_auth::Interface::isAlgorithmSupported( 25 static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo))) 26 { 27 response->status_code = 28 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO); 29 return outPayload; 30 } 31 32 // Check for valid Integrity Algorithms 33 if (!cipher::integrity::Interface::isAlgorithmSupported( 34 static_cast<cipher::integrity::Algorithms>(request->intAlgo))) 35 { 36 response->status_code = 37 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO); 38 return outPayload; 39 } 40 41 session::Privilege priv; 42 43 // 0h in the requested maximum privilege role field indicates highest level 44 // matching proposed algorithms. The maximum privilege level the session 45 // can take is set to Administrator level. In the RAKP12 command sequence 46 // the session maximum privilege role is set again based on the user's 47 // permitted privilege level. 48 if (!request->maxPrivLevel) 49 { 50 priv = session::Privilege::ADMIN; 51 } 52 else 53 { 54 priv = static_cast<session::Privilege>(request->maxPrivLevel); 55 } 56 57 // Check for valid Confidentiality Algorithms 58 if (!cipher::crypt::Interface::isAlgorithmSupported( 59 static_cast<cipher::crypt::Algorithms>(request->confAlgo))) 60 { 61 response->status_code = 62 static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO); 63 return outPayload; 64 } 65 66 std::shared_ptr<session::Session> session; 67 try 68 { 69 // Start an IPMI session 70 session = 71 std::get<session::Manager&>(singletonPool) 72 .startSession( 73 endian::from_ipmi<>(request->remoteConsoleSessionID), priv, 74 static_cast<cipher::rakp_auth::Algorithms>( 75 request->authAlgo), 76 static_cast<cipher::integrity::Algorithms>( 77 request->intAlgo), 78 static_cast<cipher::crypt::Algorithms>(request->confAlgo)); 79 } 80 catch (std::exception& e) 81 { 82 response->status_code = 83 static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE); 84 log<level::ERR>("openSession : Problem opening a session", 85 entry("EXCEPTION=%s", e.what())); 86 return outPayload; 87 } 88 89 response->messageTag = request->messageTag; 90 response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR); 91 response->maxPrivLevel = static_cast<uint8_t>(session->reqMaxPrivLevel); 92 response->remoteConsoleSessionID = request->remoteConsoleSessionID; 93 response->managedSystemSessionID = 94 endian::to_ipmi<>(session->getBMCSessionID()); 95 96 response->authPayload = request->authPayload; 97 response->authPayloadLen = request->authPayloadLen; 98 response->authAlgo = request->authAlgo; 99 100 response->intPayload = request->intPayload; 101 response->intPayloadLen = request->intPayloadLen; 102 response->intAlgo = request->intAlgo; 103 104 response->confPayload = request->confPayload; 105 response->confPayloadLen = request->confPayloadLen; 106 response->confAlgo = request->confAlgo; 107 108 session->updateLastTransactionTime(); 109 110 // Session state is Setup in progress 111 session->state(static_cast<uint8_t>(session::State::setupInProgress)); 112 return outPayload; 113 } 114 115 } // namespace command 116