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_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_ 6 #define CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_ 7 8 #include <gnome-keyring.h> 9 10 #include <string> 11 12 #include "base/basictypes.h" 13 #include "base/time/time.h" 14 #include "chrome/browser/password_manager/password_store_factory.h" 15 #include "chrome/browser/password_manager/password_store_x.h" 16 #include "chrome/browser/profiles/profile.h" 17 18 namespace autofill { 19 struct PasswordForm; 20 } 21 22 // Many of the gnome_keyring_* functions use variable arguments, which makes 23 // them difficult if not impossible to truly wrap in C. Therefore, we use 24 // appropriately-typed function pointers and scoping to make the fact that we 25 // might be dynamically loading the library almost invisible. As a bonus, we 26 // also get a simple way to mock the library for testing. Classes that inherit 27 // from GnomeKeyringLoader will use its versions of the gnome_keyring_* 28 // functions. Note that it has only static fields. 29 class GnomeKeyringLoader { 30 protected: 31 static bool LoadGnomeKeyring(); 32 33 // Call a given parameter with the name of each function we use from GNOME 34 // Keyring. Make sure to adjust the unit test if you change these. 35 // The list of functions is divided into those we plan to mock in the unittest, 36 // and those which we use without mocking in the test. 37 #define GNOME_KEYRING_FOR_EACH_MOCKED_FUNC(F) \ 38 F(is_available) \ 39 F(store_password) \ 40 F(delete_password) \ 41 F(find_items) \ 42 F(result_to_message) 43 #define GNOME_KEYRING_FOR_EACH_NON_MOCKED_FUNC(F) \ 44 F(attribute_list_free) \ 45 F(attribute_list_new) \ 46 F(attribute_list_append_string) \ 47 F(attribute_list_append_uint32) 48 #define GNOME_KEYRING_FOR_EACH_FUNC(F) \ 49 GNOME_KEYRING_FOR_EACH_NON_MOCKED_FUNC(F) \ 50 GNOME_KEYRING_FOR_EACH_MOCKED_FUNC(F) 51 52 // Declare the actual function pointers that we'll use in client code. 53 #define GNOME_KEYRING_DECLARE_POINTER(name) \ 54 static typeof(&::gnome_keyring_##name) gnome_keyring_##name; 55 GNOME_KEYRING_FOR_EACH_FUNC(GNOME_KEYRING_DECLARE_POINTER) 56 #undef GNOME_KEYRING_DECLARE_POINTER 57 58 // Set to true if LoadGnomeKeyring() has already succeeded. 59 static bool keyring_loaded; 60 61 private: 62 #if defined(DLOPEN_GNOME_KEYRING) 63 struct FunctionInfo { 64 const char* name; 65 void** pointer; 66 }; 67 68 // Make it easy to initialize the function pointers in LoadGnomeKeyring(). 69 static const FunctionInfo functions[]; 70 #endif // defined(DLOPEN_GNOME_KEYRING) 71 }; 72 73 // NativeBackend implementation using GNOME Keyring. 74 class NativeBackendGnome : public PasswordStoreX::NativeBackend, 75 public GnomeKeyringLoader { 76 public: 77 explicit NativeBackendGnome(LocalProfileId id); 78 79 virtual ~NativeBackendGnome(); 80 81 virtual bool Init() OVERRIDE; 82 83 // Implements NativeBackend interface. 84 virtual password_manager::PasswordStoreChangeList AddLogin( 85 const autofill::PasswordForm& form) OVERRIDE; 86 virtual bool UpdateLogin( 87 const autofill::PasswordForm& form, 88 password_manager::PasswordStoreChangeList* changes) OVERRIDE; 89 virtual bool RemoveLogin(const autofill::PasswordForm& form) OVERRIDE; 90 virtual bool RemoveLoginsCreatedBetween( 91 base::Time delete_begin, 92 base::Time delete_end, 93 password_manager::PasswordStoreChangeList* changes) OVERRIDE; 94 virtual bool RemoveLoginsSyncedBetween( 95 base::Time delete_begin, 96 base::Time delete_end, 97 password_manager::PasswordStoreChangeList* changes) OVERRIDE; 98 virtual bool GetLogins(const autofill::PasswordForm& form, 99 PasswordFormList* forms) OVERRIDE; 100 virtual bool GetAutofillableLogins(PasswordFormList* forms) OVERRIDE; 101 virtual bool GetBlacklistLogins(PasswordFormList* forms) OVERRIDE; 102 103 private: 104 enum TimestampToCompare { 105 CREATION_TIMESTAMP, 106 SYNC_TIMESTAMP, 107 }; 108 109 // Adds a login form without checking for one to replace first. 110 bool RawAddLogin(const autofill::PasswordForm& form); 111 112 // Reads PasswordForms from the keyring with the given autofillability state. 113 bool GetLoginsList(PasswordFormList* forms, bool autofillable); 114 115 // Helper for GetLoginsCreatedBetween(). 116 bool GetAllLogins(PasswordFormList* forms); 117 118 // Retrieves password created/synced in the time interval. Returns |true| if 119 // the operation succeeded. 120 bool GetLoginsBetween(base::Time get_begin, 121 base::Time get_end, 122 TimestampToCompare date_to_compare, 123 PasswordFormList* forms); 124 125 // Removes password created/synced in the time interval. Returns |true| if the 126 // operation succeeded. |changes| will contain the changes applied. 127 bool RemoveLoginsBetween(base::Time get_begin, 128 base::Time get_end, 129 TimestampToCompare date_to_compare, 130 password_manager::PasswordStoreChangeList* changes); 131 132 // Generates a profile-specific app string based on profile_id_. 133 std::string GetProfileSpecificAppString() const; 134 135 // The local profile id, used to generate the app string. 136 const LocalProfileId profile_id_; 137 138 // The app string, possibly based on the local profile id. 139 std::string app_string_; 140 141 DISALLOW_COPY_AND_ASSIGN(NativeBackendGnome); 142 }; 143 144 #endif // CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_ 145