| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2018 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 | #pragma once | 
 | 17 |  | 
| John Edward Broadbent | 7e860f1 | 2021-04-08 15:57:16 -0700 | [diff] [blame] | 18 | #include <app.hpp> | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 19 | #include <boost/container/flat_map.hpp> | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 20 | #include <boost/process/async_pipe.hpp> | 
 | 21 | #include <boost/type_traits/has_dereference.hpp> | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 22 | #include <utils/json_utils.hpp> | 
 | 23 | // for GetObjectType and ManagedObjectType | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 24 |  | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 25 | #include <account_service.hpp> | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 26 | #include <boost/url/url_view.hpp> | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 27 | #include <registries/privilege_registry.hpp> | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 28 |  | 
 | 29 | namespace redfish | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 30 | { | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 31 | /** | 
 | 32 |  * @brief Function extracts transfer protocol name from URI. | 
 | 33 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 34 | inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri) | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 35 | { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 36 |     boost::urls::error_code ec; | 
 | 37 |     boost::urls::url_view url = | 
 | 38 |         boost::urls::parse_uri(boost::string_view(imageUri), ec); | 
 | 39 |     if (ec) | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 40 |     { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 41 |         return "None"; | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 42 |     } | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 43 |     boost::string_view scheme = url.scheme(); | 
 | 44 |     if (scheme == "smb") | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 45 |     { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 46 |         return "CIFS"; | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 47 |     } | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 48 |     if (scheme == "https") | 
 | 49 |     { | 
 | 50 |         return "HTTPS"; | 
 | 51 |     } | 
 | 52 |  | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 53 |     return "None"; | 
 | 54 | } | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 55 |  | 
 | 56 | /** | 
 | 57 |  * @brief Read all known properties from VM object interfaces | 
 | 58 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 59 | inline void | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 60 |     vmParseInterfaceObject(const DbusInterfaceType& interface, | 
 | 61 |                            const std::shared_ptr<bmcweb::AsyncResp>& aResp) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 62 | { | 
 | 63 |     const auto mountPointIface = | 
 | 64 |         interface.find("xyz.openbmc_project.VirtualMedia.MountPoint"); | 
 | 65 |     if (mountPointIface == interface.cend()) | 
 | 66 |     { | 
 | 67 |         BMCWEB_LOG_DEBUG << "Interface MountPoint not found"; | 
 | 68 |         return; | 
 | 69 |     } | 
 | 70 |  | 
 | 71 |     const auto processIface = | 
 | 72 |         interface.find("xyz.openbmc_project.VirtualMedia.Process"); | 
 | 73 |     if (processIface == interface.cend()) | 
 | 74 |     { | 
 | 75 |         BMCWEB_LOG_DEBUG << "Interface Process not found"; | 
 | 76 |         return; | 
 | 77 |     } | 
 | 78 |  | 
 | 79 |     const auto endpointIdProperty = mountPointIface->second.find("EndpointId"); | 
 | 80 |     if (endpointIdProperty == mountPointIface->second.cend()) | 
 | 81 |     { | 
 | 82 |         BMCWEB_LOG_DEBUG << "Property EndpointId not found"; | 
 | 83 |         return; | 
 | 84 |     } | 
 | 85 |  | 
 | 86 |     const auto activeProperty = processIface->second.find("Active"); | 
 | 87 |     if (activeProperty == processIface->second.cend()) | 
 | 88 |     { | 
 | 89 |         BMCWEB_LOG_DEBUG << "Property Active not found"; | 
 | 90 |         return; | 
 | 91 |     } | 
 | 92 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 93 |     const bool* activeValue = std::get_if<bool>(&activeProperty->second); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 94 |     if (!activeValue) | 
 | 95 |     { | 
 | 96 |         BMCWEB_LOG_DEBUG << "Value Active not found"; | 
 | 97 |         return; | 
 | 98 |     } | 
 | 99 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 100 |     const std::string* endpointIdValue = | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 101 |         std::get_if<std::string>(&endpointIdProperty->second); | 
 | 102 |     if (endpointIdValue) | 
 | 103 |     { | 
 | 104 |         if (!endpointIdValue->empty()) | 
 | 105 |         { | 
 | 106 |             // Proxy mode | 
| Przemyslaw Czarnowski | d04ba32 | 2020-01-21 12:41:56 +0100 | [diff] [blame] | 107 |             aResp->res.jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] = | 
 | 108 |                 *endpointIdValue; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 109 |             aResp->res.jsonValue["TransferProtocolType"] = "OEM"; | 
 | 110 |             aResp->res.jsonValue["Inserted"] = *activeValue; | 
 | 111 |             if (*activeValue == true) | 
 | 112 |             { | 
 | 113 |                 aResp->res.jsonValue["ConnectedVia"] = "Applet"; | 
 | 114 |             } | 
 | 115 |         } | 
 | 116 |         else | 
 | 117 |         { | 
 | 118 |             // Legacy mode | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 119 |             for (const auto& property : mountPointIface->second) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 120 |             { | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 121 |                 if (property.first == "ImageURL") | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 122 |                 { | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 123 |                     const std::string* imageUrlValue = | 
 | 124 |                         std::get_if<std::string>(&property.second); | 
 | 125 |                     if (imageUrlValue && !imageUrlValue->empty()) | 
| Przemyslaw Czarnowski | da4784d | 2020-11-06 09:58:25 +0100 | [diff] [blame] | 126 |                     { | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 127 |                         std::filesystem::path filePath = *imageUrlValue; | 
 | 128 |                         if (!filePath.has_filename()) | 
 | 129 |                         { | 
 | 130 |                             // this will handle https share, which not | 
 | 131 |                             // necessarily has to have filename given. | 
 | 132 |                             aResp->res.jsonValue["ImageName"] = ""; | 
 | 133 |                         } | 
 | 134 |                         else | 
 | 135 |                         { | 
 | 136 |                             aResp->res.jsonValue["ImageName"] = | 
 | 137 |                                 filePath.filename(); | 
 | 138 |                         } | 
| Przemyslaw Czarnowski | da4784d | 2020-11-06 09:58:25 +0100 | [diff] [blame] | 139 |  | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 140 |                         aResp->res.jsonValue["Image"] = *imageUrlValue; | 
 | 141 |                         aResp->res.jsonValue["Inserted"] = *activeValue; | 
 | 142 |                         aResp->res.jsonValue["TransferProtocolType"] = | 
 | 143 |                             getTransferProtocolTypeFromUri(*imageUrlValue); | 
 | 144 |  | 
 | 145 |                         if (*activeValue == true) | 
 | 146 |                         { | 
 | 147 |                             aResp->res.jsonValue["ConnectedVia"] = "URI"; | 
 | 148 |                         } | 
 | 149 |                     } | 
 | 150 |                 } | 
 | 151 |                 else if (property.first == "WriteProtected") | 
 | 152 |                 { | 
 | 153 |                     const bool* writeProtectedValue = | 
 | 154 |                         std::get_if<bool>(&property.second); | 
 | 155 |                     if (writeProtectedValue) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 156 |                     { | 
| Anna Platash | 9e319cf | 2020-11-17 10:18:31 +0100 | [diff] [blame] | 157 |                         aResp->res.jsonValue["WriteProtected"] = | 
 | 158 |                             *writeProtectedValue; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 159 |                     } | 
 | 160 |                 } | 
 | 161 |             } | 
 | 162 |         } | 
 | 163 |     } | 
 | 164 | } | 
 | 165 |  | 
 | 166 | /** | 
 | 167 |  * @brief Fill template for Virtual Media Item. | 
 | 168 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 169 | inline nlohmann::json vmItemTemplate(const std::string& name, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 170 |                                      const std::string& resName) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 171 | { | 
 | 172 |     nlohmann::json item; | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 173 |  | 
 | 174 |     std::string id = "/redfish/v1/Managers/"; | 
 | 175 |     id += name; | 
 | 176 |     id += "/VirtualMedia/"; | 
 | 177 |     id += resName; | 
 | 178 |     item["@odata.id"] = std::move(id); | 
 | 179 |  | 
| Przemyslaw Czarnowski | d04ba32 | 2020-01-21 12:41:56 +0100 | [diff] [blame] | 180 |     item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia"; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 181 |     item["Name"] = "Virtual Removable Media"; | 
 | 182 |     item["Id"] = resName; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 183 |     item["WriteProtected"] = true; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 184 |     item["MediaTypes"] = {"CD", "USBStick"}; | 
 | 185 |     item["TransferMethod"] = "Stream"; | 
| Przemyslaw Czarnowski | d04ba32 | 2020-01-21 12:41:56 +0100 | [diff] [blame] | 186 |     item["Oem"]["OpenBMC"]["@odata.type"] = | 
 | 187 |         "#OemVirtualMedia.v1_0_0.VirtualMedia"; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 188 |  | 
 | 189 |     return item; | 
 | 190 | } | 
 | 191 |  | 
 | 192 | /** | 
 | 193 |  *  @brief Fills collection data | 
 | 194 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 195 | inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> aResp, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 196 |                               const std::string& service, | 
 | 197 |                               const std::string& name) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 198 | { | 
 | 199 |     BMCWEB_LOG_DEBUG << "Get available Virtual Media resources."; | 
 | 200 |     crow::connections::systemBus->async_method_call( | 
 | 201 |         [name, aResp{std::move(aResp)}](const boost::system::error_code ec, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 202 |                                         ManagedObjectType& subtree) { | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 203 |             if (ec) | 
 | 204 |             { | 
 | 205 |                 BMCWEB_LOG_DEBUG << "DBUS response error"; | 
 | 206 |                 return; | 
 | 207 |             } | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 208 |             nlohmann::json& members = aResp->res.jsonValue["Members"]; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 209 |             members = nlohmann::json::array(); | 
 | 210 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 211 |             for (const auto& object : subtree) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 212 |             { | 
 | 213 |                 nlohmann::json item; | 
| Ed Tanous | 2dfd18e | 2020-12-18 00:41:31 +0000 | [diff] [blame] | 214 |                 std::string path = object.first.filename(); | 
 | 215 |                 if (path.empty()) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 216 |                 { | 
 | 217 |                     continue; | 
 | 218 |                 } | 
 | 219 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 220 |                 std::string id = "/redfish/v1/Managers/"; | 
 | 221 |                 id += name; | 
 | 222 |                 id += "/VirtualMedia/"; | 
 | 223 |                 id += path; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 224 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 225 |                 item["@odata.id"] = std::move(id); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 226 |                 members.emplace_back(std::move(item)); | 
 | 227 |             } | 
 | 228 |             aResp->res.jsonValue["Members@odata.count"] = members.size(); | 
 | 229 |         }, | 
 | 230 |         service, "/xyz/openbmc_project/VirtualMedia", | 
 | 231 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 232 | } | 
 | 233 |  | 
 | 234 | /** | 
 | 235 |  *  @brief Fills data for specific resource | 
 | 236 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 237 | inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& aResp, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 238 |                       const std::string& service, const std::string& name, | 
 | 239 |                       const std::string& resName) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 240 | { | 
 | 241 |     BMCWEB_LOG_DEBUG << "Get Virtual Media resource data."; | 
 | 242 |  | 
 | 243 |     crow::connections::systemBus->async_method_call( | 
 | 244 |         [resName, name, aResp](const boost::system::error_code ec, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 245 |                                ManagedObjectType& subtree) { | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 246 |             if (ec) | 
 | 247 |             { | 
 | 248 |                 BMCWEB_LOG_DEBUG << "DBUS response error"; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 249 |  | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 250 |                 return; | 
 | 251 |             } | 
 | 252 |  | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 253 |             for (auto& item : subtree) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 254 |             { | 
| Ed Tanous | 2dfd18e | 2020-12-18 00:41:31 +0000 | [diff] [blame] | 255 |                 std::string thispath = item.first.filename(); | 
 | 256 |                 if (thispath.empty()) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 257 |                 { | 
 | 258 |                     continue; | 
 | 259 |                 } | 
 | 260 |  | 
| Ed Tanous | 2dfd18e | 2020-12-18 00:41:31 +0000 | [diff] [blame] | 261 |                 if (thispath != resName) | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 262 |                 { | 
 | 263 |                     continue; | 
 | 264 |                 } | 
 | 265 |  | 
| Przemyslaw Czarnowski | 1a6258d | 2021-04-14 11:02:46 +0200 | [diff] [blame] | 266 |                 // "Legacy"/"Proxy" | 
 | 267 |                 auto mode = item.first.parent_path(); | 
 | 268 |                 // "VirtualMedia" | 
 | 269 |                 auto type = mode.parent_path(); | 
 | 270 |                 if (mode.filename().empty() || type.filename().empty()) | 
 | 271 |                 { | 
 | 272 |                     continue; | 
 | 273 |                 } | 
 | 274 |  | 
 | 275 |                 if (type.filename() != "VirtualMedia") | 
 | 276 |                 { | 
 | 277 |                     continue; | 
 | 278 |                 } | 
 | 279 |  | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 280 |                 aResp->res.jsonValue = vmItemTemplate(name, resName); | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 281 |                 std::string actionsId = "/redfish/v1/Managers/"; | 
 | 282 |                 actionsId += name; | 
 | 283 |                 actionsId += "/VirtualMedia/"; | 
 | 284 |                 actionsId += resName; | 
 | 285 |                 actionsId += "/Actions"; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 286 |  | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 287 |                 // Check if dbus path is Legacy type | 
| Przemyslaw Czarnowski | 1a6258d | 2021-04-14 11:02:46 +0200 | [diff] [blame] | 288 |                 if (mode.filename() == "Legacy") | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 289 |                 { | 
 | 290 |                     aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"] | 
 | 291 |                                         ["target"] = | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 292 |                         actionsId + "/VirtualMedia.InsertMedia"; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 293 |                 } | 
 | 294 |  | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 295 |                 vmParseInterfaceObject(item.second, aResp); | 
 | 296 |  | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 297 |                 aResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"] | 
 | 298 |                                     ["target"] = | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 299 |                     actionsId + "/VirtualMedia.EjectMedia"; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 300 |  | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 301 |                 return; | 
 | 302 |             } | 
 | 303 |  | 
 | 304 |             messages::resourceNotFound( | 
| Przemyslaw Czarnowski | d04ba32 | 2020-01-21 12:41:56 +0100 | [diff] [blame] | 305 |                 aResp->res, "#VirtualMedia.v1_3_0.VirtualMedia", resName); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 306 |         }, | 
 | 307 |         service, "/xyz/openbmc_project/VirtualMedia", | 
 | 308 |         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); | 
 | 309 | } | 
 | 310 |  | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 311 | /** | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 312 |  * @brief Transfer protocols supported for InsertMedia action. | 
 | 313 |  * | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 314 |  */ | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 315 | enum class TransferProtocol | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 316 | { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 317 |     https, | 
 | 318 |     smb, | 
 | 319 |     invalid | 
 | 320 | }; | 
 | 321 |  | 
 | 322 | /** | 
 | 323 |  * @brief Function extracts transfer protocol type from URI. | 
 | 324 |  * | 
 | 325 |  */ | 
 | 326 | inline std::optional<TransferProtocol> | 
 | 327 |     getTransferProtocolFromUri(const std::string& imageUri) | 
 | 328 | { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 329 |     boost::urls::error_code ec; | 
 | 330 |     boost::urls::url_view url = | 
 | 331 |         boost::urls::parse_uri(boost::string_view(imageUri), ec); | 
 | 332 |     if (ec) | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 333 |     { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 334 |         return {}; | 
| Agata Olender | c6f4e01 | 2020-03-11 15:19:07 +0100 | [diff] [blame] | 335 |     } | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 336 |  | 
 | 337 |     boost::string_view scheme = url.scheme(); | 
 | 338 |     if (scheme == "smb") | 
| Agata Olender | c6f4e01 | 2020-03-11 15:19:07 +0100 | [diff] [blame] | 339 |     { | 
| Ed Tanous | d32c4fa | 2021-09-14 13:16:51 -0700 | [diff] [blame] | 340 |         return TransferProtocol::smb; | 
 | 341 |     } | 
 | 342 |     if (scheme == "https") | 
 | 343 |     { | 
 | 344 |         return TransferProtocol::https; | 
 | 345 |     } | 
 | 346 |     if (!scheme.empty()) | 
 | 347 |     { | 
 | 348 |         return TransferProtocol::invalid; | 
| Agata Olender | c6f4e01 | 2020-03-11 15:19:07 +0100 | [diff] [blame] | 349 |     } | 
 | 350 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 351 |     return {}; | 
 | 352 | } | 
 | 353 |  | 
 | 354 | /** | 
 | 355 |  * @brief Function convert transfer protocol from string param. | 
 | 356 |  * | 
 | 357 |  */ | 
 | 358 | inline std::optional<TransferProtocol> getTransferProtocolFromParam( | 
 | 359 |     const std::optional<std::string>& transferProtocolType) | 
 | 360 | { | 
 | 361 |     if (transferProtocolType == std::nullopt) | 
| Agata Olender | c6f4e01 | 2020-03-11 15:19:07 +0100 | [diff] [blame] | 362 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 363 |         return {}; | 
| Agata Olender | c6f4e01 | 2020-03-11 15:19:07 +0100 | [diff] [blame] | 364 |     } | 
 | 365 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 366 |     if (*transferProtocolType == "CIFS") | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 367 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 368 |         return TransferProtocol::smb; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 369 |     } | 
 | 370 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 371 |     if (*transferProtocolType == "HTTPS") | 
 | 372 |     { | 
 | 373 |         return TransferProtocol::https; | 
 | 374 |     } | 
 | 375 |  | 
 | 376 |     return TransferProtocol::invalid; | 
 | 377 | } | 
 | 378 |  | 
 | 379 | /** | 
 | 380 |  * @brief Function extends URI with transfer protocol type. | 
 | 381 |  * | 
 | 382 |  */ | 
 | 383 | inline std::string | 
 | 384 |     getUriWithTransferProtocol(const std::string& imageUri, | 
 | 385 |                                const TransferProtocol& transferProtocol) | 
 | 386 | { | 
 | 387 |     if (transferProtocol == TransferProtocol::smb) | 
 | 388 |     { | 
 | 389 |         return "smb://" + imageUri; | 
 | 390 |     } | 
 | 391 |  | 
 | 392 |     if (transferProtocol == TransferProtocol::https) | 
 | 393 |     { | 
 | 394 |         return "https://" + imageUri; | 
 | 395 |     } | 
 | 396 |  | 
 | 397 |     return imageUri; | 
 | 398 | } | 
 | 399 |  | 
 | 400 | /** | 
 | 401 |  * @brief Function validate parameters of insert media request. | 
 | 402 |  * | 
 | 403 |  */ | 
 | 404 | inline bool | 
 | 405 |     validateParams(crow::Response& res, std::string& imageUrl, | 
 | 406 |                    const std::optional<bool>& inserted, | 
 | 407 |                    const std::optional<std::string>& transferMethod, | 
 | 408 |                    const std::optional<std::string>& transferProtocolType) | 
 | 409 | { | 
 | 410 |     BMCWEB_LOG_DEBUG << "Validation started"; | 
 | 411 |     // required param imageUrl must not be empty | 
 | 412 |     if (imageUrl.empty()) | 
 | 413 |     { | 
 | 414 |         BMCWEB_LOG_ERROR << "Request action parameter Image is empty."; | 
 | 415 |  | 
 | 416 |         messages::propertyValueFormatError(res, "<empty>", "Image"); | 
 | 417 |  | 
 | 418 |         return false; | 
 | 419 |     } | 
 | 420 |  | 
 | 421 |     // optional param inserted must be true | 
 | 422 |     if ((inserted != std::nullopt) && (*inserted != true)) | 
 | 423 |     { | 
 | 424 |         BMCWEB_LOG_ERROR | 
 | 425 |             << "Request action optional parameter Inserted must be true."; | 
 | 426 |  | 
 | 427 |         messages::actionParameterNotSupported(res, "Inserted", "InsertMedia"); | 
 | 428 |  | 
 | 429 |         return false; | 
 | 430 |     } | 
 | 431 |  | 
 | 432 |     // optional param transferMethod must be stream | 
 | 433 |     if ((transferMethod != std::nullopt) && (*transferMethod != "Stream")) | 
 | 434 |     { | 
 | 435 |         BMCWEB_LOG_ERROR << "Request action optional parameter " | 
 | 436 |                             "TransferMethod must be Stream."; | 
 | 437 |  | 
 | 438 |         messages::actionParameterNotSupported(res, "TransferMethod", | 
 | 439 |                                               "InsertMedia"); | 
 | 440 |  | 
 | 441 |         return false; | 
 | 442 |     } | 
 | 443 |  | 
 | 444 |     std::optional<TransferProtocol> uriTransferProtocolType = | 
 | 445 |         getTransferProtocolFromUri(imageUrl); | 
 | 446 |  | 
 | 447 |     std::optional<TransferProtocol> paramTransferProtocolType = | 
 | 448 |         getTransferProtocolFromParam(transferProtocolType); | 
 | 449 |  | 
 | 450 |     // ImageUrl does not contain valid protocol type | 
 | 451 |     if (*uriTransferProtocolType == TransferProtocol::invalid) | 
 | 452 |     { | 
 | 453 |         BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must " | 
 | 454 |                             "contain specified protocol type from list: " | 
 | 455 |                             "(smb, https)."; | 
 | 456 |  | 
 | 457 |         messages::resourceAtUriInUnknownFormat(res, imageUrl); | 
 | 458 |  | 
 | 459 |         return false; | 
 | 460 |     } | 
 | 461 |  | 
 | 462 |     // transferProtocolType should contain value from list | 
 | 463 |     if (*paramTransferProtocolType == TransferProtocol::invalid) | 
 | 464 |     { | 
 | 465 |         BMCWEB_LOG_ERROR << "Request action parameter TransferProtocolType " | 
 | 466 |                             "must be provided with value from list: " | 
 | 467 |                             "(CIFS, HTTPS)."; | 
 | 468 |  | 
 | 469 |         messages::propertyValueNotInList(res, *transferProtocolType, | 
 | 470 |                                          "TransferProtocolType"); | 
 | 471 |         return false; | 
 | 472 |     } | 
 | 473 |  | 
 | 474 |     // valid transfer protocol not provided either with URI nor param | 
 | 475 |     if ((uriTransferProtocolType == std::nullopt) && | 
 | 476 |         (paramTransferProtocolType == std::nullopt)) | 
 | 477 |     { | 
 | 478 |         BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must " | 
 | 479 |                             "contain specified protocol type or param " | 
 | 480 |                             "TransferProtocolType must be provided."; | 
 | 481 |  | 
 | 482 |         messages::resourceAtUriInUnknownFormat(res, imageUrl); | 
 | 483 |  | 
 | 484 |         return false; | 
 | 485 |     } | 
 | 486 |  | 
 | 487 |     // valid transfer protocol provided both with URI and param | 
 | 488 |     if ((paramTransferProtocolType != std::nullopt) && | 
 | 489 |         (uriTransferProtocolType != std::nullopt)) | 
 | 490 |     { | 
 | 491 |         // check if protocol is the same for URI and param | 
 | 492 |         if (*paramTransferProtocolType != *uriTransferProtocolType) | 
 | 493 |         { | 
 | 494 |             BMCWEB_LOG_ERROR << "Request action parameter " | 
 | 495 |                                 "TransferProtocolType must  contain the " | 
 | 496 |                                 "same protocol type as protocol type " | 
 | 497 |                                 "provided with param imageUrl."; | 
 | 498 |  | 
 | 499 |             messages::actionParameterValueTypeError(res, *transferProtocolType, | 
 | 500 |                                                     "TransferProtocolType", | 
 | 501 |                                                     "InsertMedia"); | 
 | 502 |  | 
 | 503 |             return false; | 
 | 504 |         } | 
 | 505 |     } | 
 | 506 |  | 
 | 507 |     // validation passed | 
 | 508 |     // add protocol to URI if needed | 
 | 509 |     if (uriTransferProtocolType == std::nullopt) | 
 | 510 |     { | 
 | 511 |         imageUrl = | 
 | 512 |             getUriWithTransferProtocol(imageUrl, *paramTransferProtocolType); | 
 | 513 |     } | 
 | 514 |  | 
 | 515 |     return true; | 
 | 516 | } | 
 | 517 |  | 
 | 518 | template <typename T> | 
 | 519 | static void secureCleanup(T& value) | 
 | 520 | { | 
 | 521 |     auto raw = const_cast<typename T::value_type*>(value.data()); | 
 | 522 |     explicit_bzero(raw, value.size() * sizeof(*raw)); | 
 | 523 | } | 
 | 524 |  | 
 | 525 | class Credentials | 
 | 526 | { | 
 | 527 |   public: | 
 | 528 |     Credentials(std::string&& user, std::string&& password) : | 
 | 529 |         userBuf(std::move(user)), passBuf(std::move(password)) | 
 | 530 |     {} | 
 | 531 |  | 
 | 532 |     ~Credentials() | 
 | 533 |     { | 
 | 534 |         secureCleanup(userBuf); | 
 | 535 |         secureCleanup(passBuf); | 
 | 536 |     } | 
 | 537 |  | 
 | 538 |     const std::string& user() | 
 | 539 |     { | 
 | 540 |         return userBuf; | 
 | 541 |     } | 
 | 542 |  | 
 | 543 |     const std::string& password() | 
 | 544 |     { | 
 | 545 |         return passBuf; | 
 | 546 |     } | 
 | 547 |  | 
 | 548 |     Credentials() = delete; | 
 | 549 |     Credentials(const Credentials&) = delete; | 
 | 550 |     Credentials& operator=(const Credentials&) = delete; | 
 | 551 |  | 
 | 552 |   private: | 
 | 553 |     std::string userBuf; | 
 | 554 |     std::string passBuf; | 
 | 555 | }; | 
 | 556 |  | 
 | 557 | class CredentialsProvider | 
 | 558 | { | 
 | 559 |   public: | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 560 |     template <typename T> | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 561 |     struct Deleter | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 562 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 563 |         void operator()(T* buff) const | 
 | 564 |         { | 
 | 565 |             if (buff) | 
 | 566 |             { | 
 | 567 |                 secureCleanup(*buff); | 
 | 568 |                 delete buff; | 
 | 569 |             } | 
 | 570 |         } | 
 | 571 |     }; | 
 | 572 |  | 
 | 573 |     using Buffer = std::vector<char>; | 
 | 574 |     using SecureBuffer = std::unique_ptr<Buffer, Deleter<Buffer>>; | 
 | 575 |     // Using explicit definition instead of std::function to avoid implicit | 
 | 576 |     // conversions eg. stack copy instead of reference | 
 | 577 |     using FormatterFunc = void(const std::string& username, | 
 | 578 |                                const std::string& password, Buffer& dest); | 
 | 579 |  | 
 | 580 |     CredentialsProvider(std::string&& user, std::string&& password) : | 
 | 581 |         credentials(std::move(user), std::move(password)) | 
 | 582 |     {} | 
 | 583 |  | 
 | 584 |     const std::string& user() | 
 | 585 |     { | 
 | 586 |         return credentials.user(); | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 587 |     } | 
 | 588 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 589 |     const std::string& password() | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 590 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 591 |         return credentials.password(); | 
 | 592 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 593 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 594 |     SecureBuffer pack(FormatterFunc formatter) | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 595 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 596 |         SecureBuffer packed{new Buffer{}}; | 
 | 597 |         if (formatter) | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 598 |         { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 599 |             formatter(credentials.user(), credentials.password(), *packed); | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 600 |         } | 
 | 601 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 602 |         return packed; | 
 | 603 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 604 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 605 |   private: | 
 | 606 |     Credentials credentials; | 
 | 607 | }; | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 608 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 609 | // Wrapper for boost::async_pipe ensuring proper pipe cleanup | 
 | 610 | template <typename Buffer> | 
 | 611 | class Pipe | 
 | 612 | { | 
 | 613 |   public: | 
 | 614 |     using unix_fd = sdbusplus::message::unix_fd; | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 615 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 616 |     Pipe(boost::asio::io_context& io, Buffer&& buffer) : | 
 | 617 |         impl(io), buffer{std::move(buffer)} | 
 | 618 |     {} | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 619 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 620 |     ~Pipe() | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 621 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 622 |         // Named pipe needs to be explicitly removed | 
 | 623 |         impl.close(); | 
 | 624 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 625 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 626 |     unix_fd fd() | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 627 |     { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 628 |         return unix_fd{impl.native_source()}; | 
 | 629 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 630 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 631 |     template <typename WriteHandler> | 
 | 632 |     void asyncWrite(WriteHandler&& handler) | 
 | 633 |     { | 
 | 634 |         impl.async_write_some(data(), std::forward<WriteHandler>(handler)); | 
 | 635 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 636 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 637 |   private: | 
 | 638 |     // Specialization for pointer types | 
 | 639 |     template <typename B = Buffer> | 
 | 640 |     typename std::enable_if<boost::has_dereference<B>::value, | 
 | 641 |                             boost::asio::const_buffer>::type | 
 | 642 |         data() | 
 | 643 |     { | 
 | 644 |         return boost::asio::buffer(*buffer); | 
 | 645 |     } | 
 | 646 |  | 
 | 647 |     template <typename B = Buffer> | 
 | 648 |     typename std::enable_if<!boost::has_dereference<B>::value, | 
 | 649 |                             boost::asio::const_buffer>::type | 
 | 650 |         data() | 
 | 651 |     { | 
 | 652 |         return boost::asio::buffer(buffer); | 
 | 653 |     } | 
 | 654 |  | 
 | 655 |     const std::string name; | 
 | 656 |     boost::process::async_pipe impl; | 
 | 657 |     Buffer buffer; | 
 | 658 | }; | 
 | 659 |  | 
 | 660 | /** | 
 | 661 |  * @brief Function transceives data with dbus directly. | 
 | 662 |  * | 
 | 663 |  * All BMC state properties will be retrieved before sending reset request. | 
 | 664 |  */ | 
 | 665 | inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 666 |                             const std::string& service, const std::string& name, | 
 | 667 |                             const std::string& imageUrl, const bool rw, | 
 | 668 |                             std::string&& userName, std::string&& password) | 
 | 669 | { | 
 | 670 |     using SecurePipe = Pipe<CredentialsProvider::SecureBuffer>; | 
 | 671 |     constexpr const size_t secretLimit = 1024; | 
 | 672 |  | 
 | 673 |     std::shared_ptr<SecurePipe> secretPipe; | 
 | 674 |     std::variant<int, SecurePipe::unix_fd> unixFd = -1; | 
 | 675 |  | 
 | 676 |     if (!userName.empty() || !password.empty()) | 
 | 677 |     { | 
 | 678 |         // Encapsulate in safe buffer | 
 | 679 |         CredentialsProvider credentials(std::move(userName), | 
 | 680 |                                         std::move(password)); | 
 | 681 |  | 
 | 682 |         // Payload must contain data + NULL delimiters | 
 | 683 |         if (credentials.user().size() + credentials.password().size() + 2 > | 
 | 684 |             secretLimit) | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 685 |         { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 686 |             BMCWEB_LOG_ERROR << "Credentials too long to handle"; | 
 | 687 |             messages::unrecognizedRequestBody(asyncResp->res); | 
 | 688 |             return; | 
 | 689 |         } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 690 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 691 |         // Pack secret | 
 | 692 |         auto secret = credentials.pack( | 
 | 693 |             [](const auto& user, const auto& pass, auto& buff) { | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 694 |                 std::copy(user.begin(), user.end(), std::back_inserter(buff)); | 
 | 695 |                 buff.push_back('\0'); | 
 | 696 |                 std::copy(pass.begin(), pass.end(), std::back_inserter(buff)); | 
 | 697 |                 buff.push_back('\0'); | 
 | 698 |             }); | 
 | 699 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 700 |         // Open pipe | 
 | 701 |         secretPipe = std::make_shared<SecurePipe>( | 
 | 702 |             crow::connections::systemBus->get_io_context(), std::move(secret)); | 
 | 703 |         unixFd = secretPipe->fd(); | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 704 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 705 |         // Pass secret over pipe | 
 | 706 |         secretPipe->asyncWrite( | 
 | 707 |             [asyncResp](const boost::system::error_code& ec, std::size_t) { | 
 | 708 |                 if (ec) | 
 | 709 |                 { | 
 | 710 |                     BMCWEB_LOG_ERROR << "Failed to pass secret: " << ec; | 
 | 711 |                     messages::internalError(asyncResp->res); | 
 | 712 |                 } | 
 | 713 |             }); | 
 | 714 |     } | 
| Adrian Ambrożewicz | 988fb7b | 2020-01-13 18:52:46 +0100 | [diff] [blame] | 715 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 716 |     crow::connections::systemBus->async_method_call( | 
 | 717 |         [asyncResp, secretPipe](const boost::system::error_code ec, | 
 | 718 |                                 bool success) { | 
 | 719 |             if (ec) | 
 | 720 |             { | 
 | 721 |                 BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec; | 
 | 722 |                 messages::internalError(asyncResp->res); | 
 | 723 |             } | 
 | 724 |             else if (!success) | 
 | 725 |             { | 
 | 726 |                 BMCWEB_LOG_ERROR << "Service responded with error"; | 
 | 727 |                 messages::generalError(asyncResp->res); | 
 | 728 |             } | 
 | 729 |         }, | 
 | 730 |         service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name, | 
 | 731 |         "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl, rw, | 
 | 732 |         unixFd); | 
 | 733 | } | 
 | 734 |  | 
 | 735 | /** | 
 | 736 |  * @brief Function transceives data with dbus directly. | 
 | 737 |  * | 
 | 738 |  * All BMC state properties will be retrieved before sending reset request. | 
 | 739 |  */ | 
 | 740 | inline void doVmAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 741 |                        const std::string& service, const std::string& name, | 
 | 742 |                        bool legacy) | 
 | 743 | { | 
 | 744 |  | 
 | 745 |     // Legacy mount requires parameter with image | 
 | 746 |     if (legacy) | 
 | 747 |     { | 
| Adrian Ambrożewicz | d6da5be | 2020-01-13 18:31:01 +0100 | [diff] [blame] | 748 |         crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 749 |             [asyncResp](const boost::system::error_code ec) { | 
| Adrian Ambrożewicz | d6da5be | 2020-01-13 18:31:01 +0100 | [diff] [blame] | 750 |                 if (ec) | 
 | 751 |                 { | 
 | 752 |                     BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec; | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 753 |  | 
| Adrian Ambrożewicz | d6da5be | 2020-01-13 18:31:01 +0100 | [diff] [blame] | 754 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 755 |                     return; | 
| Adrian Ambrożewicz | d6da5be | 2020-01-13 18:31:01 +0100 | [diff] [blame] | 756 |                 } | 
 | 757 |             }, | 
 | 758 |             service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name, | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 759 |             "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount"); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 760 |     } | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 761 |     else // proxy | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 762 |     { | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 763 |         crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 764 |             [asyncResp](const boost::system::error_code ec) { | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 765 |                 if (ec) | 
 | 766 |                 { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 767 |                     BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec; | 
 | 768 |  | 
| zhanghch05 | 8d1b46d | 2021-04-01 11:18:24 +0800 | [diff] [blame] | 769 |                     messages::internalError(asyncResp->res); | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 770 |                     return; | 
 | 771 |                 } | 
 | 772 |             }, | 
 | 773 |             service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name, | 
 | 774 |             "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount"); | 
 | 775 |     } | 
 | 776 | } | 
 | 777 |  | 
 | 778 | inline void requestNBDVirtualMediaRoutes(App& app) | 
 | 779 | { | 
 | 780 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/" | 
 | 781 |                       "VirtualMedia.InsertMedia") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 782 |         .privileges(redfish::privileges::postVirtualMedia) | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 783 |         .methods(boost::beast::http::verb::post)( | 
 | 784 |             [](const crow::Request& req, | 
 | 785 |                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 786 |                const std::string& name, const std::string& resName) { | 
 | 787 |                 if (name != "bmc") | 
 | 788 |                 { | 
 | 789 |                     messages::resourceNotFound(asyncResp->res, | 
 | 790 |                                                "VirtualMedia.Insert", resName); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 791 |  | 
 | 792 |                     return; | 
 | 793 |                 } | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 794 |  | 
 | 795 |                 crow::connections::systemBus->async_method_call( | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 796 |                     [asyncResp, req, | 
 | 797 |                      resName](const boost::system::error_code ec, | 
 | 798 |                               const GetObjectType& getObjectType) { | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 799 |                         if (ec) | 
 | 800 |                         { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 801 |                             BMCWEB_LOG_ERROR | 
 | 802 |                                 << "ObjectMapper::GetObject call failed: " | 
 | 803 |                                 << ec; | 
 | 804 |                             messages::internalError(asyncResp->res); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 805 |  | 
 | 806 |                             return; | 
 | 807 |                         } | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 808 |                         std::string service = getObjectType.begin()->first; | 
 | 809 |                         BMCWEB_LOG_DEBUG << "GetObjectType: " << service; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 810 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 811 |                         crow::connections::systemBus->async_method_call( | 
 | 812 |                             [service, resName, req, | 
 | 813 |                              asyncResp](const boost::system::error_code ec, | 
 | 814 |                                         ManagedObjectType& subtree) { | 
 | 815 |                                 if (ec) | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 816 |                                 { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 817 |                                     BMCWEB_LOG_DEBUG << "DBUS response error"; | 
 | 818 |  | 
 | 819 |                                     return; | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 820 |                                 } | 
 | 821 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 822 |                                 for (const auto& object : subtree) | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 823 |                                 { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 824 |                                     const std::string& path = | 
 | 825 |                                         static_cast<const std::string&>( | 
 | 826 |                                             object.first); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 827 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 828 |                                     std::size_t lastIndex = path.rfind('/'); | 
 | 829 |                                     if (lastIndex == std::string::npos) | 
 | 830 |                                     { | 
 | 831 |                                         continue; | 
 | 832 |                                     } | 
 | 833 |  | 
 | 834 |                                     lastIndex += 1; | 
 | 835 |  | 
 | 836 |                                     if (path.substr(lastIndex) == resName) | 
 | 837 |                                     { | 
 | 838 |                                         lastIndex = path.rfind("Proxy"); | 
 | 839 |                                         if (lastIndex != std::string::npos) | 
 | 840 |                                         { | 
 | 841 |                                             // Not possible in proxy mode | 
 | 842 |                                             BMCWEB_LOG_DEBUG | 
 | 843 |                                                 << "InsertMedia not " | 
 | 844 |                                                    "allowed in proxy mode"; | 
 | 845 |                                             messages::resourceNotFound( | 
 | 846 |                                                 asyncResp->res, | 
 | 847 |                                                 "VirtualMedia.InsertMedia", | 
 | 848 |                                                 resName); | 
 | 849 |  | 
 | 850 |                                             return; | 
 | 851 |                                         } | 
 | 852 |  | 
 | 853 |                                         lastIndex = path.rfind("Legacy"); | 
 | 854 |                                         if (lastIndex == std::string::npos) | 
 | 855 |                                         { | 
 | 856 |                                             continue; | 
 | 857 |                                         } | 
 | 858 |  | 
 | 859 |                                         // Legacy mode | 
 | 860 |                                         std::string imageUrl; | 
 | 861 |                                         std::optional<std::string> userName; | 
 | 862 |                                         std::optional<std::string> password; | 
 | 863 |                                         std::optional<std::string> | 
 | 864 |                                             transferMethod; | 
 | 865 |                                         std::optional<std::string> | 
 | 866 |                                             transferProtocolType; | 
 | 867 |                                         std::optional<bool> writeProtected = | 
 | 868 |                                             true; | 
 | 869 |                                         std::optional<bool> inserted; | 
 | 870 |  | 
 | 871 |                                         // Read obligatory parameters (url of | 
 | 872 |                                         // image) | 
 | 873 |                                         if (!json_util::readJson( | 
 | 874 |                                                 req, asyncResp->res, "Image", | 
 | 875 |                                                 imageUrl, "WriteProtected", | 
 | 876 |                                                 writeProtected, "UserName", | 
 | 877 |                                                 userName, "Password", password, | 
 | 878 |                                                 "Inserted", inserted, | 
 | 879 |                                                 "TransferMethod", | 
 | 880 |                                                 transferMethod, | 
 | 881 |                                                 "TransferProtocolType", | 
 | 882 |                                                 transferProtocolType)) | 
 | 883 |                                         { | 
 | 884 |                                             BMCWEB_LOG_DEBUG | 
 | 885 |                                                 << "Image is not provided"; | 
 | 886 |                                             return; | 
 | 887 |                                         } | 
 | 888 |  | 
 | 889 |                                         bool paramsValid = validateParams( | 
 | 890 |                                             asyncResp->res, imageUrl, inserted, | 
 | 891 |                                             transferMethod, | 
 | 892 |                                             transferProtocolType); | 
 | 893 |  | 
 | 894 |                                         if (paramsValid == false) | 
 | 895 |                                         { | 
 | 896 |                                             return; | 
 | 897 |                                         } | 
 | 898 |  | 
 | 899 |                                         // manager is irrelevant for | 
 | 900 |                                         // VirtualMedia dbus calls | 
 | 901 |                                         doMountVmLegacy(asyncResp, service, | 
 | 902 |                                                         resName, imageUrl, | 
 | 903 |                                                         !(*writeProtected), | 
 | 904 |                                                         std::move(*userName), | 
 | 905 |                                                         std::move(*password)); | 
 | 906 |  | 
 | 907 |                                         return; | 
 | 908 |                                     } | 
 | 909 |                                 } | 
 | 910 |                                 BMCWEB_LOG_DEBUG << "Parent item not found"; | 
 | 911 |                                 messages::resourceNotFound( | 
 | 912 |                                     asyncResp->res, "VirtualMedia", resName); | 
 | 913 |                             }, | 
 | 914 |                             service, "/xyz/openbmc_project/VirtualMedia", | 
 | 915 |                             "org.freedesktop.DBus.ObjectManager", | 
 | 916 |                             "GetManagedObjects"); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 917 |                     }, | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 918 |                     "xyz.openbmc_project.ObjectMapper", | 
 | 919 |                     "/xyz/openbmc_project/object_mapper", | 
 | 920 |                     "xyz.openbmc_project.ObjectMapper", "GetObject", | 
 | 921 |                     "/xyz/openbmc_project/VirtualMedia", | 
 | 922 |                     std::array<const char*, 0>()); | 
 | 923 |             }); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 924 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 925 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/" | 
 | 926 |                       "VirtualMedia.EjectMedia") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 927 |         .privileges(redfish::privileges::postVirtualMedia) | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 928 |         .methods(boost::beast::http::verb::post)( | 
 | 929 |             [](const crow::Request& req, | 
 | 930 |                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 931 |                const std::string& name, const std::string& resName) { | 
 | 932 |                 if (name != "bmc") | 
 | 933 |                 { | 
 | 934 |                     messages::resourceNotFound(asyncResp->res, | 
 | 935 |                                                "VirtualMedia.Eject", resName); | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 936 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 937 |                     return; | 
 | 938 |                 } | 
| Przemyslaw Czarnowski | e13c276 | 2019-09-02 17:32:43 +0200 | [diff] [blame] | 939 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 940 |                 crow::connections::systemBus->async_method_call( | 
 | 941 |                     [asyncResp, req, | 
 | 942 |                      resName](const boost::system::error_code ec, | 
| Gunnar Mills | 1214b7e | 2020-06-04 10:11:30 -0500 | [diff] [blame] | 943 |                               const GetObjectType& getObjectType) { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 944 |                         if (ec) | 
 | 945 |                         { | 
 | 946 |                             BMCWEB_LOG_ERROR | 
 | 947 |                                 << "ObjectMapper::GetObject call failed: " | 
 | 948 |                                 << ec; | 
 | 949 |                             messages::internalError(asyncResp->res); | 
 | 950 |  | 
 | 951 |                             return; | 
 | 952 |                         } | 
 | 953 |                         std::string service = getObjectType.begin()->first; | 
 | 954 |                         BMCWEB_LOG_DEBUG << "GetObjectType: " << service; | 
 | 955 |  | 
 | 956 |                         crow::connections::systemBus->async_method_call( | 
 | 957 |                             [resName, service, req, asyncResp{asyncResp}]( | 
 | 958 |                                 const boost::system::error_code ec, | 
 | 959 |                                 ManagedObjectType& subtree) { | 
 | 960 |                                 if (ec) | 
 | 961 |                                 { | 
 | 962 |                                     BMCWEB_LOG_DEBUG << "DBUS response error"; | 
 | 963 |  | 
 | 964 |                                     return; | 
 | 965 |                                 } | 
 | 966 |  | 
 | 967 |                                 for (const auto& object : subtree) | 
 | 968 |                                 { | 
 | 969 |                                     const std::string& path = | 
 | 970 |                                         static_cast<const std::string&>( | 
 | 971 |                                             object.first); | 
 | 972 |  | 
 | 973 |                                     std::size_t lastIndex = path.rfind('/'); | 
 | 974 |                                     if (lastIndex == std::string::npos) | 
 | 975 |                                     { | 
 | 976 |                                         continue; | 
 | 977 |                                     } | 
 | 978 |  | 
 | 979 |                                     lastIndex += 1; | 
 | 980 |  | 
 | 981 |                                     if (path.substr(lastIndex) == resName) | 
 | 982 |                                     { | 
 | 983 |                                         lastIndex = path.rfind("Proxy"); | 
 | 984 |                                         if (lastIndex != std::string::npos) | 
 | 985 |                                         { | 
 | 986 |                                             // Proxy mode | 
 | 987 |                                             doVmAction(asyncResp, service, | 
 | 988 |                                                        resName, false); | 
 | 989 |                                         } | 
 | 990 |  | 
 | 991 |                                         lastIndex = path.rfind("Legacy"); | 
 | 992 |                                         if (lastIndex != std::string::npos) | 
 | 993 |                                         { | 
 | 994 |                                             // Legacy mode | 
 | 995 |                                             doVmAction(asyncResp, service, | 
 | 996 |                                                        resName, true); | 
 | 997 |                                         } | 
 | 998 |  | 
 | 999 |                                         return; | 
 | 1000 |                                     } | 
 | 1001 |                                 } | 
 | 1002 |                                 BMCWEB_LOG_DEBUG << "Parent item not found"; | 
 | 1003 |                                 messages::resourceNotFound( | 
 | 1004 |                                     asyncResp->res, "VirtualMedia", resName); | 
 | 1005 |                             }, | 
 | 1006 |                             service, "/xyz/openbmc_project/VirtualMedia", | 
 | 1007 |                             "org.freedesktop.DBus.ObjectManager", | 
 | 1008 |                             "GetManagedObjects"); | 
 | 1009 |                     }, | 
 | 1010 |                     "xyz.openbmc_project.ObjectMapper", | 
 | 1011 |                     "/xyz/openbmc_project/object_mapper", | 
 | 1012 |                     "xyz.openbmc_project.ObjectMapper", "GetObject", | 
 | 1013 |                     "/xyz/openbmc_project/VirtualMedia", | 
 | 1014 |                     std::array<const char*, 0>()); | 
 | 1015 |             }); | 
 | 1016 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1017 |         .privileges(redfish::privileges::getVirtualMediaCollection) | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1018 |         .methods(boost::beast::http::verb::get)( | 
 | 1019 |             [](const crow::Request& /* req */, | 
 | 1020 |                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1021 |                const std::string& name) { | 
 | 1022 |                 if (name != "bmc") | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1023 |                 { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1024 |                     messages::resourceNotFound(asyncResp->res, "VirtualMedia", | 
 | 1025 |                                                name); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1026 |  | 
 | 1027 |                     return; | 
 | 1028 |                 } | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1029 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1030 |                 asyncResp->res.jsonValue["@odata.type"] = | 
 | 1031 |                     "#VirtualMediaCollection.VirtualMediaCollection"; | 
 | 1032 |                 asyncResp->res.jsonValue["Name"] = "Virtual Media Services"; | 
 | 1033 |                 asyncResp->res.jsonValue["@odata.id"] = | 
 | 1034 |                     "/redfish/v1/Managers/" + name + "/VirtualMedia"; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1035 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1036 |                 crow::connections::systemBus->async_method_call( | 
 | 1037 |                     [asyncResp, name](const boost::system::error_code ec, | 
 | 1038 |                                       const GetObjectType& getObjectType) { | 
 | 1039 |                         if (ec) | 
 | 1040 |                         { | 
 | 1041 |                             BMCWEB_LOG_ERROR | 
 | 1042 |                                 << "ObjectMapper::GetObject call failed: " | 
 | 1043 |                                 << ec; | 
 | 1044 |                             messages::internalError(asyncResp->res); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1045 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1046 |                             return; | 
 | 1047 |                         } | 
 | 1048 |                         std::string service = getObjectType.begin()->first; | 
 | 1049 |                         BMCWEB_LOG_DEBUG << "GetObjectType: " << service; | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1050 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1051 |                         getVmResourceList(asyncResp, service, name); | 
 | 1052 |                     }, | 
 | 1053 |                     "xyz.openbmc_project.ObjectMapper", | 
 | 1054 |                     "/xyz/openbmc_project/object_mapper", | 
 | 1055 |                     "xyz.openbmc_project.ObjectMapper", "GetObject", | 
 | 1056 |                     "/xyz/openbmc_project/VirtualMedia", | 
 | 1057 |                     std::array<const char*, 0>()); | 
 | 1058 |             }); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1059 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1060 |     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/") | 
| Ed Tanous | ed39821 | 2021-06-09 17:05:54 -0700 | [diff] [blame] | 1061 |         .privileges(redfish::privileges::getVirtualMedia) | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1062 |         .methods(boost::beast::http::verb::get)( | 
 | 1063 |             [](const crow::Request& /* req */, | 
 | 1064 |                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, | 
 | 1065 |                const std::string& name, const std::string& resName) { | 
 | 1066 |                 if (name != "bmc") | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1067 |                 { | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1068 |                     messages::resourceNotFound(asyncResp->res, "VirtualMedia", | 
 | 1069 |                                                resName); | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1070 |  | 
 | 1071 |                     return; | 
 | 1072 |                 } | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1073 |  | 
| Ed Tanous | 22db172 | 2021-06-09 10:53:51 -0700 | [diff] [blame] | 1074 |                 crow::connections::systemBus->async_method_call( | 
 | 1075 |                     [asyncResp, name, | 
 | 1076 |                      resName](const boost::system::error_code ec, | 
 | 1077 |                               const GetObjectType& getObjectType) { | 
 | 1078 |                         if (ec) | 
 | 1079 |                         { | 
 | 1080 |                             BMCWEB_LOG_ERROR | 
 | 1081 |                                 << "ObjectMapper::GetObject call failed: " | 
 | 1082 |                                 << ec; | 
 | 1083 |                             messages::internalError(asyncResp->res); | 
 | 1084 |  | 
 | 1085 |                             return; | 
 | 1086 |                         } | 
 | 1087 |                         std::string service = getObjectType.begin()->first; | 
 | 1088 |                         BMCWEB_LOG_DEBUG << "GetObjectType: " << service; | 
 | 1089 |  | 
 | 1090 |                         getVmData(asyncResp, service, name, resName); | 
 | 1091 |                     }, | 
 | 1092 |                     "xyz.openbmc_project.ObjectMapper", | 
 | 1093 |                     "/xyz/openbmc_project/object_mapper", | 
 | 1094 |                     "xyz.openbmc_project.ObjectMapper", "GetObject", | 
 | 1095 |                     "/xyz/openbmc_project/VirtualMedia", | 
 | 1096 |                     std::array<const char*, 0>()); | 
 | 1097 |             }); | 
 | 1098 | } | 
| Przemyslaw Czarnowski | 107077d | 2019-07-11 10:16:43 +0200 | [diff] [blame] | 1099 |  | 
 | 1100 | } // namespace redfish |