| Index: remoting/host/security_key/remote_security_key_main.cc
|
| diff --git a/remoting/host/security_key/remote_security_key_main.cc b/remoting/host/security_key/remote_security_key_main.cc
|
| index c68f2e6078453160fa9c18ea004020495f614e4f..b085ed2443f3bd0e3d44a76bbff9ba050a574638 100644
|
| --- a/remoting/host/security_key/remote_security_key_main.cc
|
| +++ b/remoting/host/security_key/remote_security_key_main.cc
|
| @@ -17,10 +17,101 @@
|
| #include "remoting/host/security_key/remote_security_key_ipc_client.h"
|
| #include "remoting/host/security_key/remote_security_key_message_handler.h"
|
|
|
| +#if defined(OS_WIN)
|
| +#include <aclapi.h>
|
| +#include <windows.h>
|
| +
|
| +#include "base/win/scoped_handle.h"
|
| +#endif // defined(OS_WIN)
|
| +
|
| +#if defined(OS_WIN)
|
| +namespace {
|
| +
|
| +bool AddAccessRightForWellKnownSid(WELL_KNOWN_SID_TYPE type, DWORD new_right) {
|
| + // Open a handle for the current process, read the current DACL, update it,
|
| + // and write it back. This will add |new_right| to the current process.
|
| + base::win::ScopedHandle process_handle(OpenProcess(READ_CONTROL | WRITE_DAC,
|
| + /*bInheritHandle=*/FALSE,
|
| + GetCurrentProcessId()));
|
| + if (!process_handle.IsValid()) {
|
| + PLOG(ERROR) << "OpenProcess() failed!";
|
| + return false;
|
| + }
|
| +
|
| + // TODO(joedow): Add a custom deleter to handle objects which are freed via
|
| + // LocalFree(). Tracked by crbug.com/622913
|
| + PSECURITY_DESCRIPTOR descriptor = nullptr;
|
| + // |old_dacl| is a pointer into the opaque |descriptor| struct, don't free it.
|
| + PACL old_dacl = nullptr;
|
| + PACL new_dacl = nullptr;
|
| +
|
| + if (GetSecurityInfo(process_handle.Get(),
|
| + SE_KERNEL_OBJECT,
|
| + DACL_SECURITY_INFORMATION,
|
| + /*ppsidOwner=*/nullptr,
|
| + /*ppsidGroup=*/nullptr,
|
| + &old_dacl,
|
| + /*ppSacl=*/nullptr,
|
| + &descriptor) != ERROR_SUCCESS) {
|
| + PLOG(ERROR) << "GetSecurityInfo() failed!";
|
| + return false;
|
| + }
|
| +
|
| + BYTE buffer[SECURITY_MAX_SID_SIZE] = {0};
|
| + DWORD buffer_size = SECURITY_MAX_SID_SIZE;
|
| + if (!CreateWellKnownSid(type, /*DomainSid=*/nullptr, buffer, &buffer_size)) {
|
| + PLOG(ERROR) << "CreateWellKnownSid() failed!";
|
| + LocalFree(descriptor);
|
| + return false;
|
| + }
|
| +
|
| + SID* sid = reinterpret_cast<SID*>(buffer);
|
| + EXPLICIT_ACCESS new_access = {0};
|
| + new_access.grfAccessMode = GRANT_ACCESS;
|
| + new_access.grfAccessPermissions = new_right;
|
| + new_access.grfInheritance = NO_INHERITANCE;
|
| +
|
| + new_access.Trustee.pMultipleTrustee = nullptr;
|
| + new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
| + new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
| + new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(sid);
|
| +
|
| + if (SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl) != ERROR_SUCCESS) {
|
| + PLOG(ERROR) << "SetEntriesInAcl() failed!";
|
| + LocalFree(descriptor);
|
| + return false;
|
| + }
|
| +
|
| + bool right_added = true;
|
| + if (SetSecurityInfo(process_handle.Get(),
|
| + SE_KERNEL_OBJECT,
|
| + DACL_SECURITY_INFORMATION,
|
| + /*ppsidOwner=*/nullptr,
|
| + /*ppsidGroup=*/nullptr,
|
| + new_dacl,
|
| + /*ppSacl=*/nullptr) != ERROR_SUCCESS) {
|
| + PLOG(ERROR) << "SetSecurityInfo() failed!";
|
| + right_added = false;
|
| + }
|
| +
|
| + LocalFree(new_dacl);
|
| + LocalFree(descriptor);
|
| +
|
| + return right_added;
|
| +}
|
| +
|
| +} // namespace
|
| +#endif // defined(OS_WIN)
|
| +
|
| namespace remoting {
|
|
|
| int StartRemoteSecurityKey() {
|
| #if defined(OS_WIN)
|
| + if (!AddAccessRightForWellKnownSid(WinLocalServiceSid,
|
| + PROCESS_QUERY_LIMITED_INFORMATION)) {
|
| + return kInitializationFailed;
|
| + }
|
| +
|
| // GetStdHandle() returns pseudo-handles for stdin and stdout even if
|
| // the hosting executable specifies "Windows" subsystem. However the returned
|
| // handles are invalid in that case unless standard input and output are
|
|
|