summaryrefslogtreecommitdiffstats
path: root/chrome/browser/password_manager/native_backend_gnome_x.h
blob: f6e2ddb6f288d8e781260f54c73250e8bec1652e (plain)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// 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_

// libgnome-keyring has been deprecated in favor of libsecret.
// See: https://mail.gnome.org/archives/commits-list/2013-October/msg08876.html
//
// The define below turns off the deprecations, in order to avoid build
// failures with Gnome 3.12. When we move to libsecret, the define can be
// removed, together with the include below it.
//
// The porting is tracked in http://crbug.com/355223
#define GNOME_KEYRING_DEPRECATED
#define GNOME_KEYRING_DEPRECATED_FOR(x)
#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"

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 decltype(&::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:
  explicit NativeBackendGnome(LocalProfileId id);

  ~NativeBackendGnome() override;

  bool Init() override;

  // Implements NativeBackend interface.
  password_manager::PasswordStoreChangeList AddLogin(
      const autofill::PasswordForm& form) override;
  bool UpdateLogin(const autofill::PasswordForm& form,
                   password_manager::PasswordStoreChangeList* changes) override;
  bool RemoveLogin(const autofill::PasswordForm& form) override;
  bool RemoveLoginsCreatedBetween(
      base::Time delete_begin,
      base::Time delete_end,
      password_manager::PasswordStoreChangeList* changes) override;
  bool RemoveLoginsSyncedBetween(
      base::Time delete_begin,
      base::Time delete_end,
      password_manager::PasswordStoreChangeList* changes) override;
  bool GetLogins(const autofill::PasswordForm& form,
                 PasswordFormList* forms) override;
  bool GetAutofillableLogins(PasswordFormList* forms) override;
  bool GetBlacklistLogins(PasswordFormList* forms) override;

 private:
  enum TimestampToCompare {
    CREATION_TIMESTAMP,
    SYNC_TIMESTAMP,
  };

  // 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);

  // Retrieves password created/synced in the time interval. Returns |true| if
  // the operation succeeded.
  bool GetLoginsBetween(base::Time get_begin,
                        base::Time get_end,
                        TimestampToCompare date_to_compare,
                        PasswordFormList* forms);

  // Removes password created/synced in the time interval. Returns |true| if the
  // operation succeeded. |changes| will contain the changes applied.
  bool RemoveLoginsBetween(base::Time get_begin,
                           base::Time get_end,
                           TimestampToCompare date_to_compare,
                           password_manager::PasswordStoreChangeList* changes);

  // Generates a profile-specific app string based on profile_id_.
  std::string GetProfileSpecificAppString() const;

  // The local profile id, used to generate the app string.
  const LocalProfileId profile_id_;

  // The app string, possibly based on the local profile id.
  std::string app_string_;

  DISALLOW_COPY_AND_ASSIGN(NativeBackendGnome);
};

#endif  // CHROME_BROWSER_PASSWORD_MANAGER_NATIVE_BACKEND_GNOME_X_H_