/*
 * 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.
 */

#ifndef COBALT_CSP_CONTENT_SECURITY_POLICY_H_
#define COBALT_CSP_CONTENT_SECURITY_POLICY_H_

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "cobalt/csp/parsers.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_response_headers.h"

namespace cobalt {
namespace csp {

class DirectiveList;
class Source;

// Wrap up information about a CSP violation, for passing to the Delegate.
struct ViolationInfo {
  std::string directive_text;
  std::string effective_directive;
  std::string console_message;
  GURL blocked_url;
  std::vector<std::string> endpoints;
  std::string header;
};

// A callback that a URL fetcher will call to check if the URL is permitted
// by our security policy. This may be called multiple times if the URL results
// in a redirect. The callback should return |true| if the URL is safe to
// load.
typedef base::Callback<bool(const GURL& url, bool did_redirect)>
    SecurityCallback;
typedef base::Callback<void(const ViolationInfo&)> ViolationCallback;

// Extract CSP-related headers from HttpResponseHeaders.
class ResponseHeaders {
 public:
  ResponseHeaders() {}
  explicit ResponseHeaders(
      const scoped_refptr<net::HttpResponseHeaders>& response);

  const std::string& content_security_policy() const {
    return content_security_policy_;
  }
  const std::string& content_security_policy_report_only() const {
    return content_security_policy_report_only_;
  }

 private:
  std::string content_security_policy_;
  std::string content_security_policy_report_only_;
};

class ContentSecurityPolicy {
 public:
  typedef ScopedVector<DirectiveList> PolicyList;

  // CSP Level 1 Directives
  static const char kConnectSrc[];
  static const char kDefaultSrc[];
  static const char kFontSrc[];
  static const char kFrameSrc[];
  static const char kImgSrc[];
  static const char kMediaSrc[];
  static const char kObjectSrc[];
  static const char kReportURI[];
  static const char kSandbox[];
  static const char kScriptSrc[];
  static const char kStyleSrc[];

  // CSP Level 2 Directives
  static const char kBaseURI[];
  static const char kChildSrc[];
  static const char kFormAction[];
  static const char kFrameAncestors[];
  static const char kPluginTypes[];
  static const char kReflectedXSS[];
  static const char kReferrer[];

  // Custom CSP directive for Cobalt
  static const char kLocationSrc[];

  // Manifest Directives (to be merged into CSP Level 2)
  // https://w3c.github.io/manifest/#content-security-policy
  static const char kManifestSrc[];

  // Mixed Content Directive
  // https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
  static const char kBlockAllMixedContent[];

  // https://w3c.github.io/webappsec/specs/upgrade/
  static const char kUpgradeInsecureRequests[];

  // Suborigin Directive
  // https://metromoxie.github.io/webappsec/specs/suborigins/index.html
  static const char kSuborigin[];

  enum ReportingStatus {
    kSendReport,
    kSuppressReport,
  };

  // When a resource is loaded after a redirect, source paths are
  // ignored in the matching algorithm.
  enum RedirectStatus {
    kDidRedirect,
    kDidNotRedirect,
  };

  static bool IsDirectiveName(const std::string& name);

  ContentSecurityPolicy(const GURL& url,
                        const ViolationCallback& violation_callback);
  ~ContentSecurityPolicy();

  void OnReceiveHeaders(const ResponseHeaders& headers);
  void OnReceiveHeader(const std::string& header, HeaderType header_type,
                       HeaderSource header_source);
  void SetNavigationPolicy(const std::string& header);

  bool UrlMatchesSelf(const GURL& url) const;
  bool SchemeMatchesSelf(const GURL& url) const;

  void ReportViolation(const std::string& directive_text,
                       const std::string& effective_directive,
                       const std::string& console_message,
                       const GURL& blocked_url,
                       const std::vector<std::string>& report_endpoints,
                       const std::string& header);

  // Diagnostic functions for reporting errors in the CSP directives.
  void ReportInvalidReferrer(const std::string& invalid_value);
  void ReportInvalidPluginTypes(const std::string& invalid_plugin);
  void ReportMetaOutsideHead(const std::string& header);
  void ReportValueForEmptyDirective(const std::string& directive_name,
                                    const std::string& value);
  void ReportDirectiveAsSourceExpression(const std::string& directive_name,
                                         const std::string& source_expression);
  void ReportInvalidSourceExpression(const std::string& directive_name,
                                     const std::string& source);
  void ReportInvalidPathCharacter(const std::string& directive_name,
                                  const std::string& value, char c);
  void ReportDuplicateDirective(const std::string& name);
  void ReportInvalidDirectiveValueCharacter(const std::string& directive_name,
                                            const std::string& value);
  void ReportInvalidReflectedXSS(const std::string& invalid_value);
  void ReportMissingReportURI(const std::string& policy);
  void ReportReportOnlyInMeta(const std::string& header);
  void ReportInvalidSuboriginFlags(const std::string& invalid_flags);
  void ReportUnsupportedDirective(const std::string& name);
  void ReportInvalidInReportOnly(const std::string& name);
  void ReportDirectiveNotSupportedInsideMeta(const std::string& name);

  // https://www.w3.org/TR/2015/CR-CSP2-20150721/#directives
  bool AllowJavaScriptURLs(const std::string& context_url, int context_line,
                           ReportingStatus status = kSendReport) const;
  bool AllowInlineEventHandlers(const std::string& context_url,
                                int context_line,
                                ReportingStatus status = kSendReport) const;
  bool AllowInlineScript(const std::string& context_url, int context_line,
                         const std::string& script_content,
                         ReportingStatus status = kSendReport) const;
  bool AllowInlineStyle(const std::string& context_url, int context_line,
                        const std::string& style_content,
                        ReportingStatus status = kSendReport) const;
  bool AllowEval(ReportingStatus status = kSendReport) const;
  bool AllowScriptFromSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;
  bool AllowObjectFromSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;
  bool AllowImageFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowStyleFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowFontFromSource(const GURL& url,
                           RedirectStatus redirect = kDidNotRedirect,
                           ReportingStatus report = kSendReport) const;
  bool AllowMediaFromSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowConnectToSource(const GURL& url,
                            RedirectStatus redirect = kDidNotRedirect,
                            ReportingStatus report = kSendReport) const;
  bool AllowNavigateToSource(const GURL& url,
                             RedirectStatus redirect = kDidNotRedirect,
                             ReportingStatus report = kSendReport) const;

  bool AllowFormAction(const GURL& url,
                       RedirectStatus redirect = kDidNotRedirect,
                       ReportingStatus report = kSendReport) const;
  bool AllowBaseURI(const GURL& url, RedirectStatus redirect = kDidNotRedirect,
                    ReportingStatus report = kSendReport) const;
  bool AllowManifestFromSource(const GURL& url,
                               RedirectStatus redirect = kDidNotRedirect,
                               ReportingStatus report = kSendReport) const;

  // The nonce and hash allow functions are guaranteed to not have any side
  // effects, including reporting.
  // Nonce/Hash functions check all policies relating to use of a script/style
  // with the given nonce/hash and return true all CSP policies allow it.
  // If these return true, callers can then process the content or
  // issue a load and be safe disabling any further CSP checks.
  bool AllowScriptWithNonce(const std::string& nonce) const;
  bool AllowStyleWithNonce(const std::string& nonce) const;
  bool AllowScriptWithHash(const std::string& source) const;
  bool AllowStyleWithHash(const std::string& source) const;

  void set_uses_script_hash_algorithms(uint8 algorithm) {
    script_hash_algorithms_used_ |= algorithm;
  }
  void set_uses_style_hash_algorithms(uint8 algorithm) {
    style_hash_algorithms_used_ |= algorithm;
  }

  // Configure the origin URL for the document that owns this policy.
  // This could change during loading if the document load is redirected.
  void NotifyUrlChanged(const GURL& url);
  bool DidSetReferrerPolicy() const;

  const GURL& url() const { return url_; }
  void set_enforce_strict_mixed_content_checking() {
    enforce_strict_mixed_content_checking_ = true;
  }

  const std::string& disable_eval_error_message() const {
    return disable_eval_error_message_;
  }

 private:
  void CreateSelfSource();
  // Parses CSP header and creates policy based on that.
  void AddPolicyFromHeaderValue(const std::string& header, HeaderType type,
                                HeaderSource source);

  PolicyList policies_;
  scoped_ptr<DirectiveList> navigation_policy_;
  scoped_ptr<Source> self_source_;
  std::string self_scheme_;
  std::string disable_eval_error_message_;
  GURL url_;

  // Callback to use for reporting CSP violations.
  ViolationCallback violation_callback_;

  // Fields needing initialization.
  // Bitmasks of HashAlgorithm
  uint8 script_hash_algorithms_used_;
  uint8 style_hash_algorithms_used_;
  bool enforce_strict_mixed_content_checking_;
  ReferrerPolicy referrer_policy_;

  DISALLOW_COPY_AND_ASSIGN(ContentSecurityPolicy);
};

}  // namespace csp
}  // namespace cobalt

#endif  // COBALT_CSP_CONTENT_SECURITY_POLICY_H_
