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