summaryrefslogtreecommitdiffstats
path: root/ipmid.C
diff options
context:
space:
mode:
Diffstat (limited to 'ipmid.C')
-rw-r--r--ipmid.C86
1 files changed, 85 insertions, 1 deletions
diff --git a/ipmid.C b/ipmid.C
index 9590448..7848afe 100644
--- a/ipmid.C
+++ b/ipmid.C
@@ -13,10 +13,17 @@
#include <errno.h>
#include <mapper.h>
#include "sensorhandler.h"
+#include <vector>
+#include <algorithm>
+#include <iterator>
+#include <ipmiwhitelist.H>
sd_bus *bus = NULL;
sd_bus_slot *ipmid_slot = NULL;
+// Initialise restricted mode to true
+bool restricted_mode = true;
+
FILE *ipmiio, *ipmidbus, *ipmicmddetails;
void print_usage(void) {
@@ -27,10 +34,15 @@ void print_usage(void) {
fprintf(stderr, " mask : 0xFF - Print all trace\n");
}
+// Host settings in DBUS
+constexpr char settings_host_bus[] = "org.openbmc.settings.Host";
+constexpr char settings_host_object[] = "/org/openbmc/settings/host0";
+constexpr char settings_host_intf[] = "org.freedesktop.DBus.Properties";
+
const char * DBUS_INTF = "org.openbmc.HostIpmi";
const char * FILTER = "type='signal',interface='org.openbmc.HostIpmi',member='ReceivedMessage'";
-
+constexpr char RESTRICTED_MODE_FILTER[] = "type='signal',interface='org.freedesktop.DBus.Properties',path='/org/openbmc/settings/host0'";
typedef std::pair<ipmi_netfn_t, ipmi_cmd_t> ipmi_fn_cmd_t;
typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;
@@ -128,6 +140,22 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t
// return from the Command handlers.
ipmi_ret_t rc = IPMI_CC_INVALID;
+ // If restricted mode is true and command is not whitelisted, don't
+ // execute the command
+ if(restricted_mode)
+ {
+ if (!std::binary_search(whitelist.cbegin(), whitelist.cend(),
+ std::make_pair(netfn, cmd)))
+ {
+ printf("Net function:[0x%X], Command:[0x%X] is not whitelisted\n",
+ netfn, cmd);
+ rc = IPMI_CC_INSUFFICIENT_PRIVILEGE;
+ memcpy(response, &rc, IPMI_CC_LEN);
+ *data_len = IPMI_CC_LEN;
+ return rc;
+ }
+ }
+
// Walk the map that has the registered handlers and invoke the approprite
// handlers for matching commands.
auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd));
@@ -237,6 +265,53 @@ final:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
+void cache_restricted_mode()
+{
+ sd_bus *bus = ipmid_get_sd_bus_connection();
+ sd_bus_message *reply = NULL;
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ int rc = 0;
+
+ rc = sd_bus_call_method(bus,
+ settings_host_bus,
+ settings_host_object,
+ settings_host_intf,
+ "Get",
+ &error,
+ &reply,
+ "ss",
+ settings_host_bus,
+ "restricted_mode");
+ if(rc < 0)
+ {
+ fprintf(stderr, "Failed sd_bus_call_method method for restricted mode: %s\n",
+ strerror(-rc));
+ goto cleanup;
+ }
+
+ rc = sd_bus_message_read(reply, "v", "b", &restricted_mode);
+ if(rc < 0)
+ {
+ fprintf(stderr, "Failed to parse response message for restricted mode: %s\n",
+ strerror(-rc));
+ // Fail-safe to restricted mode
+ restricted_mode = true;
+ }
+
+ printf("Restricted mode = %d\n", restricted_mode);
+
+cleanup:
+ sd_bus_error_free(&error);
+ reply = sd_bus_message_unref(reply);
+}
+
+static int handle_restricted_mode_change(sd_bus_message *m, void *user_data,
+ sd_bus_error *ret_error)
+{
+ cache_restricted_mode();
+ return 0;
+}
+
static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
*ret_error) {
int r = 0;
@@ -444,6 +519,15 @@ int main(int argc, char *argv[])
goto finish;
}
+ // Wait for changes on Restricted mode
+ r = sd_bus_add_match(bus, &ipmid_slot, RESTRICTED_MODE_FILTER, handle_restricted_mode_change, NULL);
+ if (r < 0) {
+ fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), RESTRICTED_MODE_FILTER);
+ goto finish;
+ }
+
+ // Initialise restricted mode
+ cache_restricted_mode();
for (;;) {
/* Process requests */
OpenPOWER on IntegriCloud