1 #pragma once 2 3 #include <boost/asio/buffer.hpp> 4 #include <boost/asio/io_context.hpp> 5 #include <boost/asio/write.hpp> 6 #include <boost/process/async_pipe.hpp> 7 8 #include <array> 9 #include <string> 10 11 // Wrapper for boost::async_pipe ensuring proper pipe cleanup 12 class CredentialsPipe 13 { 14 public: 15 explicit CredentialsPipe(boost::asio::io_context& io) : impl(io) {} 16 17 CredentialsPipe(const CredentialsPipe&) = delete; 18 CredentialsPipe(CredentialsPipe&&) = delete; 19 CredentialsPipe& operator=(const CredentialsPipe&) = delete; 20 CredentialsPipe& operator=(CredentialsPipe&&) = delete; 21 22 ~CredentialsPipe() 23 { 24 explicit_bzero(user.data(), user.capacity()); 25 explicit_bzero(pass.data(), pass.capacity()); 26 } 27 28 int fd() const 29 { 30 return impl.native_source(); 31 } 32 33 template <typename WriteHandler> 34 void asyncWrite(std::string&& username, std::string&& password, 35 WriteHandler&& handler) 36 { 37 user = std::move(username); 38 pass = std::move(password); 39 40 // Add +1 to ensure that the null terminator is included. 41 std::array<boost::asio::const_buffer, 2> buffer{ 42 {{user.data(), user.size() + 1}, {pass.data(), pass.size() + 1}}}; 43 boost::asio::async_write(impl, buffer, 44 std::forward<WriteHandler>(handler)); 45 } 46 47 boost::process::async_pipe impl; 48 49 private: 50 std::string user; 51 std::string pass; 52 }; 53