1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #pragma once 4 5 #include "logging.hpp" 6 7 #include <boost/asio/buffer.hpp> 8 #include <boost/asio/connect_pipe.hpp> 9 #include <boost/asio/io_context.hpp> 10 #include <boost/asio/readable_pipe.hpp> 11 #include <boost/asio/writable_pipe.hpp> 12 #include <boost/asio/write.hpp> 13 14 #include <array> 15 #include <string> 16 17 // Wrapper for boost::async_pipe ensuring proper pipe cleanup 18 class CredentialsPipe 19 { 20 public: 21 explicit CredentialsPipe(boost::asio::io_context& io) : impl(io), read(io) 22 { 23 boost::system::error_code ec; 24 boost::asio::connect_pipe(read, impl, ec); 25 if (ec) 26 { 27 BMCWEB_LOG_CRITICAL("Failed to connect pipe {}", ec.what()); 28 } 29 } 30 31 CredentialsPipe(const CredentialsPipe&) = delete; 32 CredentialsPipe(CredentialsPipe&&) = delete; 33 CredentialsPipe& operator=(const CredentialsPipe&) = delete; 34 CredentialsPipe& operator=(CredentialsPipe&&) = delete; 35 36 ~CredentialsPipe() 37 { 38 explicit_bzero(user.data(), user.capacity()); 39 explicit_bzero(pass.data(), pass.capacity()); 40 } 41 42 int releaseFd() 43 { 44 return read.release(); 45 } 46 47 template <typename WriteHandler> 48 void asyncWrite(std::string&& username, std::string&& password, 49 WriteHandler&& handler) 50 { 51 user = std::move(username); 52 pass = std::move(password); 53 54 // Add +1 to ensure that the null terminator is included. 55 std::array<boost::asio::const_buffer, 2> buffer{ 56 {{user.data(), user.size() + 1}, {pass.data(), pass.size() + 1}}}; 57 boost::asio::async_write(impl, buffer, 58 std::forward<WriteHandler>(handler)); 59 } 60 61 boost::asio::writable_pipe impl; 62 boost::asio::readable_pipe read; 63 64 private: 65 std::string user; 66 std::string pass; 67 }; 68