170141561SBorawski.Lukasz /* 270141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation 370141561SBorawski.Lukasz // 470141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License"); 570141561SBorawski.Lukasz // you may not use this file except in compliance with the License. 670141561SBorawski.Lukasz // You may obtain a copy of the License at 770141561SBorawski.Lukasz // 870141561SBorawski.Lukasz // http://www.apache.org/licenses/LICENSE-2.0 970141561SBorawski.Lukasz // 1070141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software 1170141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS, 1270141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370141561SBorawski.Lukasz // See the License for the specific language governing permissions and 1470141561SBorawski.Lukasz // limitations under the License. 1570141561SBorawski.Lukasz */ 1670141561SBorawski.Lukasz #pragma once 1770141561SBorawski.Lukasz 183a8a0088SKowalski, Kamil #include "error_messages.hpp" 1967a78d87STom Joseph #include "openbmc_dbus_rest.hpp" 2070141561SBorawski.Lukasz 217e860f15SJohn Edward Broadbent #include <app.hpp> 22*ed398213SEd Tanous #include <registries/privilege_registry.hpp> 2320e6ea5dSraviteja-b #include <utils/json_utils.hpp> 241214b7e7SGunnar Mills 251214b7e7SGunnar Mills #include <optional> 26abf2add6SEd Tanous #include <variant> 271abe55efSEd Tanous namespace redfish 281abe55efSEd Tanous { 2970141561SBorawski.Lukasz 307e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp); 317e860f15SJohn Edward Broadbent std::string getHostName(); 327e860f15SJohn Edward Broadbent 331abe55efSEd Tanous enum NetworkProtocolUnitStructFields 341abe55efSEd Tanous { 353a8a0088SKowalski, Kamil NET_PROTO_UNIT_NAME, 363a8a0088SKowalski, Kamil NET_PROTO_UNIT_DESC, 373a8a0088SKowalski, Kamil NET_PROTO_UNIT_LOAD_STATE, 383a8a0088SKowalski, Kamil NET_PROTO_UNIT_ACTIVE_STATE, 393a8a0088SKowalski, Kamil NET_PROTO_UNIT_SUB_STATE, 403a8a0088SKowalski, Kamil NET_PROTO_UNIT_DEVICE, 413a8a0088SKowalski, Kamil NET_PROTO_UNIT_OBJ_PATH, 423a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_0, 433a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_EMPTY, 443a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_ROOT_PATH 453a8a0088SKowalski, Kamil }; 463a8a0088SKowalski, Kamil 471abe55efSEd Tanous enum NetworkProtocolListenResponseElements 481abe55efSEd Tanous { 493a8a0088SKowalski, Kamil NET_PROTO_LISTEN_TYPE, 503a8a0088SKowalski, Kamil NET_PROTO_LISTEN_STREAM 513a8a0088SKowalski, Kamil }; 523a8a0088SKowalski, Kamil 533a8a0088SKowalski, Kamil /** 543a8a0088SKowalski, Kamil * @brief D-Bus Unit structure returned in array from ListUnits Method 553a8a0088SKowalski, Kamil */ 563a8a0088SKowalski, Kamil using UnitStruct = 573a8a0088SKowalski, Kamil std::tuple<std::string, std::string, std::string, std::string, std::string, 583a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path, uint32_t, 593a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path>; 603a8a0088SKowalski, Kamil 61b0972a63SEd Tanous const static std::array<std::pair<const char*, const char*>, 3> protocolToDBus{ 62b0972a63SEd Tanous {{"SSH", "dropbear"}, {"HTTPS", "bmcweb"}, {"IPMI", "phosphor-ipmi-net"}}}; 633a8a0088SKowalski, Kamil 64d24bfc7aSJennifer Lee inline void 6581ce609eSEd Tanous extractNTPServersAndDomainNamesData(const GetManagedObjects& dbusData, 66d24bfc7aSJennifer Lee std::vector<std::string>& ntpData, 67d24bfc7aSJennifer Lee std::vector<std::string>& dnData) 6820e6ea5dSraviteja-b { 6981ce609eSEd Tanous for (const auto& obj : dbusData) 7020e6ea5dSraviteja-b { 7120e6ea5dSraviteja-b for (const auto& ifacePair : obj.second) 7220e6ea5dSraviteja-b { 7320e6ea5dSraviteja-b if (obj.first == "/xyz/openbmc_project/network/eth0") 7420e6ea5dSraviteja-b { 7520e6ea5dSraviteja-b if (ifacePair.first == 7620e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface") 7720e6ea5dSraviteja-b { 7820e6ea5dSraviteja-b for (const auto& propertyPair : ifacePair.second) 7920e6ea5dSraviteja-b { 8020e6ea5dSraviteja-b if (propertyPair.first == "NTPServers") 8120e6ea5dSraviteja-b { 8220e6ea5dSraviteja-b const std::vector<std::string>* ntpServers = 838d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 8420e6ea5dSraviteja-b &propertyPair.second); 8520e6ea5dSraviteja-b if (ntpServers != nullptr) 8620e6ea5dSraviteja-b { 87f23b7296SEd Tanous ntpData = *ntpServers; 8820e6ea5dSraviteja-b } 8920e6ea5dSraviteja-b } 90d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 91d24bfc7aSJennifer Lee { 92d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 938d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 94d24bfc7aSJennifer Lee &propertyPair.second); 95d24bfc7aSJennifer Lee if (domainNames != nullptr) 96d24bfc7aSJennifer Lee { 97f23b7296SEd Tanous dnData = *domainNames; 98d24bfc7aSJennifer Lee } 99d24bfc7aSJennifer Lee } 10020e6ea5dSraviteja-b } 10120e6ea5dSraviteja-b } 10220e6ea5dSraviteja-b } 10320e6ea5dSraviteja-b } 10420e6ea5dSraviteja-b } 10520e6ea5dSraviteja-b } 10620e6ea5dSraviteja-b 10720e6ea5dSraviteja-b template <typename CallbackFunc> 10820e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback) 10920e6ea5dSraviteja-b { 11020e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 11120e6ea5dSraviteja-b [callback{std::move(callback)}]( 11281ce609eSEd Tanous const boost::system::error_code errorCode, 11381ce609eSEd Tanous const GetManagedObjects& dbusData) { 11420e6ea5dSraviteja-b std::vector<std::string> ntpServers; 115d24bfc7aSJennifer Lee std::vector<std::string> domainNames; 11620e6ea5dSraviteja-b 11781ce609eSEd Tanous if (errorCode) 11820e6ea5dSraviteja-b { 119d24bfc7aSJennifer Lee callback(false, ntpServers, domainNames); 12020e6ea5dSraviteja-b return; 12120e6ea5dSraviteja-b } 12220e6ea5dSraviteja-b 12381ce609eSEd Tanous extractNTPServersAndDomainNamesData(dbusData, ntpServers, 124d24bfc7aSJennifer Lee domainNames); 12520e6ea5dSraviteja-b 126d24bfc7aSJennifer Lee callback(true, ntpServers, domainNames); 12720e6ea5dSraviteja-b }, 12820e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 12920e6ea5dSraviteja-b "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 130271584abSEd Tanous } 13120e6ea5dSraviteja-b 13272048780SAbhishek Patel void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 13372048780SAbhishek Patel const crow::Request& req) 1341abe55efSEd Tanous { 1350f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 13661932318SXiaochao Ma "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol"; 1370f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1380f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 1390f74e643SEd Tanous asyncResp->res.jsonValue["Id"] = "NetworkProtocol"; 1400f74e643SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Network Protocol"; 1410f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = "Manager Network Service"; 1420f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 1430f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK"; 1440f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 1450f74e643SEd Tanous 14661932318SXiaochao Ma // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0, 147818ea7b8SJoshi-Mansi // but from security perspective it is not recommended to use. 148818ea7b8SJoshi-Mansi // Hence using protocolEnabled as false to make it OCP and security-wise 149818ea7b8SJoshi-Mansi // compliant 150818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["Port"] = 0; 151818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false; 152818ea7b8SJoshi-Mansi 1530f74e643SEd Tanous for (auto& protocol : protocolToDBus) 1540f74e643SEd Tanous { 1550870f8c7SJayaprakash Mutyala asyncResp->res.jsonValue[protocol.first]["Port"] = 1560870f8c7SJayaprakash Mutyala nlohmann::detail::value_t::null; 1570f74e643SEd Tanous asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false; 1580f74e643SEd Tanous } 1590f74e643SEd Tanous 160d24bfc7aSJennifer Lee std::string hostName = getHostName(); 161d24bfc7aSJennifer Lee 162d24bfc7aSJennifer Lee asyncResp->res.jsonValue["HostName"] = hostName; 1633a8a0088SKowalski, Kamil 16420e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 16520e6ea5dSraviteja-b 16620e6ea5dSraviteja-b // TODO Get eth0 interface data, and call the below callback for JSON 16720e6ea5dSraviteja-b // preparation 168271584abSEd Tanous getEthernetIfaceData( 169271584abSEd Tanous [hostName, asyncResp](const bool& success, 170d24bfc7aSJennifer Lee const std::vector<std::string>& ntpServers, 171d24bfc7aSJennifer Lee const std::vector<std::string>& domainNames) { 17220e6ea5dSraviteja-b if (!success) 17320e6ea5dSraviteja-b { 1747e860f15SJohn Edward Broadbent messages::resourceNotFound(asyncResp->res, "EthernetInterface", 1757e860f15SJohn Edward Broadbent "eth0"); 17620e6ea5dSraviteja-b return; 17720e6ea5dSraviteja-b } 17820e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 179d24bfc7aSJennifer Lee if (hostName.empty() == false) 180d24bfc7aSJennifer Lee { 181f23b7296SEd Tanous std::string fqdn = hostName; 182d24bfc7aSJennifer Lee if (domainNames.empty() == false) 183d24bfc7aSJennifer Lee { 184f23b7296SEd Tanous fqdn += "."; 185f23b7296SEd Tanous fqdn += domainNames[0]; 186d24bfc7aSJennifer Lee } 1872c70f800SEd Tanous asyncResp->res.jsonValue["FQDN"] = std::move(fqdn); 188d24bfc7aSJennifer Lee } 18920e6ea5dSraviteja-b }); 19020e6ea5dSraviteja-b 19172048780SAbhishek Patel Privileges effectiveUserPrivileges = 19272048780SAbhishek Patel redfish::getUserPrivileges(req.userRole); 19372048780SAbhishek Patel 194865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 19572048780SAbhishek Patel [asyncResp, 19672048780SAbhishek Patel &effectiveUserPrivileges](const boost::system::error_code e, 197271584abSEd Tanous const std::vector<UnitStruct>& r) { 198271584abSEd Tanous if (e) 1991abe55efSEd Tanous { 2003a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 201f12894f8SJason M. Bills messages::internalError(asyncResp->res); 202865fbb75SEd Tanous return; 2033a8a0088SKowalski, Kamil } 20472048780SAbhishek Patel // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is 20572048780SAbhishek Patel // something only ConfigureManager can access then only display when 20672048780SAbhishek Patel // the user has permissions ConfigureManager 20772048780SAbhishek Patel if (isOperationAllowedWithPrivileges({{"ConfigureManager"}}, 20872048780SAbhishek Patel effectiveUserPrivileges)) 20972048780SAbhishek Patel { 2105968caeeSMarri Devender Rao asyncResp->res.jsonValue["HTTPS"]["Certificates"] = { 2115968caeeSMarri Devender Rao {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/" 212659dd62eSJason M. Bills "HTTPS/Certificates"}}; 21372048780SAbhishek Patel } 214271584abSEd Tanous for (auto& unit : r) 2151abe55efSEd Tanous { 216ec4974ddSAppaRao Puli /* Only traverse through <xyz>.socket units */ 2173174e4dfSEd Tanous const std::string& unitName = 2183174e4dfSEd Tanous std::get<NET_PROTO_UNIT_NAME>(unit); 219ec4974ddSAppaRao Puli if (!boost::ends_with(unitName, ".socket")) 2201abe55efSEd Tanous { 221865fbb75SEd Tanous continue; 22270141561SBorawski.Lukasz } 22370141561SBorawski.Lukasz 224ec4974ddSAppaRao Puli for (auto& kv : protocolToDBus) 225ec4974ddSAppaRao Puli { 226ec4974ddSAppaRao Puli // We are interested in services, which starts with 227ec4974ddSAppaRao Puli // mapped service name 228ec4974ddSAppaRao Puli if (!boost::starts_with(unitName, kv.second)) 229ec4974ddSAppaRao Puli { 230ec4974ddSAppaRao Puli continue; 231ec4974ddSAppaRao Puli } 232ec4974ddSAppaRao Puli const char* rfServiceKey = kv.first; 2333174e4dfSEd Tanous const std::string& socketPath = 234ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_OBJ_PATH>(unit); 2353174e4dfSEd Tanous const std::string& unitState = 236ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_SUB_STATE>(unit); 237ec4974ddSAppaRao Puli 2387e860f15SJohn Edward Broadbent asyncResp->res.jsonValue[rfServiceKey]["ProtocolEnabled"] = 2397e860f15SJohn Edward Broadbent (unitState == "running") || (unitState == "listening"); 240ec4974ddSAppaRao Puli 241865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 2427e860f15SJohn Edward Broadbent [asyncResp, rfServiceKey{std::string(rfServiceKey)}]( 243865fbb75SEd Tanous const boost::system::error_code ec, 2447e860f15SJohn Edward Broadbent const std::variant<std::vector< 2457e860f15SJohn Edward Broadbent std::tuple<std::string, std::string>>>& resp) { 2461abe55efSEd Tanous if (ec) 2471abe55efSEd Tanous { 248a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 249865fbb75SEd Tanous return; 2503a8a0088SKowalski, Kamil } 251abf2add6SEd Tanous const std::vector< 252abf2add6SEd Tanous std::tuple<std::string, std::string>>* 253abf2add6SEd Tanous responsePtr = std::get_if<std::vector< 254abf2add6SEd Tanous std::tuple<std::string, std::string>>>( 2551b6b96c5SEd Tanous &resp); 2561abe55efSEd Tanous if (responsePtr == nullptr || 2571abe55efSEd Tanous responsePtr->size() < 1) 2581abe55efSEd Tanous { 259865fbb75SEd Tanous return; 26070141561SBorawski.Lukasz } 26170141561SBorawski.Lukasz 262865fbb75SEd Tanous const std::string& listenStream = 2631abe55efSEd Tanous std::get<NET_PROTO_LISTEN_STREAM>( 2641abe55efSEd Tanous (*responsePtr)[0]); 2657e860f15SJohn Edward Broadbent std::size_t lastColonPos = listenStream.rfind(':'); 2661abe55efSEd Tanous if (lastColonPos == std::string::npos) 2671abe55efSEd Tanous { 268865fbb75SEd Tanous // Not a port 269865fbb75SEd Tanous return; 270865fbb75SEd Tanous } 2711abe55efSEd Tanous std::string portStr = 2721abe55efSEd Tanous listenStream.substr(lastColonPos + 1); 273ec4974ddSAppaRao Puli if (portStr.empty()) 274ec4974ddSAppaRao Puli { 275ec4974ddSAppaRao Puli return; 276ec4974ddSAppaRao Puli } 277865fbb75SEd Tanous char* endPtr = nullptr; 278ec4974ddSAppaRao Puli errno = 0; 2791abe55efSEd Tanous // Use strtol instead of stroi to avoid 2801abe55efSEd Tanous // exceptions 2811abe55efSEd Tanous long port = 2821abe55efSEd Tanous std::strtol(portStr.c_str(), &endPtr, 10); 283ec4974ddSAppaRao Puli if ((errno == 0) && (*endPtr == '\0')) 2841abe55efSEd Tanous { 2857e860f15SJohn Edward Broadbent asyncResp->res.jsonValue[rfServiceKey]["Port"] = 2867e860f15SJohn Edward Broadbent port; 2871abe55efSEd Tanous } 288ec4974ddSAppaRao Puli return; 289865fbb75SEd Tanous }, 290865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 291865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 292865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 293ec4974ddSAppaRao Puli 294ec4974ddSAppaRao Puli // We found service, break the inner loop. 295ec4974ddSAppaRao Puli break; 296865fbb75SEd Tanous } 297865fbb75SEd Tanous } 298865fbb75SEd Tanous }, 299865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 300865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 301865fbb75SEd Tanous } 302501be32bSraviteja-b 3032db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH 3047e860f15SJohn Edward Broadbent void handleHostnamePatch(const std::string& hostName, 3058d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 306501be32bSraviteja-b { 307501be32bSraviteja-b crow::connections::systemBus->async_method_call( 308501be32bSraviteja-b [asyncResp](const boost::system::error_code ec) { 309501be32bSraviteja-b if (ec) 310501be32bSraviteja-b { 311501be32bSraviteja-b messages::internalError(asyncResp->res); 312501be32bSraviteja-b return; 313501be32bSraviteja-b } 314501be32bSraviteja-b }, 3157e860f15SJohn Edward Broadbent "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config", 316501be32bSraviteja-b "org.freedesktop.DBus.Properties", "Set", 317501be32bSraviteja-b "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 318501be32bSraviteja-b std::variant<std::string>(hostName)); 319501be32bSraviteja-b } 3202db77d34SJohnathan Mantey #endif 321501be32bSraviteja-b 3228d1b46d7Szhanghch05 void handleNTPProtocolEnabled( 3237e860f15SJohn Edward Broadbent const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 32420e6ea5dSraviteja-b { 32520e6ea5dSraviteja-b std::string timeSyncMethod; 32620e6ea5dSraviteja-b if (ntpEnabled) 32720e6ea5dSraviteja-b { 3287e860f15SJohn Edward Broadbent timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 32920e6ea5dSraviteja-b } 33020e6ea5dSraviteja-b else 33120e6ea5dSraviteja-b { 33220e6ea5dSraviteja-b timeSyncMethod = 33320e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 33420e6ea5dSraviteja-b } 33520e6ea5dSraviteja-b 33620e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 33781ce609eSEd Tanous [asyncResp](const boost::system::error_code errorCode) { 33881ce609eSEd Tanous if (errorCode) 339cb13a392SEd Tanous { 340cb13a392SEd Tanous messages::internalError(asyncResp->res); 341cb13a392SEd Tanous } 342cb13a392SEd Tanous }, 3437e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 34420e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 34520e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 34620e6ea5dSraviteja-b std::variant<std::string>{timeSyncMethod}); 34720e6ea5dSraviteja-b } 34820e6ea5dSraviteja-b 3497e860f15SJohn Edward Broadbent void handleNTPServersPatch(const std::vector<std::string>& ntpServers, 3508d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 35120e6ea5dSraviteja-b { 35220e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 353cf05f9dcSJohnathan Mantey [asyncResp](const boost::system::error_code ec) { 35420e6ea5dSraviteja-b if (ec) 35520e6ea5dSraviteja-b { 35620e6ea5dSraviteja-b messages::internalError(asyncResp->res); 35720e6ea5dSraviteja-b return; 35820e6ea5dSraviteja-b } 35920e6ea5dSraviteja-b }, 36020e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0", 36120e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 36220e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface", "NTPServers", 36320e6ea5dSraviteja-b std::variant<std::vector<std::string>>{ntpServers}); 36420e6ea5dSraviteja-b } 36520e6ea5dSraviteja-b 366e5a99777SAlbert Zhang void handleProtocolEnabled(const bool protocolEnabled, 367e5a99777SAlbert Zhang const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 368e5a99777SAlbert Zhang const std::string_view netBasePath) 36967a78d87STom Joseph { 37067a78d87STom Joseph crow::connections::systemBus->async_method_call( 371e5a99777SAlbert Zhang [protocolEnabled, asyncResp, 372e5a99777SAlbert Zhang netBasePath](const boost::system::error_code ec, 37367a78d87STom Joseph const crow::openbmc_mapper::GetSubTreeType& subtree) { 37467a78d87STom Joseph if (ec) 37567a78d87STom Joseph { 37667a78d87STom Joseph messages::internalError(asyncResp->res); 37767a78d87STom Joseph return; 37867a78d87STom Joseph } 37967a78d87STom Joseph 38067a78d87STom Joseph for (const auto& entry : subtree) 38167a78d87STom Joseph { 382e5a99777SAlbert Zhang if (boost::algorithm::starts_with(entry.first, netBasePath)) 38367a78d87STom Joseph { 38467a78d87STom Joseph crow::connections::systemBus->async_method_call( 38523a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 38623a21a1cSEd Tanous if (ec2) 38767a78d87STom Joseph { 38867a78d87STom Joseph messages::internalError(asyncResp->res); 38967a78d87STom Joseph return; 39067a78d87STom Joseph } 39167a78d87STom Joseph }, 39267a78d87STom Joseph entry.second.begin()->first, entry.first, 39367a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 39467a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 395e5a99777SAlbert Zhang "Running", std::variant<bool>{protocolEnabled}); 39667a78d87STom Joseph 39767a78d87STom Joseph crow::connections::systemBus->async_method_call( 39823a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 39923a21a1cSEd Tanous if (ec2) 40067a78d87STom Joseph { 40167a78d87STom Joseph messages::internalError(asyncResp->res); 40267a78d87STom Joseph return; 40367a78d87STom Joseph } 40467a78d87STom Joseph }, 40567a78d87STom Joseph entry.second.begin()->first, entry.first, 40667a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 40767a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 408e5a99777SAlbert Zhang "Enabled", std::variant<bool>{protocolEnabled}); 40967a78d87STom Joseph } 41067a78d87STom Joseph } 41167a78d87STom Joseph }, 41267a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", 41367a78d87STom Joseph "/xyz/openbmc_project/object_mapper", 41467a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", "GetSubTree", 41567a78d87STom Joseph "/xyz/openbmc_project/control/service", 0, 41667a78d87STom Joseph std::array<const char*, 1>{ 41767a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes"}); 41867a78d87STom Joseph } 41967a78d87STom Joseph 4207e860f15SJohn Edward Broadbent std::string getHostName() 421501be32bSraviteja-b { 4227e860f15SJohn Edward Broadbent std::string hostName; 4238d1b46d7Szhanghch05 4247e860f15SJohn Edward Broadbent std::array<char, HOST_NAME_MAX> hostNameCStr; 4257e860f15SJohn Edward Broadbent if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 4267e860f15SJohn Edward Broadbent { 4277e860f15SJohn Edward Broadbent hostName = hostNameCStr.data(); 4287e860f15SJohn Edward Broadbent } 4297e860f15SJohn Edward Broadbent return hostName; 4307e860f15SJohn Edward Broadbent } 4317e860f15SJohn Edward Broadbent 4327e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4337e860f15SJohn Edward Broadbent { 4347e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 4357e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code errorCode, 4367e860f15SJohn Edward Broadbent const std::variant<std::string>& timeSyncMethod) { 4377e860f15SJohn Edward Broadbent if (errorCode) 4387e860f15SJohn Edward Broadbent { 4397e860f15SJohn Edward Broadbent return; 4407e860f15SJohn Edward Broadbent } 4417e860f15SJohn Edward Broadbent 4427e860f15SJohn Edward Broadbent const std::string* s = std::get_if<std::string>(&timeSyncMethod); 4437e860f15SJohn Edward Broadbent 4447e860f15SJohn Edward Broadbent if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP") 4457e860f15SJohn Edward Broadbent { 4467e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 4477e860f15SJohn Edward Broadbent } 4487e860f15SJohn Edward Broadbent else if (*s == "xyz.openbmc_project.Time.Synchronization." 4497e860f15SJohn Edward Broadbent "Method.Manual") 4507e860f15SJohn Edward Broadbent { 4517e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 4527e860f15SJohn Edward Broadbent } 4537e860f15SJohn Edward Broadbent }, 4547e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 4557e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "Get", 4567e860f15SJohn Edward Broadbent "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod"); 4577e860f15SJohn Edward Broadbent } 4587e860f15SJohn Edward Broadbent 4597e860f15SJohn Edward Broadbent inline void requestRoutesNetworkProtocol(App& app) 4607e860f15SJohn Edward Broadbent { 4617e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 462*ed398213SEd Tanous .privileges(redfish::privileges::patchManagerNetworkProtocol) 4637e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 4647e860f15SJohn Edward Broadbent [](const crow::Request& req, 4657e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 466501be32bSraviteja-b std::optional<std::string> newHostName; 467cf05f9dcSJohnathan Mantey std::optional<nlohmann::json> ntp; 46867a78d87STom Joseph std::optional<nlohmann::json> ipmi; 469e5a99777SAlbert Zhang std::optional<nlohmann::json> ssh; 470501be32bSraviteja-b 4717e860f15SJohn Edward Broadbent if (!json_util::readJson(req, asyncResp->res, "NTP", ntp, 472e5a99777SAlbert Zhang "HostName", newHostName, "IPMI", ipmi, 473e5a99777SAlbert Zhang "SSH", ssh)) 474501be32bSraviteja-b { 475501be32bSraviteja-b return; 476501be32bSraviteja-b } 477cf05f9dcSJohnathan Mantey 4788d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 479501be32bSraviteja-b if (newHostName) 480501be32bSraviteja-b { 4812db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH 482501be32bSraviteja-b handleHostnamePatch(*newHostName, asyncResp); 4832db77d34SJohnathan Mantey #else 4842db77d34SJohnathan Mantey messages::propertyNotWritable(asyncResp->res, "HostName"); 4852db77d34SJohnathan Mantey #endif 486cf05f9dcSJohnathan Mantey } 487cf05f9dcSJohnathan Mantey 488cf05f9dcSJohnathan Mantey if (ntp) 489cf05f9dcSJohnathan Mantey { 490cf05f9dcSJohnathan Mantey std::optional<std::vector<std::string>> ntpServers; 491cf05f9dcSJohnathan Mantey std::optional<bool> ntpEnabled; 4928d1b46d7Szhanghch05 if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers", 4937e860f15SJohn Edward Broadbent ntpServers, "ProtocolEnabled", 4947e860f15SJohn Edward Broadbent ntpEnabled)) 495cf05f9dcSJohnathan Mantey { 496501be32bSraviteja-b return; 497501be32bSraviteja-b } 498cf05f9dcSJohnathan Mantey 49920e6ea5dSraviteja-b if (ntpEnabled) 50020e6ea5dSraviteja-b { 50120e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 50220e6ea5dSraviteja-b } 503cf05f9dcSJohnathan Mantey 50420e6ea5dSraviteja-b if (ntpServers) 50520e6ea5dSraviteja-b { 506dc3fbbd0STony Lee std::sort((*ntpServers).begin(), (*ntpServers).end()); 507dc3fbbd0STony Lee (*ntpServers) 5087e860f15SJohn Edward Broadbent .erase(std::unique((*ntpServers).begin(), 5097e860f15SJohn Edward Broadbent (*ntpServers).end()), 510dc3fbbd0STony Lee (*ntpServers).end()); 51120e6ea5dSraviteja-b handleNTPServersPatch(*ntpServers, asyncResp); 51220e6ea5dSraviteja-b } 513501be32bSraviteja-b } 51467a78d87STom Joseph 51567a78d87STom Joseph if (ipmi) 51667a78d87STom Joseph { 51767a78d87STom Joseph std::optional<bool> ipmiProtocolEnabled; 5187e860f15SJohn Edward Broadbent if (!json_util::readJson(*ipmi, asyncResp->res, 5197e860f15SJohn Edward Broadbent "ProtocolEnabled", 52067a78d87STom Joseph ipmiProtocolEnabled)) 52167a78d87STom Joseph { 52267a78d87STom Joseph return; 52367a78d87STom Joseph } 52467a78d87STom Joseph 52567a78d87STom Joseph if (ipmiProtocolEnabled) 52667a78d87STom Joseph { 527e5a99777SAlbert Zhang handleProtocolEnabled( 528e5a99777SAlbert Zhang *ipmiProtocolEnabled, asyncResp, 529e5a99777SAlbert Zhang "/xyz/openbmc_project/control/service/" 530e5a99777SAlbert Zhang "phosphor_2dipmi_2dnet_40"); 531e5a99777SAlbert Zhang } 532e5a99777SAlbert Zhang } 533e5a99777SAlbert Zhang 534e5a99777SAlbert Zhang if (ssh) 535e5a99777SAlbert Zhang { 536e5a99777SAlbert Zhang std::optional<bool> sshProtocolEnabled; 537e5a99777SAlbert Zhang if (!json_util::readJson(*ssh, asyncResp->res, 538e5a99777SAlbert Zhang "ProtocolEnabled", 539e5a99777SAlbert Zhang sshProtocolEnabled)) 540e5a99777SAlbert Zhang { 541e5a99777SAlbert Zhang return; 542e5a99777SAlbert Zhang } 543e5a99777SAlbert Zhang 544e5a99777SAlbert Zhang if (sshProtocolEnabled) 545e5a99777SAlbert Zhang { 546e5a99777SAlbert Zhang handleProtocolEnabled( 547e5a99777SAlbert Zhang *sshProtocolEnabled, asyncResp, 548e5a99777SAlbert Zhang "/xyz/openbmc_project/control/service/dropbear"); 54967a78d87STom Joseph } 55067a78d87STom Joseph } 5517e860f15SJohn Edward Broadbent }); 5527e860f15SJohn Edward Broadbent 5537e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 554*ed398213SEd Tanous .privileges(redfish::privileges::getManagerNetworkProtocol) 5557e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 55672048780SAbhishek Patel [](const crow::Request& req, 5577e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 55872048780SAbhishek Patel getNetworkData(asyncResp, req); 5597e860f15SJohn Edward Broadbent }); 560cf05f9dcSJohnathan Mantey } 56170141561SBorawski.Lukasz 56270141561SBorawski.Lukasz } // namespace redfish 563