xref: /openbmc/bmcweb/include/credential_pipe.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
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 <cstring>
16 #include <string>
17 #include <utility>
18 
19 // Wrapper for boost::async_pipe ensuring proper pipe cleanup
20 class CredentialsPipe
21 {
22   public:
CredentialsPipe(boost::asio::io_context & io)23     explicit CredentialsPipe(boost::asio::io_context& io) : impl(io), read(io)
24     {
25         boost::system::error_code ec;
26 
27         // Unclear why tidy complains here.
28         // NOLINTNEXTLINE(misc-include-cleaner)
29         boost::asio::connect_pipe(read, impl, ec);
30         if (ec)
31         {
32             BMCWEB_LOG_CRITICAL("Failed to connect pipe {}", ec.what());
33         }
34     }
35 
36     CredentialsPipe(const CredentialsPipe&) = delete;
37     CredentialsPipe(CredentialsPipe&&) = delete;
38     CredentialsPipe& operator=(const CredentialsPipe&) = delete;
39     CredentialsPipe& operator=(CredentialsPipe&&) = delete;
40 
~CredentialsPipe()41     ~CredentialsPipe()
42     {
43         // NOLINTNEXTLINE(misc-include-cleaner)
44         explicit_bzero(user.data(), user.capacity());
45         explicit_bzero(pass.data(), pass.capacity());
46     }
47 
releaseFd()48     int releaseFd()
49     {
50         return read.release();
51     }
52 
53     template <typename WriteHandler>
asyncWrite(std::string && username,std::string && password,WriteHandler && handler)54     void asyncWrite(std::string&& username, std::string&& password,
55                     WriteHandler&& handler)
56     {
57         user = std::move(username);
58         pass = std::move(password);
59 
60         // Add +1 to ensure that the null terminator is included.
61         std::array<boost::asio::const_buffer, 2> buffer{
62             {{user.data(), user.size() + 1}, {pass.data(), pass.size() + 1}}};
63         boost::asio::async_write(impl, buffer,
64                                  std::forward<WriteHandler>(handler));
65     }
66 
67     boost::asio::writable_pipe impl;
68     boost::asio::readable_pipe read;
69 
70   private:
71     std::string user;
72     std::string pass;
73 };
74