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