Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: chrome/browser/password_manager/password_manager_util_win.cc

Issue 34393007: [Win] Add option to reauthenticate the OS user before revealing passwords. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@password
Patch Set: enable reauthentication flag on Windows Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // windows.h must be first otherwise Win8 SDK breaks.
6 #include <windows.h>
7 #include <ntsecapi.h>
8 #include <wincred.h>
9
10 // SECURITY_WIN32 must be defined in order to get
11 // EXTENDED_NAME_FORMAT enumeration.
12 #define SECURITY_WIN32 1
13 #include <security.h>
14 #undef SECURITY_WIN32
15
16 #include "base/strings/utf_string_conversions.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20
21 #define PASSWORD_MANAGER_MAX_PASSWORD_TRIES 3
Garrett Casto 2013/10/23 20:39:33 Use a static constant here instead (http://google-
Will Harris 2013/10/25 16:01:42 Done.
22
23 namespace password_manager_util {
24
25 bool AuthenticateUser() {
26 bool retval = false;
27 CREDUI_INFO cui = {};
28 WCHAR username[CREDUI_MAX_USERNAME_LENGTH+1] = {};
29 WCHAR displayname[CREDUI_MAX_USERNAME_LENGTH+1] = {};
30 WCHAR password[CREDUI_MAX_PASSWORD_LENGTH+1] = {};
31 DWORD username_length = CREDUI_MAX_USERNAME_LENGTH;
32 std::wstring product_name =
33 UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
34 std::wstring password_prompt =
35 UTF16ToWide(l10n_util::GetStringUTF16(
36 IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT));
37 HANDLE handle = INVALID_HANDLE_VALUE;
38 int tries = 0;
39 bool use_displayname = false;
40 bool use_principalname = false;
41 DWORD logon_result = 0;
42
43 // On a domain, we obtain the User Principal Name
44 // for domain authentication.
45 if (GetUserNameEx(NameUserPrincipal, username, &username_length)) {
cpu_(ooo_6.6-7.5) 2013/10/23 19:54:43 I don't think we need to do SecureZeroMemory for u
Will Harris 2013/10/25 16:01:42 Done.
46 use_principalname = true;
47 } else {
48 username_length = CREDUI_MAX_USERNAME_LENGTH;
Garrett Casto 2013/10/23 20:39:33 Do you actually need this? The API for GetUserName
Will Harris 2013/10/25 16:01:42 both APIs have lpnSize as an in/out parameter so w
49 // Otherwise, we're a workstation, use the plain local username.
50 if (!GetUserName(username, &username_length)) {
51 DLOG(ERROR) << "Unable to obtain username " << GetLastError();
52 return false;
53 } else {
54 // As we are on a workstation, it's possible the user
55 // has no password, so check here.
56 logon_result = LogonUser(username,
57 L".",
58 L"",
59 LOGON32_LOGON_NETWORK,
60 LOGON32_PROVIDER_DEFAULT,
61 &handle);
62 // Windows XP and above return ERROR_ACCOUNT_RESTRICTION for
63 // when the password is blank, so check for that here.
64 // See http://support.microsoft.com/kb/303846.
65 if (logon_result || GetLastError() == ERROR_ACCOUNT_RESTRICTION) {
66 SecureZeroMemory(username, sizeof(username));
67 if (logon_result)
68 CloseHandle(handle);
69 return true;
70 }
71 }
72 }
73
74 // Try and obtain a friendly display name.
75 username_length = CREDUI_MAX_USERNAME_LENGTH;
76 if (GetUserNameEx(NameDisplay, displayname, &username_length)) {
77 use_displayname = true;
78 }
79
80 cui.cbSize = sizeof(CREDUI_INFO);
81 cui.hwndParent = NULL;
82 cui.pszMessageText = password_prompt.c_str();
83 cui.pszCaptionText = product_name.c_str();
84
85 cui.hbmBanner = NULL;
86 BOOL save_password = FALSE;
87 DWORD credErr = NO_ERROR;
88 DWORD flags = CREDUI_FLAGS_GENERIC_CREDENTIALS |
89 CREDUI_FLAGS_EXCLUDE_CERTIFICATES |
90 CREDUI_FLAGS_KEEP_USERNAME |
91 CREDUI_FLAGS_ALWAYS_SHOW_UI |
92 CREDUI_FLAGS_DO_NOT_PERSIST;
93
94 do {
95 SecureZeroMemory(password, sizeof(password));
96 tries++;
97
98 // TODO(wfh) Make sure we support smart cards here.
Garrett Casto 2013/10/23 20:39:33 indentation
Will Harris 2013/10/25 16:01:42 Done.
99 credErr = CredUIPromptForCredentials(
100 &cui,
101 product_name.c_str(),
102 NULL,
103 0,
104 use_displayname ? displayname : username,
105 CREDUI_MAX_USERNAME_LENGTH+1,
106 password,
107 CREDUI_MAX_PASSWORD_LENGTH+1,
108 &save_password,
109 flags | (tries > 1 ? CREDUI_FLAGS_INCORRECT_PASSWORD : 0));
110
111 if (credErr == NO_ERROR) {
112 logon_result = LogonUser(username,
113 use_principalname ? NULL : L".",
114 password,
115 LOGON32_LOGON_NETWORK,
116 LOGON32_PROVIDER_DEFAULT,
117 &handle);
118 if (logon_result) {
119 retval = true;
Garrett Casto 2013/10/23 20:39:33 indentation
Will Harris 2013/10/25 16:01:42 Done.
120 CloseHandle(handle);
121 } else {
122 if (GetLastError() == ERROR_ACCOUNT_RESTRICTION &&
123 wcslen(password) == 0) {
124 // Password is blank, so permit.
Garrett Casto 2013/10/23 20:39:33 You have already checked local users for blank pas
Will Harris 2013/10/25 16:01:42 I only wanted to perform the blank password check
125 retval = true;
126 } else {
127 DLOG(WARNING) << "Unable to authenticate " << GetLastError();
128 }
129 }
130 }
131 } while (credErr == NO_ERROR &&
132 (retval == false && tries < PASSWORD_MANAGER_MAX_PASSWORD_TRIES));
133
134 SecureZeroMemory(displayname, sizeof(displayname));
135 SecureZeroMemory(username, sizeof(username));
136 SecureZeroMemory(password, sizeof(password));
cpu_(ooo_6.6-7.5) 2013/10/23 19:54:43 lets move 136 to right after LogonUser line 117.
Will Harris 2013/10/25 16:01:42 can't because need wcslen(password)
137
138 return retval;
139 }
140
141 } // namespace password_manager_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698