native_backend_kwallet_x.h revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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_KWALLET_X_H_
6#define CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_KWALLET_X_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/memory/ref_counted.h"
12#include "base/time/time.h"
13#include "chrome/browser/password_manager/password_store_factory.h"
14#include "chrome/browser/password_manager/password_store_x.h"
15#include "chrome/browser/profiles/profile.h"
16
17class Pickle;
18class PickleIterator;
19class PrefService;
20
21namespace content {
22struct PasswordForm;
23}
24
25namespace base {
26class WaitableEvent;
27}
28
29namespace dbus {
30class Bus;
31class ObjectProxy;
32}
33
34// NativeBackend implementation using KWallet.
35class NativeBackendKWallet : public PasswordStoreX::NativeBackend {
36 public:
37  NativeBackendKWallet(LocalProfileId id, PrefService* prefs);
38
39  virtual ~NativeBackendKWallet();
40
41  virtual bool Init() OVERRIDE;
42
43  // Implements NativeBackend interface.
44  virtual bool AddLogin(const content::PasswordForm& form) OVERRIDE;
45  virtual bool UpdateLogin(const content::PasswordForm& form) OVERRIDE;
46  virtual bool RemoveLogin(const content::PasswordForm& form) OVERRIDE;
47  virtual bool RemoveLoginsCreatedBetween(
48      const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE;
49  virtual bool GetLogins(const content::PasswordForm& form,
50                         PasswordFormList* forms) OVERRIDE;
51  virtual bool GetLoginsCreatedBetween(const base::Time& get_begin,
52                                       const base::Time& get_end,
53                                       PasswordFormList* forms) OVERRIDE;
54  virtual bool GetAutofillableLogins(PasswordFormList* forms) OVERRIDE;
55  virtual bool GetBlacklistLogins(PasswordFormList* forms) OVERRIDE;
56
57 protected:
58  // Invalid handle returned by WalletHandle().
59  static const int kInvalidKWalletHandle = -1;
60
61  // Internally used by Init(), but also for testing to provide a mock bus.
62  bool InitWithBus(scoped_refptr<dbus::Bus> optional_bus);
63
64  // Deserializes a list of PasswordForms from the wallet.
65  static void DeserializeValue(const std::string& signon_realm,
66                               const Pickle& pickle,
67                               PasswordFormList* forms);
68
69 private:
70  enum InitResult {
71    INIT_SUCCESS,    // Init succeeded.
72    TEMPORARY_FAIL,  // Init failed, but might succeed after StartKWalletd().
73    PERMANENT_FAIL   // Init failed, and is not likely to work later either.
74  };
75
76  // Initialization.
77  bool StartKWalletd();
78  InitResult InitWallet();
79  void InitOnDBThread(scoped_refptr<dbus::Bus> optional_bus,
80                      base::WaitableEvent* event,
81                      bool* success);
82
83  // Reads PasswordForms from the wallet that match the given signon_realm.
84  bool GetLoginsList(PasswordFormList* forms,
85                     const std::string& signon_realm,
86                     int wallet_handle);
87
88  // Reads PasswordForms from the wallet with the given autofillability state.
89  bool GetLoginsList(PasswordFormList* forms,
90                     bool autofillable,
91                     int wallet_handle);
92
93  // Reads PasswordForms from the wallet created in the given time range.
94  bool GetLoginsList(PasswordFormList* forms,
95                     const base::Time& begin,
96                     const base::Time& end,
97                     int wallet_handle);
98
99  // Helper for some of the above GetLoginsList() methods.
100  bool GetAllLogins(PasswordFormList* forms, int wallet_handle);
101
102  // Writes a list of PasswordForms to the wallet with the given signon_realm.
103  // Overwrites any existing list for this signon_realm. Removes the entry if
104  // |forms| is empty. Returns true on success.
105  bool SetLoginsList(const PasswordFormList& forms,
106                     const std::string& signon_realm,
107                     int wallet_handle);
108
109  // Opens the wallet and ensures that the "Chrome Form Data" folder exists.
110  // Returns kInvalidWalletHandle on error.
111  int WalletHandle();
112
113  // Serializes a list of PasswordForms to be stored in the wallet.
114  static void SerializeValue(const PasswordFormList& forms, Pickle* pickle);
115
116  // Deserializes a list of PasswordForms from the wallet.
117  // |size_32| controls reading the size field within the pickle as 32 bits.
118  // We used to use Pickle::WriteSize() to write the number of password forms,
119  // but that has a different size on 32- and 64-bit systems. So, now we always
120  // write a 64-bit quantity, but we support trying to read it as either size
121  // when reading old pickles that fail to deserialize using the native size.
122  static bool DeserializeValueSize(const std::string& signon_realm,
123                                   const PickleIterator& iter,
124                                   bool size_32, bool warn_only,
125                                   PasswordFormList* forms);
126
127  // In case the fields in the pickle ever change, version them so we can try to
128  // read old pickles. (Note: do not eat old pickles past the expiration date.)
129  static const int kPickleVersion = 1;
130
131  // Generates a profile-specific folder name based on profile_id_.
132  std::string GetProfileSpecificFolderName() const;
133
134  // Migrates non-profile-specific logins to be profile-specific.
135  void MigrateToProfileSpecificLogins();
136
137  // The local profile id, used to generate the folder name.
138  const LocalProfileId profile_id_;
139
140  // The pref service to use for persistent migration settings.
141  PrefService* prefs_;
142
143  // The KWallet folder name, possibly based on the local profile id.
144  std::string folder_name_;
145
146  // True once MigrateToProfileSpecificLogins() has been attempted.
147  bool migrate_tried_;
148
149  // DBus handle for communication with klauncher and kwalletd.
150  scoped_refptr<dbus::Bus> session_bus_;
151  // Object proxy for kwalletd. We do not own this.
152  dbus::ObjectProxy* kwallet_proxy_;
153
154  // The name of the wallet we've opened. Set during Init().
155  std::string wallet_name_;
156  // The application name (e.g. "Chromium"), shown in KWallet auth dialogs.
157  const std::string app_name_;
158
159  DISALLOW_COPY_AND_ASSIGN(NativeBackendKWallet);
160};
161
162#endif  // CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_KWALLET_X_H_
163