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