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