// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "rpc/cookie-util.h"

#include <gutil/strings/escaping.h>
#include <gutil/strings/split.h>
#include <gutil/strings/strcat.h>
#include <gutil/strings/strip.h>

#include "util/network-util.h"
#include "util/openssl-util.h"
#include "util/string-parser.h"

DECLARE_bool(ldap_passwords_in_clear_ok);
DEFINE_int64(max_cookie_lifetime_s, 24 * 60 * 60,
    "Maximum amount of time in seconds that an authentication cookie will remain valid. "
    "Setting to 0 disables use of cookies. Defaults to 1 day.");

using namespace strings;

namespace impala {

// Used to separate values in cookies. All generated cookies will be of the form:
// <signature>&<username>&<timestamp>&<random number>
static const string COOKIE_SEPARATOR = "&";

// Cookies generated and processed by the HTTP server will be of the form:
// COOKIE_NAME=<cookie>
static const string COOKIE_NAME = "impala.auth";

// The maximum lenth for the base64 encoding of a SHA256 hash.
static const int SHA256_BASE64_LEN =
    CalculateBase64EscapedLen(AuthenticationHash::HashLen(), /* do_padding */ true);

// Since we only return cookies with a single name, well behaved clients should only ever
// return one cookie to us. To accomodate non-malicious but poorly behaved clients, we
// allow for checking a limited number of cookies, up to MAX_COOKIES_TO_CHECK or until we
// find the first one with COOKIE_NAME.
static const int MAX_COOKIES_TO_CHECK = 5;

Status AuthenticateCookie(
    const AuthenticationHash& hash, const string& cookie_header, string* username) {
  // The 'Cookie' header allows sending multiple name/value pairs separated by ';'.
  vector<string> cookies = strings::Split(cookie_header, ";");
  if (cookies.size() > MAX_COOKIES_TO_CHECK) {
    LOG(WARNING) << "Received cookie header with large number of cookies: "
                 << cookie_header << ". Only checking the first " << MAX_COOKIES_TO_CHECK
                 << " cookies.";
  }
  for (int i = 0; i < cookies.size() && i < MAX_COOKIES_TO_CHECK; ++i) {
    string cookie_pair = cookies[i];
    StripWhiteSpace(&cookie_pair);
    string cookie;
    if (!TryStripPrefixString(cookie_pair, StrCat(COOKIE_NAME, "="), &cookie)) {
      continue;
    }
    if (cookie[0] == '"' && cookie[cookie.length() - 1] == '"') {
      cookie = cookie.substr(1, cookie.length() - 2);
    }
    // Split the cookie into the signature and the cookie value.
    vector<string> cookie_split = Split(cookie, delimiter::Limit(COOKIE_SEPARATOR, 1));
    if (cookie_split.size() != 2) {
      return Status("The cookie has an invalid format.");
    }
    const string& base64_signature = cookie_split[0];
    const string& cookie_value = cookie_split[1];

    string signature;
    if (!WebSafeBase64Unescape(base64_signature, &signature)) {
      return Status("Unable to decode base64 signature.");
    }
    if (signature.length() != AuthenticationHash::HashLen()) {
      return Status("Signature is an incorrect length.");
    }
    bool verified = hash.Verify(reinterpret_cast<const uint8_t*>(cookie_value.data()),
        cookie_value.length(), reinterpret_cast<const uint8_t*>(signature.data()));
    if (!verified) {
      return Status("The signature is incorrect.");
    }

    // Split the cookie value into username, timestamp, and random number.
    vector<string> cookie_value_split = Split(cookie_value, COOKIE_SEPARATOR);
    if (cookie_value_split.size() != 3) {
      return Status("The cookie value has an invalid format.");
    }
    StringParser::ParseResult result;
    int64_t create_time = StringParser::StringToInt<int64_t>(
        cookie_value_split[1].c_str(), cookie_value_split[1].length(), &result);
    if (result != StringParser::PARSE_SUCCESS) {
      return Status("Could not parse cookie timestamp.");
    }
    // Check that the timestamp contained in the cookie is recent enough for the cookie
    // to still be valid.
    if (MonotonicMillis() - create_time <= FLAGS_max_cookie_lifetime_s * 1000) {
      // We've successfully authenticated.
      *username = cookie_value_split[0];
      return Status::OK();
    } else {
      return Status("Cookie is past its max lifetime.");
    }
  }

  return Status(Substitute("Did not find expected cookie name: $0", COOKIE_NAME));
}

string GenerateCookie(const string& username, const AuthenticationHash& hash) {
  // Its okay to use rand() here even though its a weak RNG because being able to guess
  // the random numbers generated won't help an attacker. The important thing is that
  // we're using a strong RNG to create the key and a strong HMAC function.
  string cookie_value =
      StrCat(username, COOKIE_SEPARATOR, MonotonicMillis(), COOKIE_SEPARATOR, rand());
  uint8_t signature[AuthenticationHash::HashLen()];
  Status compute_status =
      hash.Compute(reinterpret_cast<const uint8_t*>(cookie_value.data()),
          cookie_value.length(), signature);
  if (!compute_status.ok()) {
    LOG(ERROR) << "Failed to compute cookie signature: " << compute_status;
    return "";
  }
  DCHECK_EQ(SHA256_BASE64_LEN, 44);
  char base64_signature[SHA256_BASE64_LEN + 1];
  WebSafeBase64Escape(signature, AuthenticationHash::HashLen(), base64_signature,
      SHA256_BASE64_LEN, /* do_padding */ true);
  base64_signature[SHA256_BASE64_LEN] = '\0';

  const char* secure_flag = ";Secure";
  if (FLAGS_ldap_passwords_in_clear_ok) {
    // If the user specified password can be sent without TLS/SSL, don't include the
    // 'Secure' flag, which indicates the cookie should only be returned over secured
    // connections. This is for testing only.
    secure_flag = "";
  }
  return Substitute("$0=$1$2$3;HttpOnly;Max-Age=$4$5", COOKIE_NAME, base64_signature,
      COOKIE_SEPARATOR, cookie_value, FLAGS_max_cookie_lifetime_s, secure_flag);
}

string GetDeleteCookie() {
  return Substitute("$0=;HttpOnly;Max-Age=0", COOKIE_NAME);
}

} // namespace impala
