summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Kosenkov <NKosenkov@IBS.RU>2022-09-02 17:59:05 +0300
committerNikita Kosenkov <NKosenkov@IBS.RU>2022-09-02 17:59:05 +0300
commit8b95d0e092a55e28b933767b92130203a3dbaf09 (patch)
tree94365e99da18aaf9d44fad47dbf41e7d216d0a9d
parent5572218ea878453ef86268b7fe7be2973272074b (diff)
downloadopenbmc-8b95d0e092a55e28b933767b92130203a3dbaf09.tar.xz
bmcweb: Added check the user priv before creating KVM and SOL sessions
-rw-r--r--meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb/0011-Added-check-user-priv-before-creating-KVM-and-SOL.patch205
-rw-r--r--meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend1
2 files changed, 206 insertions, 0 deletions
diff --git a/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb/0011-Added-check-user-priv-before-creating-KVM-and-SOL.patch b/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb/0011-Added-check-user-priv-before-creating-KVM-and-SOL.patch
new file mode 100644
index 0000000000..95be56db0f
--- /dev/null
+++ b/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb/0011-Added-check-user-priv-before-creating-KVM-and-SOL.patch
@@ -0,0 +1,205 @@
+From fc68d0a7de824044a824963a7144a35166b669d1 Mon Sep 17 00:00:00 2001
+From: Nikita Kosenkov <NKosenkov@IBS.RU>
+Date: Fri, 2 Sep 2022 16:53:55 +0300
+Subject: [PATCH] Added check the user priv before creating KVM and SOL
+ sessions
+
+---
+ include/kvm_websocket.hpp | 73 +++++++++++++++++++++++++++++----
+ include/obmc_console.hpp | 86 ++++++++++++++++++++++++++++++++-------
+ 2 files changed, 137 insertions(+), 22 deletions(-)
+
+diff --git a/include/kvm_websocket.hpp b/include/kvm_websocket.hpp
+index 79975d2c..1c5a47cf 100644
+--- a/include/kvm_websocket.hpp
++++ b/include/kvm_websocket.hpp
+@@ -4,7 +4,9 @@
+ #include <app.hpp>
+ #include <async_resp.hpp>
+ #include <boost/container/flat_map.hpp>
++#include <registries/privilege_registry.hpp>
+ #include <websocket.hpp>
++#include <iostream>
+
+ namespace crow
+ {
+@@ -162,15 +164,72 @@ inline void requestRoutes(App& app)
+ .privileges({{"ConfigureComponents", "ConfigureManager"}})
+ .websocket()
+ .onopen([](crow::websocket::Connection& conn) {
+- BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
++ // Check the user info before creating session
++ crow::connections::systemBus->async_method_call(
++ [&conn](const boost::system::error_code ec,
++ std::map<std::string,
++ std::variant<bool, std::string,
++ std::vector<std::string>>> userInfo) {
+
+- if (sessions.size() == maxSessions)
+- {
+- conn.close("Max sessions are already connected");
+- return;
+- }
++ if (ec)
++ {
++ BMCWEB_LOG_ERROR << "GetUserInfo failed...";
++ conn.close("Failed to get user information");
++ return;
++ }
++
++ const std::string* userRolePtr = nullptr;
++ auto userInfoIter = userInfo.find("UserPrivilege");
++ if (userInfoIter != userInfo.end())
++ {
++ userRolePtr =
++ std::get_if<std::string>(&userInfoIter->second);
++ }
++
++ std::string userRole{};
++ if (userRolePtr != nullptr)
++ {
++ userRole = *userRolePtr;
++ BMCWEB_LOG_ERROR << "userName = " << conn.getUserName()
++ << " userRole = " << *userRolePtr;
++
++ redfish::Privileges userPrivileges =
++ redfish::getUserPrivileges(userRole);
++
++ const ::redfish::Privileges requiredPrivileges{
++ {"ConfigureComponents", "ConfigureManager"}};
++
++ if (!userPrivileges.isSupersetOf(requiredPrivileges))
++ {
++ BMCWEB_LOG_ERROR
++ << "Create session failed. User: "
++ << conn.getUserName()
++ << " has prev: " << *userRolePtr;
++
++ BMCWEB_LOG_DEBUG << "User " << conn.getUserName()
++ << " not authorized for kvm connection";
++
++ conn.close("Unathourized access");
++
++ return;
++ }
++
++ BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
++
++ if (sessions.size() == maxSessions)
++ {
++ conn.close("Max sessions are already connected");
++ return;
++ }
++ sessions[&conn] = std::make_unique<KvmSession>(conn);
++ }
++
++ },
++ "xyz.openbmc_project.User.Manager",
++ "/xyz/openbmc_project/user",
++ "xyz.openbmc_project.User.Manager", "GetUserInfo",
++ conn.getUserName());
+
+- sessions[&conn] = std::make_unique<KvmSession>(conn);
+ })
+ .onclose([](crow::websocket::Connection& conn, const std::string&) {
+ sessions.erase(&conn);
+diff --git a/include/obmc_console.hpp b/include/obmc_console.hpp
+index d5eaf819..83e19621 100644
+--- a/include/obmc_console.hpp
++++ b/include/obmc_console.hpp
+@@ -117,21 +117,77 @@ inline void requestRoutes(App& app)
+ BMCWEB_ROUTE(app, "/console0")
+ .privileges({{"ConfigureComponents", "ConfigureManager"}})
+ .websocket()
+- .onopen(
+- [](crow::websocket::Connection& conn) {
+- BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
+-
+- sessions.insert(&conn);
+- if (hostSocket == nullptr)
+- {
+- const std::string consoleName("\0obmc-console", 13);
+- boost::asio::local::stream_protocol::endpoint ep(consoleName);
+-
+- hostSocket =
+- std::make_unique<boost::asio::local::stream_protocol::socket>(
+- conn.getIoContext());
+- hostSocket->async_connect(ep, connectHandler);
+- }
++ .onopen([](crow::websocket::Connection& conn) {
++ // Check the user info before creating session
++ crow::connections::systemBus->async_method_call(
++ [&conn](const boost::system::error_code ec,
++ std::map<std::string,
++ std::variant<bool, std::string,
++ std::vector<std::string>>> userInfo) {
++
++ if (ec)
++ {
++ BMCWEB_LOG_ERROR << "GetUserInfo failed...";
++ conn.close("Failed to get user information");
++ return;
++ }
++
++ const std::string* userRolePtr = nullptr;
++ auto userInfoIter = userInfo.find("UserPrivilege");
++ if (userInfoIter != userInfo.end())
++ {
++ userRolePtr =
++ std::get_if<std::string>(&userInfoIter->second);
++ }
++
++ std::string userRole{};
++ if (userRolePtr != nullptr)
++ {
++ userRole = *userRolePtr;
++ BMCWEB_LOG_ERROR << "userName = " << conn.getUserName()
++ << " userRole = " << *userRolePtr;
++
++ redfish::Privileges userPrivileges =
++ redfish::getUserPrivileges(userRole);
++
++ const ::redfish::Privileges requiredPrivileges{
++ {"ConfigureComponents", "ConfigureManager"}};
++
++ if (!userPrivileges.isSupersetOf(requiredPrivileges))
++ {
++ BMCWEB_LOG_ERROR
++ << "Create session failed. User: "
++ << conn.getUserName()
++ << " has prev: " << *userRolePtr;
++
++ BMCWEB_LOG_DEBUG << "User " << conn.getUserName()
++ << " not authorized for obmc console connection";
++
++ conn.close("Unathourized access");
++
++ return;
++ }
++
++ BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
++
++ sessions.insert(&conn);
++ if (hostSocket == nullptr)
++ {
++ const std::string consoleName("\0obmc-console", 13);
++ boost::asio::local::stream_protocol::endpoint ep(consoleName);
++
++ hostSocket =
++ std::make_unique<boost::asio::local::stream_protocol::socket>(
++ conn.getIoContext());
++ hostSocket->async_connect(ep, connectHandler);
++ }
++ }
++
++ },
++ "xyz.openbmc_project.User.Manager",
++ "/xyz/openbmc_project/user",
++ "xyz.openbmc_project.User.Manager", "GetUserInfo",
++ conn.getUserName());
+ })
+ .onclose([](crow::websocket::Connection& conn,
+ [[maybe_unused]] const std::string& reason) {
+--
+2.35.1
+
diff --git a/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
index f57c3bb4ee..9b58e58b37 100644
--- a/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
+++ b/meta-ibs/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -13,6 +13,7 @@ SRC_URI += "\
file://0008-Add-additional-logs-about-time-sync.patch \
file://0009-Added-additional-log-about-NTP-sync-status.patch \
file://0010-Fix-coreCount-in-ProcessorSummary.patch \
+ file://0011-Added-check-user-priv-before-creating-KVM-and-SOL.patch \
"
EXTRA_OEMESON += "\