Commit 7da9460a authored by joedow's avatar joedow Committed by Commit bot

Removing WinXP and Vista specific code from Chromoting.

Since we no longer support WinXP/WS2K3 and Vista/WS2K8, we can clean up our
code a bit by removing logic and conditions which only apply to those versions.

BUG=607676

Review-Url: https://codereview.chromium.org/2037163002
Cr-Commit-Position: refs/heads/master@{#398169}
parent f164daa4
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/win/message_window.h" #include "base/win/message_window.h"
#include "base/win/scoped_hglobal.h" #include "base/win/scoped_hglobal.h"
#include "base/win/windows_version.h"
#include "remoting/base/constants.h" #include "remoting/base/constants.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "remoting/proto/event.pb.h" #include "remoting/proto/event.pb.h"
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/win/windows_version.h"
#include "remoting/host/client_session_control.h" #include "remoting/host/client_session_control.h"
namespace remoting { namespace remoting {
...@@ -28,11 +27,6 @@ CurtainModeWin::CurtainModeWin() { ...@@ -28,11 +27,6 @@ CurtainModeWin::CurtainModeWin() {
} }
bool CurtainModeWin::Activate() { bool CurtainModeWin::Activate() {
if (base::win::GetVersion() < base::win::VERSION_VISTA) {
LOG(ERROR) << "Curtain mode is not supported on Windows XP/2003";
return false;
}
DWORD session_id; DWORD session_id;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &session_id)) { if (!ProcessIdToSessionId(GetCurrentProcessId(), &session_id)) {
PLOG(ERROR) << "Failed to map the current PID to session ID"; PLOG(ERROR) << "Failed to map the current PID to session ID";
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/values.h" #include "base/values.h"
#include "base/win/scoped_bstr.h" #include "base/win/scoped_bstr.h"
#include "base/win/windows_version.h"
#include "remoting/base/scoped_sc_handle_win.h" #include "remoting/base/scoped_sc_handle_win.h"
#include "remoting/host/branding.h" #include "remoting/host/branding.h"
#include "remoting/host/host_config.h" #include "remoting/host/host_config.h"
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#if defined(OS_WIN) #if defined(OS_WIN)
#include "base/win/registry.h" #include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "remoting/host/pairing_registry_delegate_win.h" #include "remoting/host/pairing_registry_delegate_win.h"
#include "remoting/host/win/elevation_helpers.h" #include "remoting/host/win/elevation_helpers.h"
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/typed_buffer.h" #include "remoting/base/typed_buffer.h"
#include "remoting/host/host_exit_codes.h" #include "remoting/host/host_exit_codes.h"
...@@ -184,9 +183,8 @@ HRESULT ChromotingModule::RevokeClassObjects() { ...@@ -184,9 +183,8 @@ HRESULT ChromotingModule::RevokeClassObjects() {
int RdpDesktopSessionMain() { int RdpDesktopSessionMain() {
// Lower the integrity level to medium, which is the lowest level at which // Lower the integrity level to medium, which is the lowest level at which
// the RDP ActiveX control can run. // the RDP ActiveX control can run.
if (base::win::GetVersion() >= base::win::VERSION_VISTA) { if (!LowerProcessIntegrityLevel(SECURITY_MANDATORY_MEDIUM_RID)) {
if (!LowerProcessIntegrityLevel(SECURITY_MANDATORY_MEDIUM_RID)) return kInitializationFailed;
return kInitializationFailed;
} }
ATL::_ATL_OBJMAP_ENTRY rdp_client_entry[] = { ATL::_ATL_OBJMAP_ENTRY rdp_client_entry[] = {
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/win/windows_version.h"
#include "remoting/host/win/security_descriptor.h" #include "remoting/host/win/security_descriptor.h"
namespace remoting { namespace remoting {
...@@ -16,10 +15,7 @@ namespace remoting { ...@@ -16,10 +15,7 @@ namespace remoting {
bool InitializeComSecurity(const std::string& security_descriptor, bool InitializeComSecurity(const std::string& security_descriptor,
const std::string& mandatory_label, const std::string& mandatory_label,
bool activate_as_activator) { bool activate_as_activator) {
std::string sddl = security_descriptor; std::string sddl = security_descriptor + mandatory_label;
if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
sddl += mandatory_label;
}
// Convert the SDDL description into a security descriptor in absolute format. // Convert the SDDL description into a security descriptor in absolute format.
ScopedSd relative_sd = ConvertSddlToSd(sddl); ScopedSd relative_sd = ConvertSddlToSd(sddl);
......
...@@ -19,14 +19,11 @@ ...@@ -19,14 +19,11 @@
namespace remoting { namespace remoting {
// Initializes COM security of the process applying the passed security // Initializes COM security of the process applying the passed security
// descriptor. The mandatory label is applied if mandatory integrity control is // descriptor. The function configures the following settings:
// supported by the OS (i.e. on Vista and above). The function configures // - Server authenticates that all data received is from the expected client.
// the following settings: // - Server can impersonate clients to check their identity but cannot act on
// - the server authenticates that all data received is from the expected // their behalf.
// client. // - Caller's identity is verified on every call (Dynamic cloaking).
// - the server can impersonate clients to check their identity but cannot act
// on their behalf.
// - the caller's identity is verified on every call (Dynamic cloaking).
// - Unless |activate_as_activator| is true, activations where the server would // - Unless |activate_as_activator| is true, activations where the server would
// run under this process's identity are prohibited. // run under this process's identity are prohibited.
bool InitializeComSecurity(const std::string& security_descriptor, bool InitializeComSecurity(const std::string& security_descriptor,
......
...@@ -5,123 +5,17 @@ ...@@ -5,123 +5,17 @@
#include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/launch_process_with_token.h"
#include <windows.h> #include <windows.h>
#include <stddef.h>
#include <winternl.h>
#include <limits>
#include <memory>
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "base/rand_util.h"
#include "base/scoped_native_library.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "base/win/scoped_process_information.h" #include "base/win/scoped_process_information.h"
#include "base/win/windows_version.h"
using base::win::ScopedHandle; using base::win::ScopedHandle;
namespace { namespace {
const char kCreateProcessDefaultPipeNameFormat[] =
"\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d";
// Undocumented WINSTATIONINFOCLASS value causing
// winsta!WinStationQueryInformationW() to return the name of the pipe for
// requesting cross-session process creation.
const WINSTATIONINFOCLASS kCreateProcessPipeNameClass =
static_cast<WINSTATIONINFOCLASS>(0x21);
const int kPipeBusyWaitTimeoutMs = 2000;
const int kPipeConnectMaxAttempts = 3;
// Terminates the process and closes process and thread handles in
// |process_information| structure.
void CloseHandlesAndTerminateProcess(PROCESS_INFORMATION* process_information) {
if (process_information->hThread) {
CloseHandle(process_information->hThread);
process_information->hThread = nullptr;
}
if (process_information->hProcess) {
TerminateProcess(process_information->hProcess, CONTROL_C_EXIT);
CloseHandle(process_information->hProcess);
process_information->hProcess = nullptr;
}
}
// Connects to the executor server corresponding to |session_id|.
bool ConnectToExecutionServer(uint32_t session_id,
base::win::ScopedHandle* pipe_out) {
base::string16 pipe_name;
// Use winsta!WinStationQueryInformationW() to determine the process creation
// pipe name for the session.
base::FilePath winsta_path(
base::GetNativeLibraryName(base::UTF8ToUTF16("winsta")));
base::ScopedNativeLibrary winsta(winsta_path);
if (winsta.is_valid()) {
PWINSTATIONQUERYINFORMATIONW win_station_query_information =
reinterpret_cast<PWINSTATIONQUERYINFORMATIONW>(
winsta.GetFunctionPointer("WinStationQueryInformationW"));
if (win_station_query_information) {
wchar_t name[MAX_PATH];
ULONG name_length;
if (win_station_query_information(0,
session_id,
kCreateProcessPipeNameClass,
name,
sizeof(name),
&name_length)) {
pipe_name.assign(name);
}
}
}
// Use the default pipe name if we couldn't query its name.
if (pipe_name.empty()) {
pipe_name = base::UTF8ToUTF16(
base::StringPrintf(kCreateProcessDefaultPipeNameFormat, session_id));
}
// Try to connect to the named pipe.
base::win::ScopedHandle pipe;
for (int i = 0; i < kPipeConnectMaxAttempts; ++i) {
pipe.Set(CreateFile(pipe_name.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
nullptr,
OPEN_EXISTING,
0,
nullptr));
if (pipe.IsValid()) {
break;
}
// Cannot continue retrying if error is something other than
// ERROR_PIPE_BUSY.
if (GetLastError() != ERROR_PIPE_BUSY) {
break;
}
// Cannot continue retrying if wait on pipe fails.
if (!WaitNamedPipe(pipe_name.c_str(), kPipeBusyWaitTimeoutMs)) {
break;
}
}
if (!pipe.IsValid()) {
PLOG(ERROR) << "Failed to connect to '" << pipe_name << "'";
return false;
}
*pipe_out = std::move(pipe);
return true;
}
// Copies the process token making it a primary impersonation token. // Copies the process token making it a primary impersonation token.
// The returned handle will have |desired_access| rights. // The returned handle will have |desired_access| rights.
bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) { bool CopyProcessToken(DWORD desired_access, ScopedHandle* token_out) {
...@@ -177,230 +71,6 @@ bool CreatePrivilegedToken(ScopedHandle* token_out) { ...@@ -177,230 +71,6 @@ bool CreatePrivilegedToken(ScopedHandle* token_out) {
return true; return true;
} }
// Fills the process and thread handles in the passed |process_information|
// structure and resume the process if the caller didn't want to suspend it.
bool ProcessCreateProcessResponse(DWORD creation_flags,
PROCESS_INFORMATION* process_information) {
// The execution server does not return handles to the created process and
// thread.
if (!process_information->hProcess) {
// N.B. PROCESS_ALL_ACCESS is different in XP and Vista+ versions of
// the SDK. |desired_access| below is effectively PROCESS_ALL_ACCESS from
// the XP version of the SDK.
DWORD desired_access =
STANDARD_RIGHTS_REQUIRED |
SYNCHRONIZE |
PROCESS_TERMINATE |
PROCESS_CREATE_THREAD |
PROCESS_SET_SESSIONID |
PROCESS_VM_OPERATION |
PROCESS_VM_READ |
PROCESS_VM_WRITE |
PROCESS_DUP_HANDLE |
PROCESS_CREATE_PROCESS |
PROCESS_SET_QUOTA |
PROCESS_SET_INFORMATION |
PROCESS_QUERY_INFORMATION |
PROCESS_SUSPEND_RESUME;
process_information->hProcess =
OpenProcess(desired_access,
FALSE,
process_information->dwProcessId);
if (!process_information->hProcess) {
PLOG(ERROR) << "Failed to open the process "
<< process_information->dwProcessId;
return false;
}
}
if (!process_information->hThread) {
// N.B. THREAD_ALL_ACCESS is different in XP and Vista+ versions of
// the SDK. |desired_access| below is effectively THREAD_ALL_ACCESS from
// the XP version of the SDK.
DWORD desired_access =
STANDARD_RIGHTS_REQUIRED |
SYNCHRONIZE |
THREAD_TERMINATE |
THREAD_SUSPEND_RESUME |
THREAD_GET_CONTEXT |
THREAD_SET_CONTEXT |
THREAD_QUERY_INFORMATION |
THREAD_SET_INFORMATION |
THREAD_SET_THREAD_TOKEN |
THREAD_IMPERSONATE |
THREAD_DIRECT_IMPERSONATION;
process_information->hThread =
OpenThread(desired_access,
FALSE,
process_information->dwThreadId);
if (!process_information->hThread) {
PLOG(ERROR) << "Failed to open the thread "
<< process_information->dwThreadId;
return false;
}
}
// Resume the thread if the caller didn't want to suspend the process.
if ((creation_flags & CREATE_SUSPENDED) == 0) {
if (!ResumeThread(process_information->hThread)) {
PLOG(ERROR) << "Failed to resume the thread "
<< process_information->dwThreadId;
return false;
}
}
return true;
}
// Receives the response to a remote process create request.
bool ReceiveCreateProcessResponse(
HANDLE pipe,
PROCESS_INFORMATION* process_information_out) {
struct CreateProcessResponse {
DWORD size;
BOOL success;
DWORD last_error;
PROCESS_INFORMATION process_information;
};
DWORD bytes;
CreateProcessResponse response;
if (!ReadFile(pipe, &response, sizeof(response), &bytes, nullptr)) {
PLOG(ERROR) << "Failed to receive CreateProcessAsUser response";
return false;
}
// The server sends the data in one chunk so if we didn't received a complete
// answer something bad happend and there is no point in retrying.
if (bytes != sizeof(response)) {
SetLastError(ERROR_RECEIVE_PARTIAL);
return false;
}
if (!response.success) {
SetLastError(response.last_error);
return false;
}
*process_information_out = response.process_information;
return true;
}
// Sends a remote process create request to the execution server.
bool SendCreateProcessRequest(
HANDLE pipe,
const base::FilePath::StringType& application_name,
const base::CommandLine::StringType& command_line,
DWORD creation_flags,
const base::char16* desktop_name) {
// |CreateProcessRequest| structure passes the same parameters to
// the execution server as CreateProcessAsUser() function does. Strings are
// stored as wide strings immediately after the structure. String pointers are
// represented as byte offsets to string data from the beginning of
// the structure.
struct CreateProcessRequest {
DWORD size;
DWORD process_id;
BOOL use_default_token;
HANDLE token;
LPWSTR application_name;
LPWSTR command_line;
SECURITY_ATTRIBUTES process_attributes;
SECURITY_ATTRIBUTES thread_attributes;
BOOL inherit_handles;
DWORD creation_flags;
LPVOID environment;
LPWSTR current_directory;
STARTUPINFOW startup_info;
PROCESS_INFORMATION process_information;
};
base::string16 desktop;
if (desktop_name)
desktop = desktop_name;
// Allocate a large enough buffer to hold the CreateProcessRequest structure
// and three nullptr-terminated string parameters.
size_t size = sizeof(CreateProcessRequest) + sizeof(wchar_t) *
(application_name.size() + command_line.size() + desktop.size() + 3);
std::unique_ptr<char[]> buffer(new char[size]);
memset(buffer.get(), 0, size);
// Marshal the input parameters.
CreateProcessRequest* request =
reinterpret_cast<CreateProcessRequest*>(buffer.get());
request->size = size;
request->process_id = GetCurrentProcessId();
request->use_default_token = TRUE;
// Always pass CREATE_SUSPENDED to avoid a race between the created process
// exiting too soon and OpenProcess() call below.
request->creation_flags = creation_flags | CREATE_SUSPENDED;
request->startup_info.cb = sizeof(request->startup_info);
size_t buffer_offset = sizeof(CreateProcessRequest);
request->application_name = reinterpret_cast<LPWSTR>(buffer_offset);
std::copy(application_name.begin(),
application_name.end(),
reinterpret_cast<wchar_t*>(buffer.get() + buffer_offset));
buffer_offset += (application_name.size() + 1) * sizeof(wchar_t);
request->command_line = reinterpret_cast<LPWSTR>(buffer_offset);
std::copy(command_line.begin(),
command_line.end(),
reinterpret_cast<wchar_t*>(buffer.get() + buffer_offset));
buffer_offset += (command_line.size() + 1) * sizeof(wchar_t);
request->startup_info.lpDesktop =
reinterpret_cast<LPWSTR>(buffer_offset);
std::copy(desktop.begin(),
desktop.end(),
reinterpret_cast<wchar_t*>(buffer.get() + buffer_offset));
// Pass the request to create a process in the target session.
DWORD bytes;
if (!WriteFile(pipe, buffer.get(), size, &bytes, nullptr)) {
PLOG(ERROR) << "Failed to send CreateProcessAsUser request";
return false;
}
return true;
}
// Requests the execution server to create a process in the specified session
// using the default (i.e. Winlogon) token. This routine relies on undocumented
// OS functionality and will likely not work on anything but XP or W2K3.
bool CreateRemoteSessionProcess(
uint32_t session_id,
const base::FilePath::StringType& application_name,
const base::CommandLine::StringType& command_line,
DWORD creation_flags,
const base::char16* desktop_name,
PROCESS_INFORMATION* process_information_out) {
DCHECK_LT(base::win::GetVersion(), base::win::VERSION_VISTA);
base::win::ScopedHandle pipe;
if (!ConnectToExecutionServer(session_id, &pipe))
return false;
if (!SendCreateProcessRequest(pipe.Get(), application_name, command_line,
creation_flags, desktop_name)) {
return false;
}
PROCESS_INFORMATION process_information;
if (!ReceiveCreateProcessResponse(pipe.Get(), &process_information))
return false;
if (!ProcessCreateProcessResponse(creation_flags, &process_information)) {
CloseHandlesAndTerminateProcess(&process_information);
return false;
}
*process_information_out = process_information;
return true;
}
} // namespace } // namespace
namespace remoting { namespace remoting {
...@@ -480,36 +150,6 @@ bool LaunchProcessWithToken(const base::FilePath& binary, ...@@ -480,36 +150,6 @@ bool LaunchProcessWithToken(const base::FilePath& binary,
&startup_info, &startup_info,
&temp_process_info); &temp_process_info);
// CreateProcessAsUser will fail on XP and W2K3 with ERROR_PIPE_NOT_CONNECTED
// if the user hasn't logged to the target session yet. In such a case
// we try to talk to the execution server directly emulating what
// the undocumented and not-exported advapi32!CreateRemoteSessionProcessW()
// function does. The created process will run under Winlogon'a token instead
// of |user_token|. Since Winlogon runs as SYSTEM, this suits our needs.
if (!result &&
GetLastError() == ERROR_PIPE_NOT_CONNECTED &&
base::win::GetVersion() < base::win::VERSION_VISTA) {
DWORD session_id;
DWORD return_length;
result = GetTokenInformation(user_token,
TokenSessionId,
&session_id,
sizeof(session_id),
&return_length);
if (result && session_id != 0) {
result = CreateRemoteSessionProcess(session_id,
application_name,
command_line,
creation_flags,
desktop_name,
&temp_process_info);
} else {
// Restore the error status returned by CreateProcessAsUser().
result = FALSE;
SetLastError(ERROR_PIPE_NOT_CONNECTED);
}
}
if (!result) { if (!result) {
PLOG(ERROR) << "Failed to launch a process with a user token"; PLOG(ERROR) << "Failed to launch a process with a user token";
return false; return false;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "base/location.h" #include "base/location.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/win/windows_version.h"
#include "remoting/host/sas_injector.h" #include "remoting/host/sas_injector.h"
#include "remoting/proto/event.pb.h" #include "remoting/proto/event.pb.h"
#include "third_party/webrtc/modules/desktop_capture/win/desktop.h" #include "third_party/webrtc/modules/desktop_capture/win/desktop.h"
...@@ -89,7 +88,7 @@ class SessionInputInjectorWin::Core ...@@ -89,7 +88,7 @@ class SessionInputInjectorWin::Core
webrtc::ScopedThreadDesktop desktop_; webrtc::ScopedThreadDesktop desktop_;
// Used to inject Secure Attention Sequence on Vista+. // Used to inject Secure Attention Sequence.
base::Closure inject_sas_; base::Closure inject_sas_;
// Used to lock the current session on non-home SKUs of Windows. // Used to lock the current session on non-home SKUs of Windows.
...@@ -156,15 +155,7 @@ void SessionInputInjectorWin::Core::InjectKeyEvent(const KeyEvent& event) { ...@@ -156,15 +155,7 @@ void SessionInputInjectorWin::Core::InjectKeyEvent(const KeyEvent& event) {
if (dom_code == ui::DomCode::DEL && if (dom_code == ui::DomCode::DEL &&
CheckCtrlAndAltArePressed(pressed_keys_)) { CheckCtrlAndAltArePressed(pressed_keys_)) {
VLOG(3) << "Sending Secure Attention Sequence to the session"; VLOG(3) << "Sending Secure Attention Sequence to the session";
execute_action_task_runner_->PostTask(FROM_HERE, inject_sas_);
if (base::win::GetVersion() < base::win::VERSION_VISTA) {
if (!sas_injector_)
sas_injector_ = SasInjector::Create();
if (!sas_injector_->InjectSas())
LOG(ERROR) << "Failed to inject Secure Attention Sequence.";
} else {
execute_action_task_runner_->PostTask(FROM_HERE, inject_sas_);
}
} else if (dom_code == ui::DomCode::US_L && } else if (dom_code == ui::DomCode::US_L &&
IsWinKeyPressed(pressed_keys_)) { IsWinKeyPressed(pressed_keys_)) {
execute_action_task_runner_->PostTask(FROM_HERE, lock_workstation_); execute_action_task_runner_->PostTask(FROM_HERE, lock_workstation_);
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "ipc/attachment_broker.h" #include "ipc/attachment_broker.h"
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_channel_proxy.h"
...@@ -92,34 +91,23 @@ bool CreateRestrictedToken(ScopedHandle* token_out) { ...@@ -92,34 +91,23 @@ bool CreateRestrictedToken(ScopedHandle* token_out) {
if (restricted_token.Init(token.Get()) != ERROR_SUCCESS) if (restricted_token.Init(token.Get()) != ERROR_SUCCESS)
return false; return false;
if (base::win::GetVersion() >= base::win::VERSION_VISTA) { // "SeChangeNotifyPrivilege" is needed to access the machine certificate
// "SeChangeNotifyPrivilege" is needed to access the machine certificate // (including its private key) in the "Local Machine" cert store. This is
// (including its private key) in the "Local Machine" cert store. This is // needed for HTTPS client third-party authentication . But the presence of
// needed for HTTPS client third-party authentication . But the presence of // "SeChangeNotifyPrivilege" also allows it to open and manipulate objects
// "SeChangeNotifyPrivilege" also allows it to open and manipulate objects // owned by the same user. This risk is only mitigated by setting the
// owned by the same user. This risk is only mitigated by setting the // process integrity level to Low.
// process integrity level to Low, which is why it is unsafe to enable std::vector<base::string16> exceptions;
// "SeChangeNotifyPrivilege" on Windows XP where we don't have process exceptions.push_back(base::string16(L"SeChangeNotifyPrivilege"));
// integrity to protect us.
std::vector<base::string16> exceptions; // Remove privileges in the token.
exceptions.push_back(base::string16(L"SeChangeNotifyPrivilege")); if (restricted_token.DeleteAllPrivileges(&exceptions) != ERROR_SUCCESS)
return false;
// Remove privileges in the token.
if (restricted_token.DeleteAllPrivileges(&exceptions) != ERROR_SUCCESS) // Set low integrity level.
return false; if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW) !=
ERROR_SUCCESS) {
// Set low integrity level if supported by the OS. return false;
if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW)
!= ERROR_SUCCESS) {
return false;
}
} else {
// Remove all privileges in the token.
// Since "SeChangeNotifyPrivilege" is among the privileges being removed,
// the network process won't be able to acquire certificates from the local
// machine store. This means third-party authentication won't work.
if (restricted_token.DeleteAllPrivileges(nullptr) != ERROR_SUCCESS)
return false;
} }
// Return the resulting token. // Return the resulting token.
...@@ -145,17 +133,12 @@ bool CreateWindowStationAndDesktop(ScopedSid logon_sid, ...@@ -145,17 +133,12 @@ bool CreateWindowStationAndDesktop(ScopedSid logon_sid,
// Format the security descriptors in SDDL form. // Format the security descriptors in SDDL form.
std::string desktop_sddl = std::string desktop_sddl =
base::StringPrintf(kDesktopSdFormat, logon_sid_string.c_str()); base::StringPrintf(kDesktopSdFormat, logon_sid_string.c_str()) +
kLowIntegrityMandatoryLabel;
std::string window_station_sddl = std::string window_station_sddl =
base::StringPrintf(kWindowStationSdFormat, logon_sid_string.c_str(), base::StringPrintf(kWindowStationSdFormat, logon_sid_string.c_str(),
logon_sid_string.c_str()); logon_sid_string.c_str()) +
kLowIntegrityMandatoryLabel;
// The worker runs at low integrity level. Make sure it will be able to attach
// to the window station and desktop.
if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
desktop_sddl += kLowIntegrityMandatoryLabel;
window_station_sddl += kLowIntegrityMandatoryLabel;
}
// Create the desktop and window station security descriptors. // Create the desktop and window station security descriptors.
ScopedSd desktop_sd = ConvertSddlToSd(desktop_sddl); ScopedSd desktop_sd = ConvertSddlToSd(desktop_sddl);
...@@ -177,9 +160,7 @@ bool CreateWindowStationAndDesktop(ScopedSid logon_sid, ...@@ -177,9 +160,7 @@ bool CreateWindowStationAndDesktop(ScopedSid logon_sid,
// Make sure that a new window station will be created instead of opening // Make sure that a new window station will be created instead of opening
// an existing one. // an existing one.
DWORD window_station_flags = 0; DWORD window_station_flags = CWF_CREATE_ONLY;
if (base::win::GetVersion() >= base::win::VERSION_VISTA)
window_station_flags = CWF_CREATE_ONLY;
// Request full access because this handle will be inherited by the worker // Request full access because this handle will be inherited by the worker
// process which needs full access in order to attach to the window station. // process which needs full access in order to attach to the window station.
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/win/windows_version.h"
#include "ipc/ipc_message.h" #include "ipc/ipc_message.h"
#include "remoting/host/chromoting_messages.h" #include "remoting/host/chromoting_messages.h"
#include "remoting/host/host_exit_codes.h" #include "remoting/host/host_exit_codes.h"
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "ipc/attachment_broker.h" #include "ipc/attachment_broker.h"
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_channel_proxy.h"
...@@ -163,10 +162,6 @@ WtsSessionProcessDelegate::Core::Core( ...@@ -163,10 +162,6 @@ WtsSessionProcessDelegate::Core::Core(
bool WtsSessionProcessDelegate::Core::Initialize(uint32_t session_id) { bool WtsSessionProcessDelegate::Core::Initialize(uint32_t session_id) {
DCHECK(caller_task_runner_->BelongsToCurrentThread()); DCHECK(caller_task_runner_->BelongsToCurrentThread());
// Windows XP does not support elevation.
if (base::win::GetVersion() < base::win::VERSION_VISTA)
launch_elevated_ = false;
if (launch_elevated_) { if (launch_elevated_) {
// GetNamedPipeClientProcessId() is available starting from Vista. // GetNamedPipeClientProcessId() is available starting from Vista.
HMODULE kernel32 = ::GetModuleHandle(L"kernel32.dll"); HMODULE kernel32 = ::GetModuleHandle(L"kernel32.dll");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment