summaryrefslogtreecommitdiffstats
path: root/ipmid-new.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipmid-new.cpp')
-rw-r--r--ipmid-new.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index a9aff36..4986e49 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -135,6 +135,13 @@ static std::unordered_map<unsigned int, /* key is Iana/Cmd (NetFn is 2Eh) */
HandlerTuple>
oemHandlerMap;
+using FilterTuple = std::tuple<int, /* prio */
+ FilterBase::ptr /* filter */
+ >;
+
+/* list to hold all registered ipmi command filters */
+static std::forward_list<FilterTuple> filterList;
+
namespace impl
{
/* common function to register all standard IPMI handlers */
@@ -198,12 +205,54 @@ bool registerOemHandler(int prio, Iana iana, Cmd cmd, Privilege priv,
return false;
}
+/* common function to register all IPMI filter handlers */
+void registerFilter(int prio, FilterBase::ptr filter)
+{
+ // check for initial placement
+ if (filterList.empty() || std::get<int>(filterList.front()) < prio)
+ {
+ filterList.emplace_front(std::make_tuple(prio, filter));
+ }
+ // walk the list and put it in the right place
+ auto j = filterList.begin();
+ for (auto i = j; i != filterList.end() && std::get<int>(*i) > prio; i++)
+ {
+ j = i;
+ }
+ filterList.emplace_after(j, std::make_tuple(prio, filter));
+}
+
} // namespace impl
+message::Response::ptr filterIpmiCommand(message::Request::ptr request)
+{
+ // pass the command through the filter mechanism
+ // This can be the firmware firewall or any OEM mechanism like
+ // whitelist filtering based on operational mode
+ for (auto& item : filterList)
+ {
+ FilterBase::ptr filter = std::get<FilterBase::ptr>(item);
+ ipmi::Cc cc = filter->call(request);
+ if (ipmi::ccSuccess != cc)
+ {
+ return errorResponse(request, cc);
+ }
+ }
+ return message::Response::ptr();
+}
+
message::Response::ptr executeIpmiCommandCommon(
std::unordered_map<unsigned int, HandlerTuple>& handlers,
unsigned int keyCommon, message::Request::ptr request)
{
+ // filter the command first; a non-null message::Response::ptr
+ // means that the message has been rejected for some reason
+ message::Response::ptr response = filterIpmiCommand(request);
+ if (response)
+ {
+ return response;
+ }
+
Cmd cmd = request->ctx->cmd;
unsigned int key = makeCmdKey(keyCommon, cmd);
auto cmdIter = handlers.find(key);
OpenPOWER on IntegriCloud