1// Copyright 2013 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_EXTENSIONS_INSTALL_VERIFIER_H_
6#define CHROME_BROWSER_EXTENSIONS_INSTALL_VERIFIER_H_
7
8#include <queue>
9#include <set>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/memory/linked_ptr.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/weak_ptr.h"
17#include "extensions/browser/management_policy.h"
18#include "extensions/common/extension.h"
19
20namespace content {
21class BrowserContext;
22}
23
24namespace net {
25class URLRequestContextGetter;
26}
27
28namespace extensions {
29
30class ExtensionPrefs;
31class InstallSigner;
32struct InstallSignature;
33
34// This class implements verification that a set of extensions are either from
35// the webstore or are whitelisted by enterprise policy.  The webstore
36// verification process works by sending a request to a backend server to get a
37// signature proving that a set of extensions are verified. This signature is
38// written into the extension preferences and is checked for validity when
39// being read back again.
40//
41// This class should be kept notified of runtime changes to the set of
42// extensions installed from the webstore.
43class InstallVerifier : public ManagementPolicy::Provider {
44 public:
45  InstallVerifier(ExtensionPrefs* prefs, content::BrowserContext* context);
46  virtual ~InstallVerifier();
47
48  // Returns whether |extension| is of a type that needs verification.
49  static bool NeedsVerification(const Extension& extension);
50
51  // Determines if an extension claims to be from the webstore.
52  static bool IsFromStore(const Extension& extension);
53
54  // Initializes this object for use, including reading preferences and
55  // validating the stored signature.
56  void Init();
57
58  // Returns the timestamp of our InstallSignature, if we have one.
59  base::Time SignatureTimestamp();
60
61  // Returns true if |id| is either verified or our stored signature explicitly
62  // tells us that it was invalid when we asked the server about it.
63  bool IsKnownId(const std::string& id) const;
64
65  // Returns whether the given |id| is considered invalid by our verified
66  // signature.
67  bool IsInvalid(const std::string& id) const;
68
69  // Attempts to verify a single extension and add it to the verified list.
70  void VerifyExtension(const std::string& extension_id);
71
72  // Attempts to verify all extensions.
73  void VerifyAllExtensions();
74
75  // Call this to add a set of ids that will immediately be considered allowed,
76  // and kick off an aysnchronous request to Add.
77  void AddProvisional(const ExtensionIdSet& ids);
78
79  // Removes an id or set of ids from the verified list.
80  void Remove(const std::string& id);
81  void RemoveMany(const ExtensionIdSet& ids);
82
83  // Returns whether an extension id is allowed by policy.
84  bool AllowedByEnterprisePolicy(const std::string& id) const;
85
86  // ManagementPolicy::Provider interface.
87  virtual std::string GetDebugPolicyProviderName() const OVERRIDE;
88  virtual bool MustRemainDisabled(const Extension* extension,
89                                  Extension::DisableReason* reason,
90                                  base::string16* error) const OVERRIDE;
91
92 private:
93  // We keep a list of operations to the current set of extensions.
94  enum OperationType {
95    ADD_SINGLE,         // Adding a single extension to be verified.
96    ADD_ALL,            // Adding all extensions to be verified.
97    ADD_ALL_BOOTSTRAP,  // Adding all extensions because of a bootstrapping.
98    ADD_PROVISIONAL,    // Adding one or more provisionally-allowed extensions.
99    REMOVE              // Remove one or more extensions.
100  };
101
102  // This is an operation we want to apply to the current set of verified ids.
103  struct PendingOperation {
104    OperationType type;
105
106    // This is the set of ids being either added or removed.
107    ExtensionIdSet ids;
108
109    explicit PendingOperation(OperationType type);
110    ~PendingOperation();
111  };
112
113  // Returns the set of IDs for all extensions that potentially need to be
114  // verified.
115  ExtensionIdSet GetExtensionsToVerify() const;
116
117  // Bootstrap the InstallVerifier if we do not already have a signature, or if
118  // there are unknown extensions which need to be verified.
119  void MaybeBootstrapSelf();
120
121  // Try adding a new set of |ids| to the list of verified ids.
122  void AddMany(const ExtensionIdSet& ids, OperationType type);
123
124  // Record the result of the verification for the histograms, and notify the
125  // ExtensionPrefs if we verified all extensions.
126  void OnVerificationComplete(bool success, OperationType type);
127
128  // Removes any no-longer-installed ids, requesting a new signature if needed.
129  void GarbageCollect();
130
131  // Returns whether the given |id| is included in our verified signature.
132  bool IsVerified(const std::string& id) const;
133
134  // Returns true if the extension with |id| was installed later than the
135  // timestamp of our signature.
136  bool WasInstalledAfterSignature(const std::string& id) const;
137
138  // Begins the process of fetching a new signature, based on applying the
139  // operation at the head of the queue to the current set of ids in
140  // |signature_| (if any) and then sending a request to sign that.
141  void BeginFetch();
142
143  // Saves the current value of |signature_| to the prefs;
144  void SaveToPrefs();
145
146  // Called with the result of a signature request, or NULL on failure.
147  void SignatureCallback(scoped_ptr<InstallSignature> signature);
148
149  ExtensionPrefs* prefs_;
150
151  // The context with which the InstallVerifier is associated.
152  content::BrowserContext* context_;
153
154  // Have we finished our bootstrap check yet?
155  bool bootstrap_check_complete_;
156
157  // This is the most up-to-date signature, read out of |prefs_| during
158  // initialization and updated anytime we get new id's added.
159  scoped_ptr<InstallSignature> signature_;
160
161  // The current InstallSigner, if we have a signature request running.
162  scoped_ptr<InstallSigner> signer_;
163
164  // A queue of operations to apply to the current set of allowed ids.
165  std::queue<linked_ptr<PendingOperation> > operation_queue_;
166
167  // A set of ids that have been provisionally added, which we're willing to
168  // consider allowed until we hear back from the server signature request.
169  ExtensionIdSet provisional_;
170
171  base::WeakPtrFactory<InstallVerifier> weak_factory_;
172
173  DISALLOW_COPY_AND_ASSIGN(InstallVerifier);
174};
175
176}  // namespace extensions
177
178#endif  // CHROME_BROWSER_EXTENSIONS_INSTALL_VERIFIER_H_
179