diff options
author | Nikita Kosenkov <NKosenkov@IBS.RU> | 2022-09-02 17:59:05 +0300 |
---|---|---|
committer | Nikita Kosenkov <NKosenkov@IBS.RU> | 2022-09-02 17:59:05 +0300 |
commit | 8b95d0e092a55e28b933767b92130203a3dbaf09 (patch) | |
tree | 94365e99da18aaf9d44fad47dbf41e7d216d0a9d | |
parent | 5572218ea878453ef86268b7fe7be2973272074b (diff) | |
download | openbmc-8b95d0e092a55e28b933767b92130203a3dbaf09.tar.xz |
bmcweb: Added check the user priv before creating KVM and SOL sessions
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 += "\ |