123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- // Copyright (c) 2010 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/http/mock_gssapi_library_posix.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace net {
- namespace test {
- struct GssNameMockImpl {
- std::string name;
- gss_OID_desc name_type;
- static GssNameMockImpl* FromGssName(gss_name_t name) {
- return reinterpret_cast<GssNameMockImpl*>(name);
- }
- static gss_name_t ToGssName(GssNameMockImpl* name) {
- return reinterpret_cast<gss_name_t>(name);
- }
- };
- } // namespace test
- 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 = nullptr;
- }
- 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);
- }
- // gss_buffer_t helpers.
- void ClearBuffer(gss_buffer_t dest) {
- if (!dest)
- return;
- dest->length = 0;
- if (dest->value) {
- delete[] reinterpret_cast<char*>(dest->value);
- dest->value = nullptr;
- }
- }
- void SetBuffer(gss_buffer_t dest, const void* src, size_t length) {
- if (!dest)
- return;
- ClearBuffer(dest);
- if (!src)
- return;
- dest->length = length;
- if (length) {
- dest->value = new char[length];
- memcpy(dest->value, src, length);
- }
- }
- void CopyBuffer(gss_buffer_t dest, const gss_buffer_t src) {
- if (!dest)
- return;
- ClearBuffer(dest);
- if (!src)
- return;
- SetBuffer(dest, src->value, src->length);
- }
- std::string BufferToString(const gss_buffer_t src) {
- std::string dest;
- if (!src)
- return dest;
- const char* string = reinterpret_cast<char*>(src->value);
- dest.assign(string, src->length);
- return dest;
- }
- void BufferFromString(const std::string& src, gss_buffer_t dest) {
- if (!dest)
- return;
- SetBuffer(dest, src.c_str(), src.length());
- }
- // gss_name_t helpers.
- void ClearName(gss_name_t dest) {
- if (!dest)
- return;
- auto* name = test::GssNameMockImpl::FromGssName(dest);
- name->name.clear();
- ClearOid(&name->name_type);
- }
- void SetName(gss_name_t dest, const void* src, size_t length) {
- if (!dest)
- return;
- ClearName(dest);
- if (!src)
- return;
- auto* name = test::GssNameMockImpl::FromGssName(dest);
- name->name.assign(reinterpret_cast<const char*>(src), length);
- }
- gss_name_t NameFromString(const std::string& src) {
- gss_name_t dest = test::GssNameMockImpl::ToGssName(
- new test::GssNameMockImpl{"", {0, nullptr}});
- SetName(dest, src.c_str(), src.length());
- return dest;
- }
- } // 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,
- OM_uint32 lifetime_rec_in,
- const gss_OID_desc& mech_type_in,
- OM_uint32 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);
- }
- void GssContextMockImpl::Assign(
- const GssContextMockImpl& other) {
- if (&other == this)
- return;
- src_name = other.src_name;
- targ_name = other.targ_name;
- lifetime_rec = other.lifetime_rec;
- CopyOid(&mech_type, &other.mech_type);
- ctx_flags = other.ctx_flags;
- locally_initiated = other.locally_initiated;
- open = other.open;
- }
- MockGSSAPILibrary::SecurityContextQuery::SecurityContextQuery()
- : expected_package(),
- response_code(0),
- minor_response_code(0),
- context_info() {
- expected_input_token.length = 0;
- expected_input_token.value = nullptr;
- output_token.length = 0;
- output_token.value = nullptr;
- }
- MockGSSAPILibrary::SecurityContextQuery::SecurityContextQuery(
- const std::string& in_expected_package,
- OM_uint32 in_response_code,
- OM_uint32 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.length = strlen(in_expected_input_token);
- expected_input_token.value = const_cast<char*>(in_expected_input_token);
- } else {
- expected_input_token.length = 0;
- expected_input_token.value = nullptr;
- }
- if (in_output_token) {
- output_token.length = strlen(in_output_token);
- output_token.value = const_cast<char*>(in_output_token);
- } else {
- output_token.length = 0;
- output_token.value = nullptr;
- }
- }
- MockGSSAPILibrary::SecurityContextQuery::SecurityContextQuery(
- const SecurityContextQuery& other) = default;
- MockGSSAPILibrary::SecurityContextQuery::~SecurityContextQuery() = default;
- MockGSSAPILibrary::MockGSSAPILibrary() = default;
- MockGSSAPILibrary::~MockGSSAPILibrary() = default;
- void MockGSSAPILibrary::ExpectSecurityContext(
- const std::string& expected_package,
- OM_uint32 response_code,
- OM_uint32 minor_response_code,
- const GssContextMockImpl& context_info,
- const gss_buffer_desc& expected_input_token,
- const gss_buffer_desc& output_token) {
- SecurityContextQuery security_query;
- security_query.expected_package = expected_package;
- security_query.response_code = response_code;
- security_query.minor_response_code = minor_response_code;
- security_query.context_info.Assign(context_info);
- security_query.expected_input_token = expected_input_token;
- security_query.output_token = output_token;
- expected_security_queries_.push_back(security_query);
- }
- bool MockGSSAPILibrary::Init(const NetLogWithSource&) {
- return true;
- }
- // These methods match the ones in the GSSAPI library.
- OM_uint32 MockGSSAPILibrary::import_name(
- OM_uint32* minor_status,
- const gss_buffer_t input_name_buffer,
- const gss_OID input_name_type,
- gss_name_t* output_name) {
- if (minor_status)
- *minor_status = 0;
- if (!output_name)
- return GSS_S_BAD_NAME;
- if (!input_name_buffer)
- return GSS_S_CALL_BAD_STRUCTURE;
- if (!input_name_type)
- return GSS_S_BAD_NAMETYPE;
- GssNameMockImpl* output = new GssNameMockImpl;
- if (output == nullptr)
- return GSS_S_FAILURE;
- output->name_type.length = 0;
- output->name_type.elements = nullptr;
- // Save the data.
- output->name = BufferToString(input_name_buffer);
- CopyOid(&output->name_type, input_name_type);
- *output_name = test::GssNameMockImpl::ToGssName(output);
- return GSS_S_COMPLETE;
- }
- OM_uint32 MockGSSAPILibrary::release_name(
- OM_uint32* minor_status,
- gss_name_t* input_name) {
- if (minor_status)
- *minor_status = 0;
- if (!input_name)
- return GSS_S_BAD_NAME;
- if (!*input_name)
- return GSS_S_COMPLETE;
- GssNameMockImpl* name = GssNameMockImpl::FromGssName(*input_name);
- ClearName(*input_name);
- delete name;
- *input_name = GSS_C_NO_NAME;
- return GSS_S_COMPLETE;
- }
- OM_uint32 MockGSSAPILibrary::release_buffer(
- OM_uint32* minor_status,
- gss_buffer_t buffer) {
- if (minor_status)
- *minor_status = 0;
- if (!buffer)
- return GSS_S_BAD_NAME;
- ClearBuffer(buffer);
- return GSS_S_COMPLETE;
- }
- OM_uint32 MockGSSAPILibrary::display_name(
- OM_uint32* minor_status,
- const gss_name_t input_name,
- gss_buffer_t output_name_buffer,
- gss_OID* output_name_type) {
- if (minor_status)
- *minor_status = 0;
- if (!input_name)
- return GSS_S_BAD_NAME;
- if (!output_name_buffer)
- return GSS_S_CALL_BAD_STRUCTURE;
- if (!output_name_type)
- return GSS_S_CALL_BAD_STRUCTURE;
- GssNameMockImpl* internal_name = GssNameMockImpl::FromGssName(input_name);
- std::string name = internal_name->name;
- BufferFromString(name, output_name_buffer);
- if (output_name_type) {
- *output_name_type =
- internal_name ? &internal_name->name_type : GSS_C_NO_OID;
- }
- return GSS_S_COMPLETE;
- }
- OM_uint32 MockGSSAPILibrary::display_status(
- OM_uint32* minor_status,
- OM_uint32 status_value,
- int status_type,
- const gss_OID mech_type,
- OM_uint32* message_context,
- gss_buffer_t status_string) {
- OM_uint32 rv = GSS_S_COMPLETE;
- *minor_status = 0;
- std::string msg;
- switch (static_cast<DisplayStatusSpecials>(status_value)) {
- case DisplayStatusSpecials::MultiLine:
- msg = base::StringPrintf("Line %u for status %u", ++*message_context,
- status_value);
- if (*message_context >= 5u)
- *message_context = 0u;
- break;
- case DisplayStatusSpecials::InfiniteLines:
- msg = base::StringPrintf("Line %u for status %u", ++*message_context,
- status_value);
- break;
- case DisplayStatusSpecials::Fail:
- rv = GSS_S_BAD_MECH;
- msg = "You should not see this";
- EXPECT_EQ(*message_context, 0u);
- break;
- case DisplayStatusSpecials::EmptyMessage:
- EXPECT_EQ(*message_context, 0u);
- break;
- case DisplayStatusSpecials::UninitalizedBuffer:
- EXPECT_EQ(*message_context, 0u);
- return GSS_S_COMPLETE;
- case DisplayStatusSpecials::InvalidUtf8:
- msg = "\xff\xff\xff";
- EXPECT_EQ(*message_context, 0u);
- break;
- default:
- msg = base::StringPrintf("Value: %u, Type %u", status_value, status_type);
- EXPECT_EQ(*message_context, 0u);
- }
- BufferFromString(msg, status_string);
- return rv;
- }
- OM_uint32 MockGSSAPILibrary::init_sec_context(
- OM_uint32* minor_status,
- const gss_cred_id_t initiator_cred_handle,
- gss_ctx_id_t* context_handle,
- const gss_name_t target_name,
- const gss_OID mech_type,
- OM_uint32 req_flags,
- OM_uint32 time_req,
- const gss_channel_bindings_t input_chan_bindings,
- const gss_buffer_t input_token,
- gss_OID* actual_mech_type,
- gss_buffer_t output_token,
- OM_uint32* ret_flags,
- OM_uint32* time_rec) {
- if (minor_status)
- *minor_status = 0;
- if (!context_handle)
- return GSS_S_CALL_BAD_STRUCTURE;
- GssContextMockImpl** internal_context_handle =
- reinterpret_cast<test::GssContextMockImpl**>(context_handle);
- // Create it if necessary.
- if (!*internal_context_handle) {
- *internal_context_handle = new GssContextMockImpl;
- }
- EXPECT_TRUE(*internal_context_handle);
- GssContextMockImpl& context = **internal_context_handle;
- if (expected_security_queries_.empty()) {
- return GSS_S_UNAVAILABLE;
- }
- SecurityContextQuery security_query = expected_security_queries_.front();
- expected_security_queries_.pop_front();
- EXPECT_EQ(std::string("Negotiate"), security_query.expected_package);
- OM_uint32 major_status = security_query.response_code;
- if (minor_status)
- *minor_status = security_query.minor_response_code;
- context.src_name = security_query.context_info.src_name;
- context.targ_name = security_query.context_info.targ_name;
- context.lifetime_rec = security_query.context_info.lifetime_rec;
- CopyOid(&context.mech_type, &security_query.context_info.mech_type);
- context.ctx_flags = security_query.context_info.ctx_flags;
- context.locally_initiated = security_query.context_info.locally_initiated;
- context.open = security_query.context_info.open;
- if (!input_token) {
- EXPECT_FALSE(security_query.expected_input_token.length);
- } else {
- EXPECT_EQ(input_token->length, security_query.expected_input_token.length);
- if (input_token->length) {
- EXPECT_EQ(0, memcmp(input_token->value,
- security_query.expected_input_token.value,
- input_token->length));
- }
- }
- CopyBuffer(output_token, &security_query.output_token);
- if (actual_mech_type)
- CopyOid(*actual_mech_type, mech_type);
- if (ret_flags)
- *ret_flags = req_flags;
- return major_status;
- }
- OM_uint32 MockGSSAPILibrary::wrap_size_limit(
- OM_uint32* minor_status,
- const gss_ctx_id_t context_handle,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_output_size,
- OM_uint32* max_input_size) {
- if (minor_status)
- *minor_status = 0;
- ADD_FAILURE();
- return GSS_S_UNAVAILABLE;
- }
- OM_uint32 MockGSSAPILibrary::delete_sec_context(
- OM_uint32* minor_status,
- gss_ctx_id_t* context_handle,
- gss_buffer_t output_token) {
- if (minor_status)
- *minor_status = 0;
- if (!context_handle)
- return GSS_S_CALL_BAD_STRUCTURE;
- GssContextMockImpl** internal_context_handle =
- reinterpret_cast<GssContextMockImpl**>(context_handle);
- if (*internal_context_handle) {
- delete *internal_context_handle;
- *internal_context_handle = nullptr;
- }
- return GSS_S_COMPLETE;
- }
- OM_uint32 MockGSSAPILibrary::inquire_context(
- OM_uint32* minor_status,
- const gss_ctx_id_t context_handle,
- gss_name_t* src_name,
- gss_name_t* targ_name,
- OM_uint32* lifetime_rec,
- gss_OID* mech_type,
- OM_uint32* ctx_flags,
- int* locally_initiated,
- int* open) {
- if (minor_status)
- *minor_status = 0;
- if (!context_handle)
- return GSS_S_CALL_BAD_STRUCTURE;
- GssContextMockImpl* internal_context_ptr =
- reinterpret_cast<GssContextMockImpl*>(context_handle);
- GssContextMockImpl& context = *internal_context_ptr;
- if (src_name)
- *src_name = NameFromString(context.src_name);
- if (targ_name)
- *targ_name = NameFromString(context.targ_name);
- if (lifetime_rec)
- *lifetime_rec = context.lifetime_rec;
- if (mech_type)
- CopyOid(*mech_type, &context.mech_type);
- if (ctx_flags)
- *ctx_flags = context.ctx_flags;
- if (locally_initiated)
- *locally_initiated = context.locally_initiated;
- if (open)
- *open = context.open;
- return GSS_S_COMPLETE;
- }
- const std::string& MockGSSAPILibrary::GetLibraryNameForTesting() {
- return library_name_;
- }
- } // namespace test
- } // namespace net
|