Chromium Code Reviews| 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/verify_config_window_win.h" | 5 #include "remoting/host/verify_config_window_win.h" |
| 6 | 6 |
| 7 #include <atlbase.h> | 7 #include <atlbase.h> |
| 8 #include <atlwin.h> | |
| 8 #include <windows.h> | 9 #include <windows.h> |
| 9 | 10 |
| 10 #include "base/base64.h" | 11 #include "base/base64.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 14 #include "remoting/host/elevated_controller_resource.h" | 15 #include "remoting/host/elevated_controller_resource.h" |
| 15 #include "remoting/protocol/authentication_method.h" | 16 #include "remoting/protocol/authentication_method.h" |
| 16 | 17 |
| 17 namespace remoting { | 18 namespace remoting { |
| 18 | 19 |
| 19 VerifyConfigWindowWin::VerifyConfigWindowWin(const std::string& email, | 20 VerifyConfigWindowWin::VerifyConfigWindowWin(const std::string& email, |
| 20 const std::string& host_id, const std::string& host_secret_hash) | 21 const std::string& host_id, const std::string& host_secret_hash) |
| 21 : hwnd_(NULL), | 22 : email_(email), |
| 22 email_(email), | |
| 23 host_id_(host_id), | 23 host_id_(host_id), |
| 24 host_secret_hash_(host_secret_hash) { | 24 host_secret_hash_(host_secret_hash) { |
| 25 } | 25 } |
| 26 | 26 |
| 27 VerifyConfigWindowWin::~VerifyConfigWindowWin() { | 27 void VerifyConfigWindowWin::OnCancel(UINT code, int id, HWND control) { |
| 28 EndDialog(); | 28 EndDialog(IDCANCEL); |
| 29 } | 29 } |
| 30 | 30 |
| 31 bool VerifyConfigWindowWin::Run() { | 31 void VerifyConfigWindowWin::OnClose() { |
| 32 // TODO(simonmorris): Provide a handle of a parent window for this dialog. | 32 EndDialog(IDCANCEL); |
| 33 return (DialogBoxParam(ATL::_AtlBaseModule.GetModuleInstance(), | |
| 34 MAKEINTRESOURCE(IDD_VERIFY_CONFIG_DIALOG), | |
| 35 NULL, | |
| 36 (DLGPROC)DialogProc, | |
| 37 (LPARAM)this) != 0); | |
| 38 } | 33 } |
| 39 | 34 |
| 40 BOOL CALLBACK VerifyConfigWindowWin::DialogProc(HWND hwnd, UINT msg, | 35 LRESULT VerifyConfigWindowWin::OnInitDialog(HWND wparam, LPARAM lparam) { |
| 41 WPARAM wParam, LPARAM lParam) { | 36 CenterWindow(); |
| 42 VerifyConfigWindowWin* win = NULL; | 37 |
| 43 if (msg == WM_INITDIALOG) { | 38 // TODO(simonmorris): l10n. |
| 44 win = reinterpret_cast<VerifyConfigWindowWin*>(lParam); | 39 SetWindowText(L"Chrome Remote Desktop"); |
| 45 CHECK(win); | 40 |
| 46 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)win); | 41 CWindow email_label(GetDlgItem(IDC_EMAIL_LABEL)); |
| 47 } else { | 42 email_label.SetWindowText(L"Account:"); |
| 48 LONG_PTR lp = GetWindowLongPtr(hwnd, DWLP_USER); | 43 |
| 49 win = reinterpret_cast<VerifyConfigWindowWin*>(lp); | 44 CWindow pin_label(GetDlgItem(IDC_PIN_LABEL)); |
| 50 } | 45 pin_label.SetWindowText(L"PIN:"); |
| 51 if (win == NULL) | 46 |
| 52 return FALSE; | 47 CWindow ok_button(GetDlgItem(IDOK)); |
| 53 return win->OnDialogMessage(hwnd, msg, wParam, lParam); | 48 ok_button.SetWindowText(L"Confirm"); |
| 49 | |
| 50 CWindow cancel_button(GetDlgItem(IDCANCEL)); | |
| 51 cancel_button.SetWindowText(L"Cancel"); | |
| 52 | |
| 53 CWindow message_text(GetDlgItem(IDC_MESSAGE)); | |
| 54 message_text.SetWindowText(L"Please confirm your account and PIN below to " | |
| 55 L"allow access by Chrome Remote Desktop."); | |
| 56 | |
| 57 CWindow email_text(GetDlgItem(IDC_EMAIL)); | |
| 58 email_text.SetWindowText(UTF8ToUTF16(email_).c_str()); | |
| 59 return TRUE; | |
| 54 } | 60 } |
| 55 | 61 |
| 56 BOOL VerifyConfigWindowWin::OnDialogMessage(HWND hwnd, UINT msg, | 62 void VerifyConfigWindowWin::OnOk(UINT code, int id, HWND control) { |
| 57 WPARAM wParam, LPARAM lParam) { | 63 if (VerifyHostSecretHash()) { |
| 58 switch (msg) { | 64 EndDialog(IDOK); |
| 59 case WM_INITDIALOG: | 65 } else { |
| 60 hwnd_ = hwnd; | 66 EndDialog(IDCANCEL); |
| 61 InitDialog(); | |
| 62 return TRUE; | |
| 63 case WM_DESTROY: | |
| 64 ::EndDialog(hwnd, 0); | |
| 65 case WM_COMMAND: | |
| 66 switch (LOWORD(wParam)) { | |
| 67 case IDOK: | |
| 68 ::EndDialog(hwnd, VerifyHostSecretHash()); | |
| 69 hwnd_ = NULL; | |
| 70 return TRUE; | |
| 71 case IDCANCEL: | |
| 72 ::EndDialog(hwnd, 0); | |
| 73 hwnd_ = NULL; | |
| 74 return TRUE; | |
| 75 } | |
| 76 } | |
| 77 return FALSE; | |
| 78 } | |
| 79 | |
| 80 void VerifyConfigWindowWin::InitDialog() { | |
| 81 // TODO(simonmorris): l10n. | |
| 82 SetWindowText(hwnd_, L"Chrome Remote Desktop"); | |
| 83 | |
| 84 HWND hwndOk = GetDlgItem(hwnd_, IDOK); | |
| 85 CHECK(hwndOk); | |
| 86 SetWindowText(hwndOk, L"OK"); | |
| 87 | |
| 88 HWND hwndCancel = GetDlgItem(hwnd_, IDCANCEL); | |
| 89 CHECK(hwndCancel); | |
| 90 SetWindowText(hwndCancel, L"Cancel"); | |
| 91 | |
| 92 HWND hwndMessage = GetDlgItem(hwnd_, IDC_MESSAGE); | |
| 93 CHECK(hwndMessage); | |
| 94 SetWindowText(hwndMessage, L"To confirm that your Chrome Remote Desktop " | |
| 95 L"should be accessible by this account, please enter your PIN below."); | |
| 96 | |
| 97 HWND hwndEmail = GetDlgItem(hwnd_, IDC_EMAIL); | |
| 98 CHECK(hwndEmail); | |
| 99 SetWindowText(hwndEmail, UTF8ToUTF16(email_).c_str()); | |
| 100 | |
| 101 HWND hwndPin = GetDlgItem(hwnd_, IDC_PIN); | |
| 102 CHECK(hwndPin); | |
| 103 SetFocus(hwndPin); | |
| 104 } | |
| 105 | |
| 106 void VerifyConfigWindowWin::EndDialog() { | |
| 107 if (hwnd_) { | |
| 108 ::EndDialog(hwnd_, 0); | |
| 109 hwnd_ = NULL; | |
| 110 } | 67 } |
| 111 } | 68 } |
| 112 | 69 |
| 70 void VerifyConfigWindowWin::CenterWindow() { | |
| 71 // Get the window dimensions. | |
| 72 RECT rect; | |
| 73 if (!GetWindowRect(&rect)) { | |
| 74 return; | |
| 75 } | |
| 76 | |
| 77 // Center against the owner window unless it is minimized or invisible. | |
| 78 HWND owner = ::GetWindow(m_hWnd, GW_OWNER); | |
| 79 if (owner != NULL) { | |
| 80 DWORD style = ::GetWindowLong(owner, GWL_STYLE); | |
| 81 if ((style & WS_MINIMIZE) != 0 || (style & WS_VISIBLE) == 0) { | |
| 82 owner = NULL; | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 // Make sure that the window will not end up split by a monitor's boundary. | |
| 87 RECT area_rect; | |
| 88 if (!::SystemParametersInfo(SPI_GETWORKAREA, NULL, &area_rect, NULL)) { | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 // On a multi-monitor system use the monitor where the owner window is shown. | |
| 93 RECT owner_rect = area_rect; | |
| 94 if (owner != NULL && ::GetWindowRect(owner, &owner_rect)) { | |
| 95 HMONITOR monitor = ::MonitorFromRect(&owner_rect, MONITOR_DEFAULTTONEAREST); | |
| 96 if (monitor != NULL) { | |
| 97 MONITORINFO monitor_info = {0}; | |
| 98 monitor_info.cbSize = sizeof(monitor_info); | |
| 99 if (::GetMonitorInfo(monitor, &monitor_info)) { | |
| 100 area_rect = monitor_info.rcWork; | |
| 101 } | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 LONG width = rect.right - rect.left; | |
| 106 LONG height = rect.bottom - rect.top; | |
| 107 LONG x = (owner_rect.left + owner_rect.right - width) / 2; | |
| 108 LONG y = (owner_rect.top + owner_rect.bottom - height) / 2; | |
| 109 | |
| 110 x = std::max(x, area_rect.left); | |
| 111 if (x + width > area_rect.right) { | |
| 112 x = area_rect.right - width; | |
| 113 } | |
|
simonmorris
2012/05/01 18:25:45
Or just "x = std::min(x, area_rect.right - width);
alexeypa (please no reviews)
2012/05/01 18:30:08
Done.
| |
| 114 y = std::max(y, area_rect.top); | |
| 115 if (y + width > area_rect.bottom) { | |
| 116 y = area_rect.bottom - width; | |
| 117 } | |
|
simonmorris
2012/05/01 18:25:45
Same suggestion.
alexeypa (please no reviews)
2012/05/01 18:30:08
Done.
| |
| 118 | |
| 119 SetWindowPos(NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); | |
| 120 } | |
| 121 | |
| 113 bool VerifyConfigWindowWin::VerifyHostSecretHash() { | 122 bool VerifyConfigWindowWin::VerifyHostSecretHash() { |
| 114 const int kMaxPinLength = 256; | 123 CWindow pin_edit(GetDlgItem(IDC_PIN)); |
| 115 // TODO(simonmorris): Use ATL's string class, if it's more convenient. | 124 |
| 116 scoped_array<WCHAR> pinWSTR(new WCHAR[kMaxPinLength]); | 125 // Get the PIN length. |
| 117 HWND hwndPin = GetDlgItem(hwnd_, IDC_PIN); | 126 int pin_length = pin_edit.GetWindowTextLength(); |
| 118 CHECK(hwndPin); | 127 scoped_array<char16> pin(new char16[pin_length + 1]); |
| 119 GetWindowText(hwndPin, pinWSTR.get(), kMaxPinLength); | 128 |
| 129 // Get the PIN making sure it is NULL terminated even if an error occurs. | |
| 130 int result = pin_edit.GetWindowText(pin.get(), pin_length + 1); | |
| 131 pin[std::min(result, pin_length)] = 0; | |
| 120 | 132 |
| 121 // TODO(simonmorris): This code was copied from host_script_object.cc. | 133 // TODO(simonmorris): This code was copied from host_script_object.cc. |
| 122 // Refactor to use PinIsValid(), from CL 10008092. | 134 // Refactor to use PinIsValid(), from CL 10008092. |
| 123 std::string pin(UTF16ToUTF8(pinWSTR.get())); | |
| 124 std::string hash = protocol::AuthenticationMethod::ApplyHashFunction( | 135 std::string hash = protocol::AuthenticationMethod::ApplyHashFunction( |
| 125 protocol::AuthenticationMethod::HMAC_SHA256, host_id_, pin); | 136 protocol::AuthenticationMethod::HMAC_SHA256, host_id_, |
| 137 UTF16ToUTF8(pin.get())); | |
| 126 std::string hash_base64; | 138 std::string hash_base64; |
| 127 bool base64_result = base::Base64Encode(hash, &hash_base64); | 139 bool base64_result = base::Base64Encode(hash, &hash_base64); |
| 128 if (!base64_result) { | 140 if (!base64_result) { |
| 129 LOG(FATAL) << "Base64Encode failed"; | 141 LOG(FATAL) << "Base64Encode failed"; |
| 130 return false; | 142 return false; |
| 131 } | 143 } |
| 132 hash_base64 = "hmac:" + hash_base64; | 144 hash_base64 = "hmac:" + hash_base64; |
| 133 | 145 |
| 134 return (hash_base64 == host_secret_hash_); | 146 return (hash_base64 == host_secret_hash_); |
| 135 } | 147 } |
| 136 | 148 |
| 137 } // namespace remoting | 149 } // namespace remoting |
| OLD | NEW |