// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/csp/source_list.h"

#include <algorithm>

#include "base/base64.h"
#include "base/string_number_conversions.h"
#include "cobalt/network/socket_address_parser.h"
#include "googleurl/src/url_canon_ip.h"
#include "googleurl/src/url_constants.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"
#include "starboard/socket.h"

namespace cobalt {
namespace csp {

namespace {

bool IsSourceListNone(const char* begin, const char* end) {
  SkipWhile<IsAsciiWhitespace>(&begin, end);

  const char* position = begin;
  SkipWhile<IsSourceCharacter>(&position, end);
  size_t len = static_cast<size_t>(position - begin);
  if (base::strncasecmp("'none'", begin, len) != 0) {
    return false;
  }

  SkipWhile<IsAsciiWhitespace>(&position, end);
  if (position != end) {
    return false;
  }

  return true;
}

struct HashPrefix {
  const char* prefix;
  HashAlgorithm type;
};

HashPrefix kSupportedPrefixes[] = {
    {"'sha256-", kHashAlgorithmSha256},  {"'sha384-", kHashAlgorithmSha384},
    {"'sha512-", kHashAlgorithmSha512},  {"'sha-256-", kHashAlgorithmSha256},
    {"'sha-384-", kHashAlgorithmSha384}, {"'sha-512-", kHashAlgorithmSha512},
};

bool SchemeCanMatchStar(const GURL& url) {
  return !(url.SchemeIs("blob") || url.SchemeIs("data") ||
           url.SchemeIs("filesystem"));
}

bool IsInsecureScheme(const GURL& url) {
  return url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kWsScheme);
}

}  // namespace

SourceList::SourceList(const LocalNetworkCheckerInterface* checker,
                       ContentSecurityPolicy* policy,
                       const std::string& directive_name)
    : policy_(policy),
      directive_name_(directive_name),
      allow_self_(false),
      allow_star_(false),
      allow_inline_(false),
      allow_eval_(false),
      allow_insecure_connections_to_local_network_(false),
      allow_insecure_connections_to_localhost_(false),
      allow_insecure_connections_to_private_range_(false),
      hash_algorithms_used_(0),
      local_network_checker_(checker) {}

bool SourceList::Matches(
    const GURL& url,
    ContentSecurityPolicy::RedirectStatus redirect_status) const {
  if (allow_star_ && SchemeCanMatchStar(url)) {
    return true;
  }

  if (allow_self_ && policy_->UrlMatchesSelf(url)) {
    return true;
  }

  for (size_t i = 0; i < list_.size(); ++i) {
    if (list_[i].Matches(url, redirect_status)) {
      return true;
    }
  }

  if (!url.is_valid() || url.is_empty()) {
    return false;
  }
  // Since url is valid, we can now use possibly_invalid_spec() below.
  const std::string& valid_spec = url.possibly_invalid_spec();

  const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec();

  if (!url.has_host() || !parsed.host.is_valid() ||
      !parsed.host.is_nonempty()) {
    return false;
  }

  if (!IsInsecureScheme(url)) {
    return false;
  }

  if (allow_insecure_connections_to_localhost_) {
    std::string host;
#if SB_HAS(IPV6)
    host = url.HostNoBrackets();
#else
    host.append(valid_spec.c_str() + parsed.host.begin,
                valid_spec.c_str() + parsed.host.begin + parsed.host.len);
#endif
    if (net::IsLocalhost(host)) {
      return true;
    }
  }

  /* allow mixed content for local network or private ranges? */
  if (!(allow_insecure_connections_to_local_network_ ||
        allow_insecure_connections_to_private_range_)) {
    return false;
  }

  SbSocketAddress destination;
  // Note that GetDestinationForHost will only pass if host is a numeric IP.
  if (!cobalt::network::ParseSocketAddress(valid_spec.c_str(), parsed.host,
                                           &destination)) {
    return false;
  }

  if (allow_insecure_connections_to_private_range_ &&
      local_network_checker_->IsIPInPrivateRange(destination)) {
    return true;
  }

  if (allow_insecure_connections_to_local_network_ &&
      local_network_checker_->IsIPInLocalNetwork(destination)) {
    return true;
  }

  return false;
}

bool SourceList::AllowInline() const { return allow_inline_; }

bool SourceList::AllowEval() const { return allow_eval_; }

bool SourceList::AllowNonce(const std::string& nonce) const {
  return !nonce.empty() && nonces_.find(nonce) != nonces_.end();
}

bool SourceList::AllowHash(const HashValue& hash_value) const {
  return hashes_.find(hash_value) != hashes_.end();
}

bool SourceList::hash_or_nonce_present() const {
  return nonces_.size() > 0 || hash_algorithms_used_ != kHashAlgorithmNone;
}

// source-list       = *WSP [ source *( 1*WSP source ) *WSP ]
//                   / *WSP "'none'" *WSP
//
void SourceList::Parse(const base::StringPiece& str) {
  // We represent 'none' as an empty list_.
  const char* begin = str.begin();
  const char* end = str.end();

  if (IsSourceListNone(begin, end)) {
    return;
  }

  const char* position = begin;
  while (position < end) {
    SkipWhile<IsAsciiWhitespace>(&position, end);
    if (position == end) {
      return;
    }

    const char* begin_source = position;
    SkipWhile<IsSourceCharacter>(&position, end);

    SourceConfig config;
    if (ParseSource(begin_source, position, &config)) {
      // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
      // etc.) aren't stored in m_list, but as attributes on the source
      // list itself.
      if (config.scheme.empty() && config.host.empty()) {
        continue;
      }
      if (policy_->IsDirectiveName(config.host)) {
        policy_->ReportDirectiveAsSourceExpression(directive_name_,
                                                   config.host);
      }
      list_.push_back(Source(policy_, config));
    } else {
      policy_->ReportInvalidSourceExpression(directive_name_,
                                             ToString(begin_source, position));
    }

    DCHECK(position == end || IsAsciiWhitespace(*position));
  }
}

// source            = scheme ":"
//                   / ( [ scheme "://" ] host [ port ] [ path ] )
//                   / "'self'"
bool SourceList::ParseSource(const char* begin, const char* end,
                             SourceConfig* config) {
  if (begin == end) {
    return false;
  }

  if (LowerCaseEqualsASCII(begin, end, "'none'")) {
    return false;
  }

  base::StringPiece begin_piece(begin, static_cast<size_t>(end - begin));
  if (begin_piece.length() == 1 && begin_piece[0] == '*') {
    AddSourceStar();
    return true;
  }
  if (LowerCaseEqualsASCII(begin, end, "'self'")) {
    AddSourceSelf();
    return true;
  }

  if (LowerCaseEqualsASCII(begin, end, "'unsafe-inline'")) {
    AddSourceUnsafeInline();
    return true;
  }

  if (LowerCaseEqualsASCII(begin, end, "'unsafe-eval'")) {
    AddSourceUnsafeEval();
    return true;
  }

  if (directive_name_.compare(ContentSecurityPolicy::kConnectSrc) == 0) {
    if (LowerCaseEqualsASCII(begin, end, "'cobalt-insecure-localhost'")) {
      AddSourceLocalhost();
      return true;
    }
    if (LowerCaseEqualsASCII(begin, end, "'cobalt-insecure-local-network'")) {
      AddSourceLocalNetwork();
      return true;
    }
    if (LowerCaseEqualsASCII(begin, end, "'cobalt-insecure-private-range'")) {
      AddSourcePrivateRange();
      return true;
    }
  }

  std::string nonce;
  if (!ParseNonce(begin, end, &nonce)) {
    return false;
  }

  if (!nonce.empty()) {
    AddSourceNonce(nonce);
    return true;
  }

  DigestValue hash;
  HashAlgorithm algorithm = kHashAlgorithmNone;
  if (!ParseHash(begin, end, &hash, &algorithm)) {
    return false;
  }

  if (hash.size() > 0) {
    AddSourceHash(algorithm, hash);
    return true;
  }

  const char* position = begin;
  const char* begin_host = begin;
  const char* begin_path = end;
  const char* begin_port = 0;

  SkipWhile<IsNotColonOrSlash>(&position, end);

  if (position == end) {
    // host
    //     ^
    return ParseHost(begin_host, position, &config->host,
                     &config->host_wildcard);
  }

  if (position < end && *position == '/') {
    // host/path || host/ || /
    //     ^            ^    ^
    return ParseHost(begin_host, position, &config->host,
                     &config->host_wildcard) &&
           ParsePath(position, end, &config->path);
  }

  if (position < end && *position == ':') {
    if (end - position == 1) {
      // scheme:
      //       ^
      return ParseScheme(begin, position, &config->scheme);
    }

    if (position[1] == '/') {
      // scheme://host || scheme://
      //       ^                ^
      if (!ParseScheme(begin, position, &config->scheme) ||
          !SkipExactly(&position, end, ':') ||
          !SkipExactly(&position, end, '/') ||
          !SkipExactly(&position, end, '/')) {
        return false;
      }
      if (position == end) {
        return false;
      }
      begin_host = position;
      SkipWhile<IsNotColonOrSlash>(&position, end);
    }

    if (position < end && *position == ':') {
      // host:port || scheme://host:port
      //     ^                     ^
      begin_port = position;
      SkipUntil(&position, end, '/');
    }
  }

  if (position < end && *position == '/') {
    // scheme://host/path || scheme://host:port/path
    //              ^                          ^
    if (position == begin_host) {
      return false;
    }
    begin_path = position;
  }

  if (!ParseHost(begin_host, begin_port ? begin_port : begin_path,
                 &config->host, &config->host_wildcard)) {
    return false;
  }

  if (begin_port) {
    if (!ParsePort(begin_port, begin_path, &config->port,
                   &config->port_wildcard)) {
      return false;
    }
  } else {
    config->port = url_parse::PORT_UNSPECIFIED;
  }

  if (begin_path != end) {
    if (!ParsePath(begin_path, end, &config->path)) {
      return false;
    }
  }

  return true;
}

// nonce-source      = "'nonce-" nonce-value "'"
// nonce-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
//
bool SourceList::ParseNonce(const char* begin, const char* end,
                            std::string* nonce) {
  size_t nonce_length = static_cast<size_t>(end - begin);
  const char* prefix = "'nonce-";

  if (nonce_length <= strlen(prefix) ||
      base::strncasecmp(prefix, begin, strlen(prefix)) != 0) {
    return true;
  }

  const char* position = begin + strlen(prefix);
  const char* nonce_begin = position;

  DCHECK_LT(position, end);
  SkipWhile<IsNonceCharacter>(&position, end);
  DCHECK_LE(nonce_begin, position);

  if (position + 1 != end || *position != '\'' || position == nonce_begin) {
    return false;
  }

  *nonce = ToString(nonce_begin, position);
  return true;
}

// hash-source       = "'" hash-algorithm "-" hash-value "'"
// hash-algorithm    = "sha1" / "sha256" / "sha384" / "sha512"
// hash-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
//
bool SourceList::ParseHash(const char* begin, const char* end,
                           DigestValue* hash, HashAlgorithm* hash_algorithm) {
  std::string prefix;
  *hash_algorithm = kHashAlgorithmNone;
  size_t hash_length = static_cast<size_t>(end - begin);

  for (size_t i = 0; i < arraysize(kSupportedPrefixes); ++i) {
    const HashPrefix& algorithm = kSupportedPrefixes[i];
    if (hash_length > strlen(algorithm.prefix) &&
        base::strncasecmp(algorithm.prefix, begin, strlen(algorithm.prefix)) ==
            0) {
      prefix = algorithm.prefix;
      *hash_algorithm = algorithm.type;
      break;
    }
  }

  if (*hash_algorithm == kHashAlgorithmNone) {
    return true;
  }

  const char* position = begin + prefix.length();
  const char* hash_begin = position;

  DCHECK_LT(position, end);
  SkipWhile<IsBase64EncodedCharacter>(&position, end);
  DCHECK_LE(hash_begin, position);

  // Base64 encodings may end with exactly one or two '=' characters
  if (position < end) {
    SkipExactly(&position, position + 1, '=');
  }
  if (position < end) {
    SkipExactly(&position, position + 1, '=');
  }

  if (position + 1 != end || *position != '\'' || position == hash_begin) {
    return false;
  }

  // We accept base64url-encoded data here by normalizing it to base64.
  // TODO: Blink has a NormalizeToBase64() step here.
  std::string hash_vector;
  base::Base64Decode(
      base::StringPiece(hash_begin, static_cast<size_t>(position - hash_begin)),
      &hash_vector);
  if (hash_vector.size() > kMaxDigestSize) {
    return false;
  }
  hash->assign(hash_vector.begin(), hash_vector.end());
  return true;
}

//                     ; <scheme> production from RFC 3986
// scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
//
bool SourceList::ParseScheme(const char* begin, const char* end,
                             std::string* scheme) {
  DCHECK_LE(begin, end);
  DCHECK(scheme && scheme->empty());

  if (begin == end) {
    return false;
  }

  const char* position = begin;

  if (!SkipExactly<IsAsciiAlpha>(&position, end)) {
    return false;
  }

  SkipWhile<IsSchemeContinuationCharacter>(&position, end);

  if (position != end) {
    return false;
  }

  *scheme = ToString(begin, end);
  return true;
}

// host              = [ "*." ] 1*host-char *( "." 1*host-char )
//                   / "*"
// host-char         = ALPHA / DIGIT / "-"
//
bool SourceList::ParseHost(const char* begin, const char* end,
                           std::string* host,
                           SourceConfig::WildcardDisposition* host_wildcard) {
  DCHECK_LE(begin, end);
  DCHECK(host && host->empty());
  DCHECK(host_wildcard && *host_wildcard == SourceConfig::kNoWildcard);

  if (begin == end) {
    return false;
  }
  const char* position = begin;

  if (SkipExactly(&position, end, '*')) {
    *host_wildcard = SourceConfig::kHasWildcard;

    if (position == end) {
      return true;
    }

    if (!SkipExactly(&position, end, '.')) {
      return false;
    }
  }

  const char* host_begin = position;

  while (position < end) {
    if (!SkipExactly<IsHostCharacter>(&position, end)) {
      return false;
    }

    SkipWhile<IsHostCharacter>(&position, end);

    if (position < end && !SkipExactly(&position, end, '.')) {
      return false;
    }
  }

  DCHECK_EQ(position, end);
  *host = ToString(host_begin, end);
  return true;
}

bool SourceList::ParsePath(const char* begin, const char* end,
                           std::string* path) {
  DCHECK_LE(begin, end);
  DCHECK(path && path->empty());

  const char* position = begin;
  SkipWhile<IsPathComponentCharacter>(&position, end);
  // path/to/file.js?query=string || path/to/file.js#anchor
  //                ^                               ^
  if (position < end) {
    policy_->ReportInvalidPathCharacter(directive_name_, ToString(begin, end),
                                        *position);
  }

  *path = net::UnescapeURLComponent(
      ToString(begin, position),
      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);

  DCHECK_LE(position, end);
  DCHECK(position == end || (*position == '#' || *position == '?'));
  return true;
}

// port              = ":" ( 1*DIGIT / "*" )
//
bool SourceList::ParsePort(const char* begin, const char* end, int* port,
                           SourceConfig::WildcardDisposition* port_wildcard) {
  DCHECK_LE(begin, end);
  DCHECK(port && *port == url_parse::PORT_UNSPECIFIED);
  DCHECK(port_wildcard && *port_wildcard == SourceConfig::kNoWildcard);

  if (!SkipExactly(&begin, end, ':')) {
    NOTREACHED();
  }

  if (begin == end) {
    return false;
  }

  if (end - begin == 1 && *begin == '*') {
    *port = url_parse::PORT_UNSPECIFIED;
    *port_wildcard = SourceConfig::kHasWildcard;
    return true;
  }

  const char* position = begin;
  SkipWhile<IsAsciiDigit>(&position, end);

  if (position != end) {
    return false;
  }

  bool ok = base::StringToInt(
      base::StringPiece(begin, static_cast<size_t>(end - begin)), port);
  return ok;
}

void SourceList::AddSourceLocalhost() {
  allow_insecure_connections_to_localhost_ = true;
}

void SourceList::AddSourceLocalNetwork() {
  allow_insecure_connections_to_local_network_ = true;
}

void SourceList::AddSourcePrivateRange() {
  allow_insecure_connections_to_private_range_ = true;
}

void SourceList::AddSourceSelf() { allow_self_ = true; }

void SourceList::AddSourceStar() { allow_star_ = true; }

void SourceList::AddSourceUnsafeInline() { allow_inline_ = true; }

void SourceList::AddSourceUnsafeEval() { allow_eval_ = true; }

void SourceList::AddSourceNonce(const std::string& nonce) {
  nonces_.insert(nonce);
}

void SourceList::AddSourceHash(const HashAlgorithm& algorithm,
                               const DigestValue& hash) {
  hashes_.insert(HashValue(algorithm, hash));
  hash_algorithms_used_ |= algorithm;
}

}  // namespace csp
}  // namespace cobalt
