X-Git-Url: https://git.josue.xyz/?p=VSoRC%2F.git;a=blobdiff_plain;f=node_modules%2Fnode-pty%2Fdeps%2Fwinpty%2Fsrc%2Fshared%2FWindowsSecurity.cc;fp=node_modules%2Fnode-pty%2Fdeps%2Fwinpty%2Fsrc%2Fshared%2FWindowsSecurity.cc;h=0000000000000000000000000000000000000000;hp=711a8637c8cb82e74179d9505e0f87cadeecec2f;hb=5e96dd57ddd883604e87f62bdddcb111c63a6e1a;hpb=acb5f682a2b75b972710cabd81658f63071324b0 diff --git a/node_modules/node-pty/deps/winpty/src/shared/WindowsSecurity.cc b/node_modules/node-pty/deps/winpty/src/shared/WindowsSecurity.cc deleted file mode 100644 index 711a863..0000000 --- a/node_modules/node-pty/deps/winpty/src/shared/WindowsSecurity.cc +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (c) 2016 Ryan Prichard -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -#include "WindowsSecurity.h" - -#include - -#include "DebugClient.h" -#include "OsModule.h" -#include "OwnedHandle.h" -#include "StringBuilder.h" -#include "WindowsVersion.h" -#include "WinptyAssert.h" -#include "WinptyException.h" - -namespace { - -struct LocalFreer { - void operator()(void *ptr) { - if (ptr != nullptr) { - LocalFree(reinterpret_cast(ptr)); - } - } -}; - -typedef std::unique_ptr PointerLocal; - -template -SecurityItem localItem(typename T::type v) { - typedef typename T::type P; - struct Impl : SecurityItem::Impl { - P m_v; - Impl(P v) : m_v(v) {} - virtual ~Impl() { - LocalFree(reinterpret_cast(m_v)); - } - }; - return SecurityItem(v, std::unique_ptr(new Impl { v })); -} - -Sid allocatedSid(PSID v) { - struct Impl : Sid::Impl { - PSID m_v; - Impl(PSID v) : m_v(v) {} - virtual ~Impl() { - if (m_v != nullptr) { - FreeSid(m_v); - } - } - }; - return Sid(v, std::unique_ptr(new Impl { v })); -} - -} // anonymous namespace - -// Returns a handle to the thread's effective security token. If the thread -// is impersonating another user, its token is returned, and otherwise, the -// process' security token is opened. The handle is opened with TOKEN_QUERY. -static OwnedHandle openSecurityTokenForQuery() { - HANDLE token = nullptr; - // It is unclear to me whether OpenAsSelf matters for winpty, or what the - // most appropriate value is. - if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, - /*OpenAsSelf=*/FALSE, &token)) { - if (GetLastError() != ERROR_NO_TOKEN) { - throwWindowsError(L"OpenThreadToken failed"); - } - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { - throwWindowsError(L"OpenProcessToken failed"); - } - } - ASSERT(token != nullptr && - "OpenThreadToken/OpenProcessToken token is NULL"); - return OwnedHandle(token); -} - -// Returns the TokenOwner of the thread's effective security token. -Sid getOwnerSid() { - struct Impl : Sid::Impl { - std::unique_ptr buffer; - }; - - OwnedHandle token = openSecurityTokenForQuery(); - DWORD actual = 0; - BOOL success; - success = GetTokenInformation(token.get(), TokenOwner, - nullptr, 0, &actual); - if (success) { - throwWinptyException(L"getOwnerSid: GetTokenInformation: " - L"expected ERROR_INSUFFICIENT_BUFFER"); - } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - throwWindowsError(L"getOwnerSid: GetTokenInformation: " - L"expected ERROR_INSUFFICIENT_BUFFER"); - } - std::unique_ptr impl(new Impl); - impl->buffer = std::unique_ptr(new char[actual]); - success = GetTokenInformation(token.get(), TokenOwner, - impl->buffer.get(), actual, &actual); - if (!success) { - throwWindowsError(L"getOwnerSid: GetTokenInformation"); - } - TOKEN_OWNER tmp; - ASSERT(actual >= sizeof(tmp)); - std::copy( - impl->buffer.get(), - impl->buffer.get() + sizeof(tmp), - reinterpret_cast(&tmp)); - return Sid(tmp.Owner, std::move(impl)); -} - -Sid wellKnownSid( - const wchar_t *debuggingName, - SID_IDENTIFIER_AUTHORITY authority, - BYTE authorityCount, - DWORD subAuthority0/*=0*/, - DWORD subAuthority1/*=0*/) { - PSID psid = nullptr; - if (!AllocateAndInitializeSid(&authority, authorityCount, - subAuthority0, - subAuthority1, - 0, 0, 0, 0, 0, 0, - &psid)) { - const auto err = GetLastError(); - const auto msg = - std::wstring(L"wellKnownSid: error getting ") + - debuggingName + L" SID"; - throwWindowsError(msg.c_str(), err); - } - return allocatedSid(psid); -} - -Sid builtinAdminsSid() { - // S-1-5-32-544 - SID_IDENTIFIER_AUTHORITY authority = { SECURITY_NT_AUTHORITY }; - return wellKnownSid(L"BUILTIN\\Administrators group", - authority, 2, - SECURITY_BUILTIN_DOMAIN_RID, // 32 - DOMAIN_ALIAS_RID_ADMINS); // 544 -} - -Sid localSystemSid() { - // S-1-5-18 - SID_IDENTIFIER_AUTHORITY authority = { SECURITY_NT_AUTHORITY }; - return wellKnownSid(L"LocalSystem account", - authority, 1, - SECURITY_LOCAL_SYSTEM_RID); // 18 -} - -Sid everyoneSid() { - // S-1-1-0 - SID_IDENTIFIER_AUTHORITY authority = { SECURITY_WORLD_SID_AUTHORITY }; - return wellKnownSid(L"Everyone account", - authority, 1, - SECURITY_WORLD_RID); // 0 -} - -static SecurityDescriptor finishSecurityDescriptor( - size_t daclEntryCount, - EXPLICIT_ACCESSW *daclEntries, - Acl &outAcl) { - { - PACL aclRaw = nullptr; - DWORD aclError = - SetEntriesInAclW(daclEntryCount, - daclEntries, - nullptr, &aclRaw); - if (aclError != ERROR_SUCCESS) { - WStringBuilder sb(64); - sb << L"finishSecurityDescriptor: " - << L"SetEntriesInAcl failed: " << aclError; - throwWinptyException(sb.c_str()); - } - outAcl = localItem(aclRaw); - } - - const PSECURITY_DESCRIPTOR sdRaw = - reinterpret_cast( - LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH)); - if (sdRaw == nullptr) { - throwWinptyException(L"finishSecurityDescriptor: LocalAlloc failed"); - } - SecurityDescriptor sd = localItem(sdRaw); - if (!InitializeSecurityDescriptor(sdRaw, SECURITY_DESCRIPTOR_REVISION)) { - throwWindowsError( - L"finishSecurityDescriptor: InitializeSecurityDescriptor"); - } - if (!SetSecurityDescriptorDacl(sdRaw, TRUE, outAcl.get(), FALSE)) { - throwWindowsError( - L"finishSecurityDescriptor: SetSecurityDescriptorDacl"); - } - - return std::move(sd); -} - -// Create a security descriptor that grants full control to the local system -// account, built-in administrators, and the owner. -SecurityDescriptor -createPipeSecurityDescriptorOwnerFullControl() { - - struct Impl : SecurityDescriptor::Impl { - Sid localSystem; - Sid builtinAdmins; - Sid owner; - std::array daclEntries = {}; - Acl dacl; - SecurityDescriptor value; - }; - - std::unique_ptr impl(new Impl); - impl->localSystem = localSystemSid(); - impl->builtinAdmins = builtinAdminsSid(); - impl->owner = getOwnerSid(); - - for (auto &ea : impl->daclEntries) { - ea.grfAccessPermissions = GENERIC_ALL; - ea.grfAccessMode = SET_ACCESS; - ea.grfInheritance = NO_INHERITANCE; - ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; - } - impl->daclEntries[0].Trustee.ptstrName = - reinterpret_cast(impl->localSystem.get()); - impl->daclEntries[1].Trustee.ptstrName = - reinterpret_cast(impl->builtinAdmins.get()); - impl->daclEntries[2].Trustee.ptstrName = - reinterpret_cast(impl->owner.get()); - - impl->value = finishSecurityDescriptor( - impl->daclEntries.size(), - impl->daclEntries.data(), - impl->dacl); - - const auto retValue = impl->value.get(); - return SecurityDescriptor(retValue, std::move(impl)); -} - -SecurityDescriptor -createPipeSecurityDescriptorOwnerFullControlEveryoneWrite() { - - struct Impl : SecurityDescriptor::Impl { - Sid localSystem; - Sid builtinAdmins; - Sid owner; - Sid everyone; - std::array daclEntries = {}; - Acl dacl; - SecurityDescriptor value; - }; - - std::unique_ptr impl(new Impl); - impl->localSystem = localSystemSid(); - impl->builtinAdmins = builtinAdminsSid(); - impl->owner = getOwnerSid(); - impl->everyone = everyoneSid(); - - for (auto &ea : impl->daclEntries) { - ea.grfAccessPermissions = GENERIC_ALL; - ea.grfAccessMode = SET_ACCESS; - ea.grfInheritance = NO_INHERITANCE; - ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; - } - impl->daclEntries[0].Trustee.ptstrName = - reinterpret_cast(impl->localSystem.get()); - impl->daclEntries[1].Trustee.ptstrName = - reinterpret_cast(impl->builtinAdmins.get()); - impl->daclEntries[2].Trustee.ptstrName = - reinterpret_cast(impl->owner.get()); - impl->daclEntries[3].Trustee.ptstrName = - reinterpret_cast(impl->everyone.get()); - // Avoid using FILE_GENERIC_WRITE because it includes FILE_APPEND_DATA, - // which is equal to FILE_CREATE_PIPE_INSTANCE. Instead, include all the - // flags that comprise FILE_GENERIC_WRITE, except for the one. - impl->daclEntries[3].grfAccessPermissions = - FILE_GENERIC_READ | - FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA | - STANDARD_RIGHTS_WRITE | SYNCHRONIZE; - - impl->value = finishSecurityDescriptor( - impl->daclEntries.size(), - impl->daclEntries.data(), - impl->dacl); - - const auto retValue = impl->value.get(); - return SecurityDescriptor(retValue, std::move(impl)); -} - -SecurityDescriptor getObjectSecurityDescriptor(HANDLE handle) { - PACL dacl = nullptr; - PSECURITY_DESCRIPTOR sd = nullptr; - const DWORD errCode = GetSecurityInfo(handle, SE_KERNEL_OBJECT, - OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, - nullptr, nullptr, &dacl, nullptr, &sd); - if (errCode != ERROR_SUCCESS) { - throwWindowsError(L"GetSecurityInfo failed"); - } - return localItem(sd); -} - -// The (SID/SD)<->string conversion APIs are useful for testing/debugging, so -// create convenient accessor functions for them. They're too slow for -// ordinary use. The APIs exist in XP and up, but the MinGW headers only -// declare the SID<->string APIs, not the SD APIs. MinGW also gets the -// prototype wrong for ConvertStringSidToSidW (LPWSTR instead of LPCWSTR) and -// requires WINVER to be defined. MSVC and MinGW-w64 get everything right, but -// for consistency, use LoadLibrary/GetProcAddress for all four APIs. - -typedef BOOL WINAPI ConvertStringSidToSidW_t( - LPCWSTR StringSid, - PSID *Sid); - -typedef BOOL WINAPI ConvertSidToStringSidW_t( - PSID Sid, - LPWSTR *StringSid); - -typedef BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW_t( - LPCWSTR StringSecurityDescriptor, - DWORD StringSDRevision, - PSECURITY_DESCRIPTOR *SecurityDescriptor, - PULONG SecurityDescriptorSize); - -typedef BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW_t( - PSECURITY_DESCRIPTOR SecurityDescriptor, - DWORD RequestedStringSDRevision, - SECURITY_INFORMATION SecurityInformation, - LPWSTR *StringSecurityDescriptor, - PULONG StringSecurityDescriptorLen); - -#define GET_MODULE_PROC(mod, funcName) \ - const auto p##funcName = \ - reinterpret_cast( \ - mod.proc(#funcName)); \ - if (p##funcName == nullptr) { \ - throwWinptyException( \ - L"" L ## #funcName L" API is missing from ADVAPI32.DLL"); \ - } - -const DWORD kSDDL_REVISION_1 = 1; - -std::wstring sidToString(PSID sid) { - OsModule advapi32(L"advapi32.dll"); - GET_MODULE_PROC(advapi32, ConvertSidToStringSidW); - wchar_t *sidString = NULL; - BOOL success = pConvertSidToStringSidW(sid, &sidString); - if (!success) { - throwWindowsError(L"ConvertSidToStringSidW failed"); - } - PointerLocal freer(sidString); - return std::wstring(sidString); -} - -Sid stringToSid(const std::wstring &str) { - // Cast the string from const wchar_t* to LPWSTR because the function is - // incorrectly prototyped in the MinGW sddl.h header. The API does not - // modify the string -- it is correctly prototyped as taking LPCWSTR in - // MinGW-w64, MSVC, and MSDN. - OsModule advapi32(L"advapi32.dll"); - GET_MODULE_PROC(advapi32, ConvertStringSidToSidW); - PSID psid = nullptr; - BOOL success = pConvertStringSidToSidW(const_cast(str.c_str()), - &psid); - if (!success) { - const auto err = GetLastError(); - throwWindowsError( - (std::wstring(L"ConvertStringSidToSidW failed on \"") + - str + L'"').c_str(), - err); - } - return localItem(psid); -} - -SecurityDescriptor stringToSd(const std::wstring &str) { - OsModule advapi32(L"advapi32.dll"); - GET_MODULE_PROC(advapi32, ConvertStringSecurityDescriptorToSecurityDescriptorW); - PSECURITY_DESCRIPTOR desc = nullptr; - if (!pConvertStringSecurityDescriptorToSecurityDescriptorW( - str.c_str(), kSDDL_REVISION_1, &desc, nullptr)) { - const auto err = GetLastError(); - throwWindowsError( - (std::wstring(L"ConvertStringSecurityDescriptorToSecurityDescriptorW failed on \"") + - str + L'"').c_str(), - err); - } - return localItem(desc); -} - -std::wstring sdToString(PSECURITY_DESCRIPTOR sd) { - OsModule advapi32(L"advapi32.dll"); - GET_MODULE_PROC(advapi32, ConvertSecurityDescriptorToStringSecurityDescriptorW); - wchar_t *sdString = nullptr; - if (!pConvertSecurityDescriptorToStringSecurityDescriptorW( - sd, - kSDDL_REVISION_1, - OWNER_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, - &sdString, - nullptr)) { - throwWindowsError( - L"ConvertSecurityDescriptorToStringSecurityDescriptor failed"); - } - PointerLocal freer(sdString); - return std::wstring(sdString); -} - -// Vista added a useful flag to CreateNamedPipe, PIPE_REJECT_REMOTE_CLIENTS, -// that rejects remote connections. Return this flag on Vista, or return 0 -// otherwise. -DWORD rejectRemoteClientsPipeFlag() { - if (isAtLeastWindowsVista()) { - // MinGW lacks this flag; MinGW-w64 has it. - const DWORD kPIPE_REJECT_REMOTE_CLIENTS = 8; - return kPIPE_REJECT_REMOTE_CLIENTS; - } else { - trace("Omitting PIPE_REJECT_REMOTE_CLIENTS on pre-Vista OS"); - return 0; - } -} - -typedef BOOL WINAPI GetNamedPipeClientProcessId_t( - HANDLE Pipe, - PULONG ClientProcessId); - -std::tuple -getNamedPipeClientProcessId(HANDLE serverPipe) { - OsModule kernel32(L"kernel32.dll"); - const auto pGetNamedPipeClientProcessId = - reinterpret_cast( - kernel32.proc("GetNamedPipeClientProcessId")); - if (pGetNamedPipeClientProcessId == nullptr) { - return std::make_tuple( - GetNamedPipeClientProcessId_Result::UnsupportedOs, 0, 0); - } - ULONG pid = 0; - if (!pGetNamedPipeClientProcessId(serverPipe, &pid)) { - return std::make_tuple( - GetNamedPipeClientProcessId_Result::Failure, 0, GetLastError()); - } - return std::make_tuple( - GetNamedPipeClientProcessId_Result::Success, - static_cast(pid), - 0); -}