blob: 4aa712ca80ab8455b173980e86e5e0ff8ea92074 [file] [log] [blame]
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +02001/*
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
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "account_service.hpp"
19#include "app.hpp"
George Liu2b731192023-01-11 16:27:13 +080020#include "dbus_utility.hpp"
Ed Tanous739b87e2023-02-24 13:13:33 -080021#include "generated/enums/virtual_media.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080022#include "query.hpp"
23#include "registries/privilege_registry.hpp"
24#include "utils/json_utils.hpp"
25
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +010026#include <boost/process/async_pipe.hpp>
Anna Platash9e319cf2020-11-17 10:18:31 +010027#include <boost/url/url_view.hpp>
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020028
George Liu2b731192023-01-11 16:27:13 +080029#include <array>
30#include <string_view>
31
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020032namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020033{
Ed Tanous365a73f2023-02-24 12:16:49 -080034
35enum class VmMode
36{
37 Invalid,
38 Legacy,
39 Proxy
40};
41
42inline VmMode
43 parseObjectPathAndGetMode(const sdbusplus::message::object_path& itemPath,
44 const std::string& resName)
45{
46 std::string thisPath = itemPath.filename();
47 BMCWEB_LOG_DEBUG << "Filename: " << itemPath.str
48 << ", ThisPath: " << thisPath;
49
50 if (thisPath.empty())
51 {
52 return VmMode::Invalid;
53 }
54
55 if (thisPath != resName)
56 {
57 return VmMode::Invalid;
58 }
59
60 auto mode = itemPath.parent_path();
61 auto type = mode.parent_path();
62
63 if (mode.filename().empty() || type.filename().empty())
64 {
65 return VmMode::Invalid;
66 }
67
68 if (type.filename() != "VirtualMedia")
69 {
70 return VmMode::Invalid;
71 }
72 std::string modeStr = mode.filename();
73 if (modeStr == "Legacy")
74 {
75 return VmMode::Legacy;
76 }
77 if (modeStr == "Proxy")
78 {
79 return VmMode::Proxy;
80 }
81 return VmMode::Invalid;
82}
83
Anna Platash9e319cf2020-11-17 10:18:31 +010084/**
85 * @brief Function extracts transfer protocol name from URI.
86 */
Ed Tanous67df0732021-10-26 11:23:56 -070087inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
88{
89 boost::urls::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -070090 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -070091 if (!url)
92 {
93 return "None";
94 }
Ed Tanous079360a2022-06-29 10:05:19 -070095 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -070096 if (scheme == "smb")
97 {
98 return "CIFS";
99 }
100 if (scheme == "https")
101 {
102 return "HTTPS";
103 }
104
105 return "None";
106}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200107
108/**
109 * @brief Read all known properties from VM object interfaces
110 */
Ed Tanous22db1722021-06-09 10:53:51 -0700111inline void
Ed Tanous8a592812022-06-04 09:06:59 -0700112 vmParseInterfaceObject(const dbus::utility::DBusInteracesMap& interfaces,
zhanghch058d1b46d2021-04-01 11:18:24 +0800113 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200114{
Ed Tanous8a592812022-06-04 09:06:59 -0700115 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200116 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800117 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200118 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800119 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200120 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800121 if (property == "EndpointId")
122 {
123 const std::string* endpointIdValue =
124 std::get_if<std::string>(&value);
125 if (endpointIdValue == nullptr)
126 {
127 continue;
128 }
129 if (!endpointIdValue->empty())
130 {
131 // Proxy mode
132 aResp->res
133 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
134 *endpointIdValue;
135 aResp->res.jsonValue["TransferProtocolType"] = "OEM";
136 }
137 }
138 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200139 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100140 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800141 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800142 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100143 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100144 std::filesystem::path filePath = *imageUrlValue;
145 if (!filePath.has_filename())
146 {
147 // this will handle https share, which not
148 // necessarily has to have filename given.
149 aResp->res.jsonValue["ImageName"] = "";
150 }
151 else
152 {
153 aResp->res.jsonValue["ImageName"] =
154 filePath.filename();
155 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100156
Anna Platash9e319cf2020-11-17 10:18:31 +0100157 aResp->res.jsonValue["Image"] = *imageUrlValue;
Anna Platash9e319cf2020-11-17 10:18:31 +0100158 aResp->res.jsonValue["TransferProtocolType"] =
159 getTransferProtocolTypeFromUri(*imageUrlValue);
160
Ed Tanous739b87e2023-02-24 13:13:33 -0800161 aResp->res.jsonValue["ConnectedVia"] =
162 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100163 }
164 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800165 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100166 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800167 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800168 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200169 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100170 aResp->res.jsonValue["WriteProtected"] =
171 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200172 }
173 }
174 }
175 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800176 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
177 {
178 for (const auto& [property, value] : values)
179 {
180 if (property == "Active")
181 {
182 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800183 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800184 {
185 BMCWEB_LOG_DEBUG << "Value Active not found";
186 return;
187 }
188 aResp->res.jsonValue["Inserted"] = *activeValue;
189
Ed Tanouse05aec52022-01-25 10:28:56 -0800190 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800191 {
Ed Tanous739b87e2023-02-24 13:13:33 -0800192 aResp->res.jsonValue["ConnectedVia"] =
193 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800194 }
195 }
196 }
197 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200198 }
199}
200
201/**
202 * @brief Fill template for Virtual Media Item.
203 */
Ed Tanous22db1722021-06-09 10:53:51 -0700204inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500205 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200206{
207 nlohmann::json item;
Ed Tanousfdb20342022-06-03 09:56:52 -0700208 item["@odata.id"] = crow::utility::urlFromPieces(
209 "redfish", "v1", "Managers", name, "VirtualMedia", resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700210
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100211 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200212 item["Name"] = "Virtual Removable Media";
213 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200214 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800215 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700216 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200217 item["TransferMethod"] = "Stream";
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100218 item["Oem"]["OpenBMC"]["@odata.type"] =
219 "#OemVirtualMedia.v1_0_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200220
221 return item;
222}
223
224/**
225 * @brief Fills collection data
226 */
Ed Tanous22db1722021-06-09 10:53:51 -0700227inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500228 const std::string& service,
229 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200230{
231 BMCWEB_LOG_DEBUG << "Get available Virtual Media resources.";
232 crow::connections::systemBus->async_method_call(
Ed Tanous02cad962022-06-30 16:50:15 -0700233 [name, aResp{std::move(aResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800234 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700235 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700236 if (ec)
237 {
238 BMCWEB_LOG_DEBUG << "DBUS response error";
239 return;
240 }
241 nlohmann::json& members = aResp->res.jsonValue["Members"];
242 members = nlohmann::json::array();
243
244 for (const auto& object : subtree)
245 {
246 nlohmann::json item;
247 std::string path = object.first.filename();
248 if (path.empty())
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200249 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700250 continue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200251 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200252
Ed Tanousfdb20342022-06-03 09:56:52 -0700253 item["@odata.id"] = crow::utility::urlFromPieces(
254 "redfish", "v1", "Managers", name, "VirtualMedia", path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700255 members.emplace_back(std::move(item));
256 }
257 aResp->res.jsonValue["Members@odata.count"] = members.size();
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200258 },
259 service, "/xyz/openbmc_project/VirtualMedia",
260 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
261}
262
263/**
264 * @brief Fills data for specific resource
265 */
Ed Tanous22db1722021-06-09 10:53:51 -0700266inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500267 const std::string& service, const std::string& name,
268 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200269{
270 BMCWEB_LOG_DEBUG << "Get Virtual Media resource data.";
271
272 crow::connections::systemBus->async_method_call(
Ed Tanous914e2d52022-01-07 11:38:34 -0800273 [resName, name,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800274 aResp](const boost::system::error_code& ec,
Ed Tanous914e2d52022-01-07 11:38:34 -0800275 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700276 if (ec)
277 {
278 BMCWEB_LOG_DEBUG << "DBUS response error";
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200279
Ed Tanous002d39b2022-05-31 08:59:27 -0700280 return;
281 }
282
283 for (const auto& item : subtree)
284 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800285 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
286 if (mode == VmMode::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -0700287 {
288 continue;
289 }
Przemyslaw Czarnowski1a6258d2021-04-14 11:02:46 +0200290
Ed Tanous002d39b2022-05-31 08:59:27 -0700291 aResp->res.jsonValue = vmItemTemplate(name, resName);
Przemyslaw Czarnowski1a6258d2021-04-14 11:02:46 +0200292
Ed Tanous002d39b2022-05-31 08:59:27 -0700293 // Check if dbus path is Legacy type
Ed Tanous365a73f2023-02-24 12:16:49 -0800294 if (mode == VmMode::Legacy)
Ed Tanous002d39b2022-05-31 08:59:27 -0700295 {
296 aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
Ed Tanousfdb20342022-06-03 09:56:52 -0700297 ["target"] = crow::utility::urlFromPieces(
298 "redfish", "v1", "Managers", name, "VirtualMedia", resName,
299 "Actions", "VirtualMedia.InsertMedia");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200300 }
301
Ed Tanous002d39b2022-05-31 08:59:27 -0700302 vmParseInterfaceObject(item.second, aResp);
303
304 aResp->res
305 .jsonValue["Actions"]["#VirtualMedia.EjectMedia"]["target"] =
Ed Tanousfdb20342022-06-03 09:56:52 -0700306 crow::utility::urlFromPieces("redfish", "v1", "Managers", name,
307 "VirtualMedia", resName, "Actions",
308 "VirtualMedia.EjectMedia");
Ed Tanous002d39b2022-05-31 08:59:27 -0700309 return;
310 }
311
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800312 messages::resourceNotFound(aResp->res, "VirtualMedia", resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200313 },
314 service, "/xyz/openbmc_project/VirtualMedia",
315 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
316}
317
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200318/**
Ed Tanous22db1722021-06-09 10:53:51 -0700319 * @brief Transfer protocols supported for InsertMedia action.
320 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200321 */
Ed Tanous22db1722021-06-09 10:53:51 -0700322enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200323{
Ed Tanous22db1722021-06-09 10:53:51 -0700324 https,
325 smb,
326 invalid
327};
328
329/**
330 * @brief Function extracts transfer protocol type from URI.
331 *
332 */
Ed Tanous67df0732021-10-26 11:23:56 -0700333inline std::optional<TransferProtocol>
Ed Tanousace85d62021-10-26 12:45:59 -0700334 getTransferProtocolFromUri(const boost::urls::url_view& imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700335{
Ed Tanous079360a2022-06-29 10:05:19 -0700336 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700337 if (scheme == "smb")
338 {
339 return TransferProtocol::smb;
340 }
341 if (scheme == "https")
342 {
343 return TransferProtocol::https;
344 }
345 if (!scheme.empty())
346 {
347 return TransferProtocol::invalid;
348 }
349
350 return {};
351}
Ed Tanous22db1722021-06-09 10:53:51 -0700352
353/**
354 * @brief Function convert transfer protocol from string param.
355 *
356 */
357inline std::optional<TransferProtocol> getTransferProtocolFromParam(
358 const std::optional<std::string>& transferProtocolType)
359{
360 if (transferProtocolType == std::nullopt)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100361 {
Ed Tanous22db1722021-06-09 10:53:51 -0700362 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100363 }
364
Ed Tanous22db1722021-06-09 10:53:51 -0700365 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200366 {
Ed Tanous22db1722021-06-09 10:53:51 -0700367 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200368 }
369
Ed Tanous22db1722021-06-09 10:53:51 -0700370 if (*transferProtocolType == "HTTPS")
371 {
372 return TransferProtocol::https;
373 }
374
375 return TransferProtocol::invalid;
376}
377
378/**
379 * @brief Function extends URI with transfer protocol type.
380 *
381 */
382inline std::string
383 getUriWithTransferProtocol(const std::string& imageUri,
384 const TransferProtocol& transferProtocol)
385{
386 if (transferProtocol == TransferProtocol::smb)
387 {
388 return "smb://" + imageUri;
389 }
390
391 if (transferProtocol == TransferProtocol::https)
392 {
393 return "https://" + imageUri;
394 }
395
396 return imageUri;
397}
398
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200399struct InsertMediaActionParams
400{
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200401 std::optional<std::string> imageUrl;
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200402 std::optional<std::string> userName;
403 std::optional<std::string> password;
404 std::optional<std::string> transferMethod;
405 std::optional<std::string> transferProtocolType;
406 std::optional<bool> writeProtected = true;
407 std::optional<bool> inserted;
408};
409
Ed Tanous22db1722021-06-09 10:53:51 -0700410template <typename T>
411static void secureCleanup(T& value)
412{
Ed Tanous4ecc6182022-01-07 09:36:26 -0800413 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
Ed Tanous22db1722021-06-09 10:53:51 -0700414 auto raw = const_cast<typename T::value_type*>(value.data());
415 explicit_bzero(raw, value.size() * sizeof(*raw));
416}
417
418class Credentials
419{
420 public:
421 Credentials(std::string&& user, std::string&& password) :
422 userBuf(std::move(user)), passBuf(std::move(password))
423 {}
424
425 ~Credentials()
426 {
427 secureCleanup(userBuf);
428 secureCleanup(passBuf);
429 }
430
431 const std::string& user()
432 {
433 return userBuf;
434 }
435
436 const std::string& password()
437 {
438 return passBuf;
439 }
440
441 Credentials() = delete;
442 Credentials(const Credentials&) = delete;
443 Credentials& operator=(const Credentials&) = delete;
Ed Tanousecd6a3a2022-01-07 09:18:40 -0800444 Credentials(Credentials&&) = delete;
445 Credentials& operator=(Credentials&&) = delete;
Ed Tanous22db1722021-06-09 10:53:51 -0700446
447 private:
448 std::string userBuf;
449 std::string passBuf;
450};
451
452class CredentialsProvider
453{
454 public:
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500455 template <typename T>
Ed Tanous22db1722021-06-09 10:53:51 -0700456 struct Deleter
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100457 {
Ed Tanous22db1722021-06-09 10:53:51 -0700458 void operator()(T* buff) const
459 {
460 if (buff)
461 {
462 secureCleanup(*buff);
463 delete buff;
464 }
465 }
466 };
467
468 using Buffer = std::vector<char>;
469 using SecureBuffer = std::unique_ptr<Buffer, Deleter<Buffer>>;
470 // Using explicit definition instead of std::function to avoid implicit
471 // conversions eg. stack copy instead of reference
472 using FormatterFunc = void(const std::string& username,
473 const std::string& password, Buffer& dest);
474
475 CredentialsProvider(std::string&& user, std::string&& password) :
476 credentials(std::move(user), std::move(password))
477 {}
478
479 const std::string& user()
480 {
481 return credentials.user();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100482 }
483
Ed Tanous22db1722021-06-09 10:53:51 -0700484 const std::string& password()
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100485 {
Ed Tanous22db1722021-06-09 10:53:51 -0700486 return credentials.password();
487 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100488
Ed Tanous1917ee92022-06-30 22:30:50 -0700489 SecureBuffer pack(FormatterFunc* formatter)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100490 {
Ed Tanous22db1722021-06-09 10:53:51 -0700491 SecureBuffer packed{new Buffer{}};
Ed Tanouse662eae2022-01-25 10:39:19 -0800492 if (formatter != nullptr)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100493 {
Ed Tanous22db1722021-06-09 10:53:51 -0700494 formatter(credentials.user(), credentials.password(), *packed);
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100495 }
496
Ed Tanous22db1722021-06-09 10:53:51 -0700497 return packed;
498 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100499
Ed Tanous22db1722021-06-09 10:53:51 -0700500 private:
501 Credentials credentials;
502};
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100503
Ed Tanous22db1722021-06-09 10:53:51 -0700504// Wrapper for boost::async_pipe ensuring proper pipe cleanup
Ed Tanous0a483062022-07-11 10:18:50 -0700505class SecurePipe
Ed Tanous22db1722021-06-09 10:53:51 -0700506{
507 public:
508 using unix_fd = sdbusplus::message::unix_fd;
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100509
Ed Tanous0a483062022-07-11 10:18:50 -0700510 SecurePipe(boost::asio::io_context& io,
511 CredentialsProvider::SecureBuffer&& bufferIn) :
512 impl(io),
513 buffer{std::move(bufferIn)}
Ed Tanous22db1722021-06-09 10:53:51 -0700514 {}
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100515
Ed Tanous0a483062022-07-11 10:18:50 -0700516 ~SecurePipe()
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100517 {
Ed Tanous22db1722021-06-09 10:53:51 -0700518 // Named pipe needs to be explicitly removed
519 impl.close();
520 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100521
Ed Tanous0a483062022-07-11 10:18:50 -0700522 SecurePipe(const SecurePipe&) = delete;
523 SecurePipe(SecurePipe&&) = delete;
524 SecurePipe& operator=(const SecurePipe&) = delete;
525 SecurePipe& operator=(SecurePipe&&) = delete;
Ed Tanousecd6a3a2022-01-07 09:18:40 -0800526
Ed Tanous0a483062022-07-11 10:18:50 -0700527 unix_fd fd() const
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200528 {
Ed Tanous22db1722021-06-09 10:53:51 -0700529 return unix_fd{impl.native_source()};
530 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100531
Ed Tanous22db1722021-06-09 10:53:51 -0700532 template <typename WriteHandler>
533 void asyncWrite(WriteHandler&& handler)
534 {
Ed Tanous0a483062022-07-11 10:18:50 -0700535 impl.async_write_some(boost::asio::buffer(*buffer),
536 std::forward<WriteHandler>(handler));
Ed Tanous22db1722021-06-09 10:53:51 -0700537 }
538
539 const std::string name;
540 boost::process::async_pipe impl;
Ed Tanous0a483062022-07-11 10:18:50 -0700541 CredentialsProvider::SecureBuffer buffer;
Ed Tanous22db1722021-06-09 10:53:51 -0700542};
543
544/**
545 * @brief Function transceives data with dbus directly.
546 *
547 * All BMC state properties will be retrieved before sending reset request.
548 */
549inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
550 const std::string& service, const std::string& name,
551 const std::string& imageUrl, const bool rw,
552 std::string&& userName, std::string&& password)
553{
Ed Tanous22db1722021-06-09 10:53:51 -0700554 constexpr const size_t secretLimit = 1024;
555
556 std::shared_ptr<SecurePipe> secretPipe;
Ed Tanous168e20c2021-12-13 14:39:53 -0800557 dbus::utility::DbusVariantType unixFd = -1;
Ed Tanous22db1722021-06-09 10:53:51 -0700558
559 if (!userName.empty() || !password.empty())
560 {
561 // Encapsulate in safe buffer
562 CredentialsProvider credentials(std::move(userName),
563 std::move(password));
564
565 // Payload must contain data + NULL delimiters
566 if (credentials.user().size() + credentials.password().size() + 2 >
567 secretLimit)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100568 {
Ed Tanous22db1722021-06-09 10:53:51 -0700569 BMCWEB_LOG_ERROR << "Credentials too long to handle";
570 messages::unrecognizedRequestBody(asyncResp->res);
571 return;
572 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100573
Ed Tanous22db1722021-06-09 10:53:51 -0700574 // Pack secret
575 auto secret = credentials.pack(
576 [](const auto& user, const auto& pass, auto& buff) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700577 std::copy(user.begin(), user.end(), std::back_inserter(buff));
578 buff.push_back('\0');
579 std::copy(pass.begin(), pass.end(), std::back_inserter(buff));
580 buff.push_back('\0');
581 });
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100582
Ed Tanous22db1722021-06-09 10:53:51 -0700583 // Open pipe
584 secretPipe = std::make_shared<SecurePipe>(
585 crow::connections::systemBus->get_io_context(), std::move(secret));
586 unixFd = secretPipe->fd();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100587
Ed Tanous22db1722021-06-09 10:53:51 -0700588 // Pass secret over pipe
589 secretPipe->asyncWrite(
590 [asyncResp](const boost::system::error_code& ec, std::size_t) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700591 if (ec)
592 {
593 BMCWEB_LOG_ERROR << "Failed to pass secret: " << ec;
594 messages::internalError(asyncResp->res);
595 }
596 });
Ed Tanous22db1722021-06-09 10:53:51 -0700597 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100598
Ed Tanous22db1722021-06-09 10:53:51 -0700599 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800600 [asyncResp, secretPipe](const boost::system::error_code& ec,
Ed Tanous22db1722021-06-09 10:53:51 -0700601 bool success) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700602 if (ec)
603 {
604 BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
605 messages::internalError(asyncResp->res);
606 }
607 else if (!success)
608 {
609 BMCWEB_LOG_ERROR << "Service responded with error";
610 messages::generalError(asyncResp->res);
611 }
Ed Tanous22db1722021-06-09 10:53:51 -0700612 },
613 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
614 "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl, rw,
615 unixFd);
616}
617
618/**
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200619 * @brief Function validate parameters of insert media request.
620 *
621 */
622inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
623 const std::string& service,
624 const std::string& resName,
625 InsertMediaActionParams& actionParams)
626{
627 BMCWEB_LOG_DEBUG << "Validation started";
628 // required param imageUrl must not be empty
629 if (!actionParams.imageUrl)
630 {
631 BMCWEB_LOG_ERROR << "Request action parameter Image is empty.";
632
633 messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
634
635 return;
636 }
637
638 // optional param inserted must be true
639 if ((actionParams.inserted != std::nullopt) && !*actionParams.inserted)
640 {
641 BMCWEB_LOG_ERROR
642 << "Request action optional parameter Inserted must be true.";
643
644 messages::actionParameterNotSupported(asyncResp->res, "Inserted",
645 "InsertMedia");
646
647 return;
648 }
649
650 // optional param transferMethod must be stream
651 if ((actionParams.transferMethod != std::nullopt) &&
652 (*actionParams.transferMethod != "Stream"))
653 {
654 BMCWEB_LOG_ERROR << "Request action optional parameter "
655 "TransferMethod must be Stream.";
656
657 messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
658 "InsertMedia");
659
660 return;
661 }
662 boost::urls::result<boost::urls::url_view> url =
663 boost::urls::parse_uri(*actionParams.imageUrl);
664 if (!url)
665 {
666 messages::actionParameterValueFormatError(
667 asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
668 return;
669 }
670 std::optional<TransferProtocol> uriTransferProtocolType =
671 getTransferProtocolFromUri(*url);
672
673 std::optional<TransferProtocol> paramTransferProtocolType =
674 getTransferProtocolFromParam(actionParams.transferProtocolType);
675
676 // ImageUrl does not contain valid protocol type
677 if (*uriTransferProtocolType == TransferProtocol::invalid)
678 {
679 BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
680 "contain specified protocol type from list: "
681 "(smb, https).";
682
683 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
684
685 return;
686 }
687
688 // transferProtocolType should contain value from list
689 if (*paramTransferProtocolType == TransferProtocol::invalid)
690 {
691 BMCWEB_LOG_ERROR << "Request action parameter TransferProtocolType "
692 "must be provided with value from list: "
693 "(CIFS, HTTPS).";
694
695 messages::propertyValueNotInList(asyncResp->res,
696 *actionParams.transferProtocolType,
697 "TransferProtocolType");
698 return;
699 }
700
701 // valid transfer protocol not provided either with URI nor param
702 if ((uriTransferProtocolType == std::nullopt) &&
703 (paramTransferProtocolType == std::nullopt))
704 {
705 BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
706 "contain specified protocol type or param "
707 "TransferProtocolType must be provided.";
708
709 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
710
711 return;
712 }
713
714 // valid transfer protocol provided both with URI and param
715 if ((paramTransferProtocolType != std::nullopt) &&
716 (uriTransferProtocolType != std::nullopt))
717 {
718 // check if protocol is the same for URI and param
719 if (*paramTransferProtocolType != *uriTransferProtocolType)
720 {
721 BMCWEB_LOG_ERROR << "Request action parameter "
722 "TransferProtocolType must contain the "
723 "same protocol type as protocol type "
724 "provided with param imageUrl.";
725
726 messages::actionParameterValueTypeError(
727 asyncResp->res, *actionParams.transferProtocolType,
728 "TransferProtocolType", "InsertMedia");
729
730 return;
731 }
732 }
733
734 // validation passed, add protocol to URI if needed
735 if (uriTransferProtocolType == std::nullopt)
736 {
737 actionParams.imageUrl = getUriWithTransferProtocol(
738 *actionParams.imageUrl, *paramTransferProtocolType);
739 }
740
741 doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
742 !(*actionParams.writeProtected),
743 std::move(*actionParams.userName),
744 std::move(*actionParams.password));
745}
746
747/**
Ed Tanous22db1722021-06-09 10:53:51 -0700748 * @brief Function transceives data with dbus directly.
749 *
750 * All BMC state properties will be retrieved before sending reset request.
751 */
Ed Tanous24e740a2023-02-24 12:08:58 -0800752inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
753 const std::string& service, const std::string& name,
754 bool legacy)
Ed Tanous22db1722021-06-09 10:53:51 -0700755{
756
757 // Legacy mount requires parameter with image
758 if (legacy)
759 {
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100760 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800761 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700762 if (ec)
763 {
764 BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
Ed Tanous22db1722021-06-09 10:53:51 -0700765
Ed Tanous002d39b2022-05-31 08:59:27 -0700766 messages::internalError(asyncResp->res);
767 return;
768 }
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100769 },
770 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
Ed Tanous22db1722021-06-09 10:53:51 -0700771 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200772 }
Ed Tanous22db1722021-06-09 10:53:51 -0700773 else // proxy
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200774 {
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200775 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800776 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700777 if (ec)
778 {
779 BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
Ed Tanous22db1722021-06-09 10:53:51 -0700780
Ed Tanous002d39b2022-05-31 08:59:27 -0700781 messages::internalError(asyncResp->res);
782 return;
783 }
Ed Tanous22db1722021-06-09 10:53:51 -0700784 },
785 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
786 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
787 }
788}
789
Ed Tanous96825be2022-06-03 09:43:38 -0700790inline void handleManagersVirtualMediaActionInsertPost(
791 crow::App& app, const crow::Request& req,
792 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
793 const std::string& name, const std::string& resName)
794{
795 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
796 {
797 return;
798 }
799 if (name != "bmc")
800 {
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200801 messages::resourceNotFound(asyncResp->res, "VirtualMedia.InsertMedia",
Ed Tanous96825be2022-06-03 09:43:38 -0700802 resName);
803
804 return;
805 }
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200806 std::optional<InsertMediaActionParams> actionParams =
807 InsertMediaActionParams();
Ed Tanous96825be2022-06-03 09:43:38 -0700808
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200809 // Read obligatory parameters (url of image)
Ed Tanous96825be2022-06-03 09:43:38 -0700810 if (!json_util::readJsonAction(
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200811 req, asyncResp->res, "Image", actionParams->imageUrl,
812 "WriteProtected", actionParams->writeProtected, "UserName",
813 actionParams->userName, "Password", actionParams->password,
814 "Inserted", actionParams->inserted, "TransferMethod",
815 actionParams->transferMethod, "TransferProtocolType",
816 actionParams->transferProtocolType))
Ed Tanous96825be2022-06-03 09:43:38 -0700817 {
818 return;
819 }
820
George Liu2b731192023-01-11 16:27:13 +0800821 dbus::utility::getDbusObject(
822 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700823 [asyncResp, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800824 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700825 const dbus::utility::MapperGetObject& getObjectType) mutable {
826 if (ec)
827 {
828 BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: " << ec;
829 messages::internalError(asyncResp->res);
830
831 return;
832 }
833 std::string service = getObjectType.begin()->first;
834 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
835
836 crow::connections::systemBus->async_method_call(
837 [service, resName, actionParams,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800838 asyncResp](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700839 dbus::utility::ManagedObjectType& subtree) mutable {
Ed Tanous8a592812022-06-04 09:06:59 -0700840 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700841 {
842 BMCWEB_LOG_DEBUG << "DBUS response error";
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200843 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700844
845 return;
846 }
847
848 for (const auto& object : subtree)
849 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800850 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
851 if (mode == VmMode::Proxy)
Ed Tanous96825be2022-06-03 09:43:38 -0700852 {
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200853 validateParams(asyncResp, service, resName, *actionParams);
Ed Tanous96825be2022-06-03 09:43:38 -0700854
855 return;
856 }
857 }
858 BMCWEB_LOG_DEBUG << "Parent item not found";
859 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
860 },
861 service, "/xyz/openbmc_project/VirtualMedia",
862 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
George Liu2b731192023-01-11 16:27:13 +0800863 });
Ed Tanous96825be2022-06-03 09:43:38 -0700864}
865
866inline void handleManagersVirtualMediaActionEject(
867 crow::App& app, const crow::Request& req,
868 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
869 const std::string& managerName, const std::string& resName)
870{
871 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
872 {
873 return;
874 }
875 if (managerName != "bmc")
876 {
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200877 messages::resourceNotFound(asyncResp->res, "VirtualMedia.EjectMedia",
Ed Tanous96825be2022-06-03 09:43:38 -0700878 resName);
879
880 return;
881 }
882
George Liu2b731192023-01-11 16:27:13 +0800883 dbus::utility::getDbusObject(
884 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700885 [asyncResp,
George Liu2b731192023-01-11 16:27:13 +0800886 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700887 const dbus::utility::MapperGetObject& getObjectType) {
Ed Tanous8a592812022-06-04 09:06:59 -0700888 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700889 {
Ed Tanous8a592812022-06-04 09:06:59 -0700890 BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: " << ec2;
Ed Tanous96825be2022-06-03 09:43:38 -0700891 messages::internalError(asyncResp->res);
892
893 return;
894 }
895 std::string service = getObjectType.begin()->first;
896 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
897
898 crow::connections::systemBus->async_method_call(
Ed Tanous02cad962022-06-30 16:50:15 -0700899 [resName, service, asyncResp{asyncResp}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800900 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700901 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous96825be2022-06-03 09:43:38 -0700902 if (ec)
903 {
904 BMCWEB_LOG_DEBUG << "DBUS response error";
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200905 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700906
907 return;
908 }
909
910 for (const auto& object : subtree)
911 {
Ed Tanous96825be2022-06-03 09:43:38 -0700912
Ed Tanous365a73f2023-02-24 12:16:49 -0800913 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
914 if (mode != VmMode::Invalid)
Ed Tanous96825be2022-06-03 09:43:38 -0700915 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800916 doEjectAction(asyncResp, service, resName,
917 mode == VmMode::Legacy);
Ed Tanous96825be2022-06-03 09:43:38 -0700918 }
919 }
920 BMCWEB_LOG_DEBUG << "Parent item not found";
921 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
922 },
923 service, "/xyz/openbmc_project/VirtualMedia",
924 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
George Liu2b731192023-01-11 16:27:13 +0800925 });
Ed Tanous96825be2022-06-03 09:43:38 -0700926}
927
928inline void handleManagersVirtualMediaCollectionGet(
929 crow::App& app, const crow::Request& req,
930 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
931 const std::string& name)
932{
933 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
934 {
935 return;
936 }
937 if (name != "bmc")
938 {
939 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
940
941 return;
942 }
943
944 asyncResp->res.jsonValue["@odata.type"] =
945 "#VirtualMediaCollection.VirtualMediaCollection";
946 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousfdb20342022-06-03 09:56:52 -0700947 asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
948 "redfish", "v1", "Managers", name, "VirtualMedia");
Ed Tanous96825be2022-06-03 09:43:38 -0700949
George Liu2b731192023-01-11 16:27:13 +0800950 dbus::utility::getDbusObject(
951 "/xyz/openbmc_project/VirtualMedia", {},
952 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700953 const dbus::utility::MapperGetObject& getObjectType) {
954 if (ec)
955 {
956 BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: " << ec;
957 messages::internalError(asyncResp->res);
958
959 return;
960 }
961 std::string service = getObjectType.begin()->first;
962 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
963
964 getVmResourceList(asyncResp, service, name);
George Liu2b731192023-01-11 16:27:13 +0800965 });
Ed Tanous96825be2022-06-03 09:43:38 -0700966}
967
968inline void
969 handleVirtualMediaGet(crow::App& app, const crow::Request& req,
970 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
971 const std::string& name, const std::string& resName)
972{
973 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
974 {
975 return;
976 }
977 if (name != "bmc")
978 {
979 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
980
981 return;
982 }
983
George Liu2b731192023-01-11 16:27:13 +0800984 dbus::utility::getDbusObject(
985 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700986 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800987 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700988 const dbus::utility::MapperGetObject& getObjectType) {
989 if (ec)
990 {
991 BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: " << ec;
992 messages::internalError(asyncResp->res);
993
994 return;
995 }
996 std::string service = getObjectType.begin()->first;
997 BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
998
999 getVmData(asyncResp, service, name, resName);
George Liu2b731192023-01-11 16:27:13 +08001000 });
Ed Tanous96825be2022-06-03 09:43:38 -07001001}
1002
Ed Tanous22db1722021-06-09 10:53:51 -07001003inline void requestNBDVirtualMediaRoutes(App& app)
1004{
George Liu0fda0f12021-11-16 10:06:17 +08001005 BMCWEB_ROUTE(
1006 app,
1007 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -07001008 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -07001009 .methods(boost::beast::http::verb::post)(std::bind_front(
1010 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +02001011
George Liu0fda0f12021-11-16 10:06:17 +08001012 BMCWEB_ROUTE(
1013 app,
1014 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -07001015 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -07001016 .methods(boost::beast::http::verb::post)(std::bind_front(
1017 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -07001018
Ed Tanous22db1722021-06-09 10:53:51 -07001019 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -07001020 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -07001021 .methods(boost::beast::http::verb::get)(std::bind_front(
1022 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +02001023
Ed Tanous22db1722021-06-09 10:53:51 -07001024 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001025 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -07001026 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -07001027 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -07001028}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +02001029
1030} // namespace redfish