Index: chrome/browser/chromeos/plugin_selection_policy.cc |
diff --git a/chrome/browser/chromeos/plugin_selection_policy.cc b/chrome/browser/chromeos/plugin_selection_policy.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..de55d92e5788bb27e56f6aa5db8365395bc8c24a |
--- /dev/null |
+++ b/chrome/browser/chromeos/plugin_selection_policy.cc |
@@ -0,0 +1,163 @@ |
+// 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/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)); |
+ |
+ 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); |
+ initialized_ = true; |
+ 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 |