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> 22ed398213SEd 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 132*4f48d5f6SEd Tanous inline 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 304*4f48d5f6SEd Tanous inline void 305*4f48d5f6SEd Tanous handleHostnamePatch(const std::string& hostName, 3068d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 307501be32bSraviteja-b { 308501be32bSraviteja-b crow::connections::systemBus->async_method_call( 309501be32bSraviteja-b [asyncResp](const boost::system::error_code ec) { 310501be32bSraviteja-b if (ec) 311501be32bSraviteja-b { 312501be32bSraviteja-b messages::internalError(asyncResp->res); 313501be32bSraviteja-b return; 314501be32bSraviteja-b } 315501be32bSraviteja-b }, 3167e860f15SJohn Edward Broadbent "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config", 317501be32bSraviteja-b "org.freedesktop.DBus.Properties", "Set", 318501be32bSraviteja-b "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 319501be32bSraviteja-b std::variant<std::string>(hostName)); 320501be32bSraviteja-b } 3212db77d34SJohnathan Mantey #endif 322501be32bSraviteja-b 323*4f48d5f6SEd Tanous inline void handleNTPProtocolEnabled( 3247e860f15SJohn Edward Broadbent const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 32520e6ea5dSraviteja-b { 32620e6ea5dSraviteja-b std::string timeSyncMethod; 32720e6ea5dSraviteja-b if (ntpEnabled) 32820e6ea5dSraviteja-b { 3297e860f15SJohn Edward Broadbent timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 33020e6ea5dSraviteja-b } 33120e6ea5dSraviteja-b else 33220e6ea5dSraviteja-b { 33320e6ea5dSraviteja-b timeSyncMethod = 33420e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 33520e6ea5dSraviteja-b } 33620e6ea5dSraviteja-b 33720e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 33881ce609eSEd Tanous [asyncResp](const boost::system::error_code errorCode) { 33981ce609eSEd Tanous if (errorCode) 340cb13a392SEd Tanous { 341cb13a392SEd Tanous messages::internalError(asyncResp->res); 342cb13a392SEd Tanous } 343cb13a392SEd Tanous }, 3447e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 34520e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 34620e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 34720e6ea5dSraviteja-b std::variant<std::string>{timeSyncMethod}); 34820e6ea5dSraviteja-b } 34920e6ea5dSraviteja-b 350*4f48d5f6SEd Tanous inline void 351*4f48d5f6SEd Tanous handleNTPServersPatch(const std::vector<std::string>& ntpServers, 3528d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 35320e6ea5dSraviteja-b { 35420e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 355cf05f9dcSJohnathan Mantey [asyncResp](const boost::system::error_code ec) { 35620e6ea5dSraviteja-b if (ec) 35720e6ea5dSraviteja-b { 35820e6ea5dSraviteja-b messages::internalError(asyncResp->res); 35920e6ea5dSraviteja-b return; 36020e6ea5dSraviteja-b } 36120e6ea5dSraviteja-b }, 36220e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0", 36320e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 36420e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface", "NTPServers", 36520e6ea5dSraviteja-b std::variant<std::vector<std::string>>{ntpServers}); 36620e6ea5dSraviteja-b } 36720e6ea5dSraviteja-b 368*4f48d5f6SEd Tanous inline void 369*4f48d5f6SEd Tanous handleProtocolEnabled(const bool protocolEnabled, 370e5a99777SAlbert Zhang const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 371e5a99777SAlbert Zhang const std::string_view netBasePath) 37267a78d87STom Joseph { 37367a78d87STom Joseph crow::connections::systemBus->async_method_call( 374e5a99777SAlbert Zhang [protocolEnabled, asyncResp, 375e5a99777SAlbert Zhang netBasePath](const boost::system::error_code ec, 37667a78d87STom Joseph const crow::openbmc_mapper::GetSubTreeType& subtree) { 37767a78d87STom Joseph if (ec) 37867a78d87STom Joseph { 37967a78d87STom Joseph messages::internalError(asyncResp->res); 38067a78d87STom Joseph return; 38167a78d87STom Joseph } 38267a78d87STom Joseph 38367a78d87STom Joseph for (const auto& entry : subtree) 38467a78d87STom Joseph { 385e5a99777SAlbert Zhang if (boost::algorithm::starts_with(entry.first, netBasePath)) 38667a78d87STom Joseph { 38767a78d87STom Joseph crow::connections::systemBus->async_method_call( 38823a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 38923a21a1cSEd Tanous if (ec2) 39067a78d87STom Joseph { 39167a78d87STom Joseph messages::internalError(asyncResp->res); 39267a78d87STom Joseph return; 39367a78d87STom Joseph } 39467a78d87STom Joseph }, 39567a78d87STom Joseph entry.second.begin()->first, entry.first, 39667a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 39767a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 398e5a99777SAlbert Zhang "Running", std::variant<bool>{protocolEnabled}); 39967a78d87STom Joseph 40067a78d87STom Joseph crow::connections::systemBus->async_method_call( 40123a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 40223a21a1cSEd Tanous if (ec2) 40367a78d87STom Joseph { 40467a78d87STom Joseph messages::internalError(asyncResp->res); 40567a78d87STom Joseph return; 40667a78d87STom Joseph } 40767a78d87STom Joseph }, 40867a78d87STom Joseph entry.second.begin()->first, entry.first, 40967a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 41067a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 411e5a99777SAlbert Zhang "Enabled", std::variant<bool>{protocolEnabled}); 41267a78d87STom Joseph } 41367a78d87STom Joseph } 41467a78d87STom Joseph }, 41567a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", 41667a78d87STom Joseph "/xyz/openbmc_project/object_mapper", 41767a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", "GetSubTree", 41867a78d87STom Joseph "/xyz/openbmc_project/control/service", 0, 41967a78d87STom Joseph std::array<const char*, 1>{ 42067a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes"}); 42167a78d87STom Joseph } 42267a78d87STom Joseph 423*4f48d5f6SEd Tanous inline std::string getHostName() 424501be32bSraviteja-b { 4257e860f15SJohn Edward Broadbent std::string hostName; 4268d1b46d7Szhanghch05 4277e860f15SJohn Edward Broadbent std::array<char, HOST_NAME_MAX> hostNameCStr; 4287e860f15SJohn Edward Broadbent if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 4297e860f15SJohn Edward Broadbent { 4307e860f15SJohn Edward Broadbent hostName = hostNameCStr.data(); 4317e860f15SJohn Edward Broadbent } 4327e860f15SJohn Edward Broadbent return hostName; 4337e860f15SJohn Edward Broadbent } 4347e860f15SJohn Edward Broadbent 435*4f48d5f6SEd Tanous inline void 436*4f48d5f6SEd Tanous getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4377e860f15SJohn Edward Broadbent { 4387e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 4397e860f15SJohn Edward Broadbent [asyncResp](const boost::system::error_code errorCode, 4407e860f15SJohn Edward Broadbent const std::variant<std::string>& timeSyncMethod) { 4417e860f15SJohn Edward Broadbent if (errorCode) 4427e860f15SJohn Edward Broadbent { 4437e860f15SJohn Edward Broadbent return; 4447e860f15SJohn Edward Broadbent } 4457e860f15SJohn Edward Broadbent 4467e860f15SJohn Edward Broadbent const std::string* s = std::get_if<std::string>(&timeSyncMethod); 4477e860f15SJohn Edward Broadbent 4487e860f15SJohn Edward Broadbent if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP") 4497e860f15SJohn Edward Broadbent { 4507e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 4517e860f15SJohn Edward Broadbent } 4527e860f15SJohn Edward Broadbent else if (*s == "xyz.openbmc_project.Time.Synchronization." 4537e860f15SJohn Edward Broadbent "Method.Manual") 4547e860f15SJohn Edward Broadbent { 4557e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 4567e860f15SJohn Edward Broadbent } 4577e860f15SJohn Edward Broadbent }, 4587e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 4597e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "Get", 4607e860f15SJohn Edward Broadbent "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod"); 4617e860f15SJohn Edward Broadbent } 4627e860f15SJohn Edward Broadbent 4637e860f15SJohn Edward Broadbent inline void requestRoutesNetworkProtocol(App& app) 4647e860f15SJohn Edward Broadbent { 4657e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 466ed398213SEd Tanous .privileges(redfish::privileges::patchManagerNetworkProtocol) 4677e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 4687e860f15SJohn Edward Broadbent [](const crow::Request& req, 4697e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 470501be32bSraviteja-b std::optional<std::string> newHostName; 471cf05f9dcSJohnathan Mantey std::optional<nlohmann::json> ntp; 47267a78d87STom Joseph std::optional<nlohmann::json> ipmi; 473e5a99777SAlbert Zhang std::optional<nlohmann::json> ssh; 474501be32bSraviteja-b 4757e860f15SJohn Edward Broadbent if (!json_util::readJson(req, asyncResp->res, "NTP", ntp, 476e5a99777SAlbert Zhang "HostName", newHostName, "IPMI", ipmi, 477e5a99777SAlbert Zhang "SSH", ssh)) 478501be32bSraviteja-b { 479501be32bSraviteja-b return; 480501be32bSraviteja-b } 481cf05f9dcSJohnathan Mantey 4828d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 483501be32bSraviteja-b if (newHostName) 484501be32bSraviteja-b { 4852db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH 486501be32bSraviteja-b handleHostnamePatch(*newHostName, asyncResp); 4872db77d34SJohnathan Mantey #else 4882db77d34SJohnathan Mantey messages::propertyNotWritable(asyncResp->res, "HostName"); 4892db77d34SJohnathan Mantey #endif 490cf05f9dcSJohnathan Mantey } 491cf05f9dcSJohnathan Mantey 492cf05f9dcSJohnathan Mantey if (ntp) 493cf05f9dcSJohnathan Mantey { 494cf05f9dcSJohnathan Mantey std::optional<std::vector<std::string>> ntpServers; 495cf05f9dcSJohnathan Mantey std::optional<bool> ntpEnabled; 4968d1b46d7Szhanghch05 if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers", 4977e860f15SJohn Edward Broadbent ntpServers, "ProtocolEnabled", 4987e860f15SJohn Edward Broadbent ntpEnabled)) 499cf05f9dcSJohnathan Mantey { 500501be32bSraviteja-b return; 501501be32bSraviteja-b } 502cf05f9dcSJohnathan Mantey 50320e6ea5dSraviteja-b if (ntpEnabled) 50420e6ea5dSraviteja-b { 50520e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 50620e6ea5dSraviteja-b } 507cf05f9dcSJohnathan Mantey 50820e6ea5dSraviteja-b if (ntpServers) 50920e6ea5dSraviteja-b { 510dc3fbbd0STony Lee std::sort((*ntpServers).begin(), (*ntpServers).end()); 511dc3fbbd0STony Lee (*ntpServers) 5127e860f15SJohn Edward Broadbent .erase(std::unique((*ntpServers).begin(), 5137e860f15SJohn Edward Broadbent (*ntpServers).end()), 514dc3fbbd0STony Lee (*ntpServers).end()); 51520e6ea5dSraviteja-b handleNTPServersPatch(*ntpServers, asyncResp); 51620e6ea5dSraviteja-b } 517501be32bSraviteja-b } 51867a78d87STom Joseph 51967a78d87STom Joseph if (ipmi) 52067a78d87STom Joseph { 52167a78d87STom Joseph std::optional<bool> ipmiProtocolEnabled; 5227e860f15SJohn Edward Broadbent if (!json_util::readJson(*ipmi, asyncResp->res, 5237e860f15SJohn Edward Broadbent "ProtocolEnabled", 52467a78d87STom Joseph ipmiProtocolEnabled)) 52567a78d87STom Joseph { 52667a78d87STom Joseph return; 52767a78d87STom Joseph } 52867a78d87STom Joseph 52967a78d87STom Joseph if (ipmiProtocolEnabled) 53067a78d87STom Joseph { 531e5a99777SAlbert Zhang handleProtocolEnabled( 532e5a99777SAlbert Zhang *ipmiProtocolEnabled, asyncResp, 533e5a99777SAlbert Zhang "/xyz/openbmc_project/control/service/" 534e5a99777SAlbert Zhang "phosphor_2dipmi_2dnet_40"); 535e5a99777SAlbert Zhang } 536e5a99777SAlbert Zhang } 537e5a99777SAlbert Zhang 538e5a99777SAlbert Zhang if (ssh) 539e5a99777SAlbert Zhang { 540e5a99777SAlbert Zhang std::optional<bool> sshProtocolEnabled; 541e5a99777SAlbert Zhang if (!json_util::readJson(*ssh, asyncResp->res, 542e5a99777SAlbert Zhang "ProtocolEnabled", 543e5a99777SAlbert Zhang sshProtocolEnabled)) 544e5a99777SAlbert Zhang { 545e5a99777SAlbert Zhang return; 546e5a99777SAlbert Zhang } 547e5a99777SAlbert Zhang 548e5a99777SAlbert Zhang if (sshProtocolEnabled) 549e5a99777SAlbert Zhang { 550e5a99777SAlbert Zhang handleProtocolEnabled( 551e5a99777SAlbert Zhang *sshProtocolEnabled, asyncResp, 552e5a99777SAlbert Zhang "/xyz/openbmc_project/control/service/dropbear"); 55367a78d87STom Joseph } 55467a78d87STom Joseph } 5557e860f15SJohn Edward Broadbent }); 5567e860f15SJohn Edward Broadbent 5577e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 558ed398213SEd Tanous .privileges(redfish::privileges::getManagerNetworkProtocol) 5597e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 56072048780SAbhishek Patel [](const crow::Request& req, 5617e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 56272048780SAbhishek Patel getNetworkData(asyncResp, req); 5637e860f15SJohn Edward Broadbent }); 564cf05f9dcSJohnathan Mantey } 56570141561SBorawski.Lukasz 56670141561SBorawski.Lukasz } // namespace redfish 567