diff options
Diffstat (limited to 'ipmid-new.cpp')
-rw-r--r-- | ipmid-new.cpp | 49 |
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); |