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 "extensions/common/manifest_handlers/sandboxed_page_info.h" 6 7#include "base/lazy_instance.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/utf_string_conversions.h" 11#include "base/values.h" 12#include "extensions/common/csp_validator.h" 13#include "extensions/common/error_utils.h" 14#include "extensions/common/manifest_constants.h" 15#include "extensions/common/url_pattern.h" 16 17namespace extensions { 18 19namespace { 20 21namespace keys = extensions::manifest_keys; 22namespace errors = manifest_errors; 23 24const char kDefaultSandboxedPageContentSecurityPolicy[] = 25 "sandbox allow-scripts allow-forms allow-popups"; 26 27static base::LazyInstance<SandboxedPageInfo> g_empty_sandboxed_info = 28 LAZY_INSTANCE_INITIALIZER; 29 30const SandboxedPageInfo& GetSandboxedPageInfo(const Extension* extension) { 31 SandboxedPageInfo* info = static_cast<SandboxedPageInfo*>( 32 extension->GetManifestData(keys::kSandboxedPages)); 33 return info ? *info : g_empty_sandboxed_info.Get(); 34} 35 36} // namespace 37 38SandboxedPageInfo::SandboxedPageInfo() { 39} 40 41SandboxedPageInfo::~SandboxedPageInfo() { 42} 43 44const std::string& SandboxedPageInfo::GetContentSecurityPolicy( 45 const Extension* extension) { 46 return GetSandboxedPageInfo(extension).content_security_policy; 47} 48 49const URLPatternSet& SandboxedPageInfo::GetPages(const Extension* extension) { 50 return GetSandboxedPageInfo(extension).pages; 51} 52 53bool SandboxedPageInfo::IsSandboxedPage(const Extension* extension, 54 const std::string& relative_path) { 55 return extension->ResourceMatches(GetPages(extension), relative_path); 56} 57 58SandboxedPageHandler::SandboxedPageHandler() { 59} 60 61SandboxedPageHandler::~SandboxedPageHandler() { 62} 63 64bool SandboxedPageHandler::Parse(Extension* extension, base::string16* error) { 65 scoped_ptr<SandboxedPageInfo> sandboxed_info(new SandboxedPageInfo); 66 67 const base::ListValue* list_value = NULL; 68 if (!extension->manifest()->GetList(keys::kSandboxedPages, &list_value)) { 69 *error = base::ASCIIToUTF16(errors::kInvalidSandboxedPagesList); 70 return false; 71 } 72 73 for (size_t i = 0; i < list_value->GetSize(); ++i) { 74 std::string relative_path; 75 if (!list_value->GetString(i, &relative_path)) { 76 *error = ErrorUtils::FormatErrorMessageUTF16( 77 errors::kInvalidSandboxedPage, base::IntToString(i)); 78 return false; 79 } 80 URLPattern pattern(URLPattern::SCHEME_EXTENSION); 81 if (pattern.Parse(extension->url().spec()) != URLPattern::PARSE_SUCCESS) { 82 *error = ErrorUtils::FormatErrorMessageUTF16( 83 errors::kInvalidURLPatternError, extension->url().spec()); 84 return false; 85 } 86 while (relative_path[0] == '/') 87 relative_path = relative_path.substr(1, relative_path.length() - 1); 88 pattern.SetPath(pattern.path() + relative_path); 89 sandboxed_info->pages.AddPattern(pattern); 90 } 91 92 if (extension->manifest()->HasPath(keys::kSandboxedPagesCSP)) { 93 if (!extension->manifest()->GetString( 94 keys::kSandboxedPagesCSP, 95 &sandboxed_info->content_security_policy)) { 96 *error = base::ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP); 97 return false; 98 } 99 100 if (!csp_validator::ContentSecurityPolicyIsLegal( 101 sandboxed_info->content_security_policy) || 102 !csp_validator::ContentSecurityPolicyIsSandboxed( 103 sandboxed_info->content_security_policy, extension->GetType())) { 104 *error = base::ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP); 105 return false; 106 } 107 } else { 108 sandboxed_info->content_security_policy = 109 kDefaultSandboxedPageContentSecurityPolicy; 110 CHECK(csp_validator::ContentSecurityPolicyIsSandboxed( 111 sandboxed_info->content_security_policy, extension->GetType())); 112 } 113 114 extension->SetManifestData(keys::kSandboxedPages, sandboxed_info.release()); 115 return true; 116} 117 118const std::vector<std::string> SandboxedPageHandler::Keys() const { 119 return SingleKey(keys::kSandboxedPages); 120} 121 122} // namespace extensions 123