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