|
|
@ -39,11 +39,13 @@ using namespace epee;
|
|
|
|
#include "net/http_client.h" // epee::net_utils::...
|
|
|
|
#include "net/http_client.h" // epee::net_utils::...
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#ifdef WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <shlobj.h>
|
|
|
|
#include <shlobj.h>
|
|
|
|
#include <strsafe.h>
|
|
|
|
#include <strsafe.h>
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#include <sys/file.h>
|
|
|
|
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#include <boost/asio.hpp>
|
|
|
|
#include <boost/asio.hpp>
|
|
|
@ -53,7 +55,12 @@ namespace tools
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::function<void(int)> signal_handler::m_handler;
|
|
|
|
std::function<void(int)> signal_handler::m_handler;
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<std::FILE, tools::close_file> create_private_file(const std::string& name)
|
|
|
|
private_file::private_file() noexcept : m_handle(), m_filename() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private_file::private_file(std::FILE* handle, std::string&& filename) noexcept
|
|
|
|
|
|
|
|
: m_handle(handle), m_filename(std::move(filename)) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private_file private_file::create(std::string name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
#ifdef WIN32
|
|
|
|
struct close_handle
|
|
|
|
struct close_handle
|
|
|
@ -70,17 +77,17 @@ namespace tools
|
|
|
|
const bool fail = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, std::addressof(temp)) == 0;
|
|
|
|
const bool fail = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, std::addressof(temp)) == 0;
|
|
|
|
process.reset(temp);
|
|
|
|
process.reset(temp);
|
|
|
|
if (fail)
|
|
|
|
if (fail)
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD sid_size = 0;
|
|
|
|
DWORD sid_size = 0;
|
|
|
|
GetTokenInformation(process.get(), TokenOwner, nullptr, 0, std::addressof(sid_size));
|
|
|
|
GetTokenInformation(process.get(), TokenOwner, nullptr, 0, std::addressof(sid_size));
|
|
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<char[]> sid{new char[sid_size]};
|
|
|
|
std::unique_ptr<char[]> sid{new char[sid_size]};
|
|
|
|
if (!GetTokenInformation(process.get(), TokenOwner, sid.get(), sid_size, std::addressof(sid_size)))
|
|
|
|
if (!GetTokenInformation(process.get(), TokenOwner, sid.get(), sid_size, std::addressof(sid_size)))
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
const PSID psid = reinterpret_cast<const PTOKEN_OWNER>(sid.get())->Owner;
|
|
|
|
const PSID psid = reinterpret_cast<const PTOKEN_OWNER>(sid.get())->Owner;
|
|
|
|
const DWORD daclSize =
|
|
|
|
const DWORD daclSize =
|
|
|
@ -88,17 +95,17 @@ namespace tools
|
|
|
|
|
|
|
|
|
|
|
|
const std::unique_ptr<char[]> dacl{new char[daclSize]};
|
|
|
|
const std::unique_ptr<char[]> dacl{new char[daclSize]};
|
|
|
|
if (!InitializeAcl(reinterpret_cast<PACL>(dacl.get()), daclSize, ACL_REVISION))
|
|
|
|
if (!InitializeAcl(reinterpret_cast<PACL>(dacl.get()), daclSize, ACL_REVISION))
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
if (!AddAccessAllowedAce(reinterpret_cast<PACL>(dacl.get()), ACL_REVISION, (READ_CONTROL | FILE_GENERIC_READ | DELETE), psid))
|
|
|
|
if (!AddAccessAllowedAce(reinterpret_cast<PACL>(dacl.get()), ACL_REVISION, (READ_CONTROL | FILE_GENERIC_READ | DELETE), psid))
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
SECURITY_DESCRIPTOR descriptor{};
|
|
|
|
SECURITY_DESCRIPTOR descriptor{};
|
|
|
|
if (!InitializeSecurityDescriptor(std::addressof(descriptor), SECURITY_DESCRIPTOR_REVISION))
|
|
|
|
if (!InitializeSecurityDescriptor(std::addressof(descriptor), SECURITY_DESCRIPTOR_REVISION))
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
if (!SetSecurityDescriptorDacl(std::addressof(descriptor), true, reinterpret_cast<PACL>(dacl.get()), false))
|
|
|
|
if (!SetSecurityDescriptorDacl(std::addressof(descriptor), true, reinterpret_cast<PACL>(dacl.get()), false))
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
|
|
SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false};
|
|
|
|
SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false};
|
|
|
|
std::unique_ptr<void, close_handle> file{
|
|
|
|
std::unique_ptr<void, close_handle> file{
|
|
|
@ -106,7 +113,7 @@ namespace tools
|
|
|
|
name.c_str(),
|
|
|
|
name.c_str(),
|
|
|
|
GENERIC_WRITE, FILE_SHARE_READ,
|
|
|
|
GENERIC_WRITE, FILE_SHARE_READ,
|
|
|
|
std::addressof(attributes),
|
|
|
|
std::addressof(attributes),
|
|
|
|
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
|
|
|
|
CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE),
|
|
|
|
nullptr
|
|
|
|
nullptr
|
|
|
|
)
|
|
|
|
)
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -121,22 +128,49 @@ namespace tools
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_close(fd);
|
|
|
|
_close(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {real_file, tools::close_file{}};
|
|
|
|
return {real_file, std::move(name)};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
const int fd = open(name.c_str(), (O_RDWR | O_EXCL | O_CREAT), S_IRUSR);
|
|
|
|
const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR);
|
|
|
|
if (0 <= fd)
|
|
|
|
if (0 <= fdr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct stat rstats = {};
|
|
|
|
|
|
|
|
if (fstat(fdr, std::addressof(rstats)) != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
close(fdr);
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fchmod(fdr, (S_IRUSR | S_IWUSR));
|
|
|
|
|
|
|
|
const int fdw = open(name.c_str(), O_RDWR);
|
|
|
|
|
|
|
|
fchmod(fdr, rstats.st_mode);
|
|
|
|
|
|
|
|
close(fdr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (0 <= fdw)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::FILE* file = fdopen(fd, "w");
|
|
|
|
struct stat wstats = {};
|
|
|
|
if (!file)
|
|
|
|
if (fstat(fdw, std::addressof(wstats)) == 0 &&
|
|
|
|
|
|
|
|
rstats.st_dev == wstats.st_dev && rstats.st_ino == wstats.st_ino &&
|
|
|
|
|
|
|
|
flock(fdw, (LOCK_EX | LOCK_NB)) == 0 && ftruncate(fdw, 0) == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
close(fd);
|
|
|
|
std::FILE* file = fdopen(fdw, "w");
|
|
|
|
|
|
|
|
if (file) return {file, std::move(name)};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
close(fdw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {file, tools::close_file{}};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
return nullptr;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private_file::~private_file() noexcept
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
boost::system::error_code ec{};
|
|
|
|
|
|
|
|
boost::filesystem::remove(filename(), ec);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (...) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#ifdef WIN32
|
|
|
|