summaryrefslogtreecommitdiffstats
path: root/command/open_session.cpp
blob: d29cbf1e35df895d7ee350d52d8b7d24175697c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "open_session.hpp"

#include <iostream>

#include "comm_module.hpp"
#include "endian.hpp"
#include "main.hpp"

namespace command
{

std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload,
                                 const message::Handler& handler)
{
    std::cout << ">> openSession\n";

    std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse));
    auto request = reinterpret_cast<const OpenSessionRequest*>(inPayload.data());
    auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data());

    // Check for valid Authentication Algorithms
    if (request->authAlgo != static_cast<uint8_t>
        (cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA1))
    {
        response->status_code =
            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO);
        return outPayload;
    }

    // Check for valid Integrity Algorithms
    if(!cipher::integrity::Interface::isAlgorithmSupported(static_cast
                    <cipher::integrity::Algorithms>(request->intAlgo)))
    {
        response->status_code =
            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO);
        return outPayload;
    }

    // Check for valid Confidentiality Algorithms
    if(!cipher::crypt::Interface::isAlgorithmSupported(static_cast
                    <cipher::crypt::Algorithms>(request->confAlgo)))
    {
        response->status_code =
            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO);
        return outPayload;
    }

    std::shared_ptr<session::Session> session;
    try
    {
        // Start an IPMI session
        session = (std::get<session::Manager&>(singletonPool).startSession(
                  endian::from_ipmi<>(request->remoteConsoleSessionID),
                  static_cast<session::Privilege>(request->maxPrivLevel),
                  static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo),
                  static_cast<cipher::integrity::Algorithms>(request->intAlgo),
                  static_cast<cipher::crypt::Algorithms>(request->confAlgo)
                  )).lock();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << "\n";
        response->status_code = static_cast<uint8_t>
                                (RAKP_ReturnCode::INSUFFICIENT_RESOURCE);
        std::cerr << "openSession : Problem opening a session\n";
        return outPayload;
    }

    response->messageTag = request->messageTag;
    response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR);
    response->maxPrivLevel = static_cast<uint8_t>(session->curPrivLevel);
    response->remoteConsoleSessionID = request->remoteConsoleSessionID;
    response->managedSystemSessionID = endian::to_ipmi<>
                                       (session->getBMCSessionID());

    response->authPayload = request->authPayload ;
    response->authPayloadLen = request->authPayloadLen ;
    response->authAlgo = request->authAlgo;

    response->intPayload = request->intPayload ;
    response->intPayloadLen = request->intPayloadLen ;
    response->intAlgo = request->intAlgo;

    response->confPayload = request->confPayload ;
    response->confPayloadLen = request->confPayloadLen ;
    response->confAlgo = request->confAlgo;

    session->updateLastTransactionTime();

    // Session state is Setup in progress
    session->state = session::State::SETUP_IN_PROGRESS;

    std::cout << "<< openSession\n";
    return outPayload;
}

} // namespace command
OpenPOWER on IntegriCloud