1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file. 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/plugin_selection_policy.h" 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <algorithm> 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <iostream> 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <map> 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <sstream> 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <string> 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <vector> 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/auto_reset.h" 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/file_path.h" 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/file_util.h" 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/logging.h" 18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_util.h" 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "googleurl/src/gurl.h" 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if !defined(OS_CHROMEOS) 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#error This file is meant to be compiled on ChromeOS only. 24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif 25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing std::vector; 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing std::string; 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing std::pair; 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing std::map; 30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace chromeos { 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kPluginSelectionPolicyFile[] = 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "/usr/share/chromeos-assets/flash/plugin_policy"; 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 36513209b27ff55e2841eac0e4120199c23acce758Ben MurdochPluginSelectionPolicy::PluginSelectionPolicy() 37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : init_from_file_finished_(false) { 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid PluginSelectionPolicy::StartInit() { 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Initialize the policy on the FILE thread, since it reads from a 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // policy file. 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::FILE, FROM_HERE, 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NewRunnableMethod(this, &chromeos::PluginSelectionPolicy::Init)); 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool PluginSelectionPolicy::Init() { 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return InitFromFile(FilePath(kPluginSelectionPolicyFile)); 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool PluginSelectionPolicy::InitFromFile(const FilePath& policy_file) { 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // This must always be called from the FILE thread. 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string data; 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // This should be a really small file, so we're OK with just 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // slurping it. 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!file_util::ReadFileToString(policy_file, &data)) { 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Unable to read plugin policy file \"" 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << policy_file.value() << "\"."; 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch init_from_file_finished_ = true; 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::istringstream input_stream(data); 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string line; 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick map<string, Policy> policies; 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Policy policy; 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string last_plugin; 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick while (std::getline(input_stream, line)) { 73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Strip comments. 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string::size_type pos = line.find("#"); 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (pos != string::npos) { 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick line = line.substr(0, pos); 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TrimWhitespaceASCII(line, TRIM_ALL, &line); 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (line.find("allow") == 0) { 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Has to be preceeded by a "plugin" statement. 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (last_plugin.empty()) { 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Plugin policy file error: 'allow' out of context."; 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch init_from_file_finished_ = true; 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen line = line.substr(5); 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TrimWhitespaceASCII(line, TRIM_ALL, &line); 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick line = StringToLowerASCII(line); 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policy.push_back(make_pair(true, line)); 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (line.find("deny") == 0) { 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Has to be preceeded by a "plugin" statement. 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (last_plugin.empty()) { 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Plugin policy file error: 'deny' out of context."; 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch init_from_file_finished_ = true; 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen line = line.substr(4); 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TrimWhitespaceASCII(line, TRIM_ALL, &line); 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick line = StringToLowerASCII(line); 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policy.push_back(make_pair(false, line)); 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (line.find("plugin") == 0) { 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen line = line.substr(6); 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TrimWhitespaceASCII(line, TRIM_ALL, &line); 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!policy.empty() && !last_plugin.empty()) 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policies.insert(make_pair(last_plugin, policy)); 108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick last_plugin = line; 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policy.clear(); 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!last_plugin.empty()) 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policies.insert(make_pair(last_plugin, policy)); 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policies_.swap(policies); 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch init_from_file_finished_ = true; 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint PluginSelectionPolicy::FindFirstAllowed( 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const GURL& url, 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::vector<webkit::npapi::WebPluginInfo>& info) { 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen for (std::vector<webkit::npapi::WebPluginInfo>::size_type i = 0; 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen i < info.size(); ++i) { 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (IsAllowed(url, info[i].path)) 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return i; 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return -1; 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool PluginSelectionPolicy::IsAllowed(const GURL& url, 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const FilePath& path) { 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // This must always be called from the FILE thread, to be sure 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // initialization doesn't happen at the same time. 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Make sure that we notice if this starts being called before 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // initialization is complete. Right now it is guaranteed only by 140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the startup order and the fact that InitFromFile runs on the FILE 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // thread too. 142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(init_from_file_finished_) 143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << "Tried to check policy before policy is initialized."; 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string name = path.BaseName().value(); 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PolicyMap::iterator policy_iter = policies_.find(name); 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (policy_iter != policies_.end()) { 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Policy& policy(policy_iter->second); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // We deny by default. (equivalent to "deny" at the top of the section) 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool allow = false; 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (Policy::iterator iter = policy.begin(); iter != policy.end(); ++iter) { 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool policy_allow = iter->first; 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string& policy_domain = iter->second; 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (policy_domain.empty() || url.DomainIs(policy_domain.c_str(), 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick policy_domain.size())) { 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick allow = policy_allow; 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return allow; 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If it's not in the policy file, then we assume it's OK to allow 166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // it. 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace chromeos 171