1 #include "open_session.hpp"
2 
3 #include <iostream>
4 
5 #include "comm_module.hpp"
6 #include "endian.hpp"
7 #include "main.hpp"
8 
9 namespace command
10 {
11 
12 std::vector<uint8_t> openSession(std::vector<uint8_t>& inPayload,
13                                  const message::Handler& handler)
14 {
15     std::cout << ">> openSession\n";
16 
17     std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
18     auto request = reinterpret_cast<OpenSessionRequest*>(inPayload.data());
19     auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());
20 
21     // Check for valid Authentication Algorithms
22     if (request->authAlgo != static_cast<uint8_t>
23         (cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA1))
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(static_cast
32                     <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(static_cast
41                     <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 = (std::get<session::Manager&>(singletonPool).startSession(
53                   endian::from_ipmi<>(request->remoteConsoleSessionID),
54                   static_cast<session::Privilege>(request->maxPrivLevel),
55                   static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo),
56                   static_cast<cipher::integrity::Algorithms>(request->intAlgo),
57                   static_cast<cipher::crypt::Algorithms>(request->confAlgo)
58                   )).lock();
59     }
60     catch (std::exception& e)
61     {
62         std::cerr << e.what() << "\n";
63         response->status_code = static_cast<uint8_t>
64                                 (RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
65         std::cerr << "openSession : Problem opening a session\n";
66         return outPayload;
67     }
68 
69     response->messageTag = request->messageTag;
70     response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
71     response->maxPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
72     response->remoteConsoleSessionID = request->remoteConsoleSessionID;
73     response->managedSystemSessionID = endian::to_ipmi<>
74                                        (session->getBMCSessionID());
75 
76     response->authPayload = request->authPayload ;
77     response->authPayloadLen = request->authPayloadLen ;
78     response->authAlgo = request->authAlgo;
79 
80     response->intPayload = request->intPayload ;
81     response->intPayloadLen = request->intPayloadLen ;
82     response->intAlgo = request->intAlgo;
83 
84     response->confPayload = request->confPayload ;
85     response->confPayloadLen = request->confPayloadLen ;
86     response->confAlgo = request->confAlgo;
87 
88     session->updateLastTransactionTime();
89 
90     // Session state is Setup in progress
91     session->state = session::State::SETUP_IN_PROGRESS;
92 
93     std::cout << "<< openSession\n";
94     return outPayload;
95 }
96 
97 } // namespace command
98