summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEd Tanous <edtanous@google.com>2023-08-25 00:25:18 +0300
committerEd Tanous <ed@tanous.net>2023-09-25 20:50:15 +0300
commit11e8f60df2fbe1ceafdf886132bd93d112a726bf (patch)
treea5a393b6ec81a04d7c021737ca71ba58af1482eb /include
parentb25644a1ae3bbf00ddea91ad494be959cb2632c8 (diff)
downloadbmcweb-11e8f60df2fbe1ceafdf886132bd93d112a726bf.tar.xz
Clean up vm CredentialPipe
This code is needlessly complicated for what it does. Even with the intent, which is secure buffer cleanup, it's trivial to encase all this into a single class that accepts the strings by rvalue reference, then cleans them up afterward. Doing this also cleans up a potential lifetime problem, where if the unix socket returned immediately, it would've invalidated the buffers that were being sent. It also moves to async_write, instead of async_write_some. The former could in theory fail if the socket blocks (unlikely in this scenario) but it's good to handle anyway. Tested: Need some help here. There's no backend for this, so we might just have to rely on inspection. Change-Id: I9032d458f8eb7a0689bee575aae611641bacee26 Signed-off-by: Ed Tanous <edtanous@google.com>
Diffstat (limited to 'include')
-rw-r--r--include/credential_pipe.hpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/include/credential_pipe.hpp b/include/credential_pipe.hpp
new file mode 100644
index 0000000000..169d47c6cb
--- /dev/null
+++ b/include/credential_pipe.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/write.hpp>
+#include <boost/process/async_pipe.hpp>
+
+#include <array>
+#include <string>
+
+// Wrapper for boost::async_pipe ensuring proper pipe cleanup
+class CredentialsPipe
+{
+ public:
+ explicit CredentialsPipe(boost::asio::io_context& io) : impl(io) {}
+
+ CredentialsPipe(const CredentialsPipe&) = delete;
+ CredentialsPipe(CredentialsPipe&&) = delete;
+ CredentialsPipe& operator=(const CredentialsPipe&) = delete;
+ CredentialsPipe& operator=(CredentialsPipe&&) = delete;
+
+ ~CredentialsPipe()
+ {
+ explicit_bzero(user.data(), user.capacity());
+ explicit_bzero(pass.data(), pass.capacity());
+ }
+
+ int fd() const
+ {
+ return impl.native_source();
+ }
+
+ template <typename WriteHandler>
+ void asyncWrite(std::string&& username, std::string&& password,
+ WriteHandler&& handler)
+ {
+ user = std::move(username);
+ pass = std::move(password);
+
+ // Add +1 to ensure that the null terminator is included.
+ std::array<boost::asio::const_buffer, 2> buffer{
+ {{user.data(), user.size() + 1}, {pass.data(), pass.size() + 1}}};
+ boost::asio::async_write(impl, buffer,
+ std::forward<WriteHandler>(handler));
+ }
+
+ boost::process::async_pipe impl;
+
+ private:
+ std::string user;
+ std::string pass;
+};