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 // We check the whitelist explicitly even though the extension should 66 // never have been allowed to be installed in the first place if this 67 // fails. See SharedModuleService::CheckImports for details. 68 SharedModuleInfo::IsExportAllowedByWhitelist(imported_extension, 69 host) && 70 HostIsInSet(it->extension_id, whitelist)) { 71 return true; 72 } 73 } 74 75 return false; 76 } 77 78 bool IsHostAllowedByCommandLine(const GURL& url, 79 const extensions::ExtensionSet* extension_set, 80 const char* command_line_switch) { 81 if (!url.is_valid()) 82 return false; 83 84 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 85 const std::string allowed_list = 86 command_line.GetSwitchValueASCII(command_line_switch); 87 if (allowed_list.empty()) 88 return false; 89 90 const std::string host = url.host(); 91 if (allowed_list == "*") { 92 // For now, we only allow packaged and platform apps in this wildcard. 93 if (!extension_set || !url.SchemeIs(extensions::kExtensionScheme)) 94 return false; 95 96 const Extension* extension = extension_set->GetByID(host); 97 return extension && 98 (extension->GetType() == Manifest::TYPE_LEGACY_PACKAGED_APP || 99 extension->GetType() == Manifest::TYPE_PLATFORM_APP); 100 } 101 102 base::StringTokenizer t(allowed_list, ","); 103 while (t.GetNext()) { 104 if (t.token() == host) 105 return true; 106 } 107 108 return false; 109 } 110 111 } // namespace chrome 112