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