Enforce encryption/authentication on in-session RMCP+ messages
In-session RMCP+ messages must have the encryption set to match the
negotiated encryption setting that was set at session creation time.
Tested: Attempt to send an unencrypted payload with a valid session ID.
Change-Id: Iaa20cb9df9b2224bb81e3be5808cab9202e6dbf4
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/message_parsers.cpp b/message_parsers.cpp
index f916171..b3d8dbd 100644
--- a/message_parsers.cpp
+++ b/message_parsers.cpp
@@ -171,12 +171,21 @@
throw std::runtime_error("IPMI2.0 Session Header Missing");
}
- auto message = std::make_shared<Message>();
-
auto header = reinterpret_cast<SessionHeader_t*>(inPacket.data());
+ uint32_t sessionID = endian::from_ipmi(header->sessId);
+
+ auto session =
+ std::get<session::Manager&>(singletonPool).getSession(sessionID);
+ if (!session)
+ {
+ throw std::runtime_error("RMCP+ message from unknown session");
+ }
+
+ auto message = std::make_shared<Message>();
+
message->payloadType = static_cast<PayloadType>(header->payloadType & 0x3F);
- message->bmcSessionID = endian::from_ipmi(header->sessId);
+ message->bmcSessionID = sessionID;
message->sessionSeqNum = endian::from_ipmi(header->sessSeqNum);
message->isPacketEncrypted =
((header->payloadType & PAYLOAD_ENCRYPT_MASK) ? true : false);
@@ -193,6 +202,17 @@
throw std::runtime_error("Invalid data length");
}
+ bool integrityMismatch =
+ session->isIntegrityAlgoEnabled() && !message->isPacketAuthenticated;
+ bool encryptMismatch =
+ session->isCryptAlgoEnabled() && !message->isPacketEncrypted;
+
+ if (sessionID != session::sessionZero &&
+ (integrityMismatch || encryptMismatch))
+ {
+ throw std::runtime_error("unencrypted or unauthenticated message");
+ }
+
if (message->isPacketAuthenticated)
{
if (!(internal::verifyPacketIntegrity(inPacket, message, payloadLen)))