1 #include "open_session.hpp"
2 
3 #include "comm_module.hpp"
4 #include "endian.hpp"
5 #include "main.hpp"
6 
7 #include <iostream>
8 
9 namespace command
10 {
11 
12 std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload,
13                                  const message::Handler& handler)
14 {
15 
16     std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
17     auto request =
18         reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
19     auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
20 
21     // Check for valid Authentication Algorithms
22     if (!cipher::rakp_auth::Interface::isAlgorithmSupported(
23             static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo)))
24     {
25         response->status_code =
26             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
27         return outPayload;
28     }
29 
30     // Check for valid Integrity Algorithms
31     if (!cipher::integrity::Interface::isAlgorithmSupported(
32             static_cast<cipher::integrity::Algorithms>(request->intAlgo)))
33     {
34         response->status_code =
35             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
36         return outPayload;
37     }
38 
39     // Check for valid Confidentiality Algorithms
40     if (!cipher::crypt::Interface::isAlgorithmSupported(
41             static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
42     {
43         response->status_code =
44             static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
45         return outPayload;
46     }
47 
48     std::shared_ptr<session::Session> session;
49     try
50     {
51         // Start an IPMI session
52         session =
53             (std::get<session::Manager&>(singletonPool)
54                  .startSession(
55                      endian::from_ipmi<>(request->remoteConsoleSessionID),
56                      static_cast<session::Privilege>(request->maxPrivLevel),
57                      static_cast<cipher::rakp_auth::Algorithms>(
58                          request->authAlgo),
59                      static_cast<cipher::integrity::Algorithms>(
60                          request->intAlgo),
61                      static_cast<cipher::crypt::Algorithms>(request->confAlgo)))
62                 .lock();
63     }
64     catch (std::exception& e)
65     {
66         std::cerr << e.what() << "\n";
67         response->status_code =
68             static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
69         std::cerr << "openSession : Problem opening a session\n";
70         return outPayload;
71     }
72 
73     response->messageTag = request->messageTag;
74     response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
75     response->maxPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
76     response->remoteConsoleSessionID = request->remoteConsoleSessionID;
77     response->managedSystemSessionID =
78         endian::to_ipmi<>(session->getBMCSessionID());
79 
80     response->authPayload = request->authPayload;
81     response->authPayloadLen = request->authPayloadLen;
82     response->authAlgo = request->authAlgo;
83 
84     response->intPayload = request->intPayload;
85     response->intPayloadLen = request->intPayloadLen;
86     response->intAlgo = request->intAlgo;
87 
88     response->confPayload = request->confPayload;
89     response->confPayloadLen = request->confPayloadLen;
90     response->confAlgo = request->confAlgo;
91 
92     session->updateLastTransactionTime();
93 
94     // Session state is Setup in progress
95     session->state = session::State::SETUP_IN_PROGRESS;
96     return outPayload;
97 }
98 
99 } // namespace command
100