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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ 6 #define CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/synchronization/lock.h" 15 #include "chrome/browser/chromeos/login/auth_attempt_state.h" 16 #include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h" 17 #include "chrome/browser/chromeos/login/authenticator.h" 18 #include "chrome/browser/chromeos/login/online_attempt.h" 19 #include "chrome/browser/chromeos/login/test_attempt_state.h" 20 #include "chrome/browser/chromeos/settings/device_settings_service.h" 21 #include "google_apis/gaia/gaia_auth_consumer.h" 22 23 class LoginFailure; 24 class Profile; 25 26 namespace chromeos { 27 28 class LoginStatusConsumer; 29 30 // Authenticates a Chromium OS user against cryptohome. 31 // Relies on the fact that online authentications has been already performed 32 // (i.e. using_oauth_ is true). 33 // 34 // At a high, level, here's what happens: 35 // AuthenticateToLogin() calls a Cryptohome's method to perform offline login. 36 // Resultes are stored in a AuthAttemptState owned by ParallelAuthenticator 37 // and then call Resolve(). Resolve() will attempt to 38 // determine which AuthState we're in, based on the info at hand. 39 // It then triggers further action based on the calculated AuthState; this 40 // further action might include calling back the passed-in LoginStatusConsumer 41 // to signal that login succeeded or failed, waiting for more outstanding 42 // operations to complete, or triggering some more Cryptohome method calls. 43 // 44 // Typical flows 45 // ------------- 46 // Add new user: CONTINUE > CONTINUE > CREATE_NEW > CONTINUE > ONLINE_LOGIN 47 // Login as existing user: CONTINUE > OFFLINE_LOGIN 48 // Login as existing user (failure): CONTINUE > FAILED_MOUNT 49 // Change password detected: 50 // GAIA online ok: CONTINUE > CONTINUE > NEED_OLD_PW 51 // Recreate: CREATE_NEW > CONTINUE > ONLINE_LOGIN 52 // Old password failure: NEED_OLD_PW 53 // Old password ok: RECOVER_MOUNT > CONTINUE > ONLINE_LOGIN 54 // 55 // TODO(nkostylev): Rename ParallelAuthenticator since it is not doing 56 // offline/online login operations in parallel anymore. 57 class ParallelAuthenticator : public Authenticator, 58 public AuthAttemptStateResolver { 59 public: 60 enum AuthState { 61 CONTINUE = 0, // State indeterminate; try again with more info. 62 NO_MOUNT = 1, // Cryptohome doesn't exist yet. 63 FAILED_MOUNT = 2, // Failed to mount existing cryptohome. 64 FAILED_REMOVE = 3, // Failed to remove existing cryptohome. 65 FAILED_TMPFS = 4, // Failed to mount tmpfs for guest user. 66 FAILED_TPM = 5, // Failed to mount/create cryptohome, TPM error. 67 CREATE_NEW = 6, // Need to create cryptohome for a new user. 68 RECOVER_MOUNT = 7, // After RecoverEncryptedData, mount cryptohome. 69 POSSIBLE_PW_CHANGE = 8, // Offline login failed, user may have changed pw. 70 NEED_NEW_PW = 9, // Obsolete (ClientLogin): user changed pw, 71 // we have the old one. 72 NEED_OLD_PW = 10, // User changed pw, and we have the new one 73 // (GAIA auth is OK). 74 HAVE_NEW_PW = 11, // Obsolete (ClientLogin): We have verified new pw, 75 // time to migrate key. 76 OFFLINE_LOGIN = 12, // Login succeeded offline. 77 DEMO_LOGIN = 13, // Logged in as the demo user. 78 ONLINE_LOGIN = 14, // Offline and online login succeeded. 79 UNLOCK = 15, // Screen unlock succeeded. 80 ONLINE_FAILED = 16, // Obsolete (ClientLogin): Online login disallowed, 81 // but offline succeeded. 82 GUEST_LOGIN = 17, // Logged in guest mode. 83 PUBLIC_ACCOUNT_LOGIN = 18, // Logged into a public account. 84 LOCALLY_MANAGED_USER_LOGIN = 19, // Logged in as a locally managed user. 85 LOGIN_FAILED = 20, // Login denied. 86 OWNER_REQUIRED = 21 // Login is restricted to the owner only. 87 }; 88 89 explicit ParallelAuthenticator(LoginStatusConsumer* consumer); 90 91 // Authenticator overrides. 92 virtual void CompleteLogin(Profile* profile, 93 const UserContext& user_context) OVERRIDE; 94 95 // Given |user_context|, this method attempts to authenticate to your 96 // Chrome OS device. As soon as we have successfully mounted the encrypted 97 // home directory for the user, we will call consumer_->OnLoginSuccess() 98 // with the username. 99 // Upon failure to login consumer_->OnLoginFailure() is called 100 // with an error message. 101 // 102 // Uses |profile| when doing URL fetches. 103 virtual void AuthenticateToLogin(Profile* profile, 104 const UserContext& user_context) OVERRIDE; 105 106 // Given |user_context|, this method attempts to authenticate to the cached 107 // user_context. This will never contact the server even if it's online. 108 // The auth result is sent to LoginStatusConsumer in a same way as 109 // AuthenticateToLogin does. 110 virtual void AuthenticateToUnlock( 111 const UserContext& user_context) OVERRIDE; 112 113 // Initiates locally managed user login. 114 // Creates cryptohome if missing or mounts existing one and 115 // notifies consumer on the success/failure. 116 virtual void LoginAsLocallyManagedUser( 117 const UserContext& user_context) OVERRIDE; 118 119 // Initiates retail mode login. 120 // Mounts tmpfs and notifies consumer on the success/failure. 121 virtual void LoginRetailMode() OVERRIDE; 122 123 // Initiates incognito ("browse without signing in") login. 124 // Mounts tmpfs and notifies consumer on the success/failure. 125 virtual void LoginOffTheRecord() OVERRIDE; 126 127 // Initiates login into the public account identified by |username|. 128 // Mounts an ephemeral cryptohome and notifies consumer on the 129 // success/failure. 130 virtual void LoginAsPublicAccount(const std::string& username) OVERRIDE; 131 132 // These methods must be called on the UI thread, as they make DBus calls 133 // and also call back to the login UI. 134 virtual void OnRetailModeLoginSuccess() OVERRIDE; 135 virtual void OnLoginSuccess(bool request_pending) OVERRIDE; 136 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE; 137 virtual void RecoverEncryptedData( 138 const std::string& old_password) OVERRIDE; 139 virtual void ResyncEncryptedData() OVERRIDE; 140 141 // AuthAttemptStateResolver overrides. 142 // Attempts to make a decision and call back |consumer_| based on 143 // the state we have gathered at the time of call. If a decision 144 // can't be made, defers until the next time this is called. 145 // When a decision is made, will call back to |consumer_| on the UI thread. 146 // 147 // Must be called on the UI thread. 148 virtual void Resolve() OVERRIDE; 149 150 void OnOffTheRecordLoginSuccess(); 151 void OnPasswordChangeDetected(); 152 153 protected: 154 virtual ~ParallelAuthenticator(); 155 156 private: 157 friend class ParallelAuthenticatorTest; 158 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, 159 ResolveOwnerNeededDirectFailedMount); 160 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, ResolveOwnerNeededMount); 161 FRIEND_TEST_ALL_PREFIXES(ParallelAuthenticatorTest, 162 ResolveOwnerNeededFailedMount); 163 164 // Returns the AuthState we're in, given the status info we have at 165 // the time of call. 166 // Must be called on the IO thread. 167 AuthState ResolveState(); 168 169 // Helper for ResolveState(). 170 // Given that some cryptohome operation has failed, determine which of the 171 // possible failure states we're in. 172 // Must be called on the IO thread. 173 AuthState ResolveCryptohomeFailureState(); 174 175 // Helper for ResolveState(). 176 // Given that some cryptohome operation has succeeded, determine which of 177 // the possible states we're in. 178 // Must be called on the IO thread. 179 AuthState ResolveCryptohomeSuccessState(); 180 181 // Helper for ResolveState(). 182 // Given that some online auth operation has succeeded, determine which of 183 // the possible success states we're in. 184 // Must be called on the IO thread. 185 AuthState ResolveOnlineSuccessState(AuthState offline_state); 186 187 // Used to disable oauth, used for testing. 188 void set_using_oauth(bool value) { 189 using_oauth_ = value; 190 } 191 192 // Used for testing. 193 void set_attempt_state(TestAttemptState* new_state) { // takes ownership. 194 current_state_.reset(new_state); 195 } 196 197 // Sets an online attempt for testing. 198 void set_online_attempt(OnlineAttempt* attempt) { 199 current_online_.reset(attempt); 200 } 201 202 // Used for testing to set the expected state of an owner check. 203 void SetOwnerState(bool owner_check_finished, bool check_result); 204 205 // checks if the current mounted home contains the owner case and either 206 // continues or fails the log-in. Used for policy lost mitigation "safe-mode". 207 // Returns true if the owner check has been successful or if it is not needed. 208 bool VerifyOwner(); 209 210 // Handles completion of the ownership check and continues login. 211 void OnOwnershipChecked(DeviceSettingsService::OwnershipStatus status, 212 bool is_owner); 213 214 // Signal login completion status for cases when a new user is added via 215 // an external authentication provider (i.e. GAIA extension). 216 void ResolveLoginCompletionStatus(); 217 218 scoped_ptr<AuthAttemptState> current_state_; 219 scoped_ptr<OnlineAttempt> current_online_; 220 bool migrate_attempted_; 221 bool remove_attempted_; 222 bool ephemeral_mount_attempted_; 223 bool check_key_attempted_; 224 225 // When the user has changed her password, but gives us the old one, we will 226 // be able to mount her cryptohome, but online authentication will fail. 227 // This allows us to present the same behavior to the caller, regardless 228 // of the order in which we receive these results. 229 bool already_reported_success_; 230 base::Lock success_lock_; // A lock around |already_reported_success_|. 231 232 // Flags signaling whether the owner verification has been done and the result 233 // of it. 234 bool owner_is_verified_; 235 bool user_can_login_; 236 237 // True if we use OAuth-based authentication flow. 238 bool using_oauth_; 239 240 DISALLOW_COPY_AND_ASSIGN(ParallelAuthenticator); 241 }; 242 243 } // namespace chromeos 244 245 #endif // CHROME_BROWSER_CHROMEOS_LOGIN_PARALLEL_AUTHENTICATOR_H_ 246