// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/android/dummy_spnego_authenticator.h"

#include "base/android/jni_string.h"
#include "base/base64.h"
#include "net/test/jni/DummySpnegoAuthenticator_jni.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

// iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2)
// From RFC 4178, which uses SNEGO not SPNEGO.
static const unsigned char kSpnegoOid[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x02};
gss_OID_desc CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL = {
    arraysize(kSpnegoOid),
    const_cast<unsigned char*>(kSpnegoOid)};

gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC = &CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL;

namespace {

// gss_OID helpers.
// NOTE: gss_OID's do not own the data they point to, which should be static.
void ClearOid(gss_OID dest) {
  if (!dest)
    return;
  dest->length = 0;
  dest->elements = NULL;
}

void SetOid(gss_OID dest, const void* src, size_t length) {
  if (!dest)
    return;
  ClearOid(dest);
  if (!src)
    return;
  dest->length = length;
  if (length)
    dest->elements = const_cast<void*>(src);
}

void CopyOid(gss_OID dest, const gss_OID_desc* src) {
  if (!dest)
    return;
  ClearOid(dest);
  if (!src)
    return;
  SetOid(dest, src->elements, src->length);
}

}  // namespace

namespace test {

GssContextMockImpl::GssContextMockImpl()
    : lifetime_rec(0), ctx_flags(0), locally_initiated(0), open(0) {
  ClearOid(&mech_type);
}

GssContextMockImpl::GssContextMockImpl(const GssContextMockImpl& other)
    : src_name(other.src_name),
      targ_name(other.targ_name),
      lifetime_rec(other.lifetime_rec),
      ctx_flags(other.ctx_flags),
      locally_initiated(other.locally_initiated),
      open(other.open) {
  CopyOid(&mech_type, &other.mech_type);
}

GssContextMockImpl::GssContextMockImpl(const char* src_name_in,
                                       const char* targ_name_in,
                                       uint32_t lifetime_rec_in,
                                       const gss_OID_desc& mech_type_in,
                                       uint32_t ctx_flags_in,
                                       int locally_initiated_in,
                                       int open_in)
    : src_name(src_name_in ? src_name_in : ""),
      targ_name(targ_name_in ? targ_name_in : ""),
      lifetime_rec(lifetime_rec_in),
      ctx_flags(ctx_flags_in),
      locally_initiated(locally_initiated_in),
      open(open_in) {
  CopyOid(&mech_type, &mech_type_in);
}

GssContextMockImpl::~GssContextMockImpl() {
  ClearOid(&mech_type);
}

}  // namespace test

namespace android {

DummySpnegoAuthenticator::SecurityContextQuery::SecurityContextQuery(
    const std::string& in_expected_package,
    uint32_t in_response_code,
    uint32_t in_minor_response_code,
    const test::GssContextMockImpl& in_context_info,
    const std::string& in_expected_input_token,
    const std::string& in_output_token)
    : expected_package(in_expected_package),
      response_code(in_response_code),
      minor_response_code(in_minor_response_code),
      context_info(in_context_info),
      expected_input_token(in_expected_input_token),
      output_token(in_output_token) {
}

DummySpnegoAuthenticator::SecurityContextQuery::SecurityContextQuery(
    const std::string& in_expected_package,
    uint32_t in_response_code,
    uint32_t in_minor_response_code,
    const test::GssContextMockImpl& in_context_info,
    const char* in_expected_input_token,
    const char* in_output_token)
    : expected_package(in_expected_package),
      response_code(in_response_code),
      minor_response_code(in_minor_response_code),
      context_info(in_context_info) {
  if (in_expected_input_token)
    expected_input_token = in_expected_input_token;
  if (in_output_token)
    output_token = in_output_token;
}

DummySpnegoAuthenticator::SecurityContextQuery::SecurityContextQuery()
    : response_code(0), minor_response_code(0) {
}

DummySpnegoAuthenticator::SecurityContextQuery::~SecurityContextQuery() {
}

base::android::ScopedJavaLocalRef<jstring>
DummySpnegoAuthenticator::SecurityContextQuery::GetTokenToReturn(
    JNIEnv* env,
    jobject /*obj*/) {
  return base::android::ConvertUTF8ToJavaString(env, output_token.c_str());
}
int DummySpnegoAuthenticator::SecurityContextQuery::GetResult(JNIEnv* /*env*/,
                                                              jobject /*obj*/) {
  return response_code;
}

void DummySpnegoAuthenticator::SecurityContextQuery::CheckGetTokenArguments(
    JNIEnv* env,
    jobject /*obj*/,
    jstring j_incoming_token) {
  std::string incoming_token =
      base::android::ConvertJavaStringToUTF8(env, j_incoming_token);
  EXPECT_EQ(expected_input_token, incoming_token);
}

// Needed to satisfy "complex class" clang requirements.
DummySpnegoAuthenticator::DummySpnegoAuthenticator() {
}

DummySpnegoAuthenticator::~DummySpnegoAuthenticator() {
}

void DummySpnegoAuthenticator::EnsureTestAccountExists() {
  Java_DummySpnegoAuthenticator_ensureTestAccountExists(
      base::android::AttachCurrentThread());
}

void DummySpnegoAuthenticator::RemoveTestAccounts() {
  Java_DummySpnegoAuthenticator_removeTestAccounts(
      base::android::AttachCurrentThread());
}

void DummySpnegoAuthenticator::ExpectSecurityContext(
    const std::string& expected_package,
    uint32_t response_code,
    uint32_t minor_response_code,
    const test::GssContextMockImpl& context_info,
    const std::string& expected_input_token,
    const std::string& output_token) {
  SecurityContextQuery query(expected_package, response_code,
                             minor_response_code, context_info,
                             expected_input_token, output_token);
  expected_security_queries_.push_back(query);
  Java_DummySpnegoAuthenticator_setNativeAuthenticator(
      base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this));
}

bool DummySpnegoAuthenticator::RegisterJni(JNIEnv* env) {
  return RegisterNativesImpl(env);
}

long DummySpnegoAuthenticator::GetNextQuery(JNIEnv* /*env*/,
                                            jobject /* obj */) {
  CheckQueueNotEmpty();
  current_query_ = expected_security_queries_.front();
  expected_security_queries_.pop_front();
  return reinterpret_cast<intptr_t>(&current_query_);
}

void DummySpnegoAuthenticator::CheckQueueNotEmpty() {
  ASSERT_FALSE(expected_security_queries_.empty());
}

}  // namespace android
}  // namespace net
