| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/desktop_session_win.h" | 5 #include "remoting/host/desktop_session_win.h" |
| 6 | 6 |
| 7 #include <sddl.h> | 7 #include <sddl.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 // Default dots per inch used by RDP is 96 DPI. | 80 // Default dots per inch used by RDP is 96 DPI. |
| 81 const int kDefaultRdpDpi = 96; | 81 const int kDefaultRdpDpi = 96; |
| 82 | 82 |
| 83 // The session attach notification should arrive within 30 seconds. | 83 // The session attach notification should arrive within 30 seconds. |
| 84 const int kSessionAttachTimeoutSeconds = 30; | 84 const int kSessionAttachTimeoutSeconds = 30; |
| 85 | 85 |
| 86 // The default port number used for establishing an RDP session. | 86 // The default port number used for establishing an RDP session. |
| 87 const int kDefaultRdpPort = 3389; | 87 const int kDefaultRdpPort = 3389; |
| 88 | 88 |
| 89 // Used for validating the required RDP registry values. |
| 90 const int kRdpConnectionsDisabled = 1; |
| 91 const int kNetworkLevelAuthEnabled = 1; |
| 92 const int kSecurityLayerTlsRequired = 2; |
| 93 |
| 89 // The values used to establish RDP connections are stored in the registry. | 94 // The values used to establish RDP connections are stored in the registry. |
| 95 const wchar_t kRdpSettingsKeyName[] = |
| 96 L"SYSTEM\\CurrentControlSet\\Control\\Terminal Server"; |
| 90 const wchar_t kRdpTcpSettingsKeyName[] = L"SYSTEM\\CurrentControlSet\\" | 97 const wchar_t kRdpTcpSettingsKeyName[] = L"SYSTEM\\CurrentControlSet\\" |
| 91 L"Control\\Terminal Server\\WinStations\\RDP-Tcp"; | 98 L"Control\\Terminal Server\\WinStations\\RDP-Tcp"; |
| 92 const wchar_t kRdpPortValueName[] = L"PortNumber"; | 99 const wchar_t kRdpPortValueName[] = L"PortNumber"; |
| 100 const wchar_t kDenyTsConnectionsValueName[] = L"fDenyTSConnections"; |
| 101 const wchar_t kNetworkLevelAuthValueName[] = L"UserAuthentication"; |
| 102 const wchar_t kSecurityLayerValueName[] = L"SecurityLayer"; |
| 93 | 103 |
| 94 // DesktopSession implementation which attaches to the host's physical console. | 104 // DesktopSession implementation which attaches to the host's physical console. |
| 95 // Receives IPC messages from the desktop process, running in the console | 105 // Receives IPC messages from the desktop process, running in the console |
| 96 // session, via |WorkerProcessIpcDelegate|, and monitors console session | 106 // session, via |WorkerProcessIpcDelegate|, and monitors console session |
| 97 // attach/detach events via |WtsConsoleObserver|. | 107 // attach/detach events via |WtsConsoleObserver|. |
| 98 class ConsoleSession : public DesktopSessionWin { | 108 class ConsoleSession : public DesktopSessionWin { |
| 99 public: | 109 public: |
| 100 // Same as DesktopSessionWin(). | 110 // Same as DesktopSessionWin(). |
| 101 ConsoleSession( | 111 ConsoleSession( |
| 102 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, | 112 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 180 |
| 171 // Points to the desktop session object receiving OnRdpXxx() notifications. | 181 // Points to the desktop session object receiving OnRdpXxx() notifications. |
| 172 base::WeakPtr<RdpSession> desktop_session_; | 182 base::WeakPtr<RdpSession> desktop_session_; |
| 173 | 183 |
| 174 // This class must be used on a single thread. | 184 // This class must be used on a single thread. |
| 175 base::ThreadChecker thread_checker_; | 185 base::ThreadChecker thread_checker_; |
| 176 | 186 |
| 177 DISALLOW_COPY_AND_ASSIGN(EventHandler); | 187 DISALLOW_COPY_AND_ASSIGN(EventHandler); |
| 178 }; | 188 }; |
| 179 | 189 |
| 190 // Examines the system settings required to establish an RDP session. |
| 191 // This method returns false if the values are retrieved and any of them would |
| 192 // prevent us from creating an RDP connection. |
| 193 bool VerifyRdpSettings(); |
| 194 |
| 180 // Retrieves a DWORD value from the registry. Returns true on success. | 195 // Retrieves a DWORD value from the registry. Returns true on success. |
| 181 bool RetrieveDwordRegistryValue(const wchar_t* key_name, | 196 bool RetrieveDwordRegistryValue(const wchar_t* key_name, |
| 182 const wchar_t* value_name, | 197 const wchar_t* value_name, |
| 183 DWORD* value); | 198 DWORD* value); |
| 184 | 199 |
| 185 // Used to create an RDP desktop session. | 200 // Used to create an RDP desktop session. |
| 186 base::win::ScopedComPtr<IRdpDesktopSession> rdp_desktop_session_; | 201 base::win::ScopedComPtr<IRdpDesktopSession> rdp_desktop_session_; |
| 187 | 202 |
| 188 // Used to match |rdp_desktop_session_| with the session it is attached to. | 203 // Used to match |rdp_desktop_session_| with the session it is attached to. |
| 189 std::string terminal_id_; | 204 std::string terminal_id_; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 monitor), | 247 monitor), |
| 233 weak_factory_(this) { | 248 weak_factory_(this) { |
| 234 } | 249 } |
| 235 | 250 |
| 236 RdpSession::~RdpSession() { | 251 RdpSession::~RdpSession() { |
| 237 } | 252 } |
| 238 | 253 |
| 239 bool RdpSession::Initialize(const ScreenResolution& resolution) { | 254 bool RdpSession::Initialize(const ScreenResolution& resolution) { |
| 240 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 255 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 241 | 256 |
| 257 if (!VerifyRdpSettings()) { |
| 258 LOG(ERROR) << "Could not create an RDP session due to invalid settings."; |
| 259 return false; |
| 260 } |
| 261 |
| 242 // Create the RDP wrapper object. | 262 // Create the RDP wrapper object. |
| 243 HRESULT result = rdp_desktop_session_.CreateInstance( | 263 HRESULT result = rdp_desktop_session_.CreateInstance( |
| 244 __uuidof(RdpDesktopSession)); | 264 __uuidof(RdpDesktopSession)); |
| 245 if (FAILED(result)) { | 265 if (FAILED(result)) { |
| 246 LOG(ERROR) << "Failed to create RdpSession object, 0x" | 266 LOG(ERROR) << "Failed to create RdpSession object, 0x" |
| 247 << std::hex << result << std::dec << "."; | 267 << std::hex << result << std::dec << "."; |
| 248 return false; | 268 return false; |
| 249 } | 269 } |
| 250 | 270 |
| 251 ScreenResolution local_resolution = resolution; | 271 ScreenResolution local_resolution = resolution; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 // See http://crbug.com/137696. | 334 // See http://crbug.com/137696. |
| 315 NOTIMPLEMENTED(); | 335 NOTIMPLEMENTED(); |
| 316 } | 336 } |
| 317 | 337 |
| 318 void RdpSession::InjectSas() { | 338 void RdpSession::InjectSas() { |
| 319 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 339 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 320 | 340 |
| 321 rdp_desktop_session_->InjectSas(); | 341 rdp_desktop_session_->InjectSas(); |
| 322 } | 342 } |
| 323 | 343 |
| 344 bool RdpSession::VerifyRdpSettings() { |
| 345 // Verify RDP connections are enabled. |
| 346 DWORD deny_ts_connections_flag = 0; |
| 347 if (RetrieveDwordRegistryValue(kRdpSettingsKeyName, |
| 348 kDenyTsConnectionsValueName, |
| 349 &deny_ts_connections_flag) && |
| 350 deny_ts_connections_flag == kRdpConnectionsDisabled) { |
| 351 LOG(ERROR) << "RDP Connections must be enabled."; |
| 352 return false; |
| 353 } |
| 354 |
| 355 // Verify Network Level Authentication is disabled. |
| 356 DWORD network_level_auth_flag = 0; |
| 357 if (RetrieveDwordRegistryValue(kRdpTcpSettingsKeyName, |
| 358 kNetworkLevelAuthValueName, |
| 359 &network_level_auth_flag) && |
| 360 network_level_auth_flag == kNetworkLevelAuthEnabled) { |
| 361 LOG(ERROR) << "Network Level Authentication for RDP must be disabled."; |
| 362 return false; |
| 363 } |
| 364 |
| 365 // Verify Security Layer is not set to TLS. It can be either of the other two |
| 366 // values, but forcing TLS will prevent us from establishing a connection. |
| 367 DWORD security_layer_flag = 0; |
| 368 if (RetrieveDwordRegistryValue(kRdpTcpSettingsKeyName, |
| 369 kSecurityLayerValueName, |
| 370 &security_layer_flag) && |
| 371 security_layer_flag == kSecurityLayerTlsRequired) { |
| 372 LOG(ERROR) << "RDP SecurityLayer must not be set to TLS."; |
| 373 return false; |
| 374 } |
| 375 |
| 376 return true; |
| 377 } |
| 378 |
| 324 bool RdpSession::RetrieveDwordRegistryValue(const wchar_t* key_name, | 379 bool RdpSession::RetrieveDwordRegistryValue(const wchar_t* key_name, |
| 325 const wchar_t* value_name, | 380 const wchar_t* value_name, |
| 326 DWORD* value) { | 381 DWORD* value) { |
| 327 DCHECK(key_name); | 382 DCHECK(key_name); |
| 328 DCHECK(value_name); | 383 DCHECK(value_name); |
| 329 DCHECK(value); | 384 DCHECK(value); |
| 330 | 385 |
| 331 base::win::RegKey key(HKEY_LOCAL_MACHINE, key_name, KEY_READ); | 386 base::win::RegKey key(HKEY_LOCAL_MACHINE, key_name, KEY_READ); |
| 332 if (!key.Valid()) { | 387 if (!key.Valid()) { |
| 333 LOG(WARNING) << "Failed to open key: " << key_name; | 388 LOG(WARNING) << "Failed to open key: " << key_name; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 exploded.hour, | 698 exploded.hour, |
| 644 exploded.minute, | 699 exploded.minute, |
| 645 exploded.second, | 700 exploded.second, |
| 646 exploded.millisecond, | 701 exploded.millisecond, |
| 647 passed.c_str()); | 702 passed.c_str()); |
| 648 | 703 |
| 649 last_timestamp_ = now; | 704 last_timestamp_ = now; |
| 650 } | 705 } |
| 651 | 706 |
| 652 } // namespace remoting | 707 } // namespace remoting |
| OLD | NEW |