| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_BASE_H_ |
| #define CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_BASE_H_ |
| |
| #include "chrome/credential_provider/gaiacp/stdafx.h" |
| |
| #include <memory> |
| |
| #include "base/strings/string16.h" |
| #include "base/values.h" |
| #include "base/win/scoped_handle.h" |
| #include "base/win/scoped_process_information.h" |
| #include "chrome/credential_provider/gaiacp/gaia_credential_provider_i.h" |
| #include "chrome/credential_provider/gaiacp/gcp_utils.h" |
| #include "chrome/credential_provider/gaiacp/scoped_handle.h" |
| |
| namespace base { |
| class CommandLine; |
| class FilePath; |
| } // namespace base |
| |
| namespace credential_provider { |
| |
| class OSProcessManager; |
| class OSUserManager; |
| |
| enum FIELDID { |
| FID_DESCRIPTION, |
| FID_CURRENT_PASSWORD_FIELD, |
| FID_SUBMIT, |
| FID_PROVIDER_LOGO, |
| FID_PROVIDER_LABEL, |
| FIELD_COUNT // Must be last. |
| }; |
| |
| // Implementation of an ICredentialProviderCredential backed by a Gaia account. |
| // This is used as a base class for the COM objects that implement first time |
| // sign in and password update. |
| class ATL_NO_VTABLE CGaiaCredentialBase |
| : public IGaiaCredential, |
| public ICredentialProviderCredential2 { |
| public: |
| // Size in wchar_t of string buffer to pass account information to background |
| // process to save that information into the registry. |
| static const int kAccountInfoBufferSize = 2048; |
| |
| // Called when the DLL is registered or unregistered. |
| static HRESULT OnDllRegisterServer(); |
| static HRESULT OnDllUnregisterServer(); |
| |
| // Saves gaia information in the OS account that was just created. |
| static HRESULT SaveAccountInfo(const base::DictionaryValue& properties); |
| |
| // Allocates a BSTR from a DLL string resource given by |id|. |
| static BSTR AllocErrorString(UINT id); |
| |
| // Gets the directory where the credential provider is installed. |
| static HRESULT GetInstallDirectory(base::FilePath* path); |
| |
| // Passed to WaitForLoginUI(). |
| struct UIProcessInfo { |
| UIProcessInfo(); |
| ~UIProcessInfo(); |
| |
| CComPtr<IGaiaCredential> credential; |
| base::win::ScopedHandle logon_token; |
| base::win::ScopedProcessInformation procinfo; |
| StdParentHandles parent_handles; |
| }; |
| |
| protected: |
| CGaiaCredentialBase(); |
| ~CGaiaCredentialBase(); |
| |
| // Creates a new windows OS user with the given username, fullname, and |
| // password on the local machine. Returns the SID of the new user. |
| static HRESULT CreateNewUser(OSUserManager* manager, |
| const wchar_t* username, |
| const wchar_t* password, |
| const wchar_t* fullname, |
| const wchar_t* comment, |
| bool add_to_users_group, |
| BSTR* sid); |
| |
| // Members to access user credentials. |
| const CComBSTR& get_username() const { return username_; } |
| const CComBSTR& get_password() const { return password_; } |
| const CComBSTR& get_sid() const { return user_sid_; } |
| const CComBSTR& get_current_windows_password() const { |
| return current_windows_password_; |
| } |
| void set_username(BSTR username) { username_ = username; } |
| void set_user_sid(BSTR sid) { user_sid_ = sid; } |
| void set_current_windows_password(BSTR password) { |
| current_windows_password_ = password; |
| } |
| bool AreCredentialsValid() const; |
| bool AreWindowsCredentialsAvailable() const; |
| bool AreWindowsCredentialsValid(BSTR password) const; |
| |
| // IGaiaCredential |
| IFACEMETHODIMP Initialize(IGaiaCredentialProvider* provider) override; |
| IFACEMETHODIMP Terminate() override; |
| IFACEMETHODIMP OnUserAuthenticated(BSTR authentication_info, |
| BSTR* status_text) override; |
| IFACEMETHODIMP ReportError(LONG status, |
| LONG substatus, |
| BSTR status_text) override; |
| |
| // Gets the string value for the given credential UI field. |
| HRESULT GetStringValueImpl(DWORD field_id, wchar_t** value); |
| |
| // Derived classes should implement this function to return an email address |
| // only when reauthenticating the user. |
| virtual HRESULT GetEmailForReauth(wchar_t* email, size_t length); |
| |
| // Resets the state of the credential, forgetting any username or password |
| // that may have been set previously. Derived classes may override to |
| // perform more state resetting if needed, but should always call the base |
| // class method. |
| virtual void ResetInternalState(); |
| |
| private: |
| // Gets the command line to run the Gaia Logon stub (GLS). |
| virtual HRESULT GetGlsCommandline(const wchar_t* email, |
| base::CommandLine* command_line); |
| |
| // Display error message to the user. Virtual so that tests can override. |
| virtual void DisplayErrorInUI(LONG status, LONG substatus, BSTR status_text); |
| |
| // Called from GetSerialization() to handle auto-logon. If the credential |
| // has enough information in internal state to auto-logon, the two arguments |
| // are filled in as needed and S_OK is returned. S_FALSE is returned to |
| // indicate that the UI should be shown to the user. |
| HRESULT HandleAutologon( |
| CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr, |
| CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs); |
| |
| // Writes value to omaha registry to record that GCP has been used. |
| static void TellOmahaDidRun(); |
| |
| // Sets up the envriroment for the Gaia logon stub, runs it, and waits for |
| // it to finish in a background thread. |
| HRESULT CreateAndRunLogonStub(); |
| |
| // Creates a restricted token for the Gaia account that can be used to run |
| // the logon stub. The returned SID is a logon SID and not the SID of the |
| // Gaia account. |
| static HRESULT CreateGaiaLogonToken(base::win::ScopedHandle* token, |
| PSID* sid); |
| |
| // Forks the logon stub process and waits for it to start. |
| static HRESULT ForkGaiaLogonStub(OSProcessManager* process_manager, |
| const base::CommandLine& command_line, |
| UIProcessInfo* uiprocinfo); |
| |
| // Forks a stub process to save account information for a user. |
| static HRESULT ForkSaveAccountInfoStub( |
| const std::unique_ptr<base::DictionaryValue>& dict, |
| BSTR* status_text); |
| |
| // The param is a pointer to a UIProcessInfo struct. This function must |
| // release the memory for this structure using delete operator. |
| static unsigned __stdcall WaitForLoginUI(void* param); |
| |
| // ICredentialProviderCredential2 |
| IFACEMETHODIMP Advise(ICredentialProviderCredentialEvents* cpce) override; |
| IFACEMETHODIMP UnAdvise(void) override; |
| IFACEMETHODIMP SetSelected(BOOL* auto_login) override; |
| IFACEMETHODIMP SetDeselected(void) override; |
| IFACEMETHODIMP GetFieldState( |
| DWORD dwFieldID, |
| CREDENTIAL_PROVIDER_FIELD_STATE* pcpfs, |
| CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE* pcpfis) override; |
| IFACEMETHODIMP GetStringValue(DWORD dwFieldID, wchar_t** ppsz) override; |
| IFACEMETHODIMP GetBitmapValue(DWORD dwFieldID, HBITMAP* phbmp) override; |
| IFACEMETHODIMP GetCheckboxValue(DWORD field_id, |
| BOOL* pbChecked, |
| wchar_t** ppszLabel) override; |
| IFACEMETHODIMP GetSubmitButtonValue(DWORD field_id, |
| DWORD* pdwAdjacentTo) override; |
| IFACEMETHODIMP GetComboBoxValueCount(DWORD field_id, |
| DWORD* pcItems, |
| DWORD* pdwSelectedItem) override; |
| IFACEMETHODIMP GetComboBoxValueAt(DWORD field_id, |
| DWORD dwItem, |
| wchar_t** ppszItem) override; |
| IFACEMETHODIMP SetStringValue(DWORD field_id, const wchar_t* psz) override; |
| IFACEMETHODIMP SetCheckboxValue(DWORD field_id, BOOL bChecked) override; |
| IFACEMETHODIMP SetComboBoxSelectedValue(DWORD field_id, |
| DWORD dwSelectedItem) override; |
| IFACEMETHODIMP CommandLinkClicked(DWORD field_id) override; |
| IFACEMETHODIMP GetSerialization( |
| CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* cpgsr, |
| CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* cpcs, |
| wchar_t** status_text, |
| CREDENTIAL_PROVIDER_STATUS_ICON* status_icon) override; |
| IFACEMETHODIMP ReportResult( |
| NTSTATUS ntsStatus, |
| NTSTATUS ntsSubstatus, |
| wchar_t** ppszOptionalStatusText, |
| CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon) override; |
| IFACEMETHODIMP GetUserSid(wchar_t** sid) override; |
| |
| void TerminateLogonProcess(); |
| |
| // Checks if the information for the given |username| is valid and creates it |
| // if it does not exist. |
| // Returns S_OK if the user exists and the given |password| is a valid windows |
| // login password for the user or if the user does not exist and it was |
| // created successfully. |
| // Returns S_FALSE if the user exists but the given |password| is not the |
| // right password to signin to the Windows account. Otherwise an error result |
| // depending on the failure. On failure |error_text| will be allocated and |
| // filled with an error message. The caller must take ownership of this |
| // memory. On success (S_OK or S_FALSE) |sid| will be allocated and filled |
| // with the sid of the created or existing user. The caller must take |
| // ownership of this memory. |
| HRESULT ValidateOrCreateUser(BSTR username, |
| BSTR password, |
| BSTR fullname, |
| BSTR* sid, |
| BSTR* error_text); |
| |
| CComPtr<ICredentialProviderCredentialEvents> events_; |
| |
| // Handle to the logon UI process. |
| HANDLE logon_ui_process_; |
| |
| CComPtr<IGaiaCredentialProvider> provider_; |
| |
| // Information about the just created or re-auth-ed user. |
| CComBSTR username_; |
| CComBSTR password_; |
| CComBSTR user_sid_; |
| |
| // The password entered into the FID_CURRENT_PASSWORD_FIELD to update the |
| // Windows password with the gaia password. |
| CComBSTR current_windows_password_; |
| |
| std::unique_ptr<base::DictionaryValue> authentication_results_; |
| // Whether success or failure, these members hold information about result. |
| NTSTATUS result_status_; |
| NTSTATUS result_substatus_; |
| base::string16 result_status_text_; |
| }; |
| |
| } // namespace credential_provider |
| |
| #endif // CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_BASE_H_ |