diff options
author | Vernon Mauery <vernon.mauery@linux.intel.com> | 2018-10-12 13:20:49 -0700 |
---|---|---|
committer | Vernon Mauery <vernon.mauery@linux.intel.com> | 2018-11-02 15:44:15 -0700 |
commit | 9e801a2b5b36acd307606af5eafdb885dfe8daee (patch) | |
tree | 87d6cdef2c9008d76e9a99784e83f2b3af90ebc0 | |
parent | f6110552bd0e940efe51eb11c0415bebb2ab883f (diff) | |
download | phosphor-net-ipmid-9e801a2b5b36acd307606af5eafdb885dfe8daee.tar.gz phosphor-net-ipmid-9e801a2b5b36acd307606af5eafdb885dfe8daee.zip |
netipmid: apply clang-format rules
Lots of whitespace change. Let clang-format do its job and keep the code
looking nice.
Change-Id: Idfcad1a99cab8170d55a06163de8ad3f420b68b7
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
56 files changed, 2991 insertions, 2940 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ea71ad6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,99 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^[<"](gtest|gmock)' + Priority: 5 + - Regex: '^"config.h"' + Priority: -1 + - Regex: '^".*\.hpp"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 + - Regex: '.*' + Priority: 4 +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/auth_algo.cpp b/auth_algo.cpp index b658d6a..55df86d 100644 --- a/auth_algo.cpp +++ b/auth_algo.cpp @@ -14,8 +14,8 @@ namespace rakp_auth const std::string userName = "admin"; -std::vector<uint8_t> AlgoSHA1::generateHMAC( - const std::vector<uint8_t>& input) const +std::vector<uint8_t> + AlgoSHA1::generateHMAC(const std::vector<uint8_t>& input) const { std::vector<uint8_t> output(SHA_DIGEST_LENGTH); unsigned int mdLen = 0; @@ -30,8 +30,8 @@ std::vector<uint8_t> AlgoSHA1::generateHMAC( return output; } -std::vector<uint8_t> AlgoSHA1::generateICV( - const std::vector<uint8_t>& input) const +std::vector<uint8_t> + AlgoSHA1::generateICV(const std::vector<uint8_t>& input) const { std::vector<uint8_t> output(SHA_DIGEST_LENGTH); unsigned int mdLen = 0; @@ -47,8 +47,8 @@ std::vector<uint8_t> AlgoSHA1::generateICV( return output; } -std::vector<uint8_t> AlgoSHA256::generateHMAC( - const std::vector<uint8_t>& input) const +std::vector<uint8_t> + AlgoSHA256::generateHMAC(const std::vector<uint8_t>& input) const { std::vector<uint8_t> output(SHA256_DIGEST_LENGTH); unsigned int mdLen = 0; @@ -63,15 +63,15 @@ std::vector<uint8_t> AlgoSHA256::generateHMAC( return output; } -std::vector<uint8_t> AlgoSHA256::generateICV( - const std::vector<uint8_t>& input) const +std::vector<uint8_t> + AlgoSHA256::generateICV(const std::vector<uint8_t>& input) const { std::vector<uint8_t> output(SHA256_DIGEST_LENGTH); unsigned int mdLen = 0; - if (HMAC(EVP_sha256(), - sessionIntegrityKey.data(), sessionIntegrityKey.size(), - input.data(), input.size(), output.data(), &mdLen) == NULL) + if (HMAC(EVP_sha256(), sessionIntegrityKey.data(), + sessionIntegrityKey.size(), input.data(), input.size(), + output.data(), &mdLen) == NULL) { std::cerr << "Generate HMAC_SHA256_128 Integrity Check Value failed\n"; output.resize(0); @@ -81,6 +81,6 @@ std::vector<uint8_t> AlgoSHA256::generateICV( return output; } -} // namespace auth +} // namespace rakp_auth } // namespace cipher diff --git a/auth_algo.hpp b/auth_algo.hpp index c9fb821..f4e3c49 100644 --- a/auth_algo.hpp +++ b/auth_algo.hpp @@ -1,10 +1,11 @@ #pragma once -#include <array> -#include <vector> #include "crypt_algo.hpp" #include "integrity_algo.hpp" +#include <array> +#include <vector> + namespace cipher { namespace rakp_auth @@ -46,103 +47,105 @@ enum class Algorithms : uint8_t */ class Interface { - public: - explicit Interface(integrity::Algorithms intAlgo, - crypt::Algorithms cryptAlgo) : - intAlgo(intAlgo), - cryptAlgo(cryptAlgo) {} - - Interface() = delete; - virtual ~Interface() = default; - Interface(const Interface&) = default; - Interface& operator=(const Interface&) = default; - Interface(Interface&&) = default; - Interface& operator=(Interface&&) = default; - - /** - * @brief Generate the Hash Message Authentication Code - * - * This API is invoked to generate the Key Exchange Authentication Code - * in the RAKP2 and RAKP4 sequence and for generating the Session - * Integrity Key. - * - * @param input message - * - * @return hash output - * - * @note The user key which is the secret key for the hash operation - * needs to be set before this operation. - */ - std::vector<uint8_t> virtual generateHMAC( - const std::vector<uint8_t>& input) const = 0; - - /** - * @brief Generate the Integrity Check Value - * - * This API is invoked in the RAKP4 sequence for generating the - * Integrity Check Value. - * - * @param input message - * - * @return hash output - * - * @note The session integrity key which is the secret key for the - * hash operation needs to be set before this operation. - */ - std::vector<uint8_t> virtual generateICV( - const std::vector<uint8_t>& input) const = 0; - - /** - * @brief Check if the Authentication algorithm is supported - * - * @param[in] algo - authentication algorithm - * - * @return true if algorithm is supported else false - * - */ - static bool isAlgorithmSupported(Algorithms algo) + public: + explicit Interface(integrity::Algorithms intAlgo, + crypt::Algorithms cryptAlgo) : + intAlgo(intAlgo), + cryptAlgo(cryptAlgo) + { + } + + Interface() = delete; + virtual ~Interface() = default; + Interface(const Interface&) = default; + Interface& operator=(const Interface&) = default; + Interface(Interface&&) = default; + Interface& operator=(Interface&&) = default; + + /** + * @brief Generate the Hash Message Authentication Code + * + * This API is invoked to generate the Key Exchange Authentication Code + * in the RAKP2 and RAKP4 sequence and for generating the Session + * Integrity Key. + * + * @param input message + * + * @return hash output + * + * @note The user key which is the secret key for the hash operation + * needs to be set before this operation. + */ + std::vector<uint8_t> virtual generateHMAC( + const std::vector<uint8_t>& input) const = 0; + + /** + * @brief Generate the Integrity Check Value + * + * This API is invoked in the RAKP4 sequence for generating the + * Integrity Check Value. + * + * @param input message + * + * @return hash output + * + * @note The session integrity key which is the secret key for the + * hash operation needs to be set before this operation. + */ + std::vector<uint8_t> virtual generateICV( + const std::vector<uint8_t>& input) const = 0; + + /** + * @brief Check if the Authentication algorithm is supported + * + * @param[in] algo - authentication algorithm + * + * @return true if algorithm is supported else false + * + */ + static bool isAlgorithmSupported(Algorithms algo) + { + if (algo == Algorithms::RAKP_HMAC_SHA1 || + algo == Algorithms::RAKP_HMAC_SHA256) { - if (algo == Algorithms::RAKP_HMAC_SHA1 || - algo == Algorithms::RAKP_HMAC_SHA256) - { - return true; - } - else - { - return false; - } + return true; } - - // User Key is hardcoded to PASSW0RD till the IPMI User account - // management is in place. - std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"0penBmc"}; - - // Managed System Random Number - std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum; - - // Remote Console Random Number - std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum; - - // Session Integrity Key - std::vector<uint8_t> sessionIntegrityKey; - - /** - * Integrity Algorithm is activated and set in the session data only - * once the session setup is succeeded in the RAKP34 command. But the - * integrity algorithm is negotiated in the Open Session Request command - * . So the integrity algorithm successfully negotiated is stored - * in the authentication algorithm's instance. - */ - integrity::Algorithms intAlgo; - - /** - * Confidentiality Algorithm is activated and set in the session data - * only once the session setup is succeeded in the RAKP34 command. But - * the confidentiality algorithm is negotiated in the Open Session - * Request command. So the confidentiality algorithm successfully - * negotiated is stored in the authentication algorithm's instance. - */ - crypt::Algorithms cryptAlgo; + else + { + return false; + } + } + + // User Key is hardcoded to PASSW0RD till the IPMI User account + // management is in place. + std::array<uint8_t, USER_KEY_MAX_LENGTH> userKey = {"0penBmc"}; + + // Managed System Random Number + std::array<uint8_t, BMC_RANDOM_NUMBER_LEN> bmcRandomNum; + + // Remote Console Random Number + std::array<uint8_t, REMOTE_CONSOLE_RANDOM_NUMBER_LEN> rcRandomNum; + + // Session Integrity Key + std::vector<uint8_t> sessionIntegrityKey; + + /** + * Integrity Algorithm is activated and set in the session data only + * once the session setup is succeeded in the RAKP34 command. But the + * integrity algorithm is negotiated in the Open Session Request command + * . So the integrity algorithm successfully negotiated is stored + * in the authentication algorithm's instance. + */ + integrity::Algorithms intAlgo; + + /** + * Confidentiality Algorithm is activated and set in the session data + * only once the session setup is succeeded in the RAKP34 command. But + * the confidentiality algorithm is negotiated in the Open Session + * Request command. So the confidentiality algorithm successfully + * negotiated is stored in the authentication algorithm's instance. + */ + crypt::Algorithms cryptAlgo; }; /** @@ -157,25 +160,27 @@ class Interface class AlgoSHA1 : public Interface { - public: - static constexpr size_t integrityCheckValueLength = 12; - - explicit AlgoSHA1(integrity::Algorithms intAlgo, - crypt::Algorithms cryptAlgo) : - Interface(intAlgo, cryptAlgo) {} - - AlgoSHA1() = delete; - ~AlgoSHA1() = default; - AlgoSHA1(const AlgoSHA1&) = default; - AlgoSHA1& operator=(const AlgoSHA1&) = default; - AlgoSHA1(AlgoSHA1&&) = default; - AlgoSHA1& operator=(AlgoSHA1&&) = default; - - std::vector<uint8_t> generateHMAC( - const std::vector<uint8_t>& input) const override; - - std::vector<uint8_t> generateICV( - const std::vector<uint8_t>& input) const override; + public: + static constexpr size_t integrityCheckValueLength = 12; + + explicit AlgoSHA1(integrity::Algorithms intAlgo, + crypt::Algorithms cryptAlgo) : + Interface(intAlgo, cryptAlgo) + { + } + + AlgoSHA1() = delete; + ~AlgoSHA1() = default; + AlgoSHA1(const AlgoSHA1&) = default; + AlgoSHA1& operator=(const AlgoSHA1&) = default; + AlgoSHA1(AlgoSHA1&&) = default; + AlgoSHA1& operator=(AlgoSHA1&&) = default; + + std::vector<uint8_t> + generateHMAC(const std::vector<uint8_t>& input) const override; + + std::vector<uint8_t> + generateICV(const std::vector<uint8_t>& input) const override; }; /** @@ -191,27 +196,28 @@ class AlgoSHA1 : public Interface class AlgoSHA256 : public Interface { - public: - static constexpr size_t integrityCheckValueLength = 16; - - explicit AlgoSHA256(integrity::Algorithms intAlgo, - crypt::Algorithms cryptAlgo) : - Interface(intAlgo, cryptAlgo) {} - - ~AlgoSHA256() = default; - AlgoSHA256(const AlgoSHA256&) = default; - AlgoSHA256& operator=(const AlgoSHA256&) = default; - AlgoSHA256(AlgoSHA256&&) = default; - AlgoSHA256& operator=(AlgoSHA256&&) = default; - - std::vector<uint8_t> generateHMAC( - const std::vector<uint8_t>& input) const override; - - std::vector<uint8_t> generateICV( - const std::vector<uint8_t>& input) const override; + public: + static constexpr size_t integrityCheckValueLength = 16; + + explicit AlgoSHA256(integrity::Algorithms intAlgo, + crypt::Algorithms cryptAlgo) : + Interface(intAlgo, cryptAlgo) + { + } + + ~AlgoSHA256() = default; + AlgoSHA256(const AlgoSHA256&) = default; + AlgoSHA256& operator=(const AlgoSHA256&) = default; + AlgoSHA256(AlgoSHA256&&) = default; + AlgoSHA256& operator=(AlgoSHA256&&) = default; + + std::vector<uint8_t> + generateHMAC(const std::vector<uint8_t>& input) const override; + + std::vector<uint8_t> + generateICV(const std::vector<uint8_t>& input) const override; }; -}// namespace auth - -}// namespace cipher +} // namespace rakp_auth +} // namespace cipher diff --git a/comm_module.cpp b/comm_module.cpp index d780e21..a58ca5d 100644 --- a/comm_module.cpp +++ b/comm_module.cpp @@ -1,10 +1,5 @@ #include "comm_module.hpp" -#include <algorithm> -#include <cstring> -#include <iomanip> -#include <iostream> - #include "command/channel_auth.hpp" #include "command/open_session.hpp" #include "command/rakp12.hpp" @@ -14,63 +9,60 @@ #include "main.hpp" #include "session.hpp" +#include <algorithm> +#include <cstring> +#include <iomanip> +#include <iostream> + namespace command { void sessionSetupCommands() { - static const command::CmdDetails commands[] = - { + static const command::CmdDetails commands[] = { // Open Session Request/Response - { - { - (static_cast<uint32_t> - (message::PayloadType::OPEN_SESSION_REQUEST) << 16) - }, - &openSession, session::Privilege::HIGHEST_MATCHING, true - }, + {{(static_cast<uint32_t>(message::PayloadType::OPEN_SESSION_REQUEST) + << 16)}, + &openSession, + session::Privilege::HIGHEST_MATCHING, + true}, // RAKP1 & RAKP2 Message - { - {(static_cast<uint32_t>(message::PayloadType::RAKP1) << 16)}, - &RAKP12, session::Privilege::HIGHEST_MATCHING, true - }, + {{(static_cast<uint32_t>(message::PayloadType::RAKP1) << 16)}, + &RAKP12, + session::Privilege::HIGHEST_MATCHING, + true}, // RAKP3 & RAKP4 Message - { - {(static_cast<uint32_t>(message::PayloadType::RAKP3) << 16)}, - &RAKP34, session::Privilege::HIGHEST_MATCHING, true - }, + {{(static_cast<uint32_t>(message::PayloadType::RAKP3) << 16)}, + &RAKP34, + session::Privilege::HIGHEST_MATCHING, + true}, // Get Channel Authentication Capabilities Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(command::NetFns::APP) | 0x38 - }, - &GetChannelCapabilities, - session::Privilege::HIGHEST_MATCHING, true - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(command::NetFns::APP) | 0x38}, + &GetChannelCapabilities, + session::Privilege::HIGHEST_MATCHING, + true}, // Set Session Privilege Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(command::NetFns::APP) | 0x3B - }, - &setSessionPrivilegeLevel, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(command::NetFns::APP) | 0x3B}, + &setSessionPrivilegeLevel, + session::Privilege::USER, + false}, // Close Session Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(command::NetFns::APP) | 0x3C - }, - &closeSession, session::Privilege::CALLBACK, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(command::NetFns::APP) | 0x3C}, + &closeSession, + session::Privilege::CALLBACK, + false}, }; for (auto& iter : commands) { - std::get<command::Table&>(singletonPool).registerCommand( - iter.command, std::make_unique<command::NetIpmidEntry> - (iter.command, iter.functor, iter.privilege, iter.sessionless)); + std::get<command::Table&>(singletonPool) + .registerCommand(iter.command, + std::make_unique<command::NetIpmidEntry>( + iter.command, iter.functor, iter.privilege, + iter.sessionless)); } } diff --git a/comm_module.hpp b/comm_module.hpp index e96983c..c67b413 100644 --- a/comm_module.hpp +++ b/comm_module.hpp @@ -1,9 +1,9 @@ #pragma once -#include <cstdint> - #include "message_handler.hpp" +#include <cstdint> + namespace command { @@ -12,25 +12,25 @@ namespace command */ enum class RAKP_ReturnCode : uint8_t { - NO_ERROR, //!< No errors - INSUFFICIENT_RESOURCE, //!< Insufficient resources to create a session - INVALID_SESSION_ID, //!< Invalid Session ID - INVALID_PAYLOAD_TYPE, //!< Invalid payload type - INVALID_AUTH_ALGO, //!< Invalid authentication algorithm - INVALID_INTEGRITY_ALGO, //!< Invalid integrity algorithm - NO_MATCH_AUTH_PAYLOAD, //!< No matching authentication payload - NO_MATCH_INTEGRITY_PAYLOAD, //!< No matching integrity payload - INACTIVE_SESSIONID, //!< Inactive Session ID - INACTIVE_ROLE, //!< Invalid role - UNAUTH_ROLE_PRIV, //!< Unauthorized role or privilege requested - INSUFFICIENT_RESOURCES_ROLE,//!< Insufficient resources to create a session - INVALID_NAME_LENGTH, //!< Invalid name length - UNAUTH_NAME, //!< Unauthorized name - UNAUTH_GUID, //!< Unauthorized GUID - INVALID_INTEGRITY_VALUE, //!< Invalid integrity check value - INVALID_CONF_ALGO, //!< Invalid confidentiality algorithm - NO_CIPHER_SUITE_MATCH, //!< No Cipher Suite match with security algos - ILLEGAL_PARAMETER, //!< Illegal or unrecognized parameter + NO_ERROR, //!< No errors + INSUFFICIENT_RESOURCE, //!< Insufficient resources to create a session + INVALID_SESSION_ID, //!< Invalid Session ID + INVALID_PAYLOAD_TYPE, //!< Invalid payload type + INVALID_AUTH_ALGO, //!< Invalid authentication algorithm + INVALID_INTEGRITY_ALGO, //!< Invalid integrity algorithm + NO_MATCH_AUTH_PAYLOAD, //!< No matching authentication payload + NO_MATCH_INTEGRITY_PAYLOAD, //!< No matching integrity payload + INACTIVE_SESSIONID, //!< Inactive Session ID + INACTIVE_ROLE, //!< Invalid role + UNAUTH_ROLE_PRIV, //!< Unauthorized role or privilege requested + INSUFFICIENT_RESOURCES_ROLE, //!< Insufficient resources to create a session + INVALID_NAME_LENGTH, //!< Invalid name length + UNAUTH_NAME, //!< Unauthorized name + UNAUTH_GUID, //!< Unauthorized GUID + INVALID_INTEGRITY_VALUE, //!< Invalid integrity check value + INVALID_CONF_ALGO, //!< Invalid confidentiality algorithm + NO_CIPHER_SUITE_MATCH, //!< No Cipher Suite match with security algos + ILLEGAL_PARAMETER, //!< Illegal or unrecognized parameter }; /** diff --git a/command/channel_auth.cpp b/command/channel_auth.cpp index fbb7242..1ad1472 100644 --- a/command/channel_auth.cpp +++ b/command/channel_auth.cpp @@ -1,26 +1,27 @@ #include "channel_auth.hpp" -#include <iostream> - #include <host-ipmid/ipmid-api.h> +#include <iostream> + namespace command { -std::vector<uint8_t> GetChannelCapabilities( - const std::vector<uint8_t>& inPayload, const message::Handler& handler) +std::vector<uint8_t> + GetChannelCapabilities(const std::vector<uint8_t>& inPayload, + const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(GetChannelCapabilitiesResp)); - auto response = reinterpret_cast<GetChannelCapabilitiesResp*> - (outPayload.data()); + auto response = + reinterpret_cast<GetChannelCapabilitiesResp*>(outPayload.data()); // A canned response, since there is no user and channel management. - response->completionCode = IPMI_CC_OK ; + response->completionCode = IPMI_CC_OK; // Channel Number 1 is arbitrarily applied to primary LAN channel; response->channelNumber = 1; - response->ipmiVersion = 1 ; //IPMI v2.0 extended capabilities available. + response->ipmiVersion = 1; // IPMI v2.0 extended capabilities available. response->reserved1 = 0; response->oem = 0; response->straightKey = 0; @@ -28,17 +29,16 @@ std::vector<uint8_t> GetChannelCapabilities( response->md5 = 0; response->md2 = 0; - response->reserved3 = 0; - response->KGStatus = 0; //KG is set to default - response->perMessageAuth = 0; //Per-message Authentication is enabled - response->userAuth = 0; //User Level Authentication is enabled - response->nonNullUsers = 1; //Non-null usernames enabled - response->nullUsers = 1; //Null usernames enabled - response->anonymousLogin = 0; //Anonymous Login disabled + response->KGStatus = 0; // KG is set to default + response->perMessageAuth = 0; // Per-message Authentication is enabled + response->userAuth = 0; // User Level Authentication is enabled + response->nonNullUsers = 1; // Non-null usernames enabled + response->nullUsers = 1; // Null usernames enabled + response->anonymousLogin = 0; // Anonymous Login disabled response->reserved4 = 0; - response->extCapabilities = 0x2; //Channel supports IPMI v2.0 connections + response->extCapabilities = 0x2; // Channel supports IPMI v2.0 connections response->oemID[0] = 0; response->oemID[1] = 0; diff --git a/command/channel_auth.hpp b/command/channel_auth.hpp index 9d96ac0..aea1dc8 100644 --- a/command/channel_auth.hpp +++ b/command/channel_auth.hpp @@ -1,9 +1,9 @@ #pragma once -#include <vector> - #include "message_handler.hpp" +#include <vector> + namespace command { @@ -25,9 +25,9 @@ struct GetChannelCapabilitiesReq */ struct GetChannelCapabilitiesResp { - uint8_t completionCode; // Completion Code + uint8_t completionCode; // Completion Code - uint8_t channelNumber; // Channel number that the request was + uint8_t channelNumber; // Channel number that the request was // received on #if BYTE_ORDER == LITTLE_ENDIAN @@ -35,21 +35,21 @@ struct GetChannelCapabilitiesResp uint8_t md2 : 1; uint8_t md5 : 1; uint8_t reserved2 : 1; - uint8_t straightKey : 1; // Straight password/key support + uint8_t straightKey : 1; // Straight password/key support // Support OEM identified by the IANA OEM ID in RMCP+ ping response uint8_t oem : 1; uint8_t reserved1 : 1; - uint8_t ipmiVersion : 1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0 + uint8_t ipmiVersion : 1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0 // support #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t ipmiVersion : 1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0 + uint8_t ipmiVersion : 1; // 0b = IPMIV1.5 support only, 1B = IPMI V2.0 // support uint8_t reserved1 : 1; // Support OEM identified by the IANA OEM ID in RMCP+ ping response uint8_t oem : 1; - uint8_t straightKey : 1; // Straight password/key support + uint8_t straightKey : 1; // Straight password/key support uint8_t reserved2 : 1; uint8_t md5 : 1; uint8_t md2 : 1; @@ -97,8 +97,8 @@ struct GetChannelCapabilitiesResp #endif // Below 4 bytes will all the 0's if no OEM authentication type available. - uint8_t oemID[3]; // IANA enterprise number for OEM/organization - uint8_t oemAuxillary; // Addition OEM specific information.. + uint8_t oemID[3]; // IANA enterprise number for OEM/organization + uint8_t oemAuxillary; // Addition OEM specific information.. } __attribute__((packed)); /** @@ -118,7 +118,8 @@ struct GetChannelCapabilitiesResp * * @return Response data for the command */ -std::vector<uint8_t> GetChannelCapabilities( - const std::vector<uint8_t>& inPayload, const message::Handler& handler); +std::vector<uint8_t> + GetChannelCapabilities(const std::vector<uint8_t>& inPayload, + const message::Handler& handler); } // namespace command diff --git a/command/guid.cpp b/command/guid.cpp index 0943846..67b71e2 100644 --- a/command/guid.cpp +++ b/command/guid.cpp @@ -1,12 +1,12 @@ #include "guid.hpp" +#include <host-ipmid/ipmid-api.h> +#include <mapper.h> + #include <iostream> #include <sstream> #include <string> -#include <host-ipmid/ipmid-api.h> -#include <mapper.h> - namespace cache { @@ -26,8 +26,8 @@ Guid getSystemGUID() { // Canned System GUID for QEMU where the Chassis DBUS object is not // populated - Guid guid = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; + Guid guid = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; constexpr auto chassisIntf = "org.openbmc.control.Chassis"; @@ -43,8 +43,8 @@ Guid getSystemGUID() rc = mapper_get_service(bus, guidObjPath, &busname); if (rc < 0) { - std::cerr << "Failed to get " << guidObjPath << " bus name: " - << strerror(-rc) << "\n"; + std::cerr << "Failed to get " << guidObjPath + << " bus name: " << strerror(-rc) << "\n"; break; } @@ -66,15 +66,14 @@ Guid getSystemGUID() std::string readUUID(uuid); auto len = readUUID.length(); - for (size_t iter = 0, inc = 0; - iter < len && inc < BMC_GUID_LEN; iter += 2, inc++) + for (size_t iter = 0, inc = 0; iter < len && inc < BMC_GUID_LEN; + iter += 2, inc++) { - uint8_t hexVal = std::strtoul(readUUID.substr(iter, 2).c_str(), - NULL, 16); + uint8_t hexVal = + std::strtoul(readUUID.substr(iter, 2).c_str(), NULL, 16); guid[inc] = hexVal; } - } - while (0); + } while (0); sd_bus_error_free(&error); reply = sd_bus_message_unref(reply); @@ -85,18 +84,18 @@ Guid getSystemGUID() void registerGUIDChangeCallback() { - if(matchPtr == nullptr) + if (matchPtr == nullptr) { using namespace sdbusplus::bus::match::rules; sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; matchPtr = std::make_unique<sdbusplus::bus::match_t>( bus, - path_namespace(guidObjPath) + - type::signal() + - member("PropertiesChanged") + - interface(propInterface), - [](sdbusplus::message::message&){cache::guid = getSystemGUID();}); + path_namespace(guidObjPath) + type::signal() + + member("PropertiesChanged") + interface(propInterface), + [](sdbusplus::message::message&) { + cache::guid = getSystemGUID(); + }); } } diff --git a/command/guid.hpp b/command/guid.hpp index 5941ef8..f73e449 100644 --- a/command/guid.hpp +++ b/command/guid.hpp @@ -1,9 +1,10 @@ #pragma once +#include "comm_module.hpp" + #include <cstddef> -#include <vector> #include <sdbusplus/bus/match.hpp> -#include "comm_module.hpp" +#include <vector> namespace command { @@ -32,4 +33,4 @@ namespace cache extern command::Guid guid; -} //namespace cache +} // namespace cache diff --git a/command/open_session.cpp b/command/open_session.cpp index 6e08d1a..b41eefa 100644 --- a/command/open_session.cpp +++ b/command/open_session.cpp @@ -1,11 +1,11 @@ #include "open_session.hpp" -#include <iostream> - #include "comm_module.hpp" #include "endian.hpp" #include "main.hpp" +#include <iostream> + namespace command { @@ -14,12 +14,13 @@ std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, { std::vector<uint8_t> outPayload(sizeof(OpenSessionResponse)); - auto request = reinterpret_cast<const OpenSessionRequest*>(inPayload.data()); + auto request = + reinterpret_cast<const OpenSessionRequest*>(inPayload.data()); auto response = reinterpret_cast<OpenSessionResponse*>(outPayload.data()); // Check for valid Authentication Algorithms if (!cipher::rakp_auth::Interface::isAlgorithmSupported( - static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo))) + static_cast<cipher::rakp_auth::Algorithms>(request->authAlgo))) { response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::INVALID_AUTH_ALGO); @@ -28,7 +29,7 @@ std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, // Check for valid Integrity Algorithms if (!cipher::integrity::Interface::isAlgorithmSupported( - static_cast<cipher::integrity::Algorithms>(request->intAlgo))) + static_cast<cipher::integrity::Algorithms>(request->intAlgo))) { response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_ALGO); @@ -36,8 +37,8 @@ std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, } // Check for valid Confidentiality Algorithms - if(!cipher::crypt::Interface::isAlgorithmSupported(static_cast - <cipher::crypt::Algorithms>(request->confAlgo))) + if (!cipher::crypt::Interface::isAlgorithmSupported( + static_cast<cipher::crypt::Algorithms>(request->confAlgo))) { response->status_code = static_cast<uint8_t>(RAKP_ReturnCode::INVALID_CONF_ALGO); @@ -48,19 +49,23 @@ std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, 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(); + 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); + response->status_code = + static_cast<uint8_t>(RAKP_ReturnCode::INSUFFICIENT_RESOURCE); std::cerr << "openSession : Problem opening a session\n"; return outPayload; } @@ -69,19 +74,19 @@ std::vector<uint8_t> openSession(const std::vector<uint8_t>& inPayload, 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->managedSystemSessionID = + endian::to_ipmi<>(session->getBMCSessionID()); - response->authPayload = request->authPayload ; - response->authPayloadLen = request->authPayloadLen ; + response->authPayload = request->authPayload; + response->authPayloadLen = request->authPayloadLen; response->authAlgo = request->authAlgo; - response->intPayload = request->intPayload ; - response->intPayloadLen = request->intPayloadLen ; + response->intPayload = request->intPayload; + response->intPayloadLen = request->intPayloadLen; response->intAlgo = request->intAlgo; - response->confPayload = request->confPayload ; - response->confPayloadLen = request->confPayloadLen ; + response->confPayload = request->confPayload; + response->confPayloadLen = request->confPayloadLen; response->confAlgo = request->confAlgo; session->updateLastTransactionTime(); diff --git a/command/open_session.hpp b/command/open_session.hpp index 677fe55..700c784 100644 --- a/command/open_session.hpp +++ b/command/open_session.hpp @@ -1,9 +1,9 @@ #pragma once -#include <vector> - #include "message_handler.hpp" +#include <vector> + namespace command { @@ -14,25 +14,25 @@ namespace command */ struct OpenSessionRequest { - uint8_t messageTag; // Message tag from request buffer + uint8_t messageTag; // Message tag from request buffer #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t maxPrivLevel : 4 ;// Requested maximum privilege level - uint8_t reserved1 : 4; // Reserved for future definition + uint8_t maxPrivLevel : 4; // Requested maximum privilege level + uint8_t reserved1 : 4; // Reserved for future definition #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved1 : 4; // Reserved for future definition - uint8_t maxPrivLevel : 4 ;// Requested maximum privilege level + uint8_t reserved1 : 4; // Reserved for future definition + uint8_t maxPrivLevel : 4; // Requested maximum privilege level #endif uint16_t reserved2; - uint32_t remoteConsoleSessionID ; + uint32_t remoteConsoleSessionID; - uint8_t authPayload ; - uint16_t reserved3; - uint8_t authPayloadLen; + uint8_t authPayload; + uint16_t reserved3; + uint8_t authPayloadLen; #if BYTE_ORDER == LITTLE_ENDIAN uint8_t authAlgo : 6; @@ -49,7 +49,7 @@ struct OpenSessionRequest uint8_t intPayload; uint16_t reserved7; - uint8_t intPayloadLen; + uint8_t intPayloadLen; #if BYTE_ORDER == LITTLE_ENDIAN uint8_t intAlgo : 6; @@ -66,7 +66,7 @@ struct OpenSessionRequest uint8_t confPayload; uint16_t reserved11; - uint8_t confPayloadLen; + uint8_t confPayloadLen; #if BYTE_ORDER == LITTLE_ENDIAN uint8_t confAlgo : 6; @@ -125,7 +125,7 @@ struct OpenSessionResponse uint8_t intPayload; uint16_t reserved7; - uint8_t intPayloadLen; + uint8_t intPayloadLen; #if BYTE_ORDER == LITTLE_ENDIAN uint8_t intAlgo : 6; @@ -143,7 +143,7 @@ struct OpenSessionResponse uint8_t confPayload; uint16_t reserved11; - uint8_t confPayloadLen; + uint8_t confPayloadLen; #if BYTE_ORDER == LITTLE_ENDIAN uint8_t confAlgo : 6; diff --git a/command/payload_cmds.cpp b/command/payload_cmds.cpp index 2215046..8030b92 100644 --- a/command/payload_cmds.cpp +++ b/command/payload_cmds.cpp @@ -1,10 +1,13 @@ -#include <host-ipmid/ipmid-api.h> -#include <phosphor-logging/log.hpp> -#include "main.hpp" #include "payload_cmds.hpp" + +#include "main.hpp" #include "sol/sol_manager.hpp" #include "sol_cmds.hpp" +#include <host-ipmid/ipmid-api.h> + +#include <phosphor-logging/log.hpp> + namespace sol { @@ -17,10 +20,10 @@ std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse)); - auto request = reinterpret_cast<const ActivatePayloadRequest*> - (inPayload.data()); - auto response = reinterpret_cast<ActivatePayloadResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data()); + auto response = + reinterpret_cast<ActivatePayloadResponse*>(outPayload.data()); response->completionCode = IPMI_CC_OK; @@ -44,8 +47,9 @@ std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload, return outPayload; } - auto session = (std::get<session::Manager&>(singletonPool).getSession( - handler.sessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(handler.sessionID)) + .lock(); if (!request->encryption && session->isCryptAlgoEnabled()) { @@ -53,8 +57,8 @@ std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload, return outPayload; } - auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive( - request->payloadInstance); + auto status = std::get<sol::Manager&>(singletonPool) + .isPayloadActive(request->payloadInstance); if (status) { response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE; @@ -67,9 +71,8 @@ std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload, // Start the SOL payload try { - std::get<sol::Manager&>(singletonPool).startPayloadInstance( - request->payloadInstance, - handler.sessionID); + std::get<sol::Manager&>(singletonPool) + .startPayloadInstance(request->payloadInstance, handler.sessionID); } catch (std::exception& e) { @@ -92,10 +95,10 @@ std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse)); - auto request = reinterpret_cast<const DeactivatePayloadRequest*> - (inPayload.data()); - auto response = reinterpret_cast<DeactivatePayloadResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data()); + auto response = + reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data()); response->completionCode = IPMI_CC_OK; @@ -113,8 +116,8 @@ std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload, return outPayload; } - auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive( - request->payloadInstance); + auto status = std::get<sol::Manager&>(singletonPool) + .isPayloadActive(request->payloadInstance); if (!status) { response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED; @@ -123,12 +126,12 @@ std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload, try { - auto& context = std::get<sol::Manager&>(singletonPool).getContext - (request->payloadInstance); + auto& context = std::get<sol::Manager&>(singletonPool) + .getContext(request->payloadInstance); auto sessionID = context.sessionID; - std::get<sol::Manager&>(singletonPool).stopPayloadInstance( - request->payloadInstance); + std::get<sol::Manager&>(singletonPool) + .stopPayloadInstance(request->payloadInstance); try { @@ -146,8 +149,8 @@ std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload, return outPayload; } - auto check = std::get<session::Manager&>(singletonPool).stopSession - (sessionID); + auto check = + std::get<session::Manager&>(singletonPool).stopSession(sessionID); if (!check) { response->completionCode = IPMI_CC_UNSPECIFIED_ERROR; @@ -167,10 +170,10 @@ std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse)); - auto request = reinterpret_cast<const GetPayloadStatusRequest*> - (inPayload.data()); - auto response = reinterpret_cast<GetPayloadStatusResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data()); + auto response = + reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data()); // SOL is the payload currently supported for payload status if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType) @@ -184,7 +187,7 @@ std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload, // Currently we support only one SOL session response->instance1 = - std::get<sol::Manager&>(singletonPool).isPayloadActive(1); + std::get<sol::Manager&>(singletonPool).isPayloadActive(1); return outPayload; } @@ -193,22 +196,23 @@ std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse)); - auto request = reinterpret_cast<const GetPayloadInfoRequest*> - (inPayload.data()); - auto response = reinterpret_cast<GetPayloadInfoResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data()); + auto response = + reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data()); // SOL is the payload currently supported for payload status & only one // instance of SOL is supported. - if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType - || request->payloadInstance != 1) + if (static_cast<uint8_t>(message::PayloadType::SOL) != + request->payloadType || + request->payloadInstance != 1) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; return outPayload; } - auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive( - request->payloadInstance); + auto status = std::get<sol::Manager&>(singletonPool) + .isPayloadActive(request->payloadInstance); if (!status) { @@ -216,8 +220,8 @@ std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload, return outPayload; } - auto& context = std::get<sol::Manager&>(singletonPool).getContext - (request->payloadInstance); + auto& context = std::get<sol::Manager&>(singletonPool) + .getContext(request->payloadInstance); response->sessionID = context.sessionID; return outPayload; diff --git a/command/payload_cmds.hpp b/command/payload_cmds.hpp index d751a95..f916c11 100644 --- a/command/payload_cmds.hpp +++ b/command/payload_cmds.hpp @@ -1,8 +1,9 @@ #pragma once -#include <vector> #include "message_handler.hpp" +#include <vector> + namespace sol { @@ -22,23 +23,23 @@ constexpr uint8_t IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION = 0x84; struct ActivatePayloadRequest { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t payloadType : 6; //!< Payload type. - uint8_t reserved1 : 2; //!< Reserved. + uint8_t payloadType : 6; //!< Payload type. + uint8_t reserved1 : 2; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved1 : 2; //!< Payload type. - uint8_t payloadType : 6; //!< Payload type. + uint8_t reserved1 : 2; //!< Payload type. + uint8_t payloadType : 6; //!< Payload type. #endif #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t payloadInstance : 4; //!< Payload instance. - uint8_t reserved2 : 4; //!< Reserved. + uint8_t payloadInstance : 4; //!< Payload instance. + uint8_t reserved2 : 4; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved2 : 4; //!< Reserved. - uint8_t payloadInstance : 4; //!< Payload instance. + uint8_t reserved2 : 4; //!< Reserved. + uint8_t payloadInstance : 4; //!< Payload instance. #endif /** @brief The following Auxiliary Request Data applies only for payload @@ -64,9 +65,9 @@ struct ActivatePayloadRequest uint8_t reserved4 : 1; //!< Reserved. #endif - uint8_t reserved5; //!< Reserved. - uint8_t reserved6; //!< Reserved. - uint8_t reserved7; //!< Reserved. + uint8_t reserved5; //!< Reserved. + uint8_t reserved6; //!< Reserved. + uint8_t reserved7; //!< Reserved. } __attribute__((packed)); /** @struct ActivatePayloadResponse @@ -75,26 +76,26 @@ struct ActivatePayloadRequest */ struct ActivatePayloadResponse { - uint8_t completionCode; //!< Completion code. - uint8_t reserved1; //!< Reserved. - uint8_t reserved2; //!< Reserved. - uint8_t reserved3; //!< Reserved. + uint8_t completionCode; //!< Completion code. + uint8_t reserved1; //!< Reserved. + uint8_t reserved2; //!< Reserved. + uint8_t reserved3; //!< Reserved. // Test Mode #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t testMode : 1; //!< Test mode. - uint8_t reserved4 : 7; //!< Reserved. + uint8_t testMode : 1; //!< Test mode. + uint8_t reserved4 : 7; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved4 : 7; //!< Reserved. - uint8_t testMode : 1; //!< Test mode. + uint8_t reserved4 : 7; //!< Reserved. + uint8_t testMode : 1; //!< Test mode. #endif - uint16_t inPayloadSize; //!< Inbound payload size - uint16_t outPayloadSize; //!< Outbound payload size. - uint16_t portNum; //!< Payload UDP port number. - uint16_t vlanNum; //!< Payload VLAN number. + uint16_t inPayloadSize; //!< Inbound payload size + uint16_t outPayloadSize; //!< Outbound payload size. + uint16_t portNum; //!< Payload UDP port number. + uint16_t vlanNum; //!< Payload VLAN number. } __attribute__((packed)); /** @brief Activate Payload Command. @@ -120,29 +121,29 @@ constexpr uint8_t IPMI_CC_PAYLOAD_DEACTIVATED = 0x80; struct DeactivatePayloadRequest { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t payloadType : 6; //!< Payload type. - uint8_t reserved1 : 2; //!< Reserved. + uint8_t payloadType : 6; //!< Payload type. + uint8_t reserved1 : 2; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved1 : 2; //!< Payload type. - uint8_t payloadType : 6; //!< Reserved. + uint8_t reserved1 : 2; //!< Payload type. + uint8_t payloadType : 6; //!< Reserved. #endif #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t payloadInstance : 4; //!< Payload instance. - uint8_t reserved2 : 4; //!< Reserved. + uint8_t payloadInstance : 4; //!< Payload instance. + uint8_t reserved2 : 4; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved2 : 4; //!< Reserved. - uint8_t payloadInstance : 4; //!< Payload instance. + uint8_t reserved2 : 4; //!< Reserved. + uint8_t payloadInstance : 4; //!< Payload instance. #endif /** @brief No auxiliary data for payload type SOL */ - uint8_t auxData1; //!< Auxiliary data 1 - uint8_t auxData2; //!< Auxiliary data 2 - uint8_t auxData3; //!< Auxiliary data 3 + uint8_t auxData1; //!< Auxiliary data 1 + uint8_t auxData2; //!< Auxiliary data 2 + uint8_t auxData3; //!< Auxiliary data 3 } __attribute__((packed)); /** @struct DeactivatePayloadResponse @@ -151,7 +152,7 @@ struct DeactivatePayloadRequest */ struct DeactivatePayloadResponse { - uint8_t completionCode; //!< Completion code + uint8_t completionCode; //!< Completion code } __attribute__((packed)); /** @brief Deactivate Payload Command. @@ -179,7 +180,7 @@ std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload, */ struct GetPayloadStatusRequest { - uint8_t payloadType; //!< Payload type + uint8_t payloadType; //!< Payload type } __attribute__((packed)); /** @struct GetPayloadStatusResponse @@ -190,33 +191,33 @@ struct GetPayloadStatusResponse { uint8_t completionCode; //!< Completion code. - uint8_t capacity; //!< Instance capacity. + uint8_t capacity; //!< Instance capacity. /* @brief Activation Status. */ #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t instance1 : 1; //!< If true, Instance 1 is activated. - uint8_t instance2 : 1; //!< If true, Instance 2 is activated. - uint8_t instance3 : 1; //!< If true, Instance 3 is activated. - uint8_t instance4 : 1; //!< If true, Instance 4 is activated. - uint8_t instance5 : 1; //!< If true, Instance 5 is activated. - uint8_t instance6 : 1; //!< If true, Instance 6 is activated. - uint8_t instance7 : 1; //!< If true, Instance 7 is activated. - uint8_t instance8 : 1; //!< If true, Instance 8 is activated. + uint8_t instance1 : 1; //!< If true, Instance 1 is activated. + uint8_t instance2 : 1; //!< If true, Instance 2 is activated. + uint8_t instance3 : 1; //!< If true, Instance 3 is activated. + uint8_t instance4 : 1; //!< If true, Instance 4 is activated. + uint8_t instance5 : 1; //!< If true, Instance 5 is activated. + uint8_t instance6 : 1; //!< If true, Instance 6 is activated. + uint8_t instance7 : 1; //!< If true, Instance 7 is activated. + uint8_t instance8 : 1; //!< If true, Instance 8 is activated. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t instance8 : 1; //!< If true, Instance 8 is activated. - uint8_t instance7 : 1; //!< If true, Instance 7 is activated. - uint8_t instance6 : 1; //!< If true, Instance 6 is activated. - uint8_t instance5 : 1; //!< If true, Instance 5 is activated. - uint8_t instance4 : 1; //!< If true, Instance 4 is activated. - uint8_t instance3 : 1; //!< If true, Instance 3 is activated. - uint8_t instance2 : 1; //!< If true, Instance 2 is activated. - uint8_t instance1 : 1; //!< If true, Instance 1 is activated. + uint8_t instance8 : 1; //!< If true, Instance 8 is activated. + uint8_t instance7 : 1; //!< If true, Instance 7 is activated. + uint8_t instance6 : 1; //!< If true, Instance 6 is activated. + uint8_t instance5 : 1; //!< If true, Instance 5 is activated. + uint8_t instance4 : 1; //!< If true, Instance 4 is activated. + uint8_t instance3 : 1; //!< If true, Instance 3 is activated. + uint8_t instance2 : 1; //!< If true, Instance 2 is activated. + uint8_t instance1 : 1; //!< If true, Instance 1 is activated. #endif #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t instance9 : 1; //!< If true, Instance 9 is activated. + uint8_t instance9 : 1; //!< If true, Instance 9 is activated. uint8_t instance10 : 1; //!< If true, Instance 10 is activated. uint8_t instance11 : 1; //!< If true, Instance 11 is activated. uint8_t instance12 : 1; //!< If true, Instance 12 is activated. @@ -234,7 +235,7 @@ struct GetPayloadStatusResponse uint8_t instance12 : 1; //!< If true, Instance 12 is activated. uint8_t instance11 : 1; //!< If true, Instance 11 is activated. uint8_t instance10 : 1; //!< If true, Instance 10 is activated. - uint8_t instance9 : 1; //!< If true, Instance 9 is activated. + uint8_t instance9 : 1; //!< If true, Instance 9 is activated. #endif } __attribute__((packed)); @@ -257,8 +258,8 @@ std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload, */ struct GetPayloadInfoRequest { - uint8_t payloadType; //!< Payload type - uint8_t payloadInstance;//!< Payload instance + uint8_t payloadType; //!< Payload type + uint8_t payloadInstance; //!< Payload instance } __attribute__((packed)); /** @struct GetPayloadInfoResponse diff --git a/command/rakp12.cpp b/command/rakp12.cpp index c52d188..b0aad87 100644 --- a/command/rakp12.cpp +++ b/command/rakp12.cpp @@ -1,5 +1,10 @@ #include "rakp12.hpp" +#include "comm_module.hpp" +#include "endian.hpp" +#include "guid.hpp" +#include "main.hpp" + #include <openssl/rand.h> #include <algorithm> @@ -7,11 +12,6 @@ #include <iomanip> #include <iostream> -#include "comm_module.hpp" -#include "endian.hpp" -#include "guid.hpp" -#include "main.hpp" - namespace command { @@ -23,8 +23,8 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, auto response = reinterpret_cast<RAKP2response*>(outPayload.data()); // Session ID zero is reserved for Session Setup - if(endian::from_ipmi(request->managedSystemSessionID) == - session::SESSION_ZERO) + if (endian::from_ipmi(request->managedSystemSessionID) == + session::SESSION_ZERO) { std::cerr << "RAKP12: BMC invalid Session ID\n"; response->rmcpStatusCode = @@ -35,8 +35,10 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, std::shared_ptr<session::Session> session; try { - session = (std::get<session::Manager&>(singletonPool).getSession( - endian::from_ipmi(request->managedSystemSessionID))).lock(); + session = (std::get<session::Manager&>(singletonPool) + .getSession( + endian::from_ipmi(request->managedSystemSessionID))) + .lock(); } catch (std::exception& e) { @@ -46,12 +48,12 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, return outPayload; } - auto rakp1Size = sizeof(RAKP1request) - - (userNameMaxLen - request->user_name_len); + auto rakp1Size = + sizeof(RAKP1request) - (userNameMaxLen - request->user_name_len); // Validate user name length in the message if (request->user_name_len > userNameMaxLen || - inPayload.size() != rakp1Size) + inPayload.size() != rakp1Size) { response->rmcpStatusCode = static_cast<uint8_t>(RAKP_ReturnCode::INVALID_NAME_LENGTH); @@ -92,16 +94,15 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, std::vector<uint8_t> input; input.resize(sizeof(rcSessionID) + sizeof(bmcSessionID) + cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN + - cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN + - BMC_GUID_LEN + sizeof(request->req_max_privilege_level) + - sizeof(request->user_name_len) + - session->userName.size()); + cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN + BMC_GUID_LEN + + sizeof(request->req_max_privilege_level) + + sizeof(request->user_name_len) + session->userName.size()); auto iter = input.begin(); // Remote Console Session ID - std::copy_n(reinterpret_cast<uint8_t*>(&rcSessionID), - sizeof(rcSessionID), iter); + std::copy_n(reinterpret_cast<uint8_t*>(&rcSessionID), sizeof(rcSessionID), + iter); std::advance(iter, sizeof(rcSessionID)); // Managed System Session ID @@ -111,18 +112,17 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, // Copy the Remote Console Random Number from the RAKP1 request to the // Authentication Algorithm - std::copy_n(reinterpret_cast<const uint8_t*> - (request->remote_console_random_number), - cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN, - authAlgo->rcRandomNum.begin()); + std::copy_n( + reinterpret_cast<const uint8_t*>(request->remote_console_random_number), + cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN, + authAlgo->rcRandomNum.begin()); - std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), - iter); + std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter); std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN); // Generate the Managed System Random Number if (!RAND_bytes(input.data() + sizeof(rcSessionID) + sizeof(bmcSessionID) + - cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN, + cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN, cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN)) { response->rmcpStatusCode = @@ -140,8 +140,8 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, std::advance(iter, BMC_GUID_LEN); // Requested Privilege Level - session->curPrivLevel = static_cast<session::Privilege> - (request->req_max_privilege_level); + session->curPrivLevel = + static_cast<session::Privilege>(request->req_max_privilege_level); std::copy_n(&(request->req_max_privilege_level), sizeof(request->req_max_privilege_level), iter); std::advance(iter, sizeof(request->req_max_privilege_level)); @@ -162,15 +162,14 @@ std::vector<uint8_t> RAKP12(const std::vector<uint8_t>& inPayload, response->messageTag = request->messageTag; response->rmcpStatusCode = static_cast<uint8_t>(RAKP_ReturnCode::NO_ERROR); response->reserved = 0; - response->remoteConsoleSessionID = rcSessionID ; + response->remoteConsoleSessionID = rcSessionID; // Copy Managed System Random Number to the Response std::copy(authAlgo->bmcRandomNum.begin(), authAlgo->bmcRandomNum.end(), response->managed_system_random_number); // Copy System GUID to the Response - std::copy_n(cache::guid.data(), - cache::guid.size(), + std::copy_n(cache::guid.data(), cache::guid.size(), response->managed_system_guid); // Insert the HMAC output into the payload diff --git a/command/rakp12.hpp b/command/rakp12.hpp index 189b5e5..1ce533a 100644 --- a/command/rakp12.hpp +++ b/command/rakp12.hpp @@ -1,9 +1,9 @@ #pragma once -#include <vector> - -#include "message_handler.hpp" #include "comm_module.hpp" +#include "message_handler.hpp" + +#include <vector> namespace command { diff --git a/command/rakp34.cpp b/command/rakp34.cpp index 37335a8..76236d5 100644 --- a/command/rakp34.cpp +++ b/command/rakp34.cpp @@ -1,22 +1,23 @@ #include "rakp34.hpp" -#include <algorithm> -#include <cstring> -#include <iostream> - #include "comm_module.hpp" #include "endian.hpp" #include "guid.hpp" #include "main.hpp" #include "rmcp.hpp" +#include <algorithm> +#include <cstring> +#include <iostream> + namespace command { void applyIntegrityAlgo(const uint32_t bmcSessionID) { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - bmcSessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(bmcSessionID)) + .lock(); auto authAlgo = session->getAuthAlgo(); @@ -25,15 +26,15 @@ void applyIntegrityAlgo(const uint32_t bmcSessionID) case cipher::integrity::Algorithms::HMAC_SHA1_96: { session->setIntegrityAlgo( - std::make_unique<cipher::integrity::AlgoSHA1>( - authAlgo->sessionIntegrityKey)); + std::make_unique<cipher::integrity::AlgoSHA1>( + authAlgo->sessionIntegrityKey)); break; } case cipher::integrity::Algorithms::HMAC_SHA256_128: { session->setIntegrityAlgo( std::make_unique<cipher::integrity::AlgoSHA256>( - authAlgo->sessionIntegrityKey)); + authAlgo->sessionIntegrityKey)); break; } default: @@ -43,8 +44,9 @@ void applyIntegrityAlgo(const uint32_t bmcSessionID) void applyCryptAlgo(const uint32_t bmcSessionID) { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - bmcSessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(bmcSessionID)) + .lock(); auto authAlgo = session->getAuthAlgo(); @@ -53,10 +55,10 @@ void applyCryptAlgo(const uint32_t bmcSessionID) case cipher::crypt::Algorithms::AES_CBC_128: { auto intAlgo = session->getIntegrityAlgo(); - auto k2 = intAlgo->generateKn( - authAlgo->sessionIntegrityKey, rmcp::const_2); + auto k2 = intAlgo->generateKn(authAlgo->sessionIntegrityKey, + rmcp::const_2); session->setCryptAlgo( - std::make_unique<cipher::crypt::AlgoAES128>(k2)); + std::make_unique<cipher::crypt::AlgoAES128>(k2)); break; } default: @@ -82,8 +84,8 @@ std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload, } // Session ID zero is reserved for Session Setup - if(endian::from_ipmi(request->managedSystemSessionID) == - session::SESSION_ZERO) + if (endian::from_ipmi(request->managedSystemSessionID) == + session::SESSION_ZERO) { std::cerr << "RAKP34: BMC invalid Session ID\n"; response->rmcpStatusCode = @@ -94,8 +96,10 @@ std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload, std::shared_ptr<session::Session> session; try { - session = (std::get<session::Manager&>(singletonPool).getSession( - endian::from_ipmi(request->managedSystemSessionID))).lock(); + session = (std::get<session::Manager&>(singletonPool) + .getSession( + endian::from_ipmi(request->managedSystemSessionID))) + .lock(); } catch (std::exception& e) { @@ -159,19 +163,19 @@ std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload, auto output = authAlgo->generateHMAC(input); if (inPayload.size() != (sizeof(RAKP3request) + output.size()) || - std::memcmp(output.data(), request+1, output.size())) + std::memcmp(output.data(), request + 1, output.size())) { std::cerr << "Mismatch in HMAC sent by remote console\n"; response->messageTag = request->messageTag; - response->rmcpStatusCode = static_cast<uint8_t> - (RAKP_ReturnCode::INVALID_INTEGRITY_VALUE); + response->rmcpStatusCode = + static_cast<uint8_t>(RAKP_ReturnCode::INVALID_INTEGRITY_VALUE); response->reserved = 0; response->remoteConsoleSessionID = rcSessionID; - //close the session - std::get<session::Manager&>(singletonPool).stopSession( - session->getBMCSessionID()); + // close the session + std::get<session::Manager&>(singletonPool) + .stopSession(session->getBMCSessionID()); return outPayload; } @@ -194,8 +198,7 @@ std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload, iter = input.begin(); // Remote Console Random Number - std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), - iter); + std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter); std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN); // Managed Console Random Number @@ -239,8 +242,7 @@ std::vector<uint8_t> RAKP34(const std::vector<uint8_t>& inPayload, iter = input.begin(); // Remote Console Random Number - std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), - iter); + std::copy(authAlgo->rcRandomNum.begin(), authAlgo->rcRandomNum.end(), iter); std::advance(iter, cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN); // Managed System Session ID diff --git a/command/rakp34.hpp b/command/rakp34.hpp index 2f00823..e582256 100644 --- a/command/rakp34.hpp +++ b/command/rakp34.hpp @@ -1,9 +1,9 @@ #pragma once -#include <vector> - -#include "message_handler.hpp" #include "comm_module.hpp" +#include "message_handler.hpp" + +#include <vector> namespace command { diff --git a/command/session_cmds.cpp b/command/session_cmds.cpp index e199532..fb2d074 100644 --- a/command/session_cmds.cpp +++ b/command/session_cmds.cpp @@ -1,28 +1,31 @@ #include "session_cmds.hpp" -#include <iostream> - #include "endian.hpp" #include "main.hpp" + #include <host-ipmid/ipmid-api.h> +#include <iostream> + namespace command { -std::vector<uint8_t> setSessionPrivilegeLevel( - const std::vector<uint8_t>& inPayload, const message::Handler& handler) +std::vector<uint8_t> + setSessionPrivilegeLevel(const std::vector<uint8_t>& inPayload, + const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(SetSessionPrivLevelResp)); - auto request = reinterpret_cast<const SetSessionPrivLevelReq*> - (inPayload.data()); - auto response = reinterpret_cast<SetSessionPrivLevelResp*> - (outPayload.data()); + auto request = + reinterpret_cast<const SetSessionPrivLevelReq*>(inPayload.data()); + auto response = + reinterpret_cast<SetSessionPrivLevelResp*>(outPayload.data()); response->completionCode = IPMI_CC_OK; uint8_t reqPrivilegeLevel = request->reqPrivLevel; - auto session = (std::get<session::Manager&>(singletonPool).getSession( - handler.sessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(handler.sessionID)) + .lock(); if (reqPrivilegeLevel == 0) // Just return present privilege level { @@ -30,8 +33,8 @@ std::vector<uint8_t> setSessionPrivilegeLevel( } else if (reqPrivilegeLevel <= static_cast<uint8_t>(session->maxPrivLevel)) { - session->curPrivLevel = static_cast<session::Privilege> - (reqPrivilegeLevel); + session->curPrivLevel = + static_cast<session::Privilege>(reqPrivilegeLevel); response->newPrivLevel = reqPrivilegeLevel; } else @@ -46,10 +49,10 @@ std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(CloseSessionResponse)); - auto request = reinterpret_cast<const CloseSessionRequest*> - (inPayload.data()); + auto request = + reinterpret_cast<const CloseSessionRequest*>(inPayload.data()); auto response = reinterpret_cast<CloseSessionResponse*>(outPayload.data()); - response->completionCode = IPMI_CC_OK ; + response->completionCode = IPMI_CC_OK; auto bmcSessionID = endian::from_ipmi(request->sessionID); @@ -61,9 +64,9 @@ std::vector<uint8_t> closeSession(const std::vector<uint8_t>& inPayload, } else { - auto status = std::get<session::Manager&>(singletonPool).stopSession - (bmcSessionID); - if(!status) + auto status = std::get<session::Manager&>(singletonPool) + .stopSession(bmcSessionID); + if (!status) { response->completionCode = IPMI_CC_INVALID_SESSIONID; } diff --git a/command/session_cmds.hpp b/command/session_cmds.hpp index 738bd03..9737fdb 100644 --- a/command/session_cmds.hpp +++ b/command/session_cmds.hpp @@ -1,9 +1,9 @@ #pragma once -#include <vector> - #include "message_handler.hpp" +#include <vector> + namespace command { @@ -71,8 +71,9 @@ struct SetSessionPrivLevelResp * * @return Response data for the command */ -std::vector<uint8_t> setSessionPrivilegeLevel( - const std::vector<uint8_t>& inPayload, const message::Handler& handler); +std::vector<uint8_t> + setSessionPrivilegeLevel(const std::vector<uint8_t>& inPayload, + const message::Handler& handler); constexpr uint8_t IPMI_CC_INVALID_SESSIONID = 0x87; diff --git a/command/sol_cmds.cpp b/command/sol_cmds.cpp index fffefb3..fb6f19e 100644 --- a/command/sol_cmds.cpp +++ b/command/sol_cmds.cpp @@ -1,8 +1,10 @@ -#include <phosphor-logging/log.hpp> +#include "sol_cmds.hpp" + #include "main.hpp" #include "sol/sol_context.hpp" #include "sol/sol_manager.hpp" -#include "sol_cmds.hpp" + +#include <phosphor-logging/log.hpp> namespace sol { @@ -19,23 +21,20 @@ std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload, auto solDataSize = inPayload.size() - sizeof(Payload); std::vector<uint8_t> charData(solDataSize); - if( solDataSize > 0) + if (solDataSize > 0) { - std::copy_n(inPayload.data() + sizeof(Payload), - solDataSize, + std::copy_n(inPayload.data() + sizeof(Payload), solDataSize, charData.begin()); } try { - auto& context = std::get<sol::Manager&>(singletonPool). - getContext(handler.sessionID); - - context.processInboundPayload(request->packetSeqNum, - request->packetAckSeqNum, - request->acceptedCharCount, - request->inOperation.ack, - charData); + auto& context = std::get<sol::Manager&>(singletonPool) + .getContext(handler.sessionID); + + context.processInboundPayload( + request->packetSeqNum, request->packetAckSeqNum, + request->acceptedCharCount, request->inOperation.ack, charData); } catch (std::exception& e) { @@ -50,21 +49,20 @@ void activating(uint8_t payloadInstance, uint32_t sessionID) { std::vector<uint8_t> outPayload(sizeof(ActivatingRequest)); - auto request = reinterpret_cast<ActivatingRequest*> - (outPayload.data()); + auto request = reinterpret_cast<ActivatingRequest*>(outPayload.data()); request->sessionState = 0; request->payloadInstance = payloadInstance; request->majorVersion = MAJOR_VERSION; request->minorVersion = MINOR_VERSION; - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); message::Handler msgHandler(session->channelPtr, sessionID); - msgHandler.sendUnsolicitedIPMIPayload(netfnTransport, - solActivatingCmd, + msgHandler.sendUnsolicitedIPMIPayload(netfnTransport, solActivatingCmd, outPayload); } @@ -72,10 +70,9 @@ std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse)); - auto request = reinterpret_cast<const SetConfParamsRequest*> - (inPayload.data()); - auto response = reinterpret_cast<SetConfParamsResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const SetConfParamsRequest*>(inPayload.data()); + auto response = reinterpret_cast<SetConfParamsResponse*>(outPayload.data()); response->completionCode = IPMI_CC_OK; switch (static_cast<Parameter>(request->paramSelector)) @@ -99,16 +96,16 @@ std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, response->completionCode = ipmiCCWriteReadParameter; } else if (request->auth.privilege < - static_cast<uint8_t>(session::Privilege::USER) || + static_cast<uint8_t>(session::Privilege::USER) || request->auth.privilege > - static_cast<uint8_t>(session::Privilege::OEM)) + static_cast<uint8_t>(session::Privilege::OEM)) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; } else { std::get<sol::Manager&>(singletonPool).solMinPrivilege = - static_cast<session::Privilege>(request->auth.privilege); + static_cast<session::Privilege>(request->auth.privilege); } break; } @@ -123,9 +120,9 @@ std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, } std::get<sol::Manager&>(singletonPool).accumulateInterval = - request->acc.interval * sol::accIntervalFactor * 1ms; + request->acc.interval * sol::accIntervalFactor * 1ms; std::get<sol::Manager&>(singletonPool).sendThreshold = - request->acc.threshold; + request->acc.threshold; break; } case Parameter::RETRY: @@ -133,9 +130,9 @@ std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, using namespace std::chrono_literals; std::get<sol::Manager&>(singletonPool).retryCount = - request->retry.count; + request->retry.count; std::get<sol::Manager&>(singletonPool).retryInterval = - request->retry.interval * sol::retryIntervalFactor * 1ms; + request->retry.interval * sol::retryIntervalFactor * 1ms; break; } case Parameter::PORT: @@ -157,10 +154,9 @@ std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload, const message::Handler& handler) { std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse)); - auto request = reinterpret_cast<const GetConfParamsRequest*> - (inPayload.data()); - auto response = reinterpret_cast<GetConfParamsResponse*> - (outPayload.data()); + auto request = + reinterpret_cast<const GetConfParamsRequest*>(inPayload.data()); + auto response = reinterpret_cast<GetConfParamsResponse*>(outPayload.data()); response->completionCode = IPMI_CC_OK; response->paramRev = parameterRevision; @@ -173,50 +169,51 @@ std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload, { case Parameter::PROGRESS: { - outPayload.push_back(std::get<sol::Manager&> - (singletonPool).progress); + outPayload.push_back( + std::get<sol::Manager&>(singletonPool).progress); break; } case Parameter::ENABLE: { - outPayload.push_back(std::get<sol::Manager&> - (singletonPool).enable); + outPayload.push_back(std::get<sol::Manager&>(singletonPool).enable); break; } case Parameter::AUTHENTICATION: { - Auth value {0}; + Auth value{0}; value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt; value.auth = std::get<sol::Manager&>(singletonPool).forceAuth; - value.privilege = static_cast<uint8_t>(std::get<sol::Manager&> - (singletonPool).solMinPrivilege); - auto buffer = reinterpret_cast<const uint8_t *>(&value); + value.privilege = static_cast<uint8_t>( + std::get<sol::Manager&>(singletonPool).solMinPrivilege); + auto buffer = reinterpret_cast<const uint8_t*>(&value); std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); break; } case Parameter::ACCUMULATE: { - Accumulate value {0}; + Accumulate value{0}; value.interval = std::get<sol::Manager&>(singletonPool) - .accumulateInterval.count()/sol::accIntervalFactor; - value.threshold = std::get<sol::Manager&> - (singletonPool).sendThreshold; - auto buffer = reinterpret_cast<const uint8_t *>(&value); + .accumulateInterval.count() / + sol::accIntervalFactor; + value.threshold = + std::get<sol::Manager&>(singletonPool).sendThreshold; + auto buffer = reinterpret_cast<const uint8_t*>(&value); std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); break; } case Parameter::RETRY: { - Retry value {0}; + Retry value{0}; value.count = std::get<sol::Manager&>(singletonPool).retryCount; - value.interval = std::get<sol::Manager&>(singletonPool) - .retryInterval.count()/sol::retryIntervalFactor; - auto buffer = reinterpret_cast<const uint8_t *>(&value); + value.interval = + std::get<sol::Manager&>(singletonPool).retryInterval.count() / + sol::retryIntervalFactor; + auto buffer = reinterpret_cast<const uint8_t*>(&value); std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); break; @@ -224,15 +221,15 @@ std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload, case Parameter::PORT: { auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT); - auto buffer = reinterpret_cast<const uint8_t *>(&port); + auto buffer = reinterpret_cast<const uint8_t*>(&port); std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload)); break; } case Parameter::CHANNEL: { - outPayload.push_back(std::get<sol::Manager&> - (singletonPool).channel); + outPayload.push_back( + std::get<sol::Manager&>(singletonPool).channel); break; } case Parameter::NVBITRATE: diff --git a/command/sol_cmds.hpp b/command/sol_cmds.hpp index cc19323..182b73e 100644 --- a/command/sol_cmds.hpp +++ b/command/sol_cmds.hpp @@ -1,8 +1,9 @@ #pragma once -#include <vector> #include "message_handler.hpp" +#include <vector> + namespace sol { @@ -33,18 +34,18 @@ constexpr uint8_t solActivatingCmd = 0x20; struct ActivatingRequest { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t sessionState : 4; //!< SOL session state. - uint8_t reserved : 4; //!< Reserved. + uint8_t sessionState : 4; //!< SOL session state. + uint8_t reserved : 4; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved : 4; //!< Reserved. - uint8_t sessionState : 4; //!< SOL session state. + uint8_t reserved : 4; //!< Reserved. + uint8_t sessionState : 4; //!< SOL session state. #endif - uint8_t payloadInstance; //!< Payload instance. - uint8_t majorVersion; //!< SOL format major version - uint8_t minorVersion; //!< SOL format minor version + uint8_t payloadInstance; //!< Payload instance. + uint8_t majorVersion; //!< SOL format major version + uint8_t minorVersion; //!< SOL format minor version } __attribute__((packed)); /** @brief SOL Activating Command. @@ -90,17 +91,17 @@ constexpr uint8_t enableMask = 0x01; struct Auth { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t privilege : 4; //!< SOL privilege level. - uint8_t reserved : 2; //!< Reserved. - uint8_t auth : 1; //!< Force SOL payload Authentication. - uint8_t encrypt : 1; //!< Force SOL payload encryption. + uint8_t privilege : 4; //!< SOL privilege level. + uint8_t reserved : 2; //!< Reserved. + uint8_t auth : 1; //!< Force SOL payload Authentication. + uint8_t encrypt : 1; //!< Force SOL payload encryption. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t encrypt : 1; //!< Force SOL payload encryption. - uint8_t auth : 1; //!< Force SOL payload Authentication. - uint8_t reserved : 2; //!< Reserved. - uint8_t privilege : 4; //!< SOL privilege level. + uint8_t encrypt : 1; //!< Force SOL payload encryption. + uint8_t auth : 1; //!< Force SOL payload Authentication. + uint8_t reserved : 2; //!< Reserved. + uint8_t privilege : 4; //!< SOL privilege level. #endif } __attribute__((packed)); @@ -110,8 +111,8 @@ struct Auth */ struct Accumulate { - uint8_t interval; //!< Character accumulate interval. - uint8_t threshold; //!< Character send threshold. + uint8_t interval; //!< Character accumulate interval. + uint8_t threshold; //!< Character send threshold. } __attribute__((packed)); constexpr uint8_t retryCountMask = 0x07; @@ -123,16 +124,16 @@ constexpr uint8_t retryCountMask = 0x07; struct Retry { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t count : 3; //!< SOL retry count. - uint8_t reserved : 5; //!< Reserved. + uint8_t count : 3; //!< SOL retry count. + uint8_t reserved : 5; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved : 5; //!< Reserved. - uint8_t count : 3; //!< SOL retry count. + uint8_t reserved : 5; //!< Reserved. + uint8_t count : 3; //!< SOL retry count. #endif - uint8_t interval; //!< SOL retry interval. + uint8_t interval; //!< SOL retry interval. } __attribute__((packed)); constexpr uint8_t ipmiCCParamNotSupported = 0x80; @@ -148,22 +149,22 @@ constexpr uint8_t parameterRevision = 0x11; struct SetConfParamsRequest { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t channelNumber : 4; //!< Channel number. - uint8_t reserved : 4; //!< Reserved. + uint8_t channelNumber : 4; //!< Channel number. + uint8_t reserved : 4; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved : 4; //!< Reserved. - uint8_t channelNumber : 4; //!< Channel number. + uint8_t reserved : 4; //!< Reserved. + uint8_t channelNumber : 4; //!< Channel number. #endif - uint8_t paramSelector; //!< Parameter selector. + uint8_t paramSelector; //!< Parameter selector. union { - uint8_t value; //!< Represents one byte SOL parameters. - struct Accumulate acc; //!< Character accumulate values. - struct Retry retry; //!< Retry values. - struct Auth auth; //!< Authentication parameters. + uint8_t value; //!< Represents one byte SOL parameters. + struct Accumulate acc; //!< Character accumulate values. + struct Retry retry; //!< Retry values. + struct Auth auth; //!< Authentication parameters. }; } __attribute__((packed)); @@ -173,7 +174,7 @@ struct SetConfParamsRequest */ struct SetConfParamsResponse { - uint8_t completionCode; //!< Completion code. + uint8_t completionCode; //!< Completion code. } __attribute__((packed)); /** @brief Set SOL configuration parameters command. @@ -193,20 +194,20 @@ std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, struct GetConfParamsRequest { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t channelNum : 4; //!< Channel number. - uint8_t reserved : 3; //!< Reserved. - uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision + uint8_t channelNum : 4; //!< Channel number. + uint8_t reserved : 3; //!< Reserved. + uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision - uint8_t reserved : 3; //!< Reserved. - uint8_t channelNum : 4; //!< Channel number. + uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision + uint8_t reserved : 3; //!< Reserved. + uint8_t channelNum : 4; //!< Channel number. #endif - uint8_t paramSelector; //!< Parameter selector. - uint8_t setSelector; //!< Set selector. - uint8_t blockSelector; //!< Block selector. + uint8_t paramSelector; //!< Parameter selector. + uint8_t setSelector; //!< Set selector. + uint8_t blockSelector; //!< Block selector. } __attribute__((packed)); /** @struct GetConfParamsResponse @@ -215,8 +216,8 @@ struct GetConfParamsRequest */ struct GetConfParamsResponse { - uint8_t completionCode; //!< Completion code. - uint8_t paramRev; //!< Parameter revision. + uint8_t completionCode; //!< Completion code. + uint8_t paramRev; //!< Parameter revision. } __attribute__((packed)); /** @brief Get SOL configuration parameters command. diff --git a/command_table.cpp b/command_table.cpp index 5744978..67b5bd6 100644 --- a/command_table.cpp +++ b/command_table.cpp @@ -1,15 +1,15 @@ #include "command_table.hpp" -#include <iomanip> -#include <iostream> - #include "message_handler.hpp" #include "message_parsers.hpp" #include "sessions_manager.hpp" -#include <phosphor-logging/log.hpp> -#include <phosphor-logging/elog-errors.hpp> #include "xyz/openbmc_project/Common/error.hpp" +#include <iomanip> +#include <iostream> +#include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/log.hpp> + using namespace phosphor::logging; namespace command @@ -21,8 +21,10 @@ void Table::registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry) if (command) { - log<level::DEBUG>("Already Registered", phosphor::logging::entry( - "SKIPPED_ENTRY=0x%x", uint32_t(inCommand.command))); + log<level::DEBUG>( + "Already Registered", + phosphor::logging::entry("SKIPPED_ENTRY=0x%x", + uint32_t(inCommand.command))); return; } @@ -52,23 +54,24 @@ std::vector<uint8_t> Table::executeCommand(uint32_t inCommand, auto end = std::chrono::steady_clock::now(); - auto elapsedSeconds = std::chrono::duration_cast<std::chrono::seconds> - (end - start); + auto elapsedSeconds = + std::chrono::duration_cast<std::chrono::seconds>(end - start); // If command time execution time exceeds 2 seconds, log a time // exceeded message if (elapsedSeconds > 2s) { std::cerr << "E> IPMI command timed out:Elapsed time = " - << elapsedSeconds.count() << "s" << "\n"; + << elapsedSeconds.count() << "s" + << "\n"; } } return response; } -std::vector<uint8_t> NetIpmidEntry::executeCommand( - std::vector<uint8_t>& commandData, - const message::Handler& handler) +std::vector<uint8_t> + NetIpmidEntry::executeCommand(std::vector<uint8_t>& commandData, + const message::Handler& handler) { std::vector<uint8_t> errResponse; @@ -85,9 +88,9 @@ std::vector<uint8_t> NetIpmidEntry::executeCommand( return functor(commandData, handler); } -std::vector<uint8_t> ProviderIpmidEntry::executeCommand( - std::vector<uint8_t>& commandData, - const message::Handler& handler) +std::vector<uint8_t> + ProviderIpmidEntry::executeCommand(std::vector<uint8_t>& commandData, + const message::Handler& handler) { std::vector<uint8_t> response(message::parser::MAX_PAYLOAD_SIZE - 1); size_t respSize = commandData.size(); diff --git a/command_table.hpp b/command_table.hpp index 7d2fe13..ba7eaa5 100644 --- a/command_table.hpp +++ b/command_table.hpp @@ -1,10 +1,11 @@ #pragma once -#include <functional> -#include <map> +#include "message_handler.hpp" #include <host-ipmid/ipmid-api.h> -#include "message_handler.hpp" + +#include <functional> +#include <map> namespace command { @@ -18,8 +19,8 @@ union CommandID union { - uint8_t netFn: 6; - uint8_t lun: 2; + uint8_t netFn : 6; + uint8_t lun : 2; uint8_t netFnLun; } NetFnLun; @@ -34,7 +35,7 @@ union CommandID * command is returned as a vector. */ using CommandFunctor = std::function<std::vector<uint8_t>( - const std::vector<uint8_t>&, const message::Handler&)>; + const std::vector<uint8_t>&, const message::Handler&)>; /** * @struct CmdDetails @@ -57,39 +58,39 @@ struct CmdDetails */ enum class NetFns { - CHASSIS = (0x00 << 10), - CHASSIS_RESP = (0x01 << 10), + CHASSIS = (0x00 << 10), + CHASSIS_RESP = (0x01 << 10), - BRIDGE = (0x02 << 10), - BRIDGE_RESP = (0x03 << 10), + BRIDGE = (0x02 << 10), + BRIDGE_RESP = (0x03 << 10), - SENSOR = (0x04 << 10), - SENSOR_RESP = (0x05 << 10), - EVENT = (0x04 << 10), - EVENT_RESP = (0x05 << 10), + SENSOR = (0x04 << 10), + SENSOR_RESP = (0x05 << 10), + EVENT = (0x04 << 10), + EVENT_RESP = (0x05 << 10), - APP = (0x06 << 10), - APP_RESP = (0x07 << 10), + APP = (0x06 << 10), + APP_RESP = (0x07 << 10), - FIRMWARE = (0x08 << 10), - FIRMWARE_RESP = (0x09 << 10), + FIRMWARE = (0x08 << 10), + FIRMWARE_RESP = (0x09 << 10), - STORAGE = (0x0A << 10), - STORAGE_RESP = (0x0B << 10), + STORAGE = (0x0A << 10), + STORAGE_RESP = (0x0B << 10), - TRANSPORT = (0x0C << 10), - TRANSPORT_RESP = (0x0D << 10), + TRANSPORT = (0x0C << 10), + TRANSPORT_RESP = (0x0D << 10), //>> - RESERVED_START = (0x0E << 10), - RESERVED_END = (0x2B << 10), + RESERVED_START = (0x0E << 10), + RESERVED_END = (0x2B << 10), //<< - GROUP_EXTN = (0x2C << 10), - GROUP_EXTN_RESP = (0x2D << 10), + GROUP_EXTN = (0x2C << 10), + GROUP_EXTN_RESP = (0x2D << 10), - OEM = (0x2E << 10), - OEM_RESP = (0x2F << 10), + OEM = (0x2E << 10), + OEM_RESP = (0x2F << 10), }; /** @@ -106,46 +107,47 @@ enum class NetFns class Entry { - public: - Entry(CommandID command, session::Privilege privilege): - command(command), - privilege(privilege) {} - - /** - * @brief Execute the command - * - * Execute the command - * - * @param[in] commandData - Request Data for the command - * @param[in] handler - Reference to the Message Handler - * - * @return Response data for the command - */ - virtual std::vector<uint8_t> executeCommand( - std::vector<uint8_t>& commandData, - const message::Handler& handler) = 0; - - auto getCommand() const - { - return command; - } - - auto getPrivilege() const - { - return privilege; - } - - virtual ~Entry() = default; - Entry(const Entry&) = default; - Entry& operator=(const Entry&) = default; - Entry(Entry&&) = default; - Entry& operator=(Entry&&) = default; - - protected: - CommandID command; - - //Specifies the minimum privilege level required to execute this command - session::Privilege privilege; + public: + Entry(CommandID command, session::Privilege privilege) : + command(command), privilege(privilege) + { + } + + /** + * @brief Execute the command + * + * Execute the command + * + * @param[in] commandData - Request Data for the command + * @param[in] handler - Reference to the Message Handler + * + * @return Response data for the command + */ + virtual std::vector<uint8_t> + executeCommand(std::vector<uint8_t>& commandData, + const message::Handler& handler) = 0; + + auto getCommand() const + { + return command; + } + + auto getPrivilege() const + { + return privilege; + } + + virtual ~Entry() = default; + Entry(const Entry&) = default; + Entry& operator=(const Entry&) = default; + Entry(Entry&&) = default; + Entry& operator=(Entry&&) = default; + + protected: + CommandID command; + + // Specifies the minimum privilege level required to execute this command + session::Privilege privilege; }; /** @@ -159,42 +161,41 @@ class Entry * established like Get System GUID, Get Channel Authentication Capabilities * and RAKP commands. */ -class NetIpmidEntry final: public Entry +class NetIpmidEntry final : public Entry { - public: - NetIpmidEntry(CommandID command, - CommandFunctor functor, - session::Privilege privilege, - bool sessionless): - Entry(command, privilege), - functor(functor), - sessionless(sessionless) {} - - /** - * @brief Execute the command - * - * Execute the command - * - * @param[in] commandData - Request Data for the command - * @param[in] handler - Reference to the Message Handler - * - * @return Response data for the command - */ - std::vector<uint8_t> executeCommand(std::vector<uint8_t>& commandData, - const message::Handler& handler) - override; - - virtual ~NetIpmidEntry() = default; - NetIpmidEntry(const NetIpmidEntry&) = default; - NetIpmidEntry& operator=(const NetIpmidEntry&) = default; - NetIpmidEntry(NetIpmidEntry&&) = default; - NetIpmidEntry& operator=(NetIpmidEntry&&) = default; - - private: - CommandFunctor functor; - - bool sessionless; + public: + NetIpmidEntry(CommandID command, CommandFunctor functor, + session::Privilege privilege, bool sessionless) : + Entry(command, privilege), + functor(functor), sessionless(sessionless) + { + } + + /** + * @brief Execute the command + * + * Execute the command + * + * @param[in] commandData - Request Data for the command + * @param[in] handler - Reference to the Message Handler + * + * @return Response data for the command + */ + std::vector<uint8_t> + executeCommand(std::vector<uint8_t>& commandData, + const message::Handler& handler) override; + + virtual ~NetIpmidEntry() = default; + NetIpmidEntry(const NetIpmidEntry&) = default; + NetIpmidEntry& operator=(const NetIpmidEntry&) = default; + NetIpmidEntry(NetIpmidEntry&&) = default; + NetIpmidEntry& operator=(NetIpmidEntry&&) = default; + + private: + CommandFunctor functor; + + bool sessionless; }; /** @@ -204,37 +205,38 @@ class NetIpmidEntry final: public Entry * are registered by IPMI provider libraries. * */ -class ProviderIpmidEntry final: public Entry +class ProviderIpmidEntry final : public Entry { - public: - ProviderIpmidEntry(CommandID command, - ipmid_callback_t functor, - session::Privilege privilege): - Entry(command, privilege), - functor(functor) {} - - /** - * @brief Execute the command - * - * Execute the callback handler - * - * @param[in] commandData - Request Data for the command - * @param[in] handler - Reference to the Message Handler - * - * @return Response data for the command - */ - std::vector<uint8_t> executeCommand(std::vector<uint8_t>& commandData, - const message::Handler& handler) - override; - - virtual ~ProviderIpmidEntry() = default; - ProviderIpmidEntry(const ProviderIpmidEntry&) = default; - ProviderIpmidEntry& operator=(const ProviderIpmidEntry&) = default; - ProviderIpmidEntry(ProviderIpmidEntry&&) = default; - ProviderIpmidEntry& operator=(ProviderIpmidEntry&&) = default; - - private: - ipmid_callback_t functor; + public: + ProviderIpmidEntry(CommandID command, ipmid_callback_t functor, + session::Privilege privilege) : + Entry(command, privilege), + functor(functor) + { + } + + /** + * @brief Execute the command + * + * Execute the callback handler + * + * @param[in] commandData - Request Data for the command + * @param[in] handler - Reference to the Message Handler + * + * @return Response data for the command + */ + std::vector<uint8_t> + executeCommand(std::vector<uint8_t>& commandData, + const message::Handler& handler) override; + + virtual ~ProviderIpmidEntry() = default; + ProviderIpmidEntry(const ProviderIpmidEntry&) = default; + ProviderIpmidEntry& operator=(const ProviderIpmidEntry&) = default; + ProviderIpmidEntry(ProviderIpmidEntry&&) = default; + ProviderIpmidEntry& operator=(ProviderIpmidEntry&&) = default; + + private: + ipmid_callback_t functor; }; /** @@ -246,51 +248,50 @@ class ProviderIpmidEntry final: public Entry */ class Table { - public: - - Table() = default; - ~Table() = default; - // Command Table is a singleton so copy, copy-assignment, move and - // move assignment is deleted - Table(const Table&) = delete; - Table& operator=(const Table&) = delete; - Table(Table&&) = default; - Table& operator=(Table&&) = default; - - using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>; - - /** - * @brief Register a command - * - * Register a command with the command table - * - * @param[in] inCommand - Command ID - * @param[in] entry - Command Entry - * - * @return: None - * - * @note: Duplicate registrations will be rejected. - * - */ - void registerCommand(CommandID inCommand, - std::unique_ptr<Entry>&& entry); - - /** - * @brief Execute the command - * - * Execute the command for the corresponding CommandID - * - * @param[in] inCommand - Command ID to execute. - * @param[in] commandData - Request Data for the command - * @param[in] handler - Reference to the Message Handler - * - * @return Response data for the command - */ - std::vector<uint8_t> executeCommand(uint32_t inCommand, - std::vector<uint8_t>& commandData, - const message::Handler& handler); - private: - CommandTable commandTable; + public: + Table() = default; + ~Table() = default; + // Command Table is a singleton so copy, copy-assignment, move and + // move assignment is deleted + Table(const Table&) = delete; + Table& operator=(const Table&) = delete; + Table(Table&&) = default; + Table& operator=(Table&&) = default; + + using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>; + + /** + * @brief Register a command + * + * Register a command with the command table + * + * @param[in] inCommand - Command ID + * @param[in] entry - Command Entry + * + * @return: None + * + * @note: Duplicate registrations will be rejected. + * + */ + void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry); + + /** + * @brief Execute the command + * + * Execute the command for the corresponding CommandID + * + * @param[in] inCommand - Command ID to execute. + * @param[in] commandData - Request Data for the command + * @param[in] handler - Reference to the Message Handler + * + * @return Response data for the command + */ + std::vector<uint8_t> executeCommand(uint32_t inCommand, + std::vector<uint8_t>& commandData, + const message::Handler& handler); + + private: + CommandTable commandTable; }; -}// namespace command +} // namespace command diff --git a/crypt_algo.cpp b/crypt_algo.cpp index 90ba26a..bf46c4e 100644 --- a/crypt_algo.cpp +++ b/crypt_algo.cpp @@ -1,10 +1,13 @@ +#include "crypt_algo.hpp" + +#include "message_parsers.hpp" + #include <openssl/evp.h> #include <openssl/hmac.h> #include <openssl/rand.h> + #include <algorithm> #include <numeric> -#include "crypt_algo.hpp" -#include "message_parsers.hpp" namespace cipher { @@ -13,17 +16,17 @@ namespace crypt { constexpr std::array<uint8_t, AlgoAES128::AESCBC128BlockSize - 1> - AlgoAES128::confPadBytes; + AlgoAES128::confPadBytes; -std::vector<uint8_t> AlgoAES128::decryptPayload( - const std::vector<uint8_t>& packet, - const size_t sessHeaderLen, - const size_t payloadLen) const +std::vector<uint8_t> + AlgoAES128::decryptPayload(const std::vector<uint8_t>& packet, + const size_t sessHeaderLen, + const size_t payloadLen) const { - auto plainPayload = decryptData( - packet.data() + sessHeaderLen, - packet.data() + sessHeaderLen + AESCBC128ConfHeader, - payloadLen - AESCBC128ConfHeader); + auto plainPayload = + decryptData(packet.data() + sessHeaderLen, + packet.data() + sessHeaderLen + AESCBC128ConfHeader, + payloadLen - AESCBC128ConfHeader); /* * The confidentiality pad length is the last byte in the payload, it would @@ -31,14 +34,14 @@ std::vector<uint8_t> AlgoAES128::decryptPayload( * that buffer overrun doesn't happen. */ size_t confPadLength = plainPayload.back(); - auto padLength = std::min(plainPayload.size() -1, confPadLength); + auto padLength = std::min(plainPayload.size() - 1, confPadLength); auto plainPayloadLen = plainPayload.size() - padLength - 1; // Additional check if the confidentiality pad bytes are as expected - if(!std::equal(plainPayload.begin() + plainPayloadLen, - plainPayload.begin() + plainPayloadLen + padLength, - confPadBytes.begin())) + if (!std::equal(plainPayload.begin() + plainPayloadLen, + plainPayload.begin() + plainPayloadLen + padLength, + confPadBytes.begin())) { throw std::runtime_error("Confidentiality pad bytes check failed"); } @@ -48,8 +51,8 @@ std::vector<uint8_t> AlgoAES128::decryptPayload( return plainPayload; } -std::vector<uint8_t> AlgoAES128::encryptPayload( - std::vector<uint8_t>& payload) const +std::vector<uint8_t> + AlgoAES128::encryptPayload(std::vector<uint8_t>& payload) const { auto payloadLen = payload.size(); @@ -77,8 +80,7 @@ std::vector<uint8_t> AlgoAES128::encryptPayload( if (0 != paddingLen) { std::iota(payload.begin() + payloadLen, - payload.begin() + payloadLen + paddingLen, - 1); + payload.begin() + payloadLen + paddingLen, 1); } payload.back() = paddingLen; @@ -87,19 +89,16 @@ std::vector<uint8_t> AlgoAES128::encryptPayload( } std::vector<uint8_t> AlgoAES128::decryptData(const uint8_t* iv, - const uint8_t* input, - const int inputLen) const + const uint8_t* input, + const int inputLen) const { // Initializes Cipher context EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) - { - EVP_CIPHER_CTX_free(ctx); - }; + auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); }; - std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> - ctxPtr(ctx, cleanupFunc); + std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> ctxPtr(ctx, + cleanupFunc); /* * EVP_DecryptInit_ex sets up cipher context ctx for encryption with type @@ -144,7 +143,7 @@ std::vector<uint8_t> AlgoAES128::decryptData(const uint8_t* iv, } std::vector<uint8_t> AlgoAES128::encryptData(const uint8_t* input, - const int inputLen) const + const int inputLen) const { std::vector<uint8_t> output(inputLen + AESCBC128BlockSize); @@ -157,13 +156,10 @@ std::vector<uint8_t> AlgoAES128::encryptData(const uint8_t* input, // Initializes Cipher context EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) - { - EVP_CIPHER_CTX_free(ctx); - }; + auto cleanupFunc = [](EVP_CIPHER_CTX* ctx) { EVP_CIPHER_CTX_free(ctx); }; - std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> - ctxPtr(ctx, cleanupFunc); + std::unique_ptr<EVP_CIPHER_CTX, decltype(cleanupFunc)> ctxPtr(ctx, + cleanupFunc); /* * EVP_EncryptInit_ex sets up cipher context ctx for encryption with type @@ -194,10 +190,8 @@ std::vector<uint8_t> AlgoAES128::encryptData(const uint8_t* input, * multiple of block size, we are not making the call to * EVP_DecryptFinal_ex() */ - if (!EVP_EncryptUpdate(ctxPtr.get(), - output.data() + AESCBC128ConfHeader, - &outputLen, - input, inputLen)) + if (!EVP_EncryptUpdate(ctxPtr.get(), output.data() + AESCBC128ConfHeader, + &outputLen, input, inputLen)) { throw std::runtime_error("EVP_EncryptUpdate failed for type " "AES-CBC-128"); @@ -208,8 +202,6 @@ std::vector<uint8_t> AlgoAES128::encryptData(const uint8_t* input, return output; } -}// namespace crypt - -}// namespace cipher - +} // namespace crypt +} // namespace cipher diff --git a/crypt_algo.hpp b/crypt_algo.hpp index 20f55b9..366f2b0 100644 --- a/crypt_algo.hpp +++ b/crypt_algo.hpp @@ -25,10 +25,10 @@ namespace crypt */ enum class Algorithms : uint8_t { - NONE, /**< No encryption (mandatory , not supported) */ - AES_CBC_128, /**< AES-CBC-128 Algorithm (mandatory option) */ - xRC4_128, /**< xRC4-128 Algorithm (optional option) */ - xRC4_40, /**< xRC4-40 Algorithm (optional option) */ + NONE, /**< No encryption (mandatory , not supported) */ + AES_CBC_128, /**< AES-CBC-128 Algorithm (mandatory option) */ + xRC4_128, /**< xRC4-128 Algorithm (optional option) */ + xRC4_40, /**< xRC4-40 Algorithm (optional option) */ }; /** @@ -38,73 +38,73 @@ enum class Algorithms : uint8_t */ class Interface { - public: - /** - * @brief Constructor for Interface - */ - explicit Interface(const std::vector<uint8_t>& k2) - : k2(k2) {} - - Interface() = delete; - virtual ~Interface() = default; - Interface(const Interface&) = default; - Interface& operator=(const Interface&) = default; - Interface(Interface&&) = default; - Interface& operator=(Interface&&) = default; - - /** - * @brief Decrypt the incoming payload - * - * @param[in] packet - Incoming IPMI packet - * @param[in] sessHeaderLen - Length of the IPMI Session Header - * @param[in] payloadLen - Length of the encrypted IPMI payload - * - * @return decrypted payload if the operation is successful - */ - virtual std::vector<uint8_t> decryptPayload( - const std::vector<uint8_t>& packet, - const size_t sessHeaderLen, - const size_t payloadLen) const = 0; - - /** - * @brief Encrypt the outgoing payload - * - * @param[in] payload - plain payload for the outgoing IPMI packet - * - * @return encrypted payload if the operation is successful - * - */ - virtual std::vector<uint8_t> encryptPayload( - std::vector<uint8_t>& payload) const = 0; - - /** - * @brief Check if the Confidentiality algorithm is supported - * - * @param[in] algo - confidentiality algorithm - * - * @return true if algorithm is supported else false - * - */ - static bool isAlgorithmSupported(Algorithms algo) + public: + /** + * @brief Constructor for Interface + */ + explicit Interface(const std::vector<uint8_t>& k2) : k2(k2) + { + } + + Interface() = delete; + virtual ~Interface() = default; + Interface(const Interface&) = default; + Interface& operator=(const Interface&) = default; + Interface(Interface&&) = default; + Interface& operator=(Interface&&) = default; + + /** + * @brief Decrypt the incoming payload + * + * @param[in] packet - Incoming IPMI packet + * @param[in] sessHeaderLen - Length of the IPMI Session Header + * @param[in] payloadLen - Length of the encrypted IPMI payload + * + * @return decrypted payload if the operation is successful + */ + virtual std::vector<uint8_t> + decryptPayload(const std::vector<uint8_t>& packet, + const size_t sessHeaderLen, + const size_t payloadLen) const = 0; + + /** + * @brief Encrypt the outgoing payload + * + * @param[in] payload - plain payload for the outgoing IPMI packet + * + * @return encrypted payload if the operation is successful + * + */ + virtual std::vector<uint8_t> + encryptPayload(std::vector<uint8_t>& payload) const = 0; + + /** + * @brief Check if the Confidentiality algorithm is supported + * + * @param[in] algo - confidentiality algorithm + * + * @return true if algorithm is supported else false + * + */ + static bool isAlgorithmSupported(Algorithms algo) + { + if (algo == Algorithms::AES_CBC_128) { - if (algo == Algorithms::AES_CBC_128) - { - return true; - } - else - { - return false; - } + return true; } - - protected: - - /** - * @brief The Cipher Key is the first 128-bits of key “K2”, K2 is - * generated by processing a pre-defined constant keyed by Session - * Integrity Key (SIK) that was created during session activation. - */ - std::vector<uint8_t> k2; + else + { + return false; + } + } + + protected: + /** + * @brief The Cipher Key is the first 128-bits of key “K2”, K2 is + * generated by processing a pre-defined constant keyed by Session + * Integrity Key (SIK) that was created during session activation. + */ + std::vector<uint8_t> k2; }; /** @@ -121,91 +121,88 @@ class Interface */ class AlgoAES128 final : public Interface { - public: - static constexpr size_t AESCBC128ConfHeader = 16; - static constexpr size_t AESCBC128BlockSize = 16; - - /** - * If confidentiality bytes are present, the value of the first byte is - * one (01h). and all subsequent bytes shall have a monotonically - * increasing value (e.g., 02h, 03h, 04h, etc). The receiver, as an - * additional check for proper decryption, shall check the value of each - * byte of Confidentiality Pad. For AES algorithm, the pad bytes will - * range from 0 to 15 bytes. This predefined array would help in - * doing the additional check. - */ - static constexpr std::array<uint8_t, AESCBC128BlockSize -1> - confPadBytes = - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; - - /** - * @brief Constructor for AlgoAES128 - * - * @param[in] - Session Integrity key - */ - explicit AlgoAES128(const std::vector<uint8_t>& k2) : Interface(k2) {} - - AlgoAES128() = delete; - ~AlgoAES128() = default; - AlgoAES128(const AlgoAES128&) = default; - AlgoAES128& operator=(const AlgoAES128&) = default; - AlgoAES128(AlgoAES128&&) = default; - AlgoAES128& operator=(AlgoAES128&&) = default; - - /** - * @brief Decrypt the incoming payload - * - * @param[in] packet - Incoming IPMI packet - * @param[in] sessHeaderLen - Length of the IPMI Session Header - * @param[in] payloadLen - Length of the encrypted IPMI payload - * - * @return decrypted payload if the operation is successful - */ - std::vector<uint8_t> decryptPayload( - const std::vector<uint8_t>& packet, - const size_t sessHeaderLen, - const size_t payloadLen) const override; - - /** - * @brief Encrypt the outgoing payload - * - * @param[in] payload - plain payload for the outgoing IPMI packet - * - * @return encrypted payload if the operation is successful - * - */ - std::vector<uint8_t> encryptPayload( - std::vector<uint8_t>& payload) const override; - - private: - - /** - * @brief Decrypt the passed data - * - * @param[in] iv - Initialization vector - * @param[in] input - Pointer to input data - * @param[in] inputLen - Length of input data - * - * @return decrypted data if the operation is successful - */ - std::vector<uint8_t> decryptData(const uint8_t* iv, - const uint8_t* input, - const int inputLen) const; - - /** - * @brief Encrypt the passed data - * - * @param[in] input - Pointer to input data - * @param[in] inputLen - Length of input data - * - * @return encrypted data if the operation is successful - */ - std::vector<uint8_t> encryptData(const uint8_t* input, - const int inputLen) const; + public: + static constexpr size_t AESCBC128ConfHeader = 16; + static constexpr size_t AESCBC128BlockSize = 16; + + /** + * If confidentiality bytes are present, the value of the first byte is + * one (01h). and all subsequent bytes shall have a monotonically + * increasing value (e.g., 02h, 03h, 04h, etc). The receiver, as an + * additional check for proper decryption, shall check the value of each + * byte of Confidentiality Pad. For AES algorithm, the pad bytes will + * range from 0 to 15 bytes. This predefined array would help in + * doing the additional check. + */ + static constexpr std::array<uint8_t, AESCBC128BlockSize - 1> confPadBytes = + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + + /** + * @brief Constructor for AlgoAES128 + * + * @param[in] - Session Integrity key + */ + explicit AlgoAES128(const std::vector<uint8_t>& k2) : Interface(k2) + { + } + + AlgoAES128() = delete; + ~AlgoAES128() = default; + AlgoAES128(const AlgoAES128&) = default; + AlgoAES128& operator=(const AlgoAES128&) = default; + AlgoAES128(AlgoAES128&&) = default; + AlgoAES128& operator=(AlgoAES128&&) = default; + + /** + * @brief Decrypt the incoming payload + * + * @param[in] packet - Incoming IPMI packet + * @param[in] sessHeaderLen - Length of the IPMI Session Header + * @param[in] payloadLen - Length of the encrypted IPMI payload + * + * @return decrypted payload if the operation is successful + */ + std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet, + const size_t sessHeaderLen, + const size_t payloadLen) const override; + + /** + * @brief Encrypt the outgoing payload + * + * @param[in] payload - plain payload for the outgoing IPMI packet + * + * @return encrypted payload if the operation is successful + * + */ + std::vector<uint8_t> + encryptPayload(std::vector<uint8_t>& payload) const override; + + private: + /** + * @brief Decrypt the passed data + * + * @param[in] iv - Initialization vector + * @param[in] input - Pointer to input data + * @param[in] inputLen - Length of input data + * + * @return decrypted data if the operation is successful + */ + std::vector<uint8_t> decryptData(const uint8_t* iv, const uint8_t* input, + const int inputLen) const; + + /** + * @brief Encrypt the passed data + * + * @param[in] input - Pointer to input data + * @param[in] inputLen - Length of input data + * + * @return encrypted data if the operation is successful + */ + std::vector<uint8_t> encryptData(const uint8_t* input, + const int inputLen) const; }; -}// namespace crypt - -}// namespace cipher +} // namespace crypt +} // namespace cipher @@ -16,39 +16,69 @@ struct convert static T from_network(T) = delete; }; -template<> struct convert<uint16_t> +template <> +struct convert<uint16_t> { - static uint16_t to_ipmi(uint16_t i) { return htole16(i); }; - static uint16_t from_ipmi(uint16_t i) { return le16toh(i); }; - static uint16_t to_network(uint16_t i) { return htobe16(i); }; - static uint16_t from_network(uint16_t i) { return be16toh(i); }; + static uint16_t to_ipmi(uint16_t i) + { + return htole16(i); + }; + static uint16_t from_ipmi(uint16_t i) + { + return le16toh(i); + }; + static uint16_t to_network(uint16_t i) + { + return htobe16(i); + }; + static uint16_t from_network(uint16_t i) + { + return be16toh(i); + }; }; -template<> struct convert<uint32_t> +template <> +struct convert<uint32_t> { - static uint32_t to_ipmi(uint32_t i) { return htole32(i); }; - static uint32_t from_ipmi(uint32_t i) { return le32toh(i); }; - static uint32_t to_network(uint32_t i) { return htobe32(i); }; - static uint32_t from_network(uint32_t i) { return be32toh(i); }; + static uint32_t to_ipmi(uint32_t i) + { + return htole32(i); + }; + static uint32_t from_ipmi(uint32_t i) + { + return le32toh(i); + }; + static uint32_t to_network(uint32_t i) + { + return htobe32(i); + }; + static uint32_t from_network(uint32_t i) + { + return be32toh(i); + }; }; -} +} // namespace details -template<typename T> T to_ipmi(T i) +template <typename T> +T to_ipmi(T i) { return details::convert<T>::to_ipmi(i); } -template<typename T> T from_ipmi(T i) +template <typename T> +T from_ipmi(T i) { return details::convert<T>::from_ipmi(i); } -template<typename T> T to_network(T i) +template <typename T> +T to_network(T i) { return details::convert<T>::to_network(i); } -template<typename T> T from_network(T i) +template <typename T> +T from_network(T i) { return details::convert<T>::from_network(i); } -} +} // namespace endian diff --git a/integrity_algo.cpp b/integrity_algo.cpp index 0c3efe8..bac87d7 100644 --- a/integrity_algo.cpp +++ b/integrity_algo.cpp @@ -1,8 +1,10 @@ +#include "integrity_algo.hpp" + +#include "message_parsers.hpp" + #include <openssl/evp.h> #include <openssl/hmac.h> #include <openssl/sha.h> -#include "integrity_algo.hpp" -#include "message_parsers.hpp" namespace cipher { @@ -10,20 +12,20 @@ namespace cipher namespace integrity { -AlgoSHA1::AlgoSHA1(const std::vector<uint8_t>& sik) - : Interface(SHA1_96_AUTHCODE_LENGTH) +AlgoSHA1::AlgoSHA1(const std::vector<uint8_t>& sik) : + Interface(SHA1_96_AUTHCODE_LENGTH) { k1 = generateKn(sik, rmcp::const_1); } std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input, - const size_t len) const + const size_t len) const { std::vector<uint8_t> output(SHA_DIGEST_LENGTH); unsigned int mdLen = 0; - if (HMAC(EVP_sha1(), k1.data(), k1.size(), input, len, - output.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), k1.data(), k1.size(), input, len, output.data(), + &mdLen) == NULL) { throw std::runtime_error("Generating integrity data failed"); } @@ -38,38 +40,36 @@ std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input, } bool AlgoSHA1::verifyIntegrityData( - const std::vector<uint8_t>& packet, - const size_t length, - std::vector<uint8_t>::const_iterator integrityData) const + const std::vector<uint8_t>& packet, const size_t length, + std::vector<uint8_t>::const_iterator integrityData) const { auto output = generateHMAC( - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length); + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length); // Verify if the generated integrity data for the packet and the received // integrity data matches. return (std::equal(output.begin(), output.end(), integrityData)); } -std::vector<uint8_t> AlgoSHA1::generateIntegrityData( - const std::vector<uint8_t>& packet) const +std::vector<uint8_t> + AlgoSHA1::generateIntegrityData(const std::vector<uint8_t>& packet) const { return generateHMAC( - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE); + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, + packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE); } std::vector<uint8_t> AlgoSHA1::generateKn(const std::vector<uint8_t>& sik, - const rmcp::Const_n& const_n) const + const rmcp::Const_n& const_n) const { unsigned int mdLen = 0; std::vector<uint8_t> Kn(sik.size()); // Generated Kn for the integrity algorithm with the additional key keyed // with SIK. - if (HMAC(EVP_sha1(), sik.data(), sik.size(), const_n.data(), - const_n.size(), Kn.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), sik.data(), sik.size(), const_n.data(), const_n.size(), + Kn.data(), &mdLen) == NULL) { throw std::runtime_error("Generating KeyN for integrity " "algorithm failed"); @@ -77,20 +77,20 @@ std::vector<uint8_t> AlgoSHA1::generateKn(const std::vector<uint8_t>& sik, return Kn; } -AlgoSHA256::AlgoSHA256(const std::vector<uint8_t>& sik) - : Interface(SHA256_128_AUTHCODE_LENGTH) +AlgoSHA256::AlgoSHA256(const std::vector<uint8_t>& sik) : + Interface(SHA256_128_AUTHCODE_LENGTH) { k1 = generateKn(sik, rmcp::const_1); } std::vector<uint8_t> AlgoSHA256::generateHMAC(const uint8_t* input, - const size_t len) const + const size_t len) const { std::vector<uint8_t> output(SHA256_DIGEST_LENGTH); unsigned int mdLen = 0; - if (HMAC(EVP_sha256(), k1.data(), k1.size(), input, len, - output.data(), &mdLen) == NULL) + if (HMAC(EVP_sha256(), k1.data(), k1.size(), input, len, output.data(), + &mdLen) == NULL) { throw std::runtime_error("Generating HMAC_SHA256_128 failed"); } @@ -105,30 +105,28 @@ std::vector<uint8_t> AlgoSHA256::generateHMAC(const uint8_t* input, } bool AlgoSHA256::verifyIntegrityData( - const std::vector<uint8_t>& packet, - const size_t length, - std::vector<uint8_t>::const_iterator integrityData) const + const std::vector<uint8_t>& packet, const size_t length, + std::vector<uint8_t>::const_iterator integrityData) const { auto output = generateHMAC( - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length); + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length); // Verify if the generated integrity data for the packet and the received // integrity data matches. return (std::equal(output.begin(), output.end(), integrityData)); } -std::vector<uint8_t> AlgoSHA256::generateIntegrityData( - const std::vector<uint8_t>& packet) const +std::vector<uint8_t> + AlgoSHA256::generateIntegrityData(const std::vector<uint8_t>& packet) const { return generateHMAC( - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE); + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, + packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE); } std::vector<uint8_t> AlgoSHA256::generateKn(const std::vector<uint8_t>& sik, - const rmcp::Const_n& const_n) const + const rmcp::Const_n& const_n) const { unsigned int mdLen = 0; std::vector<uint8_t> Kn(sik.size()); @@ -144,6 +142,6 @@ std::vector<uint8_t> AlgoSHA256::generateKn(const std::vector<uint8_t>& sik, return Kn; } -}// namespace integrity +} // namespace integrity -}// namespace cipher +} // namespace cipher diff --git a/integrity_algo.hpp b/integrity_algo.hpp index 3d56b82..6c8460f 100644 --- a/integrity_algo.hpp +++ b/integrity_algo.hpp @@ -1,8 +1,9 @@ #pragma once +#include "rmcp.hpp" + #include <array> #include <vector> -#include "rmcp.hpp" namespace cipher { @@ -39,109 +40,107 @@ enum class Algorithms : uint8_t */ class Interface { - public: - /** - * @brief Constructor for Interface - * - * @param[in] - AuthCode length - */ - explicit Interface(size_t authLength) - : authCodeLength(authLength) {} + public: + /** + * @brief Constructor for Interface + * + * @param[in] - AuthCode length + */ + explicit Interface(size_t authLength) : authCodeLength(authLength) + { + } - Interface() = delete; - virtual ~Interface() = default; - Interface(const Interface&) = default; - Interface& operator=(const Interface&) = default; - Interface(Interface&&) = default; - Interface& operator=(Interface&&) = default; + Interface() = delete; + virtual ~Interface() = default; + Interface(const Interface&) = default; + Interface& operator=(const Interface&) = default; + Interface(Interface&&) = default; + Interface& operator=(Interface&&) = default; - /** - * @brief Verify the integrity data of the packet - * - * @param[in] packet - Incoming IPMI packet - * @param[in] packetLen - Packet length excluding authCode - * @param[in] integrityData - Iterator to the authCode in the packet - * - * @return true if authcode in the packet is equal to one generated - * using integrity algorithm on the packet data, false otherwise - */ - bool virtual verifyIntegrityData( - const std::vector<uint8_t>& packet, - const size_t packetLen, - std::vector<uint8_t>::const_iterator integrityData) const = 0; + /** + * @brief Verify the integrity data of the packet + * + * @param[in] packet - Incoming IPMI packet + * @param[in] packetLen - Packet length excluding authCode + * @param[in] integrityData - Iterator to the authCode in the packet + * + * @return true if authcode in the packet is equal to one generated + * using integrity algorithm on the packet data, false otherwise + */ + bool virtual verifyIntegrityData( + const std::vector<uint8_t>& packet, const size_t packetLen, + std::vector<uint8_t>::const_iterator integrityData) const = 0; - /** - * @brief Generate integrity data for the outgoing IPMI packet - * - * @param[in] input - Outgoing IPMI packet - * - * @return authcode for the outgoing IPMI packet - * - */ - std::vector<uint8_t> virtual generateIntegrityData( - const std::vector<uint8_t>& input) const = 0; + /** + * @brief Generate integrity data for the outgoing IPMI packet + * + * @param[in] input - Outgoing IPMI packet + * + * @return authcode for the outgoing IPMI packet + * + */ + std::vector<uint8_t> virtual generateIntegrityData( + const std::vector<uint8_t>& input) const = 0; - /** - * @brief Check if the Integrity algorithm is supported - * - * @param[in] algo - integrity algorithm - * - * @return true if algorithm is supported else false - * - */ - static bool isAlgorithmSupported(Algorithms algo) + /** + * @brief Check if the Integrity algorithm is supported + * + * @param[in] algo - integrity algorithm + * + * @return true if algorithm is supported else false + * + */ + static bool isAlgorithmSupported(Algorithms algo) + { + if (algo == Algorithms::HMAC_SHA1_96 || + algo == Algorithms::HMAC_SHA256_128) { - if (algo == Algorithms::HMAC_SHA1_96 || - algo == Algorithms::HMAC_SHA256_128) - { - return true; - } - else - { - return false; - } + return true; } + else + { + return false; + } + } - /** - * @brief Generate additional keying material based on SIK - * - * @note - * The IPMI 2.0 spec only states that the additional keying material is - * generated by running HMAC(constN) using SIK as the key. It does not - * state whether this is the integrity algorithm or the authentication - * algorithm. Other implementations of the RMCP+ algorithm (ipmitool - * and ipmiutil) are not consistent on this matter. But it does not - * really matter because based on any of the defined cipher suites, the - * integrity and authentication algorithms are both based on the same - * digest method (integrity::Algorithms::HMAC_SHA1_96 uses SHA1 and - * rakp_auth::Algorithms::RAKP_HMAC_SHA1 uses SHA1). None of the - * defined cipher suites mix and match digests for integrity and - * authentication. Generating Kn belongs in either the integrity or - * authentication classes, so in this implementation, integrity has - * been chosen. - * - * @param[in] sik - session integrity key - * @param[in] data - 20-byte Const_n - * - * @return on success returns the Kn based on this integrity class - * - */ - std::vector<uint8_t> virtual generateKn( - const std::vector<uint8_t>& sik, - const rmcp::Const_n& data) const = 0; - - /** @brief Authcode field - * - * AuthCode field length varies based on the integrity algorithm, for - * HMAC-SHA1-96 the authcode field is 12 bytes. For HMAC-SHA256-128 and - * HMAC-MD5-128 the authcode field is 16 bytes. - */ - size_t authCodeLength; + /** + * @brief Generate additional keying material based on SIK + * + * @note + * The IPMI 2.0 spec only states that the additional keying material is + * generated by running HMAC(constN) using SIK as the key. It does not + * state whether this is the integrity algorithm or the authentication + * algorithm. Other implementations of the RMCP+ algorithm (ipmitool + * and ipmiutil) are not consistent on this matter. But it does not + * really matter because based on any of the defined cipher suites, the + * integrity and authentication algorithms are both based on the same + * digest method (integrity::Algorithms::HMAC_SHA1_96 uses SHA1 and + * rakp_auth::Algorithms::RAKP_HMAC_SHA1 uses SHA1). None of the + * defined cipher suites mix and match digests for integrity and + * authentication. Generating Kn belongs in either the integrity or + * authentication classes, so in this implementation, integrity has + * been chosen. + * + * @param[in] sik - session integrity key + * @param[in] data - 20-byte Const_n + * + * @return on success returns the Kn based on this integrity class + * + */ + std::vector<uint8_t> virtual generateKn( + const std::vector<uint8_t>& sik, const rmcp::Const_n& data) const = 0; - protected: + /** @brief Authcode field + * + * AuthCode field length varies based on the integrity algorithm, for + * HMAC-SHA1-96 the authcode field is 12 bytes. For HMAC-SHA256-128 and + * HMAC-MD5-128 the authcode field is 16 bytes. + */ + size_t authCodeLength; - /** @brief K1 key used to generated the integrity data. */ - std::vector<uint8_t> k1; + protected: + /** @brief K1 key used to generated the integrity data. */ + std::vector<uint8_t> k1; }; /** @@ -157,76 +156,73 @@ class Interface */ class AlgoSHA1 final : public Interface { - public: - static constexpr size_t SHA1_96_AUTHCODE_LENGTH = 12; + public: + static constexpr size_t SHA1_96_AUTHCODE_LENGTH = 12; - /** - * @brief Constructor for AlgoSHA1 - * - * @param[in] - Session Integrity Key - */ - explicit AlgoSHA1(const std::vector<uint8_t>& sik); + /** + * @brief Constructor for AlgoSHA1 + * + * @param[in] - Session Integrity Key + */ + explicit AlgoSHA1(const std::vector<uint8_t>& sik); - AlgoSHA1() = delete; - ~AlgoSHA1() = default; - AlgoSHA1(const AlgoSHA1&) = default; - AlgoSHA1& operator=(const AlgoSHA1&) = default; - AlgoSHA1(AlgoSHA1&&) = default; - AlgoSHA1& operator=(AlgoSHA1&&) = default; + AlgoSHA1() = delete; + ~AlgoSHA1() = default; + AlgoSHA1(const AlgoSHA1&) = default; + AlgoSHA1& operator=(const AlgoSHA1&) = default; + AlgoSHA1(AlgoSHA1&&) = default; + AlgoSHA1& operator=(AlgoSHA1&&) = default; - /** - * @brief Verify the integrity data of the packet - * - * @param[in] packet - Incoming IPMI packet - * @param[in] length - Length of the data in the packet to calculate - * the integrity data - * @param[in] integrityData - Iterator to the authCode in the packet - * - * @return true if authcode in the packet is equal to one generated - * using integrity algorithm on the packet data, false otherwise - */ - bool verifyIntegrityData( - const std::vector<uint8_t>& packet, - const size_t length, - std::vector<uint8_t>::const_iterator integrityData) - const override; + /** + * @brief Verify the integrity data of the packet + * + * @param[in] packet - Incoming IPMI packet + * @param[in] length - Length of the data in the packet to calculate + * the integrity data + * @param[in] integrityData - Iterator to the authCode in the packet + * + * @return true if authcode in the packet is equal to one generated + * using integrity algorithm on the packet data, false otherwise + */ + bool verifyIntegrityData( + const std::vector<uint8_t>& packet, const size_t length, + std::vector<uint8_t>::const_iterator integrityData) const override; - /** - * @brief Generate integrity data for the outgoing IPMI packet - * - * @param[in] input - Outgoing IPMI packet - * - * @return on success return the integrity data for the outgoing IPMI - * packet - */ - std::vector<uint8_t> generateIntegrityData( - const std::vector<uint8_t>& packet) const override; + /** + * @brief Generate integrity data for the outgoing IPMI packet + * + * @param[in] input - Outgoing IPMI packet + * + * @return on success return the integrity data for the outgoing IPMI + * packet + */ + std::vector<uint8_t> generateIntegrityData( + const std::vector<uint8_t>& packet) const override; - /** - * @brief Generate additional keying material based on SIK - * - * @param[in] sik - session integrity key - * @param[in] data - 20-byte Const_n - * - * @return on success returns the Kn based on HMAC-SHA1 - * - */ - std::vector<uint8_t> generateKn( - const std::vector<uint8_t>& sik, - const rmcp::Const_n& const_n) const; + /** + * @brief Generate additional keying material based on SIK + * + * @param[in] sik - session integrity key + * @param[in] data - 20-byte Const_n + * + * @return on success returns the Kn based on HMAC-SHA1 + * + */ + std::vector<uint8_t> generateKn(const std::vector<uint8_t>& sik, + const rmcp::Const_n& const_n) const; - private: - /** - * @brief Generate HMAC based on HMAC-SHA1-96 algorithm - * - * @param[in] input - pointer to the message - * @param[in] length - length of the message - * - * @return on success returns the message authentication code - * - */ - std::vector<uint8_t> generateHMAC(const uint8_t* input, - const size_t len) const; + private: + /** + * @brief Generate HMAC based on HMAC-SHA1-96 algorithm + * + * @param[in] input - pointer to the message + * @param[in] length - length of the message + * + * @return on success returns the message authentication code + * + */ + std::vector<uint8_t> generateHMAC(const uint8_t* input, + const size_t len) const; }; /** @@ -242,79 +238,75 @@ class AlgoSHA1 final : public Interface */ class AlgoSHA256 final : public Interface { - public: - static constexpr size_t SHA256_128_AUTHCODE_LENGTH = 16; + public: + static constexpr size_t SHA256_128_AUTHCODE_LENGTH = 16; - /** - * @brief Constructor for AlgoSHA256 - * - * @param[in] - Session Integrity Key - */ - explicit AlgoSHA256(const std::vector<uint8_t>& sik); + /** + * @brief Constructor for AlgoSHA256 + * + * @param[in] - Session Integrity Key + */ + explicit AlgoSHA256(const std::vector<uint8_t>& sik); - AlgoSHA256() = delete; - ~AlgoSHA256() = default; - AlgoSHA256(const AlgoSHA256&) = default; - AlgoSHA256& operator=(const AlgoSHA256&) = default; - AlgoSHA256(AlgoSHA256&&) = default; - AlgoSHA256& operator=(AlgoSHA256&&) = default; + AlgoSHA256() = delete; + ~AlgoSHA256() = default; + AlgoSHA256(const AlgoSHA256&) = default; + AlgoSHA256& operator=(const AlgoSHA256&) = default; + AlgoSHA256(AlgoSHA256&&) = default; + AlgoSHA256& operator=(AlgoSHA256&&) = default; - /** - * @brief Verify the integrity data of the packet - * - * @param[in] packet - Incoming IPMI packet - * @param[in] length - Length of the data in the packet to calculate - * the integrity data - * @param[in] integrityData - Iterator to the authCode in the packet - * - * @return true if authcode in the packet is equal to one generated - * using integrity algorithm on the packet data, false otherwise - */ - bool verifyIntegrityData( - const std::vector<uint8_t>& packet, - const size_t length, - std::vector<uint8_t>::const_iterator integrityData) - const override; + /** + * @brief Verify the integrity data of the packet + * + * @param[in] packet - Incoming IPMI packet + * @param[in] length - Length of the data in the packet to calculate + * the integrity data + * @param[in] integrityData - Iterator to the authCode in the packet + * + * @return true if authcode in the packet is equal to one generated + * using integrity algorithm on the packet data, false otherwise + */ + bool verifyIntegrityData( + const std::vector<uint8_t>& packet, const size_t length, + std::vector<uint8_t>::const_iterator integrityData) const override; - /** - * @brief Generate integrity data for the outgoing IPMI packet - * - * @param[in] packet - Outgoing IPMI packet - * - * @return on success return the integrity data for the outgoing IPMI - * packet - */ - std::vector<uint8_t> generateIntegrityData( - const std::vector<uint8_t>& packet) const override; + /** + * @brief Generate integrity data for the outgoing IPMI packet + * + * @param[in] packet - Outgoing IPMI packet + * + * @return on success return the integrity data for the outgoing IPMI + * packet + */ + std::vector<uint8_t> generateIntegrityData( + const std::vector<uint8_t>& packet) const override; - /** - * @brief Generate additional keying material based on SIK - * - * @param[in] sik - session integrity key - * @param[in] data - 20-byte Const_n - * - * @return on success returns the Kn based on HMAC-SHA256 - * - */ - std::vector<uint8_t> generateKn( - const std::vector<uint8_t>& sik, - const rmcp::Const_n& const_n) const; + /** + * @brief Generate additional keying material based on SIK + * + * @param[in] sik - session integrity key + * @param[in] data - 20-byte Const_n + * + * @return on success returns the Kn based on HMAC-SHA256 + * + */ + std::vector<uint8_t> generateKn(const std::vector<uint8_t>& sik, + const rmcp::Const_n& const_n) const; - private: - /** - * @brief Generate HMAC based on HMAC-SHA256-128 algorithm - * - * @param[in] input - pointer to the message - * @param[in] len - length of the message - * - * @return on success returns the message authentication code - * - */ - std::vector<uint8_t> generateHMAC(const uint8_t* input, - const size_t len) const; + private: + /** + * @brief Generate HMAC based on HMAC-SHA256-128 algorithm + * + * @param[in] input - pointer to the message + * @param[in] len - length of the message + * + * @return on success returns the message authentication code + * + */ + std::vector<uint8_t> generateHMAC(const uint8_t* input, + const size_t len) const; }; -}// namespace integrity - -}// namespace cipher +} // namespace integrity +} // namespace cipher @@ -1,19 +1,7 @@ #include "main.hpp" -#include <assert.h> -#include <dlfcn.h> -#include <dirent.h> -#include <unistd.h> - -#include <iostream> -#include <tuple> -#include <systemd/sd-bus.h> -#include <systemd/sd-daemon.h> -#include <systemd/sd-event.h> - -#include <host-ipmid/ipmid-api.h> -#include "command/guid.hpp" #include "comm_module.hpp" +#include "command/guid.hpp" #include "command_table.hpp" #include "message.hpp" #include "message_handler.hpp" @@ -22,6 +10,18 @@ #include "sol_module.hpp" #include "timer.hpp" +#include <assert.h> +#include <dirent.h> +#include <dlfcn.h> +#include <host-ipmid/ipmid-api.h> +#include <systemd/sd-bus.h> +#include <systemd/sd-daemon.h> +#include <systemd/sd-event.h> +#include <unistd.h> + +#include <iostream> +#include <tuple> + // Tuple of Global Singletons session::Manager manager; command::Table table; @@ -29,7 +29,8 @@ eventloop::EventLoop loop; sol::Manager solManager; std::tuple<session::Manager&, command::Table&, eventloop::EventLoop&, - sol::Manager&> singletonPool(manager, table, loop, solManager); + sol::Manager&> + singletonPool(manager, table, loop, solManager); sd_bus* bus = nullptr; sd_event* events = nullptr; @@ -65,7 +66,8 @@ unsigned short reserveSel(void) { // IPMI spec, Reservation ID, the value simply increases against each // execution of the Reserve SEL command. - if (++selReservationID == 0) { + if (++selReservationID == 0) + { selReservationID = 1; } selReservationValid = true; @@ -93,13 +95,14 @@ int main(int i_argc, char* i_argv[]) /* * Required by apphandler IPMI Provider Library for logging. */ - ipmidbus = fopen("/dev/null", "w"); + ipmidbus = fopen("/dev/null", "w"); // Connect to system bus auto rc = sd_bus_open_system(&bus); if (rc < 0) { - std::cerr << "Failed to connect to system bus:" << strerror(-rc) <<"\n"; + std::cerr << "Failed to connect to system bus:" << strerror(-rc) + << "\n"; goto finish; } @@ -107,7 +110,7 @@ int main(int i_argc, char* i_argv[]) rc = sd_event_default(&events); if (rc < 0) { - std::cerr << "Failure to create sd_event" << strerror(-rc) <<"\n"; + std::cerr << "Failure to create sd_event" << strerror(-rc) << "\n"; goto finish; } @@ -115,7 +118,6 @@ int main(int i_argc, char* i_argv[]) command::registerGUIDChangeCallback(); cache::guid = command::getSystemGUID(); - // Register all the IPMI provider libraries applicable for net-ipmid provider::registerCallbackHandlers(NET_IPMID_LIB_PATH); @@ -126,7 +128,8 @@ int main(int i_argc, char* i_argv[]) sol::command::registerCommands(); // Start Event Loop - return std::get<eventloop::EventLoop&>(singletonPool).startEventLoop(events); + return std::get<eventloop::EventLoop&>(singletonPool) + .startEventLoop(events); finish: sd_bus_unref(bus); @@ -1,15 +1,16 @@ #pragma once -#include <tuple> +#include "command/guid.hpp" +#include "sd_event_loop.hpp" +#include "sol/sol_manager.hpp" #include <command_table.hpp> -#include "command/guid.hpp" #include <sessions_manager.hpp> -#include "sol/sol_manager.hpp" -#include "sd_event_loop.hpp" +#include <tuple> -extern std::tuple<session::Manager&, command::Table&, - eventloop::EventLoop&, sol::Manager&> singletonPool; +extern std::tuple<session::Manager&, command::Table&, eventloop::EventLoop&, + sol::Manager&> + singletonPool; // Select call timeout is set arbitrarily set to 30 sec static constexpr size_t SELECT_CALL_TIMEOUT = 30; diff --git a/message.hpp b/message.hpp index 59aa6e6..db46c06 100644 --- a/message.hpp +++ b/message.hpp @@ -8,15 +8,15 @@ namespace message enum class PayloadType : uint8_t { - IPMI = 0x00, - SOL = 0x01, - OPEN_SESSION_REQUEST = 0x10, + IPMI = 0x00, + SOL = 0x01, + OPEN_SESSION_REQUEST = 0x10, OPEN_SESSION_RESPONSE = 0x11, - RAKP1 = 0x12, - RAKP2 = 0x13, - RAKP3 = 0x14, - RAKP4 = 0x15, - INVALID = 0xFF, + RAKP1 = 0x12, + RAKP2 = 0x13, + RAKP3 = 0x14, + RAKP4 = 0x15, + INVALID = 0xFF, }; /** @@ -32,10 +32,12 @@ struct Message { static constexpr uint32_t MESSAGE_INVALID_SESSION_ID = 0xBADBADFF; - Message() - : payloadType(PayloadType::INVALID), - rcSessionID(Message::MESSAGE_INVALID_SESSION_ID), - bmcSessionID(Message::MESSAGE_INVALID_SESSION_ID) {} + Message() : + payloadType(PayloadType::INVALID), + rcSessionID(Message::MESSAGE_INVALID_SESSION_ID), + bmcSessionID(Message::MESSAGE_INVALID_SESSION_ID) + { + } ~Message() = default; Message(const Message&) = default; @@ -43,12 +45,12 @@ struct Message Message(Message&&) = default; Message& operator=(Message&&) = default; - bool isPacketEncrypted; // Message's Encryption Status - bool isPacketAuthenticated; // Message's Authentication Status - PayloadType payloadType; // Type of message payload (IPMI,SOL ..etc) - uint32_t rcSessionID; // Remote Client's Session ID - uint32_t bmcSessionID; // BMC's session ID - uint32_t sessionSeqNum; // Session Sequence Number + bool isPacketEncrypted; // Message's Encryption Status + bool isPacketAuthenticated; // Message's Authentication Status + PayloadType payloadType; // Type of message payload (IPMI,SOL ..etc) + uint32_t rcSessionID; // Remote Client's Session ID + uint32_t bmcSessionID; // BMC's session ID + uint32_t sessionSeqNum; // Session Sequence Number /** @brief Message payload * @@ -116,4 +118,3 @@ using Response = Request; } // namespace LAN } // namespace message - diff --git a/message_handler.cpp b/message_handler.cpp index beeb798..62855a9 100644 --- a/message_handler.cpp +++ b/message_handler.cpp @@ -1,5 +1,11 @@ #include "message_handler.hpp" +#include "command_table.hpp" +#include "main.hpp" +#include "message.hpp" +#include "message_parsers.hpp" +#include "sessions_manager.hpp" + #include <sys/socket.h> #include <iostream> @@ -7,12 +13,6 @@ #include <string> #include <vector> -#include "command_table.hpp" -#include "main.hpp" -#include "message.hpp" -#include "message_parsers.hpp" -#include "sessions_manager.hpp" - namespace message { @@ -35,8 +35,9 @@ std::unique_ptr<Message> Handler::receive() std::unique_ptr<Message> message; std::tie(message, sessionHeader) = parser::unflatten(packet); - auto session = (std::get<session::Manager&>(singletonPool).getSession( - message->bmcSessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(message->bmcSessionID)) + .lock(); sessionID = message->bmcSessionID; message->rcSessionID = session->getRCSessionID(); @@ -45,29 +46,29 @@ std::unique_ptr<Message> Handler::receive() return message; } -template<> -std::unique_ptr<Message> Handler::createResponse<PayloadType::IPMI>( - std::vector<uint8_t>& output, Message& inMessage) +template <> +std::unique_ptr<Message> + Handler::createResponse<PayloadType::IPMI>(std::vector<uint8_t>& output, + Message& inMessage) { auto outMessage = std::make_unique<Message>(); outMessage->payloadType = PayloadType::IPMI; - outMessage->payload.resize(sizeof(LAN::header::Response) + - output.size() + + outMessage->payload.resize(sizeof(LAN::header::Response) + output.size() + sizeof(LAN::trailer::Response)); - auto reqHeader = reinterpret_cast<LAN::header::Request*> - (inMessage.payload.data()); - auto respHeader = reinterpret_cast<LAN::header::Response*> - (outMessage->payload.data()); + auto reqHeader = + reinterpret_cast<LAN::header::Request*>(inMessage.payload.data()); + auto respHeader = + reinterpret_cast<LAN::header::Response*>(outMessage->payload.data()); // Add IPMI LAN Message Response Header respHeader->rqaddr = reqHeader->rqaddr; - respHeader->netfn = reqHeader->netfn | 0x04; - respHeader->cs = crc8bit(&(respHeader->rqaddr), 2); + respHeader->netfn = reqHeader->netfn | 0x04; + respHeader->cs = crc8bit(&(respHeader->rqaddr), 2); respHeader->rsaddr = reqHeader->rsaddr; - respHeader->rqseq = reqHeader->rqseq; - respHeader->cmd = reqHeader->cmd; + respHeader->rqseq = reqHeader->rqseq; + respHeader->cmd = reqHeader->cmd; auto assembledSize = sizeof(LAN::header::Response); @@ -77,8 +78,8 @@ std::unique_ptr<Message> Handler::createResponse<PayloadType::IPMI>( assembledSize += output.size(); // Add the IPMI LAN Message Trailer - auto trailer = reinterpret_cast<LAN::trailer::Response*> - (outMessage->payload.data() + assembledSize); + auto trailer = reinterpret_cast<LAN::trailer::Response*>( + outMessage->payload.data() + assembledSize); trailer->checksum = crc8bit(&respHeader->rsaddr, assembledSize - 3); return outMessage; @@ -92,8 +93,8 @@ std::unique_ptr<Message> Handler::executeCommand(Message& inMessage) if (inMessage.payloadType == PayloadType::IPMI) { - if (inMessage.payload.size() < (sizeof(LAN::header::Request) + - sizeof(LAN::trailer::Request))) + if (inMessage.payload.size() < + (sizeof(LAN::header::Request) + sizeof(LAN::trailer::Request))) { return nullptr; } @@ -102,17 +103,13 @@ std::unique_ptr<Message> Handler::executeCommand(Message& inMessage) auto end = inMessage.payload.end() - sizeof(LAN::trailer::Request); std::vector<uint8_t> inPayload(start, end); - output = std::get<command::Table&>(singletonPool).executeCommand( - command, - inPayload, - *this); + output = std::get<command::Table&>(singletonPool) + .executeCommand(command, inPayload, *this); } else { - output = std::get<command::Table&>(singletonPool).executeCommand( - command, - inMessage.payload, - *this); + output = std::get<command::Table&>(singletonPool) + .executeCommand(command, inMessage.payload, *this); } std::unique_ptr<Message> outMessage = nullptr; @@ -124,7 +121,7 @@ std::unique_ptr<Message> Handler::executeCommand(Message& inMessage) break; case PayloadType::OPEN_SESSION_REQUEST: outMessage = createResponse<PayloadType::OPEN_SESSION_RESPONSE>( - output, inMessage); + output, inMessage); break; case PayloadType::RAKP1: outMessage = createResponse<PayloadType::RAKP2>(output, inMessage); @@ -149,15 +146,18 @@ std::unique_ptr<Message> Handler::executeCommand(Message& inMessage) uint32_t Handler::getCommand(Message& message) { - uint32_t command = 0 ; + uint32_t command = 0; command |= (static_cast<uint8_t>(message.payloadType) << 16); if (message.payloadType == PayloadType::IPMI) { - command |= ((reinterpret_cast<LAN::header::Request*> - (message.payload.data()))->netfn) << 8; - command |= (reinterpret_cast<LAN::header::Request*> - (message.payload.data()))->cmd; + command |= + ((reinterpret_cast<LAN::header::Request*>(message.payload.data())) + ->netfn) + << 8; + command |= + (reinterpret_cast<LAN::header::Request*>(message.payload.data())) + ->cmd; } return command; @@ -165,8 +165,9 @@ uint32_t Handler::getCommand(Message& message) void Handler::send(Message& outMessage) { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); // Flatten the packet auto packet = parser::flatten(outMessage, sessionHeader, *session); @@ -181,8 +182,9 @@ void Handler::send(Message& outMessage) void Handler::setChannelInSession() const { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); session->channelPtr = channel; } @@ -191,8 +193,9 @@ void Handler::sendSOLPayload(const std::vector<uint8_t>& input) { Message outMessage; - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); outMessage.payloadType = PayloadType::SOL; outMessage.payload = input; @@ -204,14 +207,14 @@ void Handler::sendSOLPayload(const std::vector<uint8_t>& input) send(outMessage); } -void Handler::sendUnsolicitedIPMIPayload(uint8_t netfn, - uint8_t cmd, +void Handler::sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd, const std::vector<uint8_t>& output) { Message outMessage; - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); outMessage.payloadType = PayloadType::IPMI; outMessage.isPacketEncrypted = session->isCryptAlgoEnabled(); @@ -219,32 +222,30 @@ void Handler::sendUnsolicitedIPMIPayload(uint8_t netfn, outMessage.rcSessionID = session->getRCSessionID(); outMessage.bmcSessionID = sessionID; - outMessage.payload.resize(sizeof(LAN::header::Request) + - output.size() + + outMessage.payload.resize(sizeof(LAN::header::Request) + output.size() + sizeof(LAN::trailer::Request)); - auto respHeader = reinterpret_cast<LAN::header::Request*> - (outMessage.payload.data()); + auto respHeader = + reinterpret_cast<LAN::header::Request*>(outMessage.payload.data()); // Add IPMI LAN Message Request Header respHeader->rsaddr = LAN::requesterBMCAddress; - respHeader->netfn = (netfn << 0x02); - respHeader->cs = crc8bit(&(respHeader->rsaddr), 2); + respHeader->netfn = (netfn << 0x02); + respHeader->cs = crc8bit(&(respHeader->rsaddr), 2); respHeader->rqaddr = LAN::responderBMCAddress; - respHeader->rqseq = 0; - respHeader->cmd = cmd; + respHeader->rqseq = 0; + respHeader->cmd = cmd; auto assembledSize = sizeof(LAN::header::Request); // Copy the output by the execution of the command - std::copy(output.begin(), - output.end(), + std::copy(output.begin(), output.end(), outMessage.payload.begin() + assembledSize); assembledSize += output.size(); // Add the IPMI LAN Message Trailer - auto trailer = reinterpret_cast<LAN::trailer::Request*> - (outMessage.payload.data() + assembledSize); + auto trailer = reinterpret_cast<LAN::trailer::Request*>( + outMessage.payload.data() + assembledSize); // Calculate the checksum for the field rqaddr in the header to the // command data, 3 corresponds to size of the fields before rqaddr( rsaddr, @@ -254,5 +255,4 @@ void Handler::sendUnsolicitedIPMIPayload(uint8_t netfn, send(outMessage); } -} //namespace message - +} // namespace message diff --git a/message_handler.hpp b/message_handler.hpp index 7fb06f1..063f8d2 100644 --- a/message_handler.hpp +++ b/message_handler.hpp @@ -1,142 +1,143 @@ #pragma once -#include <iostream> -#include <numeric> #include "message.hpp" #include "message_parsers.hpp" #include "session.hpp" #include "sol/console_buffer.hpp" +#include <iostream> +#include <numeric> + namespace message { class Handler { - public: - explicit Handler(std::shared_ptr<udpsocket::Channel> channel, - uint32_t sessionID = - message::Message::MESSAGE_INVALID_SESSION_ID): - sessionID(sessionID), - channel(channel) {} - - Handler() = delete; - ~Handler() = default; - Handler(const Handler&) = default; - Handler& operator=(const Handler&) = default; - Handler(Handler&&) = default; - Handler& operator=(Handler&&) = default; - - /** - * @brief Receive the IPMI packet - * - * Read the data on the socket, get the parser based on the Session - * header type and flatten the payload and generate the IPMI message - * - * @return IPMI Message on success and nullptr on failure - * - */ - std::unique_ptr<Message> receive(); - - /** - * @brief Process the incoming IPMI message - * - * The incoming message payload is handled and the command handler for - * the Network function and Command is executed and the response message - * is returned - * - * @param[in] inMessage - Incoming Message - * - * @return Outgoing message on success and nullptr on failure - */ - std::unique_ptr<Message> executeCommand(Message& inMessage); - - /** @brief Send the outgoing message - * - * The payload in the outgoing message is flattened and sent out on the - * socket - * - * @param[in] outMessage - Outgoing Message - */ - void send(Message& outMessage); - - /** @brief Set socket channel in session object */ - void setChannelInSession() const; - - /** @brief Send the SOL payload - * - * The SOL payload is flattened and sent out on the socket - * - * @param[in] input - SOL Payload - */ - void sendSOLPayload(const std::vector<uint8_t>& input); - - /** @brief Send the unsolicited IPMI payload to the remote console. - * - * This is used by commands like SOL activating, in which case the BMC - * has to notify the remote console that a SOL payload is activating - * on another channel. - * - * @param[in] netfn - Net function. - * @param[in] cmd - Command. - * @param[in] input - Command request data. - */ - void sendUnsolicitedIPMIPayload(uint8_t netfn, - uint8_t cmd, - const std::vector<uint8_t>& input); - - // BMC Session ID for the Channel - session::SessionID sessionID; - - private: - /** @brief Socket channel for communicating with the remote client.*/ - std::shared_ptr<udpsocket::Channel> channel; - - parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; - - /** - * @brief Create the response IPMI message - * - * The IPMI outgoing message is constructed out of payload and the - * corresponding fields are populated.For the payload type IPMI, the - * LAN message header and trailer are added. - * - * @tparam[in] T - Outgoing message payload type - * @param[in] output - Payload for outgoing message - * @param[in] inMessage - Incoming IPMI message - * - * @return Outgoing message on success and nullptr on failure - */ - template<PayloadType T> - std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output, - Message& inMessage) - { - auto outMessage = std::make_unique<Message>(); - outMessage->payloadType = T; - outMessage->payload = output; - return outMessage; - } - - /** - * @brief Extract the command from the IPMI payload - * - * @param[in] message - Incoming message - * - * @return Command ID in the incoming message - */ - uint32_t getCommand(Message& message); - - /** - * @brief Calculate 8 bit 2's complement checksum - * - * Initialize checksum to 0. For each byte, checksum = (checksum + byte) - * modulo 256. Then checksum = - checksum. When the checksum and the - * bytes are added together, modulo 256, the result should be 0. - */ - uint8_t crc8bit(const uint8_t* ptr, const size_t len) - { - return (0x100 - std::accumulate(ptr,ptr+len,0)); - } - + public: + explicit Handler( + std::shared_ptr<udpsocket::Channel> channel, + uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : + sessionID(sessionID), + channel(channel) + { + } + + Handler() = delete; + ~Handler() = default; + Handler(const Handler&) = default; + Handler& operator=(const Handler&) = default; + Handler(Handler&&) = default; + Handler& operator=(Handler&&) = default; + + /** + * @brief Receive the IPMI packet + * + * Read the data on the socket, get the parser based on the Session + * header type and flatten the payload and generate the IPMI message + * + * @return IPMI Message on success and nullptr on failure + * + */ + std::unique_ptr<Message> receive(); + + /** + * @brief Process the incoming IPMI message + * + * The incoming message payload is handled and the command handler for + * the Network function and Command is executed and the response message + * is returned + * + * @param[in] inMessage - Incoming Message + * + * @return Outgoing message on success and nullptr on failure + */ + std::unique_ptr<Message> executeCommand(Message& inMessage); + + /** @brief Send the outgoing message + * + * The payload in the outgoing message is flattened and sent out on the + * socket + * + * @param[in] outMessage - Outgoing Message + */ + void send(Message& outMessage); + + /** @brief Set socket channel in session object */ + void setChannelInSession() const; + + /** @brief Send the SOL payload + * + * The SOL payload is flattened and sent out on the socket + * + * @param[in] input - SOL Payload + */ + void sendSOLPayload(const std::vector<uint8_t>& input); + + /** @brief Send the unsolicited IPMI payload to the remote console. + * + * This is used by commands like SOL activating, in which case the BMC + * has to notify the remote console that a SOL payload is activating + * on another channel. + * + * @param[in] netfn - Net function. + * @param[in] cmd - Command. + * @param[in] input - Command request data. + */ + void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd, + const std::vector<uint8_t>& input); + + // BMC Session ID for the Channel + session::SessionID sessionID; + + private: + /** @brief Socket channel for communicating with the remote client.*/ + std::shared_ptr<udpsocket::Channel> channel; + + parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; + + /** + * @brief Create the response IPMI message + * + * The IPMI outgoing message is constructed out of payload and the + * corresponding fields are populated.For the payload type IPMI, the + * LAN message header and trailer are added. + * + * @tparam[in] T - Outgoing message payload type + * @param[in] output - Payload for outgoing message + * @param[in] inMessage - Incoming IPMI message + * + * @return Outgoing message on success and nullptr on failure + */ + template <PayloadType T> + std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output, + Message& inMessage) + { + auto outMessage = std::make_unique<Message>(); + outMessage->payloadType = T; + outMessage->payload = output; + return outMessage; + } + + /** + * @brief Extract the command from the IPMI payload + * + * @param[in] message - Incoming message + * + * @return Command ID in the incoming message + */ + uint32_t getCommand(Message& message); + + /** + * @brief Calculate 8 bit 2's complement checksum + * + * Initialize checksum to 0. For each byte, checksum = (checksum + byte) + * modulo 256. Then checksum = - checksum. When the checksum and the + * bytes are added together, modulo 256, the result should be 0. + */ + uint8_t crc8bit(const uint8_t* ptr, const size_t len) + { + return (0x100 - std::accumulate(ptr, ptr + len, 0)); + } }; -} //namespace message +} // namespace message diff --git a/message_parsers.cpp b/message_parsers.cpp index 66030cf..695b5b7 100644 --- a/message_parsers.cpp +++ b/message_parsers.cpp @@ -1,21 +1,21 @@ #include "message_parsers.hpp" -#include <iostream> -#include <memory> - #include "endian.hpp" #include "main.hpp" #include "message.hpp" #include "sessions_manager.hpp" +#include <iostream> +#include <memory> + namespace message { namespace parser { -std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten( - std::vector<uint8_t>& inPacket) +std::tuple<std::unique_ptr<Message>, SessionHeader> + unflatten(std::vector<uint8_t>& inPacket) { // Check if the packet has atleast the size of the RMCP Header if (inPacket.size() < sizeof(BasicHeader_t)) @@ -54,8 +54,7 @@ std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten( } } -std::vector<uint8_t> flatten(Message& outMessage, - SessionHeader authType, +std::vector<uint8_t> flatten(Message& outMessage, SessionHeader authType, session::Session& session) { // Call the flatten routine based on the header type @@ -101,9 +100,9 @@ std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket) auto payloadLen = header->payloadLength; - (message->payload).assign(inPacket.data() + sizeof(SessionHeader_t), - inPacket.data() + sizeof(SessionHeader_t) + - payloadLen); + (message->payload) + .assign(inPacket.data() + sizeof(SessionHeader_t), + inPacket.data() + sizeof(SessionHeader_t) + payloadLen); return message; } @@ -131,8 +130,8 @@ std::vector<uint8_t> flatten(Message& outMessage, session::Session& session) // Insert the Session Trailer packet.resize(packet.size() + sizeof(SessionTrailer_t)); - auto trailer = reinterpret_cast<SessionTrailer_t*>(packet.data() + - packet.size()); + auto trailer = + reinterpret_cast<SessionTrailer_t*>(packet.data() + packet.size()); trailer->legacyPad = 0x00; return packet; @@ -155,8 +154,7 @@ std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket) auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data()); - message->payloadType = static_cast<PayloadType> - (header->payloadType & 0x3F); + message->payloadType = static_cast<PayloadType>(header->payloadType & 0x3F); message->bmcSessionID = endian::from_ipmi(header->sessId); message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum); message->isPacketEncrypted = @@ -168,8 +166,7 @@ std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket) if (message->isPacketAuthenticated) { - if (!(internal::verifyPacketIntegrity(inPacket, - *(message.get()), + if (!(internal::verifyPacketIntegrity(inPacket, *(message.get()), payloadLen))) { throw std::runtime_error("Packet Integrity check failed"); @@ -180,15 +177,14 @@ std::unique_ptr<Message> unflatten(std::vector<uint8_t>& inPacket) if (message->isPacketEncrypted) { // Assign the decrypted payload to the IPMI Message - message->payload = internal::decryptPayload(inPacket, - *(message.get()), - payloadLen); + message->payload = + internal::decryptPayload(inPacket, *(message.get()), payloadLen); } else { message->payload.assign(inPacket.begin() + sizeof(SessionHeader_t), inPacket.begin() + sizeof(SessionHeader_t) + - payloadLen); + payloadLen); } return message; @@ -226,8 +222,8 @@ std::vector<uint8_t> flatten(Message& outMessage, session::Session& session) } else { - header->payloadLength = endian::to_ipmi<uint16_t>( - outMessage.payload.size()); + header->payloadLength = + endian::to_ipmi<uint16_t>(outMessage.payload.size()); payloadLen = outMessage.payload.size(); // Insert the Payload into the Packet @@ -262,8 +258,7 @@ void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session) } bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, - const Message& message, - size_t payloadLen) + const Message& message, size_t payloadLen) { /* * Padding bytes are added to cause the number of bytes in the data range @@ -275,8 +270,8 @@ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, auto sessTrailerPos = sizeof(SessionHeader_t) + payloadLen + paddingLen; - auto trailer = reinterpret_cast<const SessionTrailer_t*> - (packet.data() + sessTrailerPos); + auto trailer = reinterpret_cast<const SessionTrailer_t*>(packet.data() + + sessTrailerPos); // Check trailer->padLength against paddingLen, both should match up, // return false if the lengths don't match @@ -285,8 +280,9 @@ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, return false; } - auto session = (std::get<session::Manager&>(singletonPool).getSession( - message.bmcSessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(message.bmcSessionID)) + .lock(); auto integrityAlgo = session->getIntegrityAlgo(); @@ -294,7 +290,7 @@ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, // length is same as the length expected for the Integrity Algorithm that // was negotiated during the session open process. if ((packet.size() - sessTrailerPos - sizeof(SessionTrailer_t)) != - integrityAlgo->authCodeLength) + integrityAlgo->authCodeLength) { return false; } @@ -310,8 +306,7 @@ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, return integrityAlgo->verifyIntegrityData(packet, length, integrityIter); } -void addIntegrityData(std::vector<uint8_t>& packet, - const Message& message, +void addIntegrityData(std::vector<uint8_t>& packet, const Message& message, size_t payloadLen) { // The following logic calculates the number of padding bytes to be added to @@ -321,38 +316,38 @@ void addIntegrityData(std::vector<uint8_t>& packet, packet.resize(packet.size() + sizeof(SessionTrailer_t)); - auto trailer = reinterpret_cast<SessionTrailer_t*> - (packet.data() + packet.size() - - sizeof(SessionTrailer_t)); + auto trailer = reinterpret_cast<SessionTrailer_t*>( + packet.data() + packet.size() - sizeof(SessionTrailer_t)); trailer->padLength = paddingLen; trailer->nextHeader = parser::RMCP_MESSAGE_CLASS_IPMI; - auto session = (std::get<session::Manager&>(singletonPool).getSession( - message.bmcSessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(message.bmcSessionID)) + .lock(); - auto integrityData = session->getIntegrityAlgo()-> - generateIntegrityData(packet); + auto integrityData = + session->getIntegrityAlgo()->generateIntegrityData(packet); packet.insert(packet.end(), integrityData.begin(), integrityData.end()); } std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet, - const Message& message, - size_t payloadLen) + const Message& message, size_t payloadLen) { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - message.bmcSessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(message.bmcSessionID)) + .lock(); - return session->getCryptAlgo()->decryptPayload(packet, - sizeof(SessionHeader_t), - payloadLen); + return session->getCryptAlgo()->decryptPayload( + packet, sizeof(SessionHeader_t), payloadLen); } std::vector<uint8_t> encryptPayload(Message& message) { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - message.bmcSessionID)).lock(); + auto session = (std::get<session::Manager&>(singletonPool) + .getSession(message.bmcSessionID)) + .lock(); return session->getCryptAlgo()->encryptPayload(message.payload); } diff --git a/message_parsers.hpp b/message_parsers.hpp index e55e405..0dae43b 100644 --- a/message_parsers.hpp +++ b/message_parsers.hpp @@ -43,8 +43,8 @@ struct BasicHeader_t // IPMI partial session header union { - uint8_t reserved1: 4; - uint8_t authType: 4; + uint8_t reserved1 : 4; + uint8_t authType : 4; uint8_t formatType; } format; } __attribute__((packed)); @@ -59,8 +59,8 @@ struct BasicHeader_t * header type. In case of failure nullptr and session header type * would be invalid. */ -std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten( - std::vector<uint8_t>& inPacket); +std::tuple<std::unique_ptr<Message>, SessionHeader> + unflatten(std::vector<uint8_t>& inPacket); /** * @brief Flatten an IPMI message and generate the IPMI packet with the @@ -72,8 +72,7 @@ std::tuple<std::unique_ptr<Message>, SessionHeader> unflatten( * * @return IPMI packet on success */ -std::vector<uint8_t> flatten(Message& outMessage, - SessionHeader authType, +std::vector<uint8_t> flatten(Message& outMessage, SessionHeader authType, session::Session& session); } // namespace parser @@ -181,8 +180,7 @@ void addSequenceNumber(std::vector<uint8_t>& packet, session::Session& session); * */ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, - const Message& message, - size_t payloadLen); + const Message& message, size_t payloadLen); /** * @brief Add Integrity data to the outgoing IPMI packet @@ -191,8 +189,7 @@ bool verifyPacketIntegrity(const std::vector<uint8_t>& packet, * @param[in] message - IPMI Message populated for the outgoing packet * @param[in] payloadLen - Length of the IPMI payload */ -void addIntegrityData(std::vector<uint8_t>& packet, - const Message& message, +void addIntegrityData(std::vector<uint8_t>& packet, const Message& message, size_t payloadLen); /** @@ -205,8 +202,7 @@ void addIntegrityData(std::vector<uint8_t>& packet, * @return on successful completion, return the plain text payload */ std::vector<uint8_t> decryptPayload(const std::vector<uint8_t>& packet, - const Message& message, - size_t payloadLen); + const Message& message, size_t payloadLen); /** * @brief Encrypt the plain text payload for the outgoing IPMI packet diff --git a/provider_registration.cpp b/provider_registration.cpp index 1a9b038..f0374f3 100644 --- a/provider_registration.cpp +++ b/provider_registration.cpp @@ -1,15 +1,16 @@ +#include "provider_registration.hpp" + +#include "command_table.hpp" +#include "main.hpp" + #include <dirent.h> #include <dlfcn.h> +#include <host-ipmid/ipmid-api.h> #include <stdlib.h> #include <string.h> #include <iostream> -#include <host-ipmid/ipmid-api.h> -#include "command_table.hpp" -#include "main.hpp" -#include "provider_registration.hpp" - namespace provider { @@ -38,8 +39,8 @@ void registerCallbackHandlers(const char* providerLibPath) struct dirent** handlerList = nullptr; std::string handlerPath(providerLibPath); - auto numLibs = scandir(providerLibPath, &handlerList, handler_select, - alphasort); + auto numLibs = + scandir(providerLibPath, &handlerList, handler_select, alphasort); if (numLibs < 0) { return; @@ -81,22 +82,19 @@ void registerCallbackHandlers(const char* providerLibPath) * @param[in] priv - IPMI Command Privilege */ void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_context_t context, - ipmid_callback_t handler, ipmi_cmd_privilege_t priv) + ipmi_context_t context, ipmid_callback_t handler, + ipmi_cmd_privilege_t priv) { uint16_t netFn = netfn << 10; // The payload type of IPMI commands provided by the shared libraries // is IPMI - command::CommandID command = - { - ((static_cast<uint32_t>(message::PayloadType::IPMI)) << 16) | - netFn | cmd - }; - - std::get<command::Table&>(singletonPool).registerCommand(command, - std::make_unique<command::ProviderIpmidEntry> - (command, handler, static_cast<session::Privilege>(priv))); + command::CommandID command = { + ((static_cast<uint32_t>(message::PayloadType::IPMI)) << 16) | netFn | + cmd}; + + std::get<command::Table&>(singletonPool) + .registerCommand(command, std::make_unique<command::ProviderIpmidEntry>( + command, handler, + static_cast<session::Privilege>(priv))); } - - @@ -22,18 +22,12 @@ namespace rmcp constexpr size_t CONST_N_SIZE = 20; using Const_n = std::array<uint8_t, CONST_N_SIZE>; -static constexpr Const_n const_1 = { - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01 -}; +static constexpr Const_n const_1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; -static constexpr Const_n const_2 = { - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02 -}; +static constexpr Const_n const_2 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; } // namespace rmcp diff --git a/sd_event_loop.cpp b/sd_event_loop.cpp index 3351da7..7ec4db9 100644 --- a/sd_event_loop.cpp +++ b/sd_event_loop.cpp @@ -1,11 +1,14 @@ +#include "sd_event_loop.hpp" + +#include "main.hpp" +#include "message_handler.hpp" + #include <netinet/in.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <systemd/sd-daemon.h> + #include <phosphor-logging/log.hpp> -#include "main.hpp" -#include "message_handler.hpp" -#include "sd_event_loop.hpp" namespace eventloop { @@ -26,7 +29,6 @@ static int udp623Handler(sd_event_source* es, int fd, uint32_t revents, // Initialize the Message Handler with the socket channel message::Handler msgHandler(channelPtr); - std::unique_ptr<message::Message> inMessage; // Read the incoming IPMI packet @@ -65,7 +67,7 @@ static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents, if (ioctl(fd, FIONREAD, &readSize) < 0) { log<level::ERR>("ioctl failed for FIONREAD:", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); return 0; } @@ -88,7 +90,7 @@ static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents, else if (readDataLen < 0) // Error { log<level::ERR>("Reading from host console socket failed:", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); } } catch (std::exception& e) @@ -100,7 +102,7 @@ static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents, } static int charAccTimerHandler(sd_event_source* s, uint64_t usec, - void *userdata) + void* userdata) { // The instance is hardcoded to 1, in the case of supporting multiple // payload instances we would need to populate it from userdata @@ -110,10 +112,10 @@ static int charAccTimerHandler(sd_event_source* s, uint64_t usec, try { - if(bufferSize > 0) + if (bufferSize > 0) { - auto& context = std::get<sol::Manager&>(singletonPool).getContext - (instance); + auto& context = + std::get<sol::Manager&>(singletonPool).getContext(instance); rc = context.sendOutboundPayload(); @@ -123,8 +125,8 @@ static int charAccTimerHandler(sd_event_source* s, uint64_t usec, } } - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - instance, Timers::ACCUMULATE, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(instance, Timers::ACCUMULATE, true); } catch (std::exception& e) { @@ -134,8 +136,7 @@ static int charAccTimerHandler(sd_event_source* s, uint64_t usec, return 0; } -static int retryTimerHandler(sd_event_source* s, uint64_t usec, - void *userdata) +static int retryTimerHandler(sd_event_source* s, uint64_t usec, void* userdata) { // The instance is hardcoded to 1, in the case of supporting multiple // payload instances we would need to populate it from userdata @@ -143,24 +144,24 @@ static int retryTimerHandler(sd_event_source* s, uint64_t usec, try { - auto& context = std::get<sol::Manager&>(singletonPool).getContext - (instance); + auto& context = + std::get<sol::Manager&>(singletonPool).getContext(instance); if (context.retryCounter) { --context.retryCounter; - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (instance, Timers::RETRY, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(instance, Timers::RETRY, true); context.resendPayload(sol::Context::noClear); } else { context.retryCounter = context.maxRetryCount; context.resendPayload(sol::Context::clear); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (instance, Timers::RETRY, false); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (instance, Timers::ACCUMULATE, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(instance, Timers::RETRY, false); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(instance, Timers::ACCUMULATE, true); } } catch (std::exception& e) @@ -216,7 +217,7 @@ int EventLoop::startEventLoop(sd_event* events) goto finish; } - //Create our own socket if SysD did not supply one. + // Create our own socket if SysD did not supply one. listen_fd = sd_listen_fds(0); if (listen_fd == 1) { @@ -241,7 +242,7 @@ int EventLoop::startEventLoop(sd_event* events) address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(IPMI_STD_PORT); - if (bind(fd, (struct sockaddr *)&address, sizeof(address)) < 0) + if (bind(fd, (struct sockaddr*)&address, sizeof(address)) < 0) { r = -errno; log<level::ERR>("Unable to bind socket"); @@ -264,13 +265,13 @@ finish: if (fd >= 0) { - (void) close(fd); + (void)close(fd); } if (r < 0) { log<level::ERR>("Event Loop Failure:", - entry("FAILURE=%s", strerror(-r))); + entry("FAILURE=%s", strerror(-r))); } return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; @@ -280,7 +281,7 @@ void EventLoop::startHostConsole(const sol::CustomFD& fd) { int rc = 0; - if((fd() == -1) || hostConsole.get()) + if ((fd() == -1) || hostConsole.get()) { throw std::runtime_error("Console descriptor already added"); } @@ -288,15 +289,15 @@ void EventLoop::startHostConsole(const sol::CustomFD& fd) sd_event_source* source = nullptr; // Add the fd to the event loop for EPOLLIN - rc = sd_event_add_io( - event, &source, fd(), EPOLLIN, consoleInputHandler, nullptr); + rc = sd_event_add_io(event, &source, fd(), EPOLLIN, consoleInputHandler, + nullptr); if (rc < 0) { throw std::runtime_error("Failed to add socket descriptor"); } hostConsole.reset(source); - source=nullptr; + source = nullptr; } void EventLoop::stopHostConsole() @@ -310,7 +311,7 @@ void EventLoop::stopHostConsole() if (rc < 0) { log<level::ERR>("Failed to disable the host console socket", - entry("RC=%d", rc)); + entry("RC=%d", rc)); } hostConsole.reset(); @@ -331,37 +332,28 @@ void EventLoop::startSOLPayloadInstance(uint8_t payloadInst, if (rc < 0) { log<level::ERR>("Failed to get the current timestamp", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("Failed to get current timestamp"); } // Create character accumulate timer - rc = sd_event_add_time(event, - &accTimerSource, - CLOCK_MONOTONIC, - currentTime + accumulateInterval.count(), - 0, - charAccTimerHandler, - static_cast<void *>(&instance)); + rc = sd_event_add_time(event, &accTimerSource, CLOCK_MONOTONIC, + currentTime + accumulateInterval.count(), 0, + charAccTimerHandler, static_cast<void*>(&instance)); if (rc < 0) { log<level::ERR>("Failed to setup the accumulate timer", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("Failed to setup accumulate timer"); } // Create retry interval timer and add to the event loop - rc = sd_event_add_time(event, - &retryTimerSource, - CLOCK_MONOTONIC, - currentTime + retryInterval.count(), - 0, - retryTimerHandler, - static_cast<void *>(&instance)); + rc = sd_event_add_time(event, &retryTimerSource, CLOCK_MONOTONIC, + currentTime + retryInterval.count(), 0, + retryTimerHandler, static_cast<void*>(&instance)); if (rc < 0) { - log<level::ERR>("Failed to setup the retry timer", - entry("RC=%d", rc)); + log<level::ERR>("Failed to setup the retry timer", entry("RC=%d", rc)); throw std::runtime_error("Failed to setup retry timer"); } @@ -370,7 +362,7 @@ void EventLoop::startSOLPayloadInstance(uint8_t payloadInst, if (rc < 0) { log<level::ERR>("Failed to enable the accumulate timer", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("Failed to enable accumulate timer"); } @@ -379,7 +371,7 @@ void EventLoop::startSOLPayloadInstance(uint8_t payloadInst, if (rc < 0) { log<level::ERR>("Failed to disable the retry timer", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("Failed to disable retry timer"); } @@ -391,8 +383,8 @@ void EventLoop::startSOLPayloadInstance(uint8_t payloadInst, TimerMap timer; timer.emplace(Timers::ACCUMULATE, std::make_tuple(std::move(accEventSource), accumulateInterval)); - timer.emplace(Timers::RETRY, std::make_tuple(std::move(retryEventSource), - retryInterval)); + timer.emplace(Timers::RETRY, + std::make_tuple(std::move(retryEventSource), retryInterval)); payloadInfo.emplace(instance, std::move(timer)); } @@ -402,7 +394,7 @@ void EventLoop::stopSOLPayloadInstance(uint8_t payloadInst) if (iter == payloadInfo.end()) { log<level::ERR>("SOL Payload instance not found", - entry("PAYLOADINST=%d", payloadInst)); + entry("PAYLOADINST=%d", payloadInst)); throw std::runtime_error("SOL payload instance not found"); } @@ -410,24 +402,22 @@ void EventLoop::stopSOLPayloadInstance(uint8_t payloadInst) /* Destroy the character accumulate timer event source */ rc = sd_event_source_set_enabled( - (std::get<0>(iter->second.at(Timers::ACCUMULATE))).get(), - SD_EVENT_OFF); + (std::get<0>(iter->second.at(Timers::ACCUMULATE))).get(), SD_EVENT_OFF); if (rc < 0) { log<level::ERR>("Failed to disable the character accumulate timer", - entry("RC=%d", rc)); + entry("RC=%d", rc)); payloadInfo.erase(payloadInst); throw std::runtime_error("Failed to disable accumulate timer"); } /* Destroy the retry interval timer event source */ rc = sd_event_source_set_enabled( - (std::get<0>(iter->second.at(Timers::RETRY))).get(), - SD_EVENT_OFF); + (std::get<0>(iter->second.at(Timers::RETRY))).get(), SD_EVENT_OFF); if (rc < 0) { log<level::ERR>("Failed to disable the retry timer", - entry("RC=%d", rc)); + entry("RC=%d", rc)); payloadInfo.erase(payloadInst); throw std::runtime_error("Failed to disable retry timer"); } @@ -435,15 +425,13 @@ void EventLoop::stopSOLPayloadInstance(uint8_t payloadInst) payloadInfo.erase(payloadInst); } -void EventLoop::switchTimer(uint8_t payloadInst, - Timers type, - bool status) +void EventLoop::switchTimer(uint8_t payloadInst, Timers type, bool status) { auto iter = payloadInfo.find(payloadInst); if (iter == payloadInfo.end()) { log<level::ERR>("SOL Payload instance not found", - entry("PAYLOADINST=%d", payloadInst)); + entry("PAYLOADINST=%d", payloadInst)); throw std::runtime_error("SOL Payload instance not found"); } @@ -469,7 +457,7 @@ void EventLoop::switchTimer(uint8_t payloadInst, if (rc < 0) { log<level::ERR>("Failed to get the current timestamp", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("Failed to get current timestamp"); } @@ -477,14 +465,14 @@ void EventLoop::switchTimer(uint8_t payloadInst, if (rc < 0) { log<level::ERR>("sd_event_source_set_time function failed", - entry("RC=%d", rc)); + entry("RC=%d", rc)); throw std::runtime_error("sd_event_source_set_time function failed"); } rc = sd_event_source_set_enabled(source, SD_EVENT_ONESHOT); if (rc < 0) { - log<level::ERR>("Failed to enable the timer", entry("RC=%d",rc)); + log<level::ERR>("Failed to enable the timer", entry("RC=%d", rc)); throw std::runtime_error("Failed to enable timer"); } } diff --git a/sd_event_loop.hpp b/sd_event_loop.hpp index 2bb44d7..2faa7ad 100644 --- a/sd_event_loop.hpp +++ b/sd_event_loop.hpp @@ -1,6 +1,9 @@ #pragma once +#include "sol/sol_manager.hpp" + #include <systemd/sd-event.h> + #include <chrono> #include <map> @@ -32,124 +35,119 @@ using IntervalType = std::chrono::microseconds; */ enum class Timers { - ACCUMULATE, /**< Character Accumulate Timer */ - RETRY, /**< Retry Interval Timer */ + ACCUMULATE, /**< Character Accumulate Timer */ + RETRY, /**< Retry Interval Timer */ }; class EventLoop { - public: - - EventLoop() = default; - ~EventLoop() = default; - EventLoop(const EventLoop&) = delete; - EventLoop& operator=(const EventLoop&) = delete; - EventLoop(EventLoop&&) = delete; - EventLoop& operator=(EventLoop&&) = delete; - - /** @brief Timer Map - * - * The key for the timer map is the timer type. There are two types of - * timers, character accumulate timer and retry interval timer. The - * entries in the values is the event source for the timer and the - * interval. - */ - using TimerMap = std::map<Timers, std::tuple<EventSource, - IntervalType>>; - - /** @brief SOL Payload Map. - * - * The key for the payload map is the payload instance, the entries in - * the value are a map of timers. - */ - using PayloadMap = std::map<uint8_t, TimerMap>; - - /** @brief Initialise the event loop and add the handler for incoming - * IPMI packets. - * @param[in] events- sd bus event; - * - * @return EXIT_SUCCESS on success and EXIT_FAILURE on failure. - */ - int startEventLoop(sd_event* events); - - /** @brief Add host console I/O event source to the event loop. - * - * @param[in] fd - File descriptor for host console socket. - */ - void startHostConsole(const sol::CustomFD& fd); - - /** @brief Remove host console I/O event source. */ - void stopHostConsole(); - - /** @brief Initialize the timers for the SOL payload instance - * - * This API would add the Character accumulate interval timer event - * source and the retry interval timer event source for the SOL payload - * instance to the event loop. - * - * @param[in] payloadInst - SOL payload instance. - * @param[in] accumulateInterval - Character accumulate interval. - * @param[in] retryInterval - Retry interval. - */ - void startSOLPayloadInstance(uint8_t payloadInst, - IntervalType accumulateInterval, - IntervalType retryInterval); - - /** @brief Stop the timers for the SOL payload instance. - * - * This would remove the character accumulate interval timer event - * source and the retry interval timer event source from the event - * loop. - * - * @param[in] payloadInst - SOL payload instance - */ - void stopSOLPayloadInstance(uint8_t payloadInst); - - /** @brief Modify the timer event source to enable/disable. - * - * When the timer is enabled, the timer it set to fire again at - * timer's interval for the instance added to the event loop iteration - * timestamp. When the timer is disabled, the event source for the - * timer is disabled. - * - * @param[in] payloadInst - SOL payload instance. - * @param[in] type - Timer type. - * @param[in] status - on/off the event source. - */ - void switchTimer(uint8_t payloadInst, - Timers type, - bool status); - - /** @brief Modify the retry interval timer event source to enable/ - * disable - * - * When the timer is enabled, the timer it set to fire again at - * retry interval for the instance added to the event loop iteration - * timestamp. When the timer is disabled the event source for the - * retry interval timer is disabled. - * - * @param[in] payloadInst - SOL payload instance. - * @param[in] status - on/off the event source. - */ - void switchRetryTimer(uint8_t payloadInst, bool status); - - /** @brief Event loop object. */ - sd_event* event = nullptr; - - private: - /** @brief Event source object for host console. */ - EventSource hostConsole = nullptr; - - /** @brief Event source for the UDP socket listening on IPMI standard - * port. - */ - EventSource udpIPMI = nullptr; - - /** @brief Map to keep information regarding IPMI payload instance and - * timers for character accumulate interval and retry interval. - */ - PayloadMap payloadInfo; - + public: + EventLoop() = default; + ~EventLoop() = default; + EventLoop(const EventLoop&) = delete; + EventLoop& operator=(const EventLoop&) = delete; + EventLoop(EventLoop&&) = delete; + EventLoop& operator=(EventLoop&&) = delete; + + /** @brief Timer Map + * + * The key for the timer map is the timer type. There are two types of + * timers, character accumulate timer and retry interval timer. The + * entries in the values is the event source for the timer and the + * interval. + */ + using TimerMap = std::map<Timers, std::tuple<EventSource, IntervalType>>; + + /** @brief SOL Payload Map. + * + * The key for the payload map is the payload instance, the entries in + * the value are a map of timers. + */ + using PayloadMap = std::map<uint8_t, TimerMap>; + + /** @brief Initialise the event loop and add the handler for incoming + * IPMI packets. + * @param[in] events- sd bus event; + * + * @return EXIT_SUCCESS on success and EXIT_FAILURE on failure. + */ + int startEventLoop(sd_event* events); + + /** @brief Add host console I/O event source to the event loop. + * + * @param[in] fd - File descriptor for host console socket. + */ + void startHostConsole(const sol::CustomFD& fd); + + /** @brief Remove host console I/O event source. */ + void stopHostConsole(); + + /** @brief Initialize the timers for the SOL payload instance + * + * This API would add the Character accumulate interval timer event + * source and the retry interval timer event source for the SOL payload + * instance to the event loop. + * + * @param[in] payloadInst - SOL payload instance. + * @param[in] accumulateInterval - Character accumulate interval. + * @param[in] retryInterval - Retry interval. + */ + void startSOLPayloadInstance(uint8_t payloadInst, + IntervalType accumulateInterval, + IntervalType retryInterval); + + /** @brief Stop the timers for the SOL payload instance. + * + * This would remove the character accumulate interval timer event + * source and the retry interval timer event source from the event + * loop. + * + * @param[in] payloadInst - SOL payload instance + */ + void stopSOLPayloadInstance(uint8_t payloadInst); + + /** @brief Modify the timer event source to enable/disable. + * + * When the timer is enabled, the timer it set to fire again at + * timer's interval for the instance added to the event loop iteration + * timestamp. When the timer is disabled, the event source for the + * timer is disabled. + * + * @param[in] payloadInst - SOL payload instance. + * @param[in] type - Timer type. + * @param[in] status - on/off the event source. + */ + void switchTimer(uint8_t payloadInst, Timers type, bool status); + + /** @brief Modify the retry interval timer event source to enable/ + * disable + * + * When the timer is enabled, the timer it set to fire again at + * retry interval for the instance added to the event loop iteration + * timestamp. When the timer is disabled the event source for the + * retry interval timer is disabled. + * + * @param[in] payloadInst - SOL payload instance. + * @param[in] status - on/off the event source. + */ + void switchRetryTimer(uint8_t payloadInst, bool status); + + /** @brief Event loop object. */ + sd_event* event = nullptr; + + private: + /** @brief Event source object for host console. */ + EventSource hostConsole = nullptr; + + /** @brief Event source for the UDP socket listening on IPMI standard + * port. + */ + EventSource udpIPMI = nullptr; + + /** @brief Map to keep information regarding IPMI payload instance and + * timers for character accumulate interval and retry interval. + */ + PayloadMap payloadInfo; }; } // namespace eventloop diff --git a/session.cpp b/session.cpp index 208dfd0..9668ef2 100644 --- a/session.cpp +++ b/session.cpp @@ -1,17 +1,17 @@ #include "session.hpp" -#include <ctime> - #include "endian.hpp" +#include <ctime> + namespace session { bool Session::isSessionActive() { auto currentTime = std::chrono::steady_clock::now(); - auto elapsedSeconds = std::chrono::duration_cast<std::chrono::seconds> - (currentTime - lastTime); + auto elapsedSeconds = std::chrono::duration_cast<std::chrono::seconds>( + currentTime - lastTime); switch (state) { diff --git a/session.hpp b/session.hpp index f010a49..338a815 100644 --- a/session.hpp +++ b/session.hpp @@ -1,5 +1,11 @@ #pragma once +#include "auth_algo.hpp" +#include "crypt_algo.hpp" +#include "endian.hpp" +#include "integrity_algo.hpp" +#include "socket_channel.hpp" + #include <chrono> #include <exception> #include <list> @@ -7,12 +13,6 @@ #include <string> #include <vector> -#include "auth_algo.hpp" -#include "crypt_algo.hpp" -#include "integrity_algo.hpp" -#include "endian.hpp" -#include "socket_channel.hpp" - namespace session { @@ -31,10 +31,10 @@ enum class Privilege : uint8_t enum class State { - INACTIVE, // Session is not in use - SETUP_IN_PROGRESS, // Session Setup Sequence is progressing - ACTIVE, // Session is active - TEAR_DOWN_IN_PROGRESS,// When Closing Session + INACTIVE, // Session is not in use + SETUP_IN_PROGRESS, // Session Setup Sequence is progressing + ACTIVE, // Session is active + TEAR_DOWN_IN_PROGRESS, // When Closing Session }; // Seconds of inactivity allowed during session setup stage @@ -60,24 +60,24 @@ constexpr auto SESSION_INACTIVITY_TIMEOUT = 60s; */ struct SequenceNumbers { - auto get(bool inbound = true) const - { - return inbound ? in : out; - } - - void set(uint32_t seqNumber, bool inbound = true) - { - inbound ? (in = seqNumber) : (out = seqNumber); - } - - auto increment() - { - return ++out; - } - - private: - uint32_t in = 0; - uint32_t out = 0; + auto get(bool inbound = true) const + { + return inbound ? in : out; + } + + void set(uint32_t seqNumber, bool inbound = true) + { + inbound ? (in = seqNumber) : (out = seqNumber); + } + + auto increment() + { + return ++out; + } + + private: + uint32_t in = 0; + uint32_t out = 0; }; /** * @class Session @@ -93,183 +93,179 @@ struct SequenceNumbers */ class Session { - public: - - Session() = default; - ~Session() = default; - Session(const Session&) = delete; - Session& operator=(const Session&) = delete; - Session(Session&&) = default; - Session& operator=(Session&&) = default; - - /** - * @brief Session Constructor - * - * This is issued by the Session Manager when a session is started for - * the Open SessionRequest command - * - * @param[in] inRemoteConsoleSessID - Remote Console Session ID - * @param[in] priv - Privilege Level requested in the Command - */ - Session(SessionID inRemoteConsoleSessID, Privilege priv): - curPrivLevel(priv), - bmcSessionID(std::rand()), - remoteConsoleSessionID(inRemoteConsoleSessID) {} - - auto getBMCSessionID() const - { - return bmcSessionID; - } - - auto getRCSessionID() const - { - return remoteConsoleSessionID; - } - - auto getAuthAlgo() const + public: + Session() = default; + ~Session() = default; + Session(const Session&) = delete; + Session& operator=(const Session&) = delete; + Session(Session&&) = default; + Session& operator=(Session&&) = default; + + /** + * @brief Session Constructor + * + * This is issued by the Session Manager when a session is started for + * the Open SessionRequest command + * + * @param[in] inRemoteConsoleSessID - Remote Console Session ID + * @param[in] priv - Privilege Level requested in the Command + */ + Session(SessionID inRemoteConsoleSessID, Privilege priv) : + curPrivLevel(priv), bmcSessionID(std::rand()), + remoteConsoleSessionID(inRemoteConsoleSessID) + { + } + + auto getBMCSessionID() const + { + return bmcSessionID; + } + + auto getRCSessionID() const + { + return remoteConsoleSessionID; + } + + auto getAuthAlgo() const + { + if (authAlgoInterface) { - if(authAlgoInterface) - { - return authAlgoInterface.get(); - } - else - { - throw std::runtime_error("Authentication Algorithm Empty"); - } + return authAlgoInterface.get(); } - - void setAuthAlgo(std::unique_ptr<cipher::rakp_auth::Interface>&& - inAuthAlgo) + else { - authAlgoInterface = std::move(inAuthAlgo); + throw std::runtime_error("Authentication Algorithm Empty"); } - - /** - * @brief Get Session's Integrity Algorithm - * - * @return pointer to the integrity algorithm - */ - auto getIntegrityAlgo() const + } + + void setAuthAlgo(std::unique_ptr<cipher::rakp_auth::Interface>&& inAuthAlgo) + { + authAlgoInterface = std::move(inAuthAlgo); + } + + /** + * @brief Get Session's Integrity Algorithm + * + * @return pointer to the integrity algorithm + */ + auto getIntegrityAlgo() const + { + if (integrityAlgoInterface) { - if(integrityAlgoInterface) - { - return integrityAlgoInterface.get(); - } - else - { - throw std::runtime_error("Integrity Algorithm Empty"); - } + return integrityAlgoInterface.get(); } - - /** - * @brief Set Session's Integrity Algorithm - * - * @param[in] integrityAlgo - unique pointer to integrity algorithm - * instance - */ - void setIntegrityAlgo( - std::unique_ptr<cipher::integrity::Interface>&& integrityAlgo) - { - integrityAlgoInterface = std::move(integrityAlgo); - } - - /** @brief Check if integrity algorithm is enabled for this session. - * - * @return true if integrity algorithm is enabled else false. - */ - auto isIntegrityAlgoEnabled() - { - return integrityAlgoInterface ? true : false; - } - - /** - * @brief Get Session's Confidentiality Algorithm - * - * @return pointer to the confidentiality algorithm - */ - auto getCryptAlgo() const - { - if(cryptAlgoInterface) - { - return cryptAlgoInterface.get(); - } - else - { - throw std::runtime_error("Confidentiality Algorithm Empty"); - } - } - - /** - * @brief Set Session's Confidentiality Algorithm - * - * @param[in] confAlgo - unique pointer to confidentiality algorithm - * instance - */ - void setCryptAlgo( - std::unique_ptr<cipher::crypt::Interface>&& cryptAlgo) + else { - cryptAlgoInterface = std::move(cryptAlgo); + throw std::runtime_error("Integrity Algorithm Empty"); } - - /** @brief Check if confidentiality algorithm is enabled for this - * session. - * - * @return true if confidentiality algorithm is enabled else false. - */ - auto isCryptAlgoEnabled() + } + + /** + * @brief Set Session's Integrity Algorithm + * + * @param[in] integrityAlgo - unique pointer to integrity algorithm + * instance + */ + void setIntegrityAlgo( + std::unique_ptr<cipher::integrity::Interface>&& integrityAlgo) + { + integrityAlgoInterface = std::move(integrityAlgo); + } + + /** @brief Check if integrity algorithm is enabled for this session. + * + * @return true if integrity algorithm is enabled else false. + */ + auto isIntegrityAlgoEnabled() + { + return integrityAlgoInterface ? true : false; + } + + /** + * @brief Get Session's Confidentiality Algorithm + * + * @return pointer to the confidentiality algorithm + */ + auto getCryptAlgo() const + { + if (cryptAlgoInterface) { - return cryptAlgoInterface ? true : false; + return cryptAlgoInterface.get(); } - - void updateLastTransactionTime() + else { - lastTime = std::chrono::steady_clock::now(); + throw std::runtime_error("Confidentiality Algorithm Empty"); } - - /** - * @brief Session Active Status - * - * Session Active status is decided upon the Session State and the last - * transaction time is compared against the session inactivity timeout. - * - */ - bool isSessionActive(); - - /** - * @brief Session's Current Privilege Level - */ - Privilege curPrivLevel; - - /** - * @brief Session's Maximum Privilege Level - */ - Privilege maxPrivLevel = Privilege::CALLBACK; - - SequenceNumbers sequenceNums; // Session Sequence Numbers - State state = State::INACTIVE; // Session State - std::string userName {}; // User Name - - /** @brief Socket channel for communicating with the remote client.*/ - std::shared_ptr<udpsocket::Channel> channelPtr; - - private: - - SessionID bmcSessionID = 0; //BMC Session ID - SessionID remoteConsoleSessionID = 0; //Remote Console Session ID - - // Authentication Algorithm Interface for the Session - std::unique_ptr<cipher::rakp_auth::Interface> authAlgoInterface; - - // Integrity Algorithm Interface for the Session - std::unique_ptr<cipher::integrity::Interface> integrityAlgoInterface = - nullptr; - - // Confidentiality Algorithm Interface for the Session - std::unique_ptr<cipher::crypt::Interface> cryptAlgoInterface = - nullptr; - - // Last Transaction Time - decltype(std::chrono::steady_clock::now()) lastTime; + } + + /** + * @brief Set Session's Confidentiality Algorithm + * + * @param[in] confAlgo - unique pointer to confidentiality algorithm + * instance + */ + void setCryptAlgo(std::unique_ptr<cipher::crypt::Interface>&& cryptAlgo) + { + cryptAlgoInterface = std::move(cryptAlgo); + } + + /** @brief Check if confidentiality algorithm is enabled for this + * session. + * + * @return true if confidentiality algorithm is enabled else false. + */ + auto isCryptAlgoEnabled() + { + return cryptAlgoInterface ? true : false; + } + + void updateLastTransactionTime() + { + lastTime = std::chrono::steady_clock::now(); + } + + /** + * @brief Session Active Status + * + * Session Active status is decided upon the Session State and the last + * transaction time is compared against the session inactivity timeout. + * + */ + bool isSessionActive(); + + /** + * @brief Session's Current Privilege Level + */ + Privilege curPrivLevel; + + /** + * @brief Session's Maximum Privilege Level + */ + Privilege maxPrivLevel = Privilege::CALLBACK; + + SequenceNumbers sequenceNums; // Session Sequence Numbers + State state = State::INACTIVE; // Session State + std::string userName{}; // User Name + + /** @brief Socket channel for communicating with the remote client.*/ + std::shared_ptr<udpsocket::Channel> channelPtr; + + private: + SessionID bmcSessionID = 0; // BMC Session ID + SessionID remoteConsoleSessionID = 0; // Remote Console Session ID + + // Authentication Algorithm Interface for the Session + std::unique_ptr<cipher::rakp_auth::Interface> authAlgoInterface; + + // Integrity Algorithm Interface for the Session + std::unique_ptr<cipher::integrity::Interface> integrityAlgoInterface = + nullptr; + + // Confidentiality Algorithm Interface for the Session + std::unique_ptr<cipher::crypt::Interface> cryptAlgoInterface = nullptr; + + // Last Transaction Time + decltype(std::chrono::steady_clock::now()) lastTime; }; } // namespace session diff --git a/sessions_manager.cpp b/sessions_manager.cpp index 8d7b121..10c2764 100644 --- a/sessions_manager.cpp +++ b/sessions_manager.cpp @@ -1,13 +1,13 @@ #include "sessions_manager.hpp" +#include "session.hpp" + #include <algorithm> #include <cstdlib> #include <iomanip> #include <iostream> #include <memory> -#include "session.hpp" - namespace session { @@ -24,10 +24,11 @@ Manager::Manager() std::srand(std::time(0)); } -std::weak_ptr<Session> Manager::startSession(SessionID remoteConsoleSessID, - Privilege priv, cipher::rakp_auth::Algorithms authAlgo, - cipher::integrity::Algorithms intAlgo, - cipher::crypt::Algorithms cryptAlgo) +std::weak_ptr<Session> + Manager::startSession(SessionID remoteConsoleSessID, Privilege priv, + cipher::rakp_auth::Algorithms authAlgo, + cipher::integrity::Algorithms intAlgo, + cipher::crypt::Algorithms cryptAlgo) { std::shared_ptr<Session> session = nullptr; SessionID sessionID = 0; @@ -53,7 +54,7 @@ std::weak_ptr<Session> Manager::startSession(SessionID remoteConsoleSessID, auto iterator = sessionsMap.find(session->getBMCSessionID()); if (iterator != sessionsMap.end()) { - //Detected BMC Session ID collisions + // Detected BMC Session ID collisions session.reset(); continue; } @@ -61,8 +62,7 @@ std::weak_ptr<Session> Manager::startSession(SessionID remoteConsoleSessID, { break; } - } - while (1); + } while (1); // Set the Authentication Algorithm switch (authAlgo) @@ -70,15 +70,15 @@ std::weak_ptr<Session> Manager::startSession(SessionID remoteConsoleSessID, case cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA1: { session->setAuthAlgo( - std::make_unique<cipher::rakp_auth::AlgoSHA1>(intAlgo, - cryptAlgo)); + std::make_unique<cipher::rakp_auth::AlgoSHA1>(intAlgo, + cryptAlgo)); break; } case cipher::rakp_auth::Algorithms::RAKP_HMAC_SHA256: { session->setAuthAlgo( - std::make_unique<cipher::rakp_auth::AlgoSHA256>( - intAlgo, cryptAlgo)); + std::make_unique<cipher::rakp_auth::AlgoSHA256>(intAlgo, + cryptAlgo)); break; } default: @@ -91,9 +91,8 @@ std::weak_ptr<Session> Manager::startSession(SessionID remoteConsoleSessID, } else { - std::cerr << "E> No free sessions left: Active: " << activeSessions << - " Allowed: " << - MAX_SESSION_COUNT << "\n"; + std::cerr << "E> No free sessions left: Active: " << activeSessions + << " Allowed: " << MAX_SESSION_COUNT << "\n"; for (const auto& iterator : sessionsMap) { @@ -137,14 +136,13 @@ std::weak_ptr<Session> Manager::getSession(SessionID sessionID, } case RetrieveOption::RC_SESSION_ID: { - auto iter = std::find_if(sessionsMap.begin(), - sessionsMap.end(), - [sessionID](const std::pair<const uint32_t, - std::shared_ptr<Session>>& in) - -> bool - { - return sessionID == in.second->getRCSessionID(); - }); + auto iter = std::find_if( + sessionsMap.begin(), sessionsMap.end(), + [sessionID]( + const std::pair<const uint32_t, std::shared_ptr<Session>>& + in) -> bool { + return sessionID == in.second->getRCSessionID(); + }); if (iter != sessionsMap.end()) { @@ -161,7 +159,7 @@ std::weak_ptr<Session> Manager::getSession(SessionID sessionID, void Manager::cleanStaleEntries() { - for(auto iter = sessionsMap.begin(); iter != sessionsMap.end();) + for (auto iter = sessionsMap.begin(); iter != sessionsMap.end();) { auto session = iter->second; if ((session->getBMCSessionID() != SESSION_ZERO) && diff --git a/sessions_manager.hpp b/sessions_manager.hpp index 1d842de..cf28238 100644 --- a/sessions_manager.hpp +++ b/sessions_manager.hpp @@ -1,11 +1,11 @@ #pragma once +#include "session.hpp" + #include <map> #include <memory> #include <mutex> -#include "session.hpp" - namespace session { @@ -29,74 +29,73 @@ constexpr size_t MAX_SESSION_COUNT = 5; class Manager { - public: - - // BMC Session ID is the key for the map - using SessionMap = std::map<SessionID, std::shared_ptr<Session>>; - - Manager(); - ~Manager() = default; - Manager(const Manager&) = delete; - Manager& operator=(const Manager&) = delete; - Manager(Manager&&) = default; - Manager& operator=(Manager&&) = default; - - /** - * @brief Start an IPMI session - * - * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned - * in the Open SessionRequest Command - * @param[in] priv - Privilege level requested - * @param[in] authAlgo - Authentication Algorithm - * @param[in] intAlgo - Integrity Algorithm - * @param[in] cryptAlgo - Confidentiality Algorithm - * - * @return session handle on success and nullptr on failure - * - */ - std::weak_ptr<Session> startSession(SessionID remoteConsoleSessID, - Privilege priv, cipher::rakp_auth::Algorithms authAlgo, - cipher::integrity::Algorithms intAlgo, - cipher::crypt::Algorithms cryptAlgo); - - /** - * @brief Stop IPMI Session - * - * @param[in] bmcSessionID - BMC Session ID - * - * @return true on success and failure if session ID is invalid - * - */ - bool stopSession(SessionID bmcSessionID); - - /** - * @brief Get Session Handle - * - * @param[in] sessionID - Session ID - * @param[in] option - Select between BMC Session ID and Remote Console - * Session ID, Default option is BMC Session ID - * - * @return session handle on success and nullptr on failure - * - */ - std::weak_ptr<Session> getSession( - SessionID sessionID, - RetrieveOption option = RetrieveOption::BMC_SESSION_ID); - - private: - - /** - * @brief Session Manager keeps the session objects as a sorted - * associative container with Session ID as the unique key - */ - SessionMap sessionsMap; - - /** - * @brief Clean Session Stale Entries - * - * Removes the inactive sessions entries from the Session Map - */ - void cleanStaleEntries(); + public: + // BMC Session ID is the key for the map + using SessionMap = std::map<SessionID, std::shared_ptr<Session>>; + + Manager(); + ~Manager() = default; + Manager(const Manager&) = delete; + Manager& operator=(const Manager&) = delete; + Manager(Manager&&) = default; + Manager& operator=(Manager&&) = default; + + /** + * @brief Start an IPMI session + * + * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned + * in the Open SessionRequest Command + * @param[in] priv - Privilege level requested + * @param[in] authAlgo - Authentication Algorithm + * @param[in] intAlgo - Integrity Algorithm + * @param[in] cryptAlgo - Confidentiality Algorithm + * + * @return session handle on success and nullptr on failure + * + */ + std::weak_ptr<Session> startSession(SessionID remoteConsoleSessID, + Privilege priv, + cipher::rakp_auth::Algorithms authAlgo, + cipher::integrity::Algorithms intAlgo, + cipher::crypt::Algorithms cryptAlgo); + + /** + * @brief Stop IPMI Session + * + * @param[in] bmcSessionID - BMC Session ID + * + * @return true on success and failure if session ID is invalid + * + */ + bool stopSession(SessionID bmcSessionID); + + /** + * @brief Get Session Handle + * + * @param[in] sessionID - Session ID + * @param[in] option - Select between BMC Session ID and Remote Console + * Session ID, Default option is BMC Session ID + * + * @return session handle on success and nullptr on failure + * + */ + std::weak_ptr<Session> + getSession(SessionID sessionID, + RetrieveOption option = RetrieveOption::BMC_SESSION_ID); + + private: + /** + * @brief Session Manager keeps the session objects as a sorted + * associative container with Session ID as the unique key + */ + SessionMap sessionsMap; + + /** + * @brief Clean Session Stale Entries + * + * Removes the inactive sessions entries from the Session Map + */ + void cleanStaleEntries(); }; } // namespace session diff --git a/settings.cpp b/settings.cpp index f2f66a9..b243487 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1,7 +1,9 @@ +#include "settings.hpp" + +#include "xyz/openbmc_project/Common/error.hpp" + #include <phosphor-logging/elog-errors.hpp> #include <phosphor-logging/log.hpp> -#include "xyz/openbmc_project/Common/error.hpp" -#include "settings.hpp" namespace settings { @@ -14,14 +16,12 @@ constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper"; constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; Objects::Objects(sdbusplus::bus::bus& bus, - const std::vector<Interface>& filter): + const std::vector<Interface>& filter) : bus(bus) { auto depth = 0; - auto mapperCall = bus.new_method_call(mapperService, - mapperPath, - mapperIntf, + auto mapperCall = bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetSubTree"); mapperCall.append(root); mapperCall.append(depth); @@ -65,10 +65,8 @@ Objects::Objects(sdbusplus::bus::bus& bus, Service Objects::service(const Path& path, const Interface& interface) const { using Interfaces = std::vector<Interface>; - auto mapperCall = bus.new_method_call(mapperService, - mapperPath, - mapperIntf, - "GetObject"); + auto mapperCall = + bus.new_method_call(mapperService, mapperPath, mapperIntf, "GetObject"); mapperCall.append(path); mapperCall.append(Interfaces({interface})); @@ -118,12 +116,9 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, const Path& oneTimeSetting = paths[index]; const Path& regularSetting = paths[!index]; - auto method = - objects.bus.new_method_call( - objects.service(oneTimeSetting, iface).c_str(), - oneTimeSetting.c_str(), - propIntf, - "Get"); + auto method = objects.bus.new_method_call( + objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(), + propIntf, "Get"); method.append(enabledIntf, "Enabled"); auto reply = objects.bus.call(method); if (reply.is_method_error()) diff --git a/settings.hpp b/settings.hpp index 91c9930..5382fdd 100644 --- a/settings.hpp +++ b/settings.hpp @@ -1,8 +1,8 @@ #pragma once +#include <sdbusplus/bus.hpp> #include <string> #include <tuple> -#include <sdbusplus/bus.hpp> namespace settings { @@ -18,36 +18,36 @@ constexpr auto root = "/"; */ struct Objects { - public: - /** @brief Constructor - fetch settings objects - * - * @param[in] bus - The Dbus bus object - * @param[in] filter - A vector of settings interfaces the caller is - * interested in. - */ - Objects(sdbusplus::bus::bus& bus, const std::vector<Interface>& filter); - Objects(const Objects&) = default; - Objects& operator=(const Objects&) = default; - Objects(Objects&&) = delete; - Objects& operator=(Objects&&) = delete; - ~Objects() = default; + public: + /** @brief Constructor - fetch settings objects + * + * @param[in] bus - The Dbus bus object + * @param[in] filter - A vector of settings interfaces the caller is + * interested in. + */ + Objects(sdbusplus::bus::bus& bus, const std::vector<Interface>& filter); + Objects(const Objects&) = default; + Objects& operator=(const Objects&) = default; + Objects(Objects&&) = delete; + Objects& operator=(Objects&&) = delete; + ~Objects() = default; - /** @brief Fetch d-bus service, given a path and an interface. The - * service can't be cached because mapper returns unique - * service names. - * - * @param[in] path - The Dbus object - * @param[in] interface - The Dbus interface - * - * @return std::string - the dbus service - */ - Service service(const Path& path, const Interface& interface) const; + /** @brief Fetch d-bus service, given a path and an interface. The + * service can't be cached because mapper returns unique + * service names. + * + * @param[in] path - The Dbus object + * @param[in] interface - The Dbus interface + * + * @return std::string - the dbus service + */ + Service service(const Path& path, const Interface& interface) const; - /** @brief map of settings objects */ - std::map<Interface, std::vector<Path>> map; + /** @brief map of settings objects */ + std::map<Interface, std::vector<Path>> map; - /** @brief The Dbus bus object */ - sdbusplus::bus::bus& bus; + /** @brief The Dbus bus object */ + sdbusplus::bus::bus& bus; }; namespace boot diff --git a/socket_channel.cpp b/socket_channel.cpp index 8414f51..2fa350a 100644 --- a/socket_channel.cpp +++ b/socket_channel.cpp @@ -14,7 +14,7 @@ namespace udpsocket std::string Channel::getRemoteAddress() const { - char tmp[INET_ADDRSTRLEN] = { 0 }; + char tmp[INET_ADDRSTRLEN] = {0}; inet_ntop(AF_INET6, &address.inAddr.sin6_addr, tmp, sizeof(tmp)); return std::string(tmp); } @@ -41,12 +41,12 @@ std::tuple<int, std::vector<uint8_t>> Channel::read() do { - readDataLen = recvfrom(sockfd, // File Descriptor - outputPtr , // Buffer - bufferSize, // Bytes requested - 0, // Flags - &address.sockAddr, // Address - &address.addrSize); // Address Length + readDataLen = recvfrom(sockfd, // File Descriptor + outputPtr, // Buffer + bufferSize, // Bytes requested + 0, // Flags + &address.sockAddr, // Address + &address.addrSize); // Address Length if (readDataLen == 0) // Peer has performed an orderly shutdown { @@ -62,8 +62,7 @@ std::tuple<int, std::vector<uint8_t>> Channel::read() << "errno = " << rc << "\n"; outBuffer.resize(0); } - } - while ((readDataLen < 0) && (-(rc) == EINTR)); + } while ((readDataLen < 0) && (-(rc) == EINTR)); // Resize the vector to the actual data read from the socket outBuffer.resize(readDataLen); @@ -94,30 +93,31 @@ int Channel::write(const std::vector<uint8_t>& inBuffer) if (FD_ISSET(sockfd, &writeSet)) { address.addrSize = - static_cast<socklen_t>(sizeof(address.inAddr)); + static_cast<socklen_t>(sizeof(address.inAddr)); do { - writeDataLen = sendto(sockfd, // File Descriptor - outputPtr, // Message - bufferSize, // Length - MSG_NOSIGNAL, // Flags - &address.sockAddr,// Destination Address - address.addrSize);// Address Length + writeDataLen = + sendto(sockfd, // File Descriptor + outputPtr, // Message + bufferSize, // Length + MSG_NOSIGNAL, // Flags + &address.sockAddr, // Destination Address + address.addrSize); // Address Length if (writeDataLen < 0) { rc = -errno; - std::cerr << "Channel::Write: Write failed with errno:" - << rc << "\n"; + std::cerr + << "Channel::Write: Write failed with errno:" << rc + << "\n"; } else if (static_cast<size_t>(writeDataLen) < bufferSize) { rc = -1; std::cerr << "Channel::Write: Complete data not written" - " to the socket\n"; + " to the socket\n"; } - } - while ((writeDataLen < 0) && (-(rc) == EINTR)); + } while ((writeDataLen < 0) && (-(rc) == EINTR)); } else { @@ -137,14 +137,12 @@ int Channel::write(const std::vector<uint8_t>& inBuffer) else { // Error - rc = -errno; - std::cerr << "E> select call (writeset) had an error : " - << rc << "\n"; + rc = -errno; + std::cerr << "E> select call (writeset) had an error : " << rc + << "\n"; } - } - } - while (spuriousWakeup); + } while (spuriousWakeup); return rc; } diff --git a/socket_channel.hpp b/socket_channel.hpp index 5996b62..8a2edce 100644 --- a/socket_channel.hpp +++ b/socket_channel.hpp @@ -17,107 +17,107 @@ namespace udpsocket */ class Channel { - public: - struct SockAddr_t + public: + struct SockAddr_t + { + union { - union - { - sockaddr sockAddr; - sockaddr_in6 inAddr; - }; - socklen_t addrSize; + sockaddr sockAddr; + sockaddr_in6 inAddr; }; + socklen_t addrSize; + }; - /** - * @brief Constructor - * - * Initialize the IPMI socket object with the socket descriptor - * - * @param [in] File Descriptor for the socket - * @param [in] Timeout parameter for the select call - * - * @return None - */ - Channel(int insockfd, timeval& inTimeout) - { - sockfd = insockfd; - timeout = inTimeout; - } + /** + * @brief Constructor + * + * Initialize the IPMI socket object with the socket descriptor + * + * @param [in] File Descriptor for the socket + * @param [in] Timeout parameter for the select call + * + * @return None + */ + Channel(int insockfd, timeval& inTimeout) + { + sockfd = insockfd; + timeout = inTimeout; + } - /** - * @brief Fetch the IP address of the remote peer - * - * Returns the IP address of the remote peer which is connected to this - * socket - * - * @return IP address of the remote peer - */ - std::string getRemoteAddress() const; + /** + * @brief Fetch the IP address of the remote peer + * + * Returns the IP address of the remote peer which is connected to this + * socket + * + * @return IP address of the remote peer + */ + std::string getRemoteAddress() const; - /** - * @brief Fetch the port number of the remote peer - * - * Returns the port number of the remote peer - * - * @return Port number - * - */ - auto getPort() const - { - return address.inAddr.sin6_port; - } + /** + * @brief Fetch the port number of the remote peer + * + * Returns the port number of the remote peer + * + * @return Port number + * + */ + auto getPort() const + { + return address.inAddr.sin6_port; + } - /** - * @brief Read the incoming packet - * - * Reads the data available on the socket - * - * @return A tuple with return code and vector with the buffer - * In case of success, the vector is populated with the data - * available on the socket and return code is 0. - * In case of error, the return code is < 0 and vector is set - * to size 0. - */ - std::tuple<int, std::vector<uint8_t>> read(); + /** + * @brief Read the incoming packet + * + * Reads the data available on the socket + * + * @return A tuple with return code and vector with the buffer + * In case of success, the vector is populated with the data + * available on the socket and return code is 0. + * In case of error, the return code is < 0 and vector is set + * to size 0. + */ + std::tuple<int, std::vector<uint8_t>> read(); - /** - * @brief Write the outgoing packet - * - * Writes the data in the vector to the socket - * - * @param [in] inBuffer - * The vector would be the buffer of data to write to the socket. - * - * @return In case of success the return code is 0 and return code is - * < 0 in case of failure. - */ - int write(const std::vector<uint8_t>& inBuffer); + /** + * @brief Write the outgoing packet + * + * Writes the data in the vector to the socket + * + * @param [in] inBuffer + * The vector would be the buffer of data to write to the socket. + * + * @return In case of success the return code is 0 and return code is + * < 0 in case of failure. + */ + int write(const std::vector<uint8_t>& inBuffer); - /** - * @brief Returns file descriptor for the socket - */ - auto getHandle(void) const - { - return sockfd; - } + /** + * @brief Returns file descriptor for the socket + */ + auto getHandle(void) const + { + return sockfd; + } - ~Channel() = default; - Channel(const Channel& right) = delete; - Channel& operator=(const Channel& right) = delete; - Channel(Channel&&) = default; - Channel& operator=(Channel&&) = default; + ~Channel() = default; + Channel(const Channel& right) = delete; + Channel& operator=(const Channel& right) = delete; + Channel(Channel&&) = default; + Channel& operator=(Channel&&) = default; - private: - /* - * The socket descriptor is the UDP server socket for the IPMI port. - * The same socket descriptor is used for multiple ipmi clients and the - * life of the descriptor is lifetime of the net-ipmid server. So we - * do not need to close the socket descriptor in the cleanup of the - * udpsocket class. - */ - int sockfd; - SockAddr_t address; - timeval timeout; + private: + /* + * The socket descriptor is the UDP server socket for the IPMI port. + * The same socket descriptor is used for multiple ipmi clients and the + * life of the descriptor is lifetime of the net-ipmid server. So we + * do not need to close the socket descriptor in the cleanup of the + * udpsocket class. + */ + int sockfd; + SockAddr_t address; + timeval timeout; }; } // namespace udpsocket diff --git a/sol/console_buffer.hpp b/sol/console_buffer.hpp index fe4bfe8..51383cf 100644 --- a/sol/console_buffer.hpp +++ b/sol/console_buffer.hpp @@ -1,6 +1,7 @@ #pragma once #include <algorithm> +#include <cstdint> #include <deque> #include <vector> @@ -18,56 +19,55 @@ using ConsoleBuffer = std::deque<uint8_t>; */ class ConsoleData { - public: - /** @brief Get the current size of the host console buffer. - * - * @return size of the host console buffer. - */ - auto size() const noexcept - { - return data.size(); - } + public: + /** @brief Get the current size of the host console buffer. + * + * @return size of the host console buffer. + */ + auto size() const noexcept + { + return data.size(); + } - /** @brief Read host console data. - * - * This API would return the iterator to the read data from the - * console data buffer. - * - * @return iterator to read data from the buffer - */ - auto read() const - { - return data.cbegin(); - } + /** @brief Read host console data. + * + * This API would return the iterator to the read data from the + * console data buffer. + * + * @return iterator to read data from the buffer + */ + auto read() const + { + return data.cbegin(); + } - /** @brief Write host console data. - * - * This API would append the input data to the host console buffer. - * - * @param[in] input - data to be written to the console buffer. - */ - void write(const std::vector<uint8_t>& input) - { - data.insert(data.end(), input.begin(), input.end()); - } + /** @brief Write host console data. + * + * This API would append the input data to the host console buffer. + * + * @param[in] input - data to be written to the console buffer. + */ + void write(const std::vector<uint8_t>& input) + { + data.insert(data.end(), input.begin(), input.end()); + } - /** @brief Erase console buffer. - * - * @param[in] size - the number of bytes to be erased from the console - * buffer. - * - * @note If the console buffer has less bytes that that was requested, - * then the available size is erased. - */ - void erase(size_t size) noexcept - { - data.erase(data.begin(), data.begin() + std::min(data.size(), - size)); - } + /** @brief Erase console buffer. + * + * @param[in] size - the number of bytes to be erased from the console + * buffer. + * + * @note If the console buffer has less bytes that that was requested, + * then the available size is erased. + */ + void erase(size_t size) noexcept + { + data.erase(data.begin(), data.begin() + std::min(data.size(), size)); + } - private: - /** @brief Storage for host console data. */ - ConsoleBuffer data; + private: + /** @brief Storage for host console data. */ + ConsoleBuffer data; }; } // namespace sol diff --git a/sol/sol_context.cpp b/sol/sol_context.cpp index ffa6834..7329ed2 100644 --- a/sol/sol_context.cpp +++ b/sol/sol_context.cpp @@ -1,18 +1,18 @@ -#include <phosphor-logging/log.hpp> +#include "sol_context.hpp" + #include "main.hpp" #include "sd_event_loop.hpp" -#include "sol_context.hpp" #include "sol_manager.hpp" +#include <phosphor-logging/log.hpp> + namespace sol { using namespace phosphor::logging; -void Context::processInboundPayload(uint8_t seqNum, - uint8_t ackSeqNum, - uint8_t count, - bool status, +void Context::processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum, + uint8_t count, bool status, const std::vector<uint8_t>& input) { uint8_t respAckSeqNum = 0; @@ -26,7 +26,7 @@ void Context::processInboundPayload(uint8_t seqNum, * specification. Retried packets use the same sequence number as the first * packet. */ - if(seqNum && (seqNum != seqNums.get(true))) + if (seqNum && (seqNum != seqNums.get(true))) { log<level::INFO>("Out of sequence SOL packet - packet is dropped"); return; @@ -54,10 +54,10 @@ void Context::processInboundPayload(uint8_t seqNum, if (status || ((count != expectedCharCount) && ackSeqNum)) { resendPayload(noClear); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (payloadInstance, eventloop::Timers::RETRY, false); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (payloadInstance, eventloop::Timers::RETRY, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::RETRY, false); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::RETRY, true); return; } /* @@ -70,8 +70,8 @@ void Context::processInboundPayload(uint8_t seqNum, std::get<sol::Manager&>(singletonPool).dataBuffer.erase(count); // Once it is acknowledged stop the retry interval timer - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - payloadInstance, eventloop::Timers::RETRY, false); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::RETRY, false); retryCounter = maxRetryCount; expectedCharCount = 0; @@ -81,8 +81,8 @@ void Context::processInboundPayload(uint8_t seqNum, // Write character data to the Host Console if (!input.empty() && seqNum) { - auto rc = std::get<sol::Manager&>(singletonPool).writeConsoleSocket( - input); + auto rc = + std::get<sol::Manager&>(singletonPool).writeConsoleSocket(input); if (rc) { log<level::ERR>("Writing to console socket descriptor failed"); @@ -111,21 +111,20 @@ void Context::processInboundPayload(uint8_t seqNum, } else { - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (payloadInstance, eventloop::Timers::ACCUMULATE, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::ACCUMULATE, true); } } void Context::prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack) { - auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer. - size(); + auto bufferSize = std::get<sol::Manager&>(singletonPool).dataBuffer.size(); /* Sent a ACK only response */ if (payloadCache.size() != 0 || (bufferSize < sendThreshold)) { - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (payloadInstance, eventloop::Timers::ACCUMULATE, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::ACCUMULATE, true); std::vector<uint8_t> outPayload(sizeof(Payload)); auto response = reinterpret_cast<Payload*>(outPayload.data()); @@ -145,15 +144,14 @@ void Context::prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack) response->outOperation.ack = ack; response->packetSeqNum = seqNums.incOutboundSeqNum(); - auto handle = std::get<sol::Manager&>(singletonPool).dataBuffer.read(); std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload)); expectedCharCount = readSize; - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - payloadInstance, eventloop::Timers::RETRY, true); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer - (payloadInstance, eventloop::Timers::ACCUMULATE, false); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::RETRY, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::ACCUMULATE, false); sendPayload(payloadCache); } @@ -162,8 +160,8 @@ int Context::sendOutboundPayload() { if (payloadCache.size() != 0) { - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - payloadInstance, eventloop::Timers::ACCUMULATE, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::ACCUMULATE, true); return -1; } @@ -181,10 +179,10 @@ int Context::sendOutboundPayload() std::copy_n(handle, readSize, payloadCache.data() + sizeof(Payload)); expectedCharCount = readSize; - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - payloadInstance, eventloop::Timers::RETRY, true); - std::get<eventloop::EventLoop&>(singletonPool).switchTimer( - payloadInstance, eventloop::Timers::ACCUMULATE, false); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::RETRY, true); + std::get<eventloop::EventLoop&>(singletonPool) + .switchTimer(payloadInstance, eventloop::Timers::ACCUMULATE, false); sendPayload(payloadCache); @@ -195,19 +193,20 @@ void Context::resendPayload(bool clear) { sendPayload(payloadCache); - if(clear) + if (clear) { payloadCache.clear(); expectedCharCount = 0; - std::get<sol::Manager&>(singletonPool).dataBuffer.erase( - expectedCharCount); + std::get<sol::Manager&>(singletonPool) + .dataBuffer.erase(expectedCharCount); } } void Context::sendPayload(const std::vector<uint8_t>& out) const { - auto session = (std::get<session::Manager&>(singletonPool).getSession( - sessionID)).lock(); + auto session = + (std::get<session::Manager&>(singletonPool).getSession(sessionID)) + .lock(); message::Handler msgHandler(session->channelPtr, sessionID); diff --git a/sol/sol_context.hpp b/sol/sol_context.hpp index dadf492..220040b 100644 --- a/sol/sol_context.hpp +++ b/sol/sol_context.hpp @@ -13,23 +13,23 @@ namespace sol struct Outbound { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t testMode: 2; //!< Not supported. - uint8_t breakDetected: 1; //!< Not supported. - uint8_t transmitOverrun: 1; //!< Not supported. - uint8_t SOLDeactivating: 1; //!< 0 : SOL is active, 1 : SOL deactivated. - uint8_t charUnavailable: 1; //!< 0 : Available, 1 : Unavailable. - uint8_t ack: 1; //!< 0 : ACK, 1 : NACK. - uint8_t reserved: 1; //!< Reserved. + uint8_t testMode : 2; //!< Not supported. + uint8_t breakDetected : 1; //!< Not supported. + uint8_t transmitOverrun : 1; //!< Not supported. + uint8_t SOLDeactivating : 1; //!< 0 : SOL is active, 1 : SOL deactivated. + uint8_t charUnavailable : 1; //!< 0 : Available, 1 : Unavailable. + uint8_t ack : 1; //!< 0 : ACK, 1 : NACK. + uint8_t reserved : 1; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved: 1; //!< Reserved. - uint8_t ack: 1; //!< 0 : ACK, 1 : NACK. - uint8_t charUnavailable: 1; //!< 0 : Available, 1 : Unavailable. - uint8_t SOLDeactivating: 1; //!< 0 : SOL is active, 1 : SOL deactivated. - uint8_t transmitOverrun: 1; //!< Not supported. - uint8_t breakDetected: 1; //!< Not supported. - uint8_t testMode: 2; //!< Not supported. + uint8_t reserved : 1; //!< Reserved. + uint8_t ack : 1; //!< 0 : ACK, 1 : NACK. + uint8_t charUnavailable : 1; //!< 0 : Available, 1 : Unavailable. + uint8_t SOLDeactivating : 1; //!< 0 : SOL is active, 1 : SOL deactivated. + uint8_t transmitOverrun : 1; //!< Not supported. + uint8_t breakDetected : 1; //!< Not supported. + uint8_t testMode : 2; //!< Not supported. #endif } __attribute__((packed)); @@ -40,25 +40,25 @@ struct Outbound struct Inbound { #if BYTE_ORDER == LITTLE_ENDIAN - uint8_t flushOut: 1; //!< Not supported. - uint8_t flushIn: 1; //!< Not supported. - uint8_t dcd: 1; //!< Not supported. - uint8_t cts: 1; //!< Not supported. - uint8_t generateBreak: 1; //!< Not supported. - uint8_t ring: 1; //!< Not supported. - uint8_t ack: 1; //!< 0 : ACK, 1 : NACK. - uint8_t reserved: 1; //!< Reserved. + uint8_t flushOut : 1; //!< Not supported. + uint8_t flushIn : 1; //!< Not supported. + uint8_t dcd : 1; //!< Not supported. + uint8_t cts : 1; //!< Not supported. + uint8_t generateBreak : 1; //!< Not supported. + uint8_t ring : 1; //!< Not supported. + uint8_t ack : 1; //!< 0 : ACK, 1 : NACK. + uint8_t reserved : 1; //!< Reserved. #endif #if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved: 1; //!< Reserved. - uint8_t ack: 1; //!< 0 : ACK, 1 : NACK. - uint8_t ring: 1; //!< Not supported. - uint8_t generateBreak: 1; //!< Not supported. - uint8_t cts: 1; //!< Not supported. - uint8_t dcd: 1; //!< Not supported. - uint8_t flushIn: 1; //!< Not supported. - uint8_t flushOut: 1; //!< Not supported. + uint8_t reserved : 1; //!< Reserved. + uint8_t ack : 1; //!< 0 : ACK, 1 : NACK. + uint8_t ring : 1; //!< Not supported. + uint8_t generateBreak : 1; //!< Not supported. + uint8_t cts : 1; //!< Not supported. + uint8_t dcd : 1; //!< Not supported. + uint8_t flushIn : 1; //!< Not supported. + uint8_t flushOut : 1; //!< Not supported. #endif } __attribute__((packed)); @@ -69,14 +69,14 @@ struct Inbound */ struct Payload { - uint8_t packetSeqNum; //!< Packet sequence number - uint8_t packetAckSeqNum; //!< Packet ACK/NACK sequence number - uint8_t acceptedCharCount; //!< Accepted character count + uint8_t packetSeqNum; //!< Packet sequence number + uint8_t packetAckSeqNum; //!< Packet ACK/NACK sequence number + uint8_t acceptedCharCount; //!< Accepted character count union { - uint8_t operation; //!<Operation/Status - struct Outbound outOperation; //!<BMC to Remote Console - struct Inbound inOperation; //!<Remote Console to BMC + uint8_t operation; //!< Operation/Status + struct Outbound outOperation; //!< BMC to Remote Console + struct Inbound inOperation; //!< Remote Console to BMC }; } __attribute__((packed)); @@ -131,10 +131,10 @@ struct SequenceNumbers return out; } - private: - uint8_t in = 1; //!< Inbound sequence number. - uint8_t out = 0; //!< Outbound sequence number, since the first - //!< operation is increment, it is initialised to 0 + private: + uint8_t in = 1; //!< Inbound sequence number. + uint8_t out = 0; //!< Outbound sequence number, since the first + //!< operation is increment, it is initialised to 0 }; } // namespace internal @@ -148,116 +148,111 @@ struct SequenceNumbers */ class Context { - public: - Context() = default; - ~Context() = default; - Context(const Context&) = delete; - Context& operator=(const Context&) = delete; - Context(Context&&) = default; - Context& operator=(Context&&) = default; - - /** @brief Context Constructor. - * - * This is issued by the SOL Manager when a SOL payload instance is - * started for the activate payload command. - * - * @param[in] maxRetryCount - Retry count max value. - * @param[in] sendThreshold - Character send threshold. - * @param[in] instance - SOL payload instance. - * @param[in] sessionID - BMC session ID. - */ - Context(uint8_t maxRetryCount, - uint8_t sendThreshold, - uint8_t instance, - session::SessionID sessionID): - maxRetryCount(maxRetryCount), - retryCounter(maxRetryCount), - sendThreshold(sendThreshold), - payloadInstance(instance), - sessionID(sessionID) {} - - static constexpr auto clear = true; - static constexpr auto noClear = false; - - /** @brief Retry count max value. */ - const uint8_t maxRetryCount = 0; - - /** @brief Retry counter. */ - uint8_t retryCounter = 0; - - /** @brief Character send threshold. */ - const uint8_t sendThreshold = 0; - - /** @brief SOL payload instance. */ - const uint8_t payloadInstance = 0; - - /** @brief Session ID. */ - const session::SessionID sessionID = 0; - - /** @brief Process the Inbound SOL payload. - * - * The SOL payload from the remote console is processed and the - * acknowledgment handling is done. - * - * @param[in] seqNum - Packet sequence number. - * @param[in] ackSeqNum - Packet ACK/NACK sequence number. - * @param[in] count - Accepted character count. - * @param[in] operation - ACK is false, NACK is true - * @param[in] input - Incoming SOL character data. - */ - void processInboundPayload(uint8_t seqNum, - uint8_t ackSeqNum, - uint8_t count, - bool status, - const std::vector<uint8_t>& input); - - /** @brief Send the outbound SOL payload. - * - * @return zero on success and negative value if condition for sending - * the payload fails. - */ - int sendOutboundPayload(); - - /** @brief Resend the SOL payload. - * - * @param[in] clear - if true then send the payload and clear the - * cached payload, if false only send the payload. - */ - void resendPayload(bool clear); - - private: - /** @brief Expected character count. - * - * Expected Sequence number and expected character count is set before - * sending the SOL payload. The check is done against these values when - * an incoming SOL payload is received. - */ - size_t expectedCharCount = 0; - - /** @brief Inbound and Outbound sequence numbers. */ - internal::SequenceNumbers seqNums; - - /** @brief Copy of the last sent SOL payload. - * - * A copy of the SOL payload is kept here, so that when a retry needs - * to be attempted the payload is sent again. - */ - std::vector<uint8_t> payloadCache; - - /** - * @brief Send Response for Incoming SOL payload. - * - * @param[in] ackSeqNum - Packet ACK/NACK Sequence Number. - * @param[in] count - Accepted Character Count. - * @param[in] ack - Set ACK/NACK in the Operation. - */ - void prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack); - - /** @brief Send the outgoing SOL payload. - * - * @param[in] out - buffer containing the SOL payload. - */ - void sendPayload(const std::vector<uint8_t>& out) const; + public: + Context() = default; + ~Context() = default; + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + Context(Context&&) = default; + Context& operator=(Context&&) = default; + + /** @brief Context Constructor. + * + * This is issued by the SOL Manager when a SOL payload instance is + * started for the activate payload command. + * + * @param[in] maxRetryCount - Retry count max value. + * @param[in] sendThreshold - Character send threshold. + * @param[in] instance - SOL payload instance. + * @param[in] sessionID - BMC session ID. + */ + Context(uint8_t maxRetryCount, uint8_t sendThreshold, uint8_t instance, + session::SessionID sessionID) : + maxRetryCount(maxRetryCount), + retryCounter(maxRetryCount), sendThreshold(sendThreshold), + payloadInstance(instance), sessionID(sessionID) + { + } + + static constexpr auto clear = true; + static constexpr auto noClear = false; + + /** @brief Retry count max value. */ + const uint8_t maxRetryCount = 0; + + /** @brief Retry counter. */ + uint8_t retryCounter = 0; + + /** @brief Character send threshold. */ + const uint8_t sendThreshold = 0; + + /** @brief SOL payload instance. */ + const uint8_t payloadInstance = 0; + + /** @brief Session ID. */ + const session::SessionID sessionID = 0; + + /** @brief Process the Inbound SOL payload. + * + * The SOL payload from the remote console is processed and the + * acknowledgment handling is done. + * + * @param[in] seqNum - Packet sequence number. + * @param[in] ackSeqNum - Packet ACK/NACK sequence number. + * @param[in] count - Accepted character count. + * @param[in] operation - ACK is false, NACK is true + * @param[in] input - Incoming SOL character data. + */ + void processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum, uint8_t count, + bool status, const std::vector<uint8_t>& input); + + /** @brief Send the outbound SOL payload. + * + * @return zero on success and negative value if condition for sending + * the payload fails. + */ + int sendOutboundPayload(); + + /** @brief Resend the SOL payload. + * + * @param[in] clear - if true then send the payload and clear the + * cached payload, if false only send the payload. + */ + void resendPayload(bool clear); + + private: + /** @brief Expected character count. + * + * Expected Sequence number and expected character count is set before + * sending the SOL payload. The check is done against these values when + * an incoming SOL payload is received. + */ + size_t expectedCharCount = 0; + + /** @brief Inbound and Outbound sequence numbers. */ + internal::SequenceNumbers seqNums; + + /** @brief Copy of the last sent SOL payload. + * + * A copy of the SOL payload is kept here, so that when a retry needs + * to be attempted the payload is sent again. + */ + std::vector<uint8_t> payloadCache; + + /** + * @brief Send Response for Incoming SOL payload. + * + * @param[in] ackSeqNum - Packet ACK/NACK Sequence Number. + * @param[in] count - Accepted Character Count. + * @param[in] ack - Set ACK/NACK in the Operation. + */ + void prepareResponse(uint8_t ackSeqNum, uint8_t count, bool ack); + + /** @brief Send the outgoing SOL payload. + * + * @param[in] out - buffer containing the SOL payload. + */ + void sendPayload(const std::vector<uint8_t>& out) const; }; } // namespace sol diff --git a/sol/sol_manager.cpp b/sol/sol_manager.cpp index b6cf31d..66d2b49 100644 --- a/sol/sol_manager.cpp +++ b/sol/sol_manager.cpp @@ -1,11 +1,14 @@ +#include "sol_manager.hpp" + +#include "main.hpp" +#include "sol_context.hpp" + #include <sys/socket.h> #include <sys/un.h> + #include <chrono> #include <cmath> #include <phosphor-logging/log.hpp> -#include "main.hpp" -#include "sol_context.hpp" -#include "sol_manager.hpp" namespace sol { @@ -14,7 +17,7 @@ using namespace phosphor::logging; CustomFD::~CustomFD() { - if(fd >= 0) + if (fd >= 0) { // Remove the host console descriptor from the sd_event_loop std::get<eventloop::EventLoop&>(singletonPool).stopHostConsole(); @@ -32,7 +35,7 @@ void Manager::initHostConsoleFd() if (fd < 0) { log<level::ERR>("Failed to open the host console socket", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); throw std::runtime_error("Failed to open the host console socket"); } @@ -42,11 +45,11 @@ void Manager::initHostConsoleFd() consoleFD = std::make_unique<CustomFD>(fd); auto& conFD = *(consoleFD.get()); - rc = connect(conFD(), (struct sockaddr *)&addr, sizeof(addr)); + rc = connect(conFD(), (struct sockaddr*)&addr, sizeof(addr)); if (rc < 0) { log<level::ERR>("Failed to connect to host console socket address", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); consoleFD.reset(); throw std::runtime_error("Failed to connect to console server"); } @@ -69,7 +72,7 @@ int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const if (errno == EINTR) { log<level::INFO>(" Retrying to handle EINTR", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); rc = 0; continue; } @@ -77,7 +80,7 @@ int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const { errVal = errno; log<level::ERR>("Failed to write to host console socket", - entry("ERRNO=%d", errno)); + entry("ERRNO=%d", errno)); return -errVal; } } @@ -94,18 +97,19 @@ void Manager::startPayloadInstance(uint8_t payloadInstance, initHostConsoleFd(); // Register the fd in the sd_event_loop - std::get<eventloop::EventLoop&>(singletonPool).startHostConsole( - *(consoleFD.get())); + std::get<eventloop::EventLoop&>(singletonPool) + .startHostConsole(*(consoleFD.get())); } // Create the SOL Context data for payload instance - auto context = std::make_unique<Context>( - retryCount, sendThreshold, payloadInstance, sessionID); + auto context = std::make_unique<Context>(retryCount, sendThreshold, + payloadInstance, sessionID); - std::get<eventloop::EventLoop&>(singletonPool).startSOLPayloadInstance( + std::get<eventloop::EventLoop&>(singletonPool) + .startSOLPayloadInstance( payloadInstance, - std::chrono::duration_cast<eventloop::IntervalType> - (accumulateInterval), + std::chrono::duration_cast<eventloop::IntervalType>( + accumulateInterval), std::chrono::duration_cast<eventloop::IntervalType>(retryInterval)); payloadMap.emplace(payloadInstance, std::move(context)); @@ -121,8 +125,8 @@ void Manager::stopPayloadInstance(uint8_t payloadInstance) payloadMap.erase(iter); - std::get<eventloop::EventLoop&>(singletonPool).stopSOLPayloadInstance( - payloadInstance); + std::get<eventloop::EventLoop&>(singletonPool) + .stopSOLPayloadInstance(payloadInstance); if (payloadMap.empty()) { diff --git a/sol/sol_manager.hpp b/sol/sol_manager.hpp index a244431..5a0c18c 100644 --- a/sol/sol_manager.hpp +++ b/sol/sol_manager.hpp @@ -1,11 +1,12 @@ #pragma once -#include <map> -#include <memory> #include "console_buffer.hpp" #include "session.hpp" #include "sol_context.hpp" +#include <map> +#include <memory> + namespace sol { @@ -33,8 +34,9 @@ struct CustomFD CustomFD(CustomFD&&) = delete; CustomFD& operator=(CustomFD&&) = delete; - CustomFD(int fd) : - fd(fd) {} + CustomFD(int fd) : fd(fd) + { + } ~CustomFD(); @@ -43,8 +45,8 @@ struct CustomFD return fd; } - private: - int fd = -1; + private: + int fd = -1; }; using namespace std::chrono_literals; @@ -57,216 +59,215 @@ using namespace std::chrono_literals; */ class Manager { - public: - - /** @brief SOL Payload Instance is the key for the map, the value is the - * SOL context. - */ - using SOLPayloadMap = std::map<Instance, std::unique_ptr<Context>>; - - Manager() = default; - ~Manager() = default; - Manager(const Manager&) = delete; - Manager& operator=(const Manager&) = delete; - Manager(Manager&&) = default; - Manager& operator=(Manager&&) = default; - - /** @brief Host Console Buffer. */ - ConsoleData dataBuffer; - - /** @brief Set in Progress. - * - * This parameter is used to indicate when any of the SOL parameters - * are being updated, and when the changes are completed. The bit is - * primarily provided to alert software than some other software or - * utility is in the process of making changes to the data. This field - * is initialized to set complete. - */ - uint8_t progress = 0; - - /** @brief SOL enable - * - * This controls whether the SOL payload can be activated. By default - * the SOL is enabled. - */ - bool enable = true; - - /** @brief SOL payload encryption. - * - * Force encryption: if the cipher suite for the session supports - * encryption, then this setting will force the use of encryption for - * all SOL payload data. Encryption controlled by remote console: - * Whether SOL packets are encrypted or not is selectable by the remote - * console at the time the payload is activated. The default is force - * encryption. - */ - bool forceEncrypt = true; - - /** @brief SOL payload authentication. - * - * Force authentication: if the cipher suite for the session supports - * authentication, then this setting will force the use of for - * authentication for all SOL payload data. Authentication controlled - * by remote console: Note that for the standard Cipher Suites, - * if encryption is used authentication must also be used. Therefore, - * while encryption is being used software will not be able to select - * using unauthenticated payloads. - */ - bool forceAuth = true; - - /** @brief SOL privilege level. - * - * Sets the minimum operating privilege level that is required to be - * able to activate SOL using the Activate Payload command. - */ - session::Privilege solMinPrivilege = session::Privilege::USER; - - /** @brief Character Accumulate Interval - * - * This sets the typical amount of time that the BMC will wait before - * transmitting a partial SOL character data packet. (Where a partial - * packet is defined as a packet that has fewer characters to transmit - * than the number of characters specified by the character send - * threshold. This parameter can be modified by the set SOL - * configuration parameters command. The SOL configuration parameter, - * Character Accumulate Interval is 5 ms increments, 1-based value. The - * parameter value is accumulateInterval/5. The accumulateInterval - * needs to be a multiple of 5. - */ - std::chrono::milliseconds accumulateInterval = 100ms; - - /** @brief Character Send Threshold - * - * The BMC will automatically send an SOL character data packet - * containing this number of characters as soon as this number of - * characters (or greater) has been accepted from the baseboard serial - * controller into the BMC. This provides a mechanism to tune the - * buffer to reduce latency to when the first characters are received - * after an idle interval. In the degenerate case, setting this value - * to a ‘1’ would cause the BMC to send a packet as soon as the first - * character was received. This parameter can be modified by the set - * SOL configuration parameters command. - */ - uint8_t sendThreshold = 1; - - /** @brief Retry Count - * - * 1-based. 0 = no retries after packet is transmitted. Packet will be - * dropped if no ACK/NACK received by time retries expire. The maximum - * value for retry count is 7. This parameter can be modified by the - * set SOL configuration parameters command. - */ - uint8_t retryCount = 7; - - /** @brief Retry Interval - * - * Sets the time that the BMC will wait before the first retry and the - * time between retries when sending SOL packets to the remote console. - * This parameter can be modified by the set SOL configuration - * parameters command. The SOL configuration parameter Retry Interval - * is 10 ms increments, 1-based value. The parameter value is - * retryInterval/10. The retryInterval needs to be a multiple of 10. - */ - std::chrono::milliseconds retryInterval = 100ms; - - /** @brief Channel Number - * - * This parameter indicates which IPMI channel is being used for the - * communication parameters (e.g. IP address, MAC address) for the SOL - * Payload. Typically, these parameters will come from the same channel - * that the Activate Payload command for SOL was accepted over. The - * network channel number is defaulted to 1. - */ - uint8_t channel = 1; - - /** @brief Start a SOL payload instance. - * - * Starting a payload instance involves creating the context object, - * add the accumulate interval timer and retry interval timer to the - * event loop. - * - * @param[in] payloadInstance - SOL payload instance. - * @param[in] sessionID - BMC session ID. - */ - void startPayloadInstance(uint8_t payloadInstance, - session::SessionID sessionID); - - /** @brief Stop SOL payload instance. - * - * Stopping a payload instance involves stopping and removing the - * accumulate interval timer and retry interval timer from the event - * loop, delete the context object. - * - * @param[in] payloadInstance - SOL payload instance - */ - void stopPayloadInstance(uint8_t payloadInstance); - - /** @brief Get SOL Context by Payload Instance. - * - * @param[in] payloadInstance - SOL payload instance. - * - * @return reference to the SOL payload context. - */ - Context& getContext(uint8_t payloadInstance) + public: + /** @brief SOL Payload Instance is the key for the map, the value is the + * SOL context. + */ + using SOLPayloadMap = std::map<Instance, std::unique_ptr<Context>>; + + Manager() = default; + ~Manager() = default; + Manager(const Manager&) = delete; + Manager& operator=(const Manager&) = delete; + Manager(Manager&&) = default; + Manager& operator=(Manager&&) = default; + + /** @brief Host Console Buffer. */ + ConsoleData dataBuffer; + + /** @brief Set in Progress. + * + * This parameter is used to indicate when any of the SOL parameters + * are being updated, and when the changes are completed. The bit is + * primarily provided to alert software than some other software or + * utility is in the process of making changes to the data. This field + * is initialized to set complete. + */ + uint8_t progress = 0; + + /** @brief SOL enable + * + * This controls whether the SOL payload can be activated. By default + * the SOL is enabled. + */ + bool enable = true; + + /** @brief SOL payload encryption. + * + * Force encryption: if the cipher suite for the session supports + * encryption, then this setting will force the use of encryption for + * all SOL payload data. Encryption controlled by remote console: + * Whether SOL packets are encrypted or not is selectable by the remote + * console at the time the payload is activated. The default is force + * encryption. + */ + bool forceEncrypt = true; + + /** @brief SOL payload authentication. + * + * Force authentication: if the cipher suite for the session supports + * authentication, then this setting will force the use of for + * authentication for all SOL payload data. Authentication controlled + * by remote console: Note that for the standard Cipher Suites, + * if encryption is used authentication must also be used. Therefore, + * while encryption is being used software will not be able to select + * using unauthenticated payloads. + */ + bool forceAuth = true; + + /** @brief SOL privilege level. + * + * Sets the minimum operating privilege level that is required to be + * able to activate SOL using the Activate Payload command. + */ + session::Privilege solMinPrivilege = session::Privilege::USER; + + /** @brief Character Accumulate Interval + * + * This sets the typical amount of time that the BMC will wait before + * transmitting a partial SOL character data packet. (Where a partial + * packet is defined as a packet that has fewer characters to transmit + * than the number of characters specified by the character send + * threshold. This parameter can be modified by the set SOL + * configuration parameters command. The SOL configuration parameter, + * Character Accumulate Interval is 5 ms increments, 1-based value. The + * parameter value is accumulateInterval/5. The accumulateInterval + * needs to be a multiple of 5. + */ + std::chrono::milliseconds accumulateInterval = 100ms; + + /** @brief Character Send Threshold + * + * The BMC will automatically send an SOL character data packet + * containing this number of characters as soon as this number of + * characters (or greater) has been accepted from the baseboard serial + * controller into the BMC. This provides a mechanism to tune the + * buffer to reduce latency to when the first characters are received + * after an idle interval. In the degenerate case, setting this value + * to a ‘1’ would cause the BMC to send a packet as soon as the first + * character was received. This parameter can be modified by the set + * SOL configuration parameters command. + */ + uint8_t sendThreshold = 1; + + /** @brief Retry Count + * + * 1-based. 0 = no retries after packet is transmitted. Packet will be + * dropped if no ACK/NACK received by time retries expire. The maximum + * value for retry count is 7. This parameter can be modified by the + * set SOL configuration parameters command. + */ + uint8_t retryCount = 7; + + /** @brief Retry Interval + * + * Sets the time that the BMC will wait before the first retry and the + * time between retries when sending SOL packets to the remote console. + * This parameter can be modified by the set SOL configuration + * parameters command. The SOL configuration parameter Retry Interval + * is 10 ms increments, 1-based value. The parameter value is + * retryInterval/10. The retryInterval needs to be a multiple of 10. + */ + std::chrono::milliseconds retryInterval = 100ms; + + /** @brief Channel Number + * + * This parameter indicates which IPMI channel is being used for the + * communication parameters (e.g. IP address, MAC address) for the SOL + * Payload. Typically, these parameters will come from the same channel + * that the Activate Payload command for SOL was accepted over. The + * network channel number is defaulted to 1. + */ + uint8_t channel = 1; + + /** @brief Start a SOL payload instance. + * + * Starting a payload instance involves creating the context object, + * add the accumulate interval timer and retry interval timer to the + * event loop. + * + * @param[in] payloadInstance - SOL payload instance. + * @param[in] sessionID - BMC session ID. + */ + void startPayloadInstance(uint8_t payloadInstance, + session::SessionID sessionID); + + /** @brief Stop SOL payload instance. + * + * Stopping a payload instance involves stopping and removing the + * accumulate interval timer and retry interval timer from the event + * loop, delete the context object. + * + * @param[in] payloadInstance - SOL payload instance + */ + void stopPayloadInstance(uint8_t payloadInstance); + + /** @brief Get SOL Context by Payload Instance. + * + * @param[in] payloadInstance - SOL payload instance. + * + * @return reference to the SOL payload context. + */ + Context& getContext(uint8_t payloadInstance) + { + auto iter = payloadMap.find(payloadInstance); + + if (iter != payloadMap.end()) { - auto iter = payloadMap.find(payloadInstance); + return *(iter->second); + } - if (iter != payloadMap.end()) - { - return *(iter->second); - } + std::string msg = "Invalid SOL payload instance " + payloadInstance; + throw std::runtime_error(msg.c_str()); + } - std::string msg = "Invalid SOL payload instance " + payloadInstance; - throw std::runtime_error(msg.c_str()); - } - - /** @brief Get SOL Context by Session ID. - * - * @param[in] sessionID - IPMI Session ID. - * - * @return reference to the SOL payload context. - */ - Context& getContext(session::SessionID sessionID) + /** @brief Get SOL Context by Session ID. + * + * @param[in] sessionID - IPMI Session ID. + * + * @return reference to the SOL payload context. + */ + Context& getContext(session::SessionID sessionID) + { + for (const auto& kv : payloadMap) { - for (const auto& kv : payloadMap) + if (kv.second->sessionID == sessionID) { - if (kv.second->sessionID == sessionID) - { - return *kv.second; - } + return *kv.second; } - - std::string msg = "Invalid SOL SessionID " + sessionID; - throw std::runtime_error(msg.c_str()); } - /** @brief Check if SOL payload is active. - * - * @param[in] payloadInstance - SOL payload instance. - * - * @return true if the instance is active and false it is not active. - */ - auto isPayloadActive(uint8_t payloadInstance) const - { - return (0 != payloadMap.count(payloadInstance)); - } + std::string msg = "Invalid SOL SessionID " + sessionID; + throw std::runtime_error(msg.c_str()); + } + + /** @brief Check if SOL payload is active. + * + * @param[in] payloadInstance - SOL payload instance. + * + * @return true if the instance is active and false it is not active. + */ + auto isPayloadActive(uint8_t payloadInstance) const + { + return (0 != payloadMap.count(payloadInstance)); + } - /** @brief Write data to the host console unix socket. - * - * @param[in] input - Data from the remote console. - * - * @return 0 on success and errno on failure. - */ - int writeConsoleSocket(const std::vector<uint8_t>& input) const; + /** @brief Write data to the host console unix socket. + * + * @param[in] input - Data from the remote console. + * + * @return 0 on success and errno on failure. + */ + int writeConsoleSocket(const std::vector<uint8_t>& input) const; - private: - SOLPayloadMap payloadMap; + private: + SOLPayloadMap payloadMap; - /** @brief File descriptor for the host console. */ - std::unique_ptr<CustomFD> consoleFD = nullptr; + /** @brief File descriptor for the host console. */ + std::unique_ptr<CustomFD> consoleFD = nullptr; - /** @brief Initialize the host console file descriptor. */ - void initHostConsoleFd(); + /** @brief Initialize the host console file descriptor. */ + void initHostConsoleFd(); }; -} //namespace sol +} // namespace sol diff --git a/sol_module.cpp b/sol_module.cpp index e055817..8200e74 100644 --- a/sol_module.cpp +++ b/sol_module.cpp @@ -1,5 +1,5 @@ -#include "command/sol_cmds.hpp" #include "command/payload_cmds.hpp" +#include "command/sol_cmds.hpp" #include "command_table.hpp" #include "main.hpp" #include "session.hpp" @@ -12,69 +12,57 @@ namespace command void registerCommands() { - static const ::command::CmdDetails commands[] = - { + static const ::command::CmdDetails commands[] = { // SOL Payload Handler - { - {(static_cast<uint32_t>(message::PayloadType::SOL) << 16)}, - &payloadHandler, session::Privilege::HIGHEST_MATCHING, - false - }, + {{(static_cast<uint32_t>(message::PayloadType::SOL) << 16)}, + &payloadHandler, + session::Privilege::HIGHEST_MATCHING, + false}, // Activate Payload Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::APP) | 0x48 - }, - &activatePayload, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::APP) | 0x48}, + &activatePayload, + session::Privilege::USER, + false}, // Deactivate Payload Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::APP) | 0x49 - }, - &deactivatePayload, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::APP) | 0x49}, + &deactivatePayload, + session::Privilege::USER, + false}, // Get Payload Activation Status - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::APP) | 0x4A - }, - &getPayloadStatus, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::APP) | 0x4A}, + &getPayloadStatus, + session::Privilege::USER, + false}, // Get Payload Instance Info Command - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::APP) | 0x4B - }, - &getPayloadInfo, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::APP) | 0x4B}, + &getPayloadInfo, + session::Privilege::USER, + false}, // Set SOL Configuration Parameters - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x21 - }, - &setConfParams, session::Privilege::ADMIN, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x21}, + &setConfParams, + session::Privilege::ADMIN, + false}, // Get SOL Configuration Parameters - { - { - (static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | - static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x22 - }, - &getConfParams, session::Privilege::USER, false - }, + {{(static_cast<uint32_t>(message::PayloadType::IPMI) << 16) | + static_cast<uint16_t>(::command::NetFns::TRANSPORT) | 0x22}, + &getConfParams, + session::Privilege::USER, + false}, }; for (const auto& iter : commands) { - std::get<::command::Table&>(singletonPool).registerCommand( - iter.command, std::make_unique<::command::NetIpmidEntry> - (iter.command, iter.functor, iter.privilege, iter.sessionless)); + std::get<::command::Table&>(singletonPool) + .registerCommand(iter.command, + std::make_unique<::command::NetIpmidEntry>( + iter.command, iter.functor, iter.privilege, + iter.sessionless)); } } diff --git a/test/cipher.cpp b/test/cipher.cpp index 432612e..402a22f 100644 --- a/test/cipher.cpp +++ b/test/cipher.cpp @@ -1,13 +1,16 @@ +#include "crypt_algo.hpp" +#include "integrity_algo.hpp" +#include "message_parsers.hpp" +#include "rmcp.hpp" + #include <openssl/evp.h> #include <openssl/hmac.h> #include <openssl/rand.h> #include <openssl/sha.h> + #include <iostream> #include <vector> -#include "crypt_algo.hpp" -#include "integrity_algo.hpp" -#include "message_parsers.hpp" -#include "rmcp.hpp" + #include <gtest/gtest.h> TEST(IntegrityAlgo, HMAC_SHA1_96_GenerateIntegrityDataCheck) @@ -16,11 +19,11 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_GenerateIntegrityDataCheck) * Step-1 Generate Integrity Data for the packet, using the implemented API */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20 }; + std::vector<uint8_t> sik = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik); @@ -30,23 +33,21 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_GenerateIntegrityDataCheck) auto response = algoPtr->generateIntegrityData(packet); EXPECT_EQ(true, (response.size() == - cipher::integrity::AlgoSHA1::SHA1_96_AUTHCODE_LENGTH)); + cipher::integrity::AlgoSHA1::SHA1_96_AUTHCODE_LENGTH)); /* * Step-2 Generate Integrity data using OpenSSL SHA1 algorithm */ std::vector<uint8_t> k1(SHA_DIGEST_LENGTH); - constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01 - }; + constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; // Generated K1 for the integrity algorithm with the additional key keyed // with SIK. unsigned int mdLen = 0; - if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), - const1.size(), k1.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(), + k1.data(), &mdLen) == NULL) { FAIL() << "Generating Key1 failed"; } @@ -56,8 +57,7 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_GenerateIntegrityDataCheck) size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE; if (HMAC(EVP_sha1(), k1.data(), k1.size(), - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length, + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length, output.data(), &mdLen) == NULL) { FAIL() << "Generating integrity data failed"; @@ -80,24 +80,22 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataPass) */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20 }; + std::vector<uint8_t> sik = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; std::vector<uint8_t> k1(SHA_DIGEST_LENGTH); - constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01 - }; + constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; // Generated K1 for the integrity algorithm with the additional key keyed // with SIK. unsigned int mdLen = 0; - if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), - const1.size(), k1.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(), + k1.data(), &mdLen) == NULL) { FAIL() << "Generating Key1 failed"; } @@ -107,8 +105,7 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataPass) size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE; if (HMAC(EVP_sha1(), k1.data(), k1.size(), - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length, + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length, output.data(), &mdLen) == NULL) { FAIL() << "Generating integrity data failed"; @@ -122,23 +119,22 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataPass) auto packetSize = packet.size(); packet.insert(packet.end(), output.begin(), output.end()); - // Point to the integrity data in the packet - auto integrityIter = packet.cbegin(); - std::advance(integrityIter, packetSize); + // Point to the integrity data in the packet + auto integrityIter = packet.cbegin(); + std::advance(integrityIter, packetSize); - /* - * Step-3 Invoke the verifyIntegrityData API and validate the response - */ + /* + * Step-3 Invoke the verifyIntegrityData API and validate the response + */ - auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik); - ASSERT_EQ(true, (algoPtr != NULL)); + auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik); + ASSERT_EQ(true, (algoPtr != NULL)); - auto check = algoPtr->verifyIntegrityData( - packet, - packetSize - message::parser::RMCP_SESSION_HEADER_SIZE, - integrityIter); + auto check = algoPtr->verifyIntegrityData( + packet, packetSize - message::parser::RMCP_SESSION_HEADER_SIZE, + integrityIter); - EXPECT_EQ(true, check); + EXPECT_EQ(true, check); } TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataFail) @@ -148,9 +144,9 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataFail) */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - std::vector<uint8_t> integrity = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> integrity = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; packet.insert(packet.end(), integrity.begin(), integrity.end()); @@ -163,19 +159,17 @@ TEST(IntegrityAlgo, HMAC_SHA1_96_VerifyIntegrityDataFail) */ // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20 }; + std::vector<uint8_t> sik = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA1>(sik); ASSERT_EQ(true, (algoPtr != NULL)); - // Verify the Integrity Data auto check = algoPtr->verifyIntegrityData( - packet, - packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE, - integrityIter); + packet, packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE, + integrityIter); EXPECT_EQ(false, check); } @@ -186,12 +180,12 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_GenerateIntegrityDataCheck) * Step-1 Generate Integrity Data for the packet, using the implemented API */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 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 }; + std::vector<uint8_t> sik = {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}; auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik); @@ -200,24 +194,23 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_GenerateIntegrityDataCheck) // Generate the Integrity Data auto response = algoPtr->generateIntegrityData(packet); - EXPECT_EQ(true, (response.size() == - cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH)); + EXPECT_EQ(true, + (response.size() == + cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH)); /* * Step-2 Generate Integrity data using OpenSSL SHA256 algorithm */ std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH); - constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01 - }; + constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; // Generated K1 for the integrity algorithm with the additional key keyed // with SIK. unsigned int mdLen = 0; - if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), - const1.size(), k1.data(), &mdLen) == NULL) + if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), const1.size(), + k1.data(), &mdLen) == NULL) { FAIL() << "Generating Key1 failed"; } @@ -227,8 +220,7 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_GenerateIntegrityDataCheck) size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE; if (HMAC(EVP_sha256(), k1.data(), k1.size(), - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length, + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length, output.data(), &mdLen) == NULL) { FAIL() << "Generating integrity data failed"; @@ -251,25 +243,23 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataPass) */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 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 }; + std::vector<uint8_t> sik = {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}; std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH); - constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01 - }; + constexpr rmcp::Const_n const1 = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; // Generated K1 for the integrity algorithm with the additional key keyed // with SIK. unsigned int mdLen = 0; - if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), - const1.size(), k1.data(), &mdLen) == NULL) + if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(), const1.size(), + k1.data(), &mdLen) == NULL) { FAIL() << "Generating Key1 failed"; } @@ -279,8 +269,7 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataPass) size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE; if (HMAC(EVP_sha256(), k1.data(), k1.size(), - packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, - length, + packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE, length, output.data(), &mdLen) == NULL) { FAIL() << "Generating integrity data failed"; @@ -306,9 +295,8 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataPass) ASSERT_EQ(true, (algoPtr != NULL)); auto check = algoPtr->verifyIntegrityData( - packet, - packetSize - message::parser::RMCP_SESSION_HEADER_SIZE, - integrityIter); + packet, packetSize - message::parser::RMCP_SESSION_HEADER_SIZE, + integrityIter); EXPECT_EQ(true, check); } @@ -320,9 +308,9 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataFail) */ // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes) - std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> packet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - std::vector<uint8_t> integrity = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> integrity = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; packet.insert(packet.end(), integrity.begin(), integrity.end()); @@ -335,20 +323,18 @@ TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataFail) */ // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 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 }; + std::vector<uint8_t> sik = {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}; auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik); ASSERT_EQ(true, (algoPtr != NULL)); - // Verify the Integrity Data auto check = algoPtr->verifyIntegrityData( - packet, - packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE, - integrityIter); + packet, packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE, + integrityIter); EXPECT_EQ(false, check); } @@ -359,24 +345,22 @@ TEST(CryptAlgo, AES_CBC_128_EncryptPayloadValidate) * Step-1 Generate the encrypted data using the implemented API for * AES-CBC-128 */ - std::vector<uint8_t> payload = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + std::vector<uint8_t> payload = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20 }; + std::vector<uint8_t> sik = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; std::vector<uint8_t> k2(SHA_DIGEST_LENGTH); unsigned int mdLen = 0; - constexpr rmcp::Const_n const1 = { 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02 - }; + constexpr rmcp::Const_n const1 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; // Generated K2 for the confidentiality algorithm with the additional key // keyed with SIK. - if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), - const1.size(), k2.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(), + k2.data(), &mdLen) == NULL) { FAIL() << "Generating K2 for confidentiality algorithm failed"; } @@ -401,15 +385,14 @@ TEST(CryptAlgo, AES_CBC_128_EncryptPayloadValidate) } EVP_CIPHER_CTX_set_padding(ctx, 0); - std::vector<uint8_t> output( - cipher.size() + cipher::crypt::AlgoAES128::AESCBC128BlockSize); + std::vector<uint8_t> output(cipher.size() + + cipher::crypt::AlgoAES128::AESCBC128BlockSize); int outputLen = 0; - if (!EVP_DecryptUpdate(ctx, output.data(), &outputLen, - cipher.data() + - cipher::crypt::AlgoAES128::AESCBC128ConfHeader, - cipher.size() - - cipher::crypt::AlgoAES128::AESCBC128ConfHeader)) + if (!EVP_DecryptUpdate( + ctx, output.data(), &outputLen, + cipher.data() + cipher::crypt::AlgoAES128::AESCBC128ConfHeader, + cipher.size() - cipher::crypt::AlgoAES128::AESCBC128ConfHeader)) { EVP_CIPHER_CTX_free(ctx); FAIL() << "EVP_DecryptUpdate failed"; @@ -432,25 +415,23 @@ TEST(CryptAlgo, AES_CBC_128_DecryptPayloadValidate) * implementation */ - std::vector<uint8_t> payload = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16}; + std::vector<uint8_t> payload = {1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16}; payload.resize(payload.size() + 1); payload.back() = 0; // Hardcoded Session Integrity Key - std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20 }; + std::vector<uint8_t> sik = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; EVP_CIPHER_CTX* ctx; ctx = EVP_CIPHER_CTX_new(); std::vector<uint8_t> k2(SHA_DIGEST_LENGTH); unsigned int mdLen = 0; - constexpr rmcp::Const_n const1 = { 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02 - }; - std::vector<uint8_t> output( - payload.size() + cipher::crypt::AlgoAES128::AESCBC128BlockSize); + constexpr rmcp::Const_n const1 = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; + std::vector<uint8_t> output(payload.size() + + cipher::crypt::AlgoAES128::AESCBC128BlockSize); if (!RAND_bytes(output.data(), cipher::crypt::AlgoAES128::AESCBC128ConfHeader)) @@ -460,8 +441,8 @@ TEST(CryptAlgo, AES_CBC_128_DecryptPayloadValidate) // Generated K2 for the confidentiality algorithm with the additional key // keyed with SIK. - if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), - const1.size(), k2.data(), &mdLen) == NULL) + if (HMAC(EVP_sha1(), sik.data(), sik.size(), const1.data(), const1.size(), + k2.data(), &mdLen) == NULL) { FAIL() << "Generating K2 for confidentiality algorithm failed"; } @@ -476,12 +457,9 @@ TEST(CryptAlgo, AES_CBC_128_DecryptPayloadValidate) EVP_CIPHER_CTX_set_padding(ctx, 0); int outputLen = 0; - if (!EVP_EncryptUpdate(ctx, - output.data() + - cipher::crypt::AlgoAES128::AESCBC128ConfHeader, - &outputLen, - payload.data(), - payload.size())) + if (!EVP_EncryptUpdate( + ctx, output.data() + cipher::crypt::AlgoAES128::AESCBC128ConfHeader, + &outputLen, payload.data(), payload.size())) { EVP_CIPHER_CTX_free(ctx); FAIL() << "EVP_EncryptUpdate failed"; @@ -1,6 +1,7 @@ +#include "timer.hpp" + #include <chrono> #include <phosphor-logging/log.hpp> -#include "timer.hpp" namespace phosphor { namespace ipmi @@ -27,7 +28,7 @@ void Timer::initialize() if (r < 0) { log<level::ERR>("Failure to set initial expiration time value", - entry("ERROR=%s", strerror(-r))); + entry("ERROR=%s", strerror(-r))); throw std::runtime_error("Timer initialization failed"); } @@ -37,7 +38,7 @@ void Timer::initialize() if (r < 0) { log<level::ERR>("Failure to disable timer", - entry("ERROR=%s", strerror(-r))); + entry("ERROR=%s", strerror(-r))); throw std::runtime_error("Disabling the timer failed"); } @@ -45,15 +46,15 @@ void Timer::initialize() } /** @brief callback handler on timeout */ -int Timer::timeoutHandler(sd_event_source* eventSource, - uint64_t usec, void* userData) +int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec, + void* userData) { auto timer = static_cast<Timer*>(userData); timer->expired = true; log<level::INFO>("Timer expired"); // Call optional user call back function if available - if(timer->userCallBack) + if (timer->userCallBack) { timer->userCallBack(); } @@ -91,7 +92,7 @@ int Timer::startTimer(std::chrono::microseconds timeValue) if (r < 0) { log<level::ERR>("Failure to set timer", - entry("ERROR=%s", strerror(-r))); + entry("ERROR=%s", strerror(-r))); return r; } @@ -101,7 +102,7 @@ int Timer::startTimer(std::chrono::microseconds timeValue) if (r < 0) { log<level::ERR>("Failure to start timer", - entry("ERROR=%s", strerror(-r))); + entry("ERROR=%s", strerror(-r))); } return r; } @@ -1,8 +1,9 @@ #pragma once +#include <systemd/sd-event.h> + #include <chrono> #include <functional> -#include <systemd/sd-event.h> namespace phosphor { namespace ipmi @@ -13,88 +14,87 @@ namespace ipmi */ class Timer { - public: - /** @brief Only need the default Timer */ - Timer() = delete; - Timer(const Timer&) = delete; - Timer& operator=(const Timer&) = delete; - Timer(Timer&&) = delete; - Timer& operator=(Timer&&) = delete; - - /** @brief Constructs timer object - * - * @param[in] events - sd_event pointer - * @param[in] funcCallBack - optional function callback for timer - * expirations - */ - Timer(sd_event* events, - std::function<void()> userCallBack = nullptr) - : timeEvent(events), userCallBack(userCallBack) - { - // Initialize the timer - initialize(); - } + public: + /** @brief Only need the default Timer */ + Timer() = delete; + Timer(const Timer&) = delete; + Timer& operator=(const Timer&) = delete; + Timer(Timer&&) = delete; + Timer& operator=(Timer&&) = delete; - ~Timer() - { - if (eventSource) - { - eventSource = sd_event_source_unref(eventSource); - } - } + /** @brief Constructs timer object + * + * @param[in] events - sd_event pointer + * @param[in] funcCallBack - optional function callback for timer + * expirations + */ + Timer(sd_event* events, std::function<void()> userCallBack = nullptr) : + timeEvent(events), userCallBack(userCallBack) + { + // Initialize the timer + initialize(); + } - inline auto isExpired() const + ~Timer() + { + if (eventSource) { - return expired; + eventSource = sd_event_source_unref(eventSource); } + } + + inline auto isExpired() const + { + return expired; + } + + /** @brief Starts the timer with specified expiration value. + * input is an offset from the current steady_clock + */ + int startTimer(std::chrono::microseconds usec); + + /** @brief Enables / disables the timer */ + int setTimer(int action); + + private: + /** @brief the sd_event structure */ + sd_event* timeEvent = nullptr; + + /** @brief Source of events */ + sd_event_source* eventSource = nullptr; + + /** @brief Returns if the associated timer is expired + * + * This is set to true when the timeoutHandler is called into + */ + bool expired = true; + + /** @brief Initializes the timer object with infinite + * expiration time and sets up the callback handler + * + * @return None. + * + * @error std::runtime exception thrown + */ + void initialize(); + + /** @brief Callback function when timer goes off + * + * On getting the signal, initiate the hard power off request + * + * @param[in] eventSource - Source of the event + * @param[in] usec - time in micro seconds + * @param[in] userData - User data pointer + * + */ + static int timeoutHandler(sd_event_source* eventSource, uint64_t usec, + void* userData); + + /** @brief Gets the current time from steady clock */ + static std::chrono::microseconds getTime(); - /** @brief Starts the timer with specified expiration value. - * input is an offset from the current steady_clock - */ - int startTimer(std::chrono::microseconds usec); - - /** @brief Enables / disables the timer */ - int setTimer(int action); - - private: - /** @brief the sd_event structure */ - sd_event* timeEvent = nullptr; - - /** @brief Source of events */ - sd_event_source* eventSource = nullptr; - - /** @brief Returns if the associated timer is expired - * - * This is set to true when the timeoutHandler is called into - */ - bool expired = true; - - /** @brief Initializes the timer object with infinite - * expiration time and sets up the callback handler - * - * @return None. - * - * @error std::runtime exception thrown - */ - void initialize(); - - /** @brief Callback function when timer goes off - * - * On getting the signal, initiate the hard power off request - * - * @param[in] eventSource - Source of the event - * @param[in] usec - time in micro seconds - * @param[in] userData - User data pointer - * - */ - static int timeoutHandler(sd_event_source* eventSource, - uint64_t usec, void* userData); - - /** @brief Gets the current time from steady clock */ - static std::chrono::microseconds getTime(); - - /** @brief Optional function to call on timer expiration */ - std::function<void()> userCallBack; + /** @brief Optional function to call on timer expiration */ + std::function<void()> userCallBack; }; } // namespace ipmi |