aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2016-12-16 18:08:24 -0500
committerLee Clagett <code@leeclagett.com>2016-12-16 23:59:46 -0500
commit427054c3d50198dff65b5e003165b1f564ebd26f (patch)
tree185a13198aa77320c1b5220497f27366ecbb3465 /src/common
parentMerge pull request #1459 (diff)
downloadmonero-427054c3d50198dff65b5e003165b1f564ebd26f.tar.xz
Enabled HTTP auth support for monero-wallet-rpc
Diffstat (limited to 'src/common')
-rw-r--r--src/common/boost_serialization_helper.h8
-rw-r--r--src/common/util.cpp86
-rw-r--r--src/common/util.h27
3 files changed, 111 insertions, 10 deletions
diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h
index c640a1705..bf0023471 100644
--- a/src/common/boost_serialization_helper.h
+++ b/src/common/boost_serialization_helper.h
@@ -53,8 +53,8 @@ namespace tools
return false;
}
- FILE* data_file_file = _fdopen(data_file_descriptor, "wb");
- if (0 == data_file_file)
+ const std::unique_ptr<FILE, tools::close_file> data_file_file{_fdopen(data_file_descriptor, "wb")};
+ if (nullptr == data_file_file)
{
// Call CloseHandle is not necessary
_close(data_file_descriptor);
@@ -62,11 +62,10 @@ namespace tools
}
// HACK: undocumented constructor, this code may not compile
- std::ofstream data_file(data_file_file);
+ std::ofstream data_file(data_file_file.get());
if (data_file.fail())
{
// Call CloseHandle and _close are not necessary
- fclose(data_file_file);
return false;
}
#else
@@ -85,7 +84,6 @@ namespace tools
#if defined(_MSC_VER)
// To make sure the file is fully stored on disk
::FlushFileBuffers(data_file_handle);
- fclose(data_file_file);
#endif
return true;
diff --git a/src/common/util.cpp b/src/common/util.cpp
index a53a9be52..6dec6af2a 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -50,6 +50,92 @@ namespace tools
{
std::function<void(int)> signal_handler::m_handler;
+ std::unique_ptr<std::FILE, tools::close_file> create_private_file(const std::string& name)
+ {
+#ifdef WIN32
+ struct close_handle
+ {
+ void operator()(HANDLE handle) const noexcept
+ {
+ CloseHandle(handle);
+ }
+ };
+
+ std::unique_ptr<void, close_handle> process = nullptr;
+ {
+ HANDLE temp{};
+ const bool fail = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, std::addressof(temp)) == 0;
+ process.reset(temp);
+ if (fail)
+ return nullptr;
+ }
+
+ DWORD sid_size = 0;
+ GetTokenInformation(process.get(), TokenOwner, nullptr, 0, std::addressof(sid_size));
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return nullptr;
+
+ std::unique_ptr<char[]> sid{new char[sid_size]};
+ if (!GetTokenInformation(process.get(), TokenOwner, sid.get(), sid_size, std::addressof(sid_size)))
+ return nullptr;
+
+ const PSID psid = reinterpret_cast<const PTOKEN_OWNER>(sid.get())->Owner;
+ const DWORD daclSize =
+ sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD);
+
+ const std::unique_ptr<char[]> dacl{new char[daclSize]};
+ if (!InitializeAcl(reinterpret_cast<PACL>(dacl.get()), daclSize, ACL_REVISION))
+ return nullptr;
+
+ if (!AddAccessAllowedAce(reinterpret_cast<PACL>(dacl.get()), ACL_REVISION, (READ_CONTROL | FILE_GENERIC_READ | DELETE), psid))
+ return nullptr;
+
+ SECURITY_DESCRIPTOR descriptor{};
+ if (!InitializeSecurityDescriptor(std::addressof(descriptor), SECURITY_DESCRIPTOR_REVISION))
+ return nullptr;
+
+ if (!SetSecurityDescriptorDacl(std::addressof(descriptor), true, reinterpret_cast<PACL>(dacl.get()), false))
+ return nullptr;
+
+ SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false};
+ std::unique_ptr<void, close_handle> file{
+ CreateFile(
+ name.c_str(),
+ GENERIC_WRITE, FILE_SHARE_READ,
+ std::addressof(attributes),
+ CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
+ nullptr
+ )
+ };
+ if (file)
+ {
+ const int fd = _open_osfhandle(reinterpret_cast<intptr_t>(file.get()), 0);
+ if (0 <= fd)
+ {
+ file.release();
+ std::FILE* real_file = _fdopen(fd, "w");
+ if (!real_file)
+ {
+ _close(fd);
+ }
+ return {real_file, tools::close_file{}};
+ }
+ }
+#else
+ const int fd = open(name.c_str(), (O_RDWR | O_EXCL | O_CREAT), S_IRUSR);
+ if (0 <= fd)
+ {
+ std::FILE* file = fdopen(fd, "w");
+ if (!file)
+ {
+ close(fd);
+ }
+ return {file, tools::close_file{}};
+ }
+#endif
+ return nullptr;
+ }
+
#ifdef WIN32
std::string get_windows_version_display_string()
{
diff --git a/src/common/util.h b/src/common/util.h
index 4fcf66b8f..3bb9a053e 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -30,13 +30,15 @@
#pragma once
-#include <mutex>
-#include <system_error>
-#include <boost/filesystem.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <csignal>
+#include <cstdio>
+#include <functional>
+#include <memory>
+#include <string>
-#include "crypto/crypto.h"
#include "crypto/hash.h"
-#include "misc_language.h"
#include "p2p/p2p_protocol_defs.h"
/*! \brief Various Tools
@@ -46,6 +48,21 @@
*/
namespace tools
{
+ //! Functional class for closing C file handles.
+ struct close_file
+ {
+ void operator()(std::FILE* handle) const noexcept
+ {
+ if (handle)
+ {
+ std::fclose(handle);
+ }
+ }
+ };
+
+ //! \return File only readable by owner. nullptr if `filename` exists.
+ std::unique_ptr<std::FILE, close_file> create_private_file(const std::string& filename);
+
/*! \brief Returns the default data directory.
*
* \details Windows < Vista: C:\\Documents and Settings\\Username\\Application Data\\CRYPTONOTE_NAME