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 #include "chrome/common/pepper_permission_util.h" 6 7 #include <vector> 8 9 #include "base/command_line.h" 10 #include "base/sha1.h" 11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_tokenizer.h" 13 #include "chrome/common/extensions/extension_set.h" 14 #include "extensions/common/constants.h" 15 #include "extensions/common/extension.h" 16 #include "extensions/common/manifest_handlers/shared_module_info.h" 17 18 using extensions::Extension; 19 using extensions::Manifest; 20 21 namespace chrome { 22 23 namespace { 24 25 std::string HashHost(const std::string& host) { 26 const std::string id_hash = base::SHA1HashString(host); 27 DCHECK_EQ(id_hash.length(), base::kSHA1Length); 28 return base::HexEncode(id_hash.c_str(), id_hash.length()); 29 } 30 31 bool HostIsInSet(const std::string& host, const std::set<std::string>& set) { 32 return set.count(host) > 0 || set.count(HashHost(host)) > 0; 33 } 34 35 } // namespace 36 37 bool IsExtensionOrSharedModuleWhitelisted( 38 const GURL& url, 39 const ExtensionSet* extension_set, 40 const std::set<std::string>& whitelist) { 41 if (!url.is_valid() || !url.SchemeIs(extensions::kExtensionScheme)) 42 return false; 43 44 const std::string host = url.host(); 45 if (HostIsInSet(host, whitelist)) 46 return true; 47 48 // Check the modules that are imported by this extension to see if any of them 49 // is whitelisted. 50 const Extension* extension = extension_set ? extension_set->GetByID(host) 51 : NULL; 52 if (extension) { 53 typedef std::vector<extensions::SharedModuleInfo::ImportInfo> 54 ImportInfoVector; 55 const ImportInfoVector& imports = 56 extensions::SharedModuleInfo::GetImports(extension); 57 for (ImportInfoVector::const_iterator it = imports.begin(); 58 it != imports.end(); ++it) { 59 const Extension* imported_extension = extension_set->GetByID( 60 it->extension_id); 61 if (imported_extension && 62 extensions::SharedModuleInfo::IsSharedModule(imported_extension) && 63 HostIsInSet(it->extension_id, whitelist)) { 64 return true; 65 } 66 } 67 } 68 69 return false; 70 } 71 72 bool IsHostAllowedByCommandLine(const GURL& url, 73 const ExtensionSet* extension_set, 74 const char* command_line_switch) { 75 if (!url.is_valid()) 76 return false; 77 78 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 79 const std::string allowed_list = 80 command_line.GetSwitchValueASCII(command_line_switch); 81 if (allowed_list.empty()) 82 return false; 83 84 const std::string host = url.host(); 85 if (allowed_list == "*") { 86 // For now, we only allow packaged and platform apps in this wildcard. 87 if (!extension_set || !url.SchemeIs(extensions::kExtensionScheme)) 88 return false; 89 90 const Extension* extension = extension_set->GetByID(host); 91 return extension && 92 (extension->GetType() == Manifest::TYPE_LEGACY_PACKAGED_APP || 93 extension->GetType() == Manifest::TYPE_PLATFORM_APP); 94 } 95 96 base::StringTokenizer t(allowed_list, ","); 97 while (t.GetNext()) { 98 if (t.token() == host) 99 return true; 100 } 101 102 return false; 103 } 104 105 } // namespace chrome 106