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