diff options
author | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 23:59:26 +0000 |
---|---|---|
committer | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 23:59:26 +0000 |
commit | 6fdd418b9a50f24f7788e229bd3ae4acaf6ec1d4 (patch) | |
tree | d55a82a8551a7df61d6c84f13835e7b8e17507f3 /chrome/browser/chromeos/plugin_selection_policy.cc | |
parent | 6f7582fd31ff06faa0298ab6d530369256e9f20a (diff) | |
download | chromium_src-6fdd418b9a50f24f7788e229bd3ae4acaf6ec1d4.zip chromium_src-6fdd418b9a50f24f7788e229bd3ae4acaf6ec1d4.tar.gz chromium_src-6fdd418b9a50f24f7788e229bd3ae4acaf6ec1d4.tar.bz2 |
This adds a plugin selection policy for selecting which plugin is
allowed for a particular domain.
It is only used on ChromeOS. It reads from a file that is installed
in a known location on ChromeOS, and uses that as it's policy.
When there are multiple plugins supporting the same mime-type, the
appropriate plugin file to load is now selected based on policy.
BUG=http://crosbug.com/7403
TEST=ran new unit test, tested on device.
Review URL: http://codereview.chromium.org/3717005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62679 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/plugin_selection_policy.cc')
-rw-r--r-- | chrome/browser/chromeos/plugin_selection_policy.cc | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/plugin_selection_policy.cc b/chrome/browser/chromeos/plugin_selection_policy.cc new file mode 100644 index 0000000..b27bc42 --- /dev/null +++ b/chrome/browser/chromeos/plugin_selection_policy.cc @@ -0,0 +1,166 @@ +// Copyright (c) 2010 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. + +#include "chrome/browser/chromeos/plugin_selection_policy.h" + +#include <algorithm> +#include <iostream> +#include <map> +#include <sstream> +#include <string> +#include <vector> + +#include "base/auto_reset.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "chrome/browser/browser_thread.h" +#include "googleurl/src/gurl.h" + +#if !defined(OS_CHROMEOS) +#error This file is meant to be compiled on ChromeOS only. +#endif + +using std::vector; +using std::string; +using std::pair; +using std::map; + +namespace chromeos { + +static const char kPluginSelectionPolicyFile[] = + "/usr/share/chromeos-assets/flash/plugin_policy"; + +PluginSelectionPolicy::PluginSelectionPolicy() : initialized_(false) { +} + +void PluginSelectionPolicy::StartInit() { + // Initialize the policy on the FILE thread, since it reads from a + // policy file. + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, + NewRunnableMethod(this, &chromeos::PluginSelectionPolicy::Init)); +} + +bool PluginSelectionPolicy::Init() { + return InitFromFile(FilePath(kPluginSelectionPolicyFile)); +} + +bool PluginSelectionPolicy::InitFromFile(const FilePath& policy_file) { + // This must always be called from the FILE thread. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // Note: We're "initialized" even if loading the file fails. + initialized_ = true; + + string data; + // This should be a really small file, so we're OK with just + // slurping it. + if (!file_util::ReadFileToString(policy_file, &data)) { + LOG(ERROR) << "Unable to read plugin policy file \"" + << policy_file.value() << "\"."; + return false; + } + + std::istringstream input_stream(data); + string line; + map<string, Policy> policies; + Policy policy; + string last_plugin; + + while (std::getline(input_stream, line)) { + // Strip comments. + string::size_type pos = line.find("#"); + if (pos != string::npos) { + line = line.substr(0, pos); + } + TrimWhitespaceASCII(line, TRIM_ALL, &line); + if (line.find("allow") == 0) { + // Has to be preceeded by a "plugin" statement. + if (last_plugin.empty()) { + LOG(ERROR) << "Plugin policy file error: 'allow' out of context."; + return false; + } + line = line.substr(6); + TrimWhitespaceASCII(line, TRIM_ALL, &line); + line = StringToLowerASCII(line); + policy.push_back(make_pair(true, line)); + } + if (line.find("deny") == 0) { + // Has to be preceeded by a "plugin" statement. + if (last_plugin.empty()) { + LOG(ERROR) << "Plugin policy file error: 'deny' out of context."; + return false; + } + line = line.substr(5); + TrimWhitespaceASCII(line, TRIM_ALL, &line); + line = StringToLowerASCII(line); + policy.push_back(make_pair(false, line)); + } + if (line.find("plugin") == 0) { + line = line.substr(7); + TrimWhitespaceASCII(line, TRIM_ALL, &line); + if (!policy.empty() && !last_plugin.empty()) + policies.insert(make_pair(last_plugin, policy)); + last_plugin = line; + policy.clear(); + } + } + + if (!last_plugin.empty()) + policies.insert(make_pair(last_plugin, policy)); + + policies_.swap(policies); + return true; +} + +int PluginSelectionPolicy::FindFirstAllowed( + const GURL& url, + const std::vector<WebPluginInfo>& info) { + for (std::vector<WebPluginInfo>::size_type i = 0; i < info.size(); ++i) { + if (IsAllowed(url, info[i].path)) + return i; + } + return -1; +} + +bool PluginSelectionPolicy::IsAllowed(const GURL& url, + const FilePath& path) { + // This must always be called from the FILE thread, to be sure + // initialization doesn't happen at the same time. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // Make sure that we notice if this starts being called before + // initialization is complete. Right now it is guaranteed only by + // the startup order and the fact that InitFromFile runs on the FILE + // thread too. + DCHECK(initialized_) << "Tried to check policy before policy is initialized."; + + string name = path.BaseName().value(); + + PolicyMap::iterator policy_iter = policies_.find(name); + if (policy_iter != policies_.end()) { + Policy& policy(policy_iter->second); + + // We deny by default. (equivalent to "deny" at the top of the section) + bool allow = false; + + for (Policy::iterator iter = policy.begin(); iter != policy.end(); ++iter) { + bool policy_allow = iter->first; + string& policy_domain = iter->second; + if (policy_domain.empty() || url.DomainIs(policy_domain.c_str(), + policy_domain.size())) { + allow = policy_allow; + } + } + return allow; + } + + // If it's not in the policy file, then we assume it's OK to allow + // it. + return true; +} + +} // namespace chromeos |