| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/http/mock_gssapi_library_posix.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/string_util.h" | |
| 9 #include "base/strings/stringprintf.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace net { | |
| 13 | |
| 14 namespace test { | |
| 15 | |
| 16 struct GssNameMockImpl { | |
| 17 std::string name; | |
| 18 gss_OID_desc name_type; | |
| 19 }; | |
| 20 | |
| 21 } // namespace test | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 // gss_OID helpers. | |
| 26 // NOTE: gss_OID's do not own the data they point to, which should be static. | |
| 27 void ClearOid(gss_OID dest) { | |
| 28 if (!dest) | |
| 29 return; | |
| 30 dest->length = 0; | |
| 31 dest->elements = NULL; | |
| 32 } | |
| 33 | |
| 34 void SetOid(gss_OID dest, const void* src, size_t length) { | |
| 35 if (!dest) | |
| 36 return; | |
| 37 ClearOid(dest); | |
| 38 if (!src) | |
| 39 return; | |
| 40 dest->length = length; | |
| 41 if (length) | |
| 42 dest->elements = const_cast<void*>(src); | |
| 43 } | |
| 44 | |
| 45 void CopyOid(gss_OID dest, const gss_OID_desc* src) { | |
| 46 if (!dest) | |
| 47 return; | |
| 48 ClearOid(dest); | |
| 49 if (!src) | |
| 50 return; | |
| 51 SetOid(dest, src->elements, src->length); | |
| 52 } | |
| 53 | |
| 54 // gss_buffer_t helpers. | |
| 55 void ClearBuffer(gss_buffer_t dest) { | |
| 56 if (!dest) | |
| 57 return; | |
| 58 dest->length = 0; | |
| 59 delete [] reinterpret_cast<char*>(dest->value); | |
| 60 dest->value = NULL; | |
| 61 } | |
| 62 | |
| 63 void SetBuffer(gss_buffer_t dest, const void* src, size_t length) { | |
| 64 if (!dest) | |
| 65 return; | |
| 66 ClearBuffer(dest); | |
| 67 if (!src) | |
| 68 return; | |
| 69 dest->length = length; | |
| 70 if (length) { | |
| 71 dest->value = new char[length]; | |
| 72 memcpy(dest->value, src, length); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 void CopyBuffer(gss_buffer_t dest, const gss_buffer_t src) { | |
| 77 if (!dest) | |
| 78 return; | |
| 79 ClearBuffer(dest); | |
| 80 if (!src) | |
| 81 return; | |
| 82 SetBuffer(dest, src->value, src->length); | |
| 83 } | |
| 84 | |
| 85 std::string BufferToString(const gss_buffer_t src) { | |
| 86 std::string dest; | |
| 87 if (!src) | |
| 88 return dest; | |
| 89 const char* string = reinterpret_cast<char*>(src->value); | |
| 90 dest.assign(string, src->length); | |
| 91 return dest; | |
| 92 } | |
| 93 | |
| 94 void BufferFromString(const std::string& src, gss_buffer_t dest) { | |
| 95 if (!dest) | |
| 96 return; | |
| 97 SetBuffer(dest, src.c_str(), src.length()); | |
| 98 } | |
| 99 | |
| 100 // gss_name_t helpers. | |
| 101 void ClearName(gss_name_t dest) { | |
| 102 if (!dest) | |
| 103 return; | |
| 104 test::GssNameMockImpl* name = reinterpret_cast<test::GssNameMockImpl*>(dest); | |
| 105 name->name.clear(); | |
| 106 ClearOid(&name->name_type); | |
| 107 } | |
| 108 | |
| 109 void SetName(gss_name_t dest, const void* src, size_t length) { | |
| 110 if (!dest) | |
| 111 return; | |
| 112 ClearName(dest); | |
| 113 if (!src) | |
| 114 return; | |
| 115 test::GssNameMockImpl* name = reinterpret_cast<test::GssNameMockImpl*>(dest); | |
| 116 name->name.assign(reinterpret_cast<const char*>(src), length); | |
| 117 } | |
| 118 | |
| 119 std::string NameToString(const gss_name_t& src) { | |
| 120 std::string dest; | |
| 121 if (!src) | |
| 122 return dest; | |
| 123 test::GssNameMockImpl* string = | |
| 124 reinterpret_cast<test::GssNameMockImpl*>(src); | |
| 125 dest = string->name; | |
| 126 return dest; | |
| 127 } | |
| 128 | |
| 129 void NameFromString(const std::string& src, gss_name_t dest) { | |
| 130 if (!dest) | |
| 131 return; | |
| 132 SetName(dest, src.c_str(), src.length()); | |
| 133 } | |
| 134 | |
| 135 } // namespace | |
| 136 | |
| 137 namespace test { | |
| 138 | |
| 139 GssContextMockImpl::GssContextMockImpl() | |
| 140 : lifetime_rec(0), | |
| 141 ctx_flags(0), | |
| 142 locally_initiated(0), | |
| 143 open(0) { | |
| 144 ClearOid(&mech_type); | |
| 145 } | |
| 146 | |
| 147 GssContextMockImpl::GssContextMockImpl(const GssContextMockImpl& other) | |
| 148 : src_name(other.src_name), | |
| 149 targ_name(other.targ_name), | |
| 150 lifetime_rec(other.lifetime_rec), | |
| 151 ctx_flags(other.ctx_flags), | |
| 152 locally_initiated(other.locally_initiated), | |
| 153 open(other.open) { | |
| 154 CopyOid(&mech_type, &other.mech_type); | |
| 155 } | |
| 156 | |
| 157 GssContextMockImpl::GssContextMockImpl(const char* src_name_in, | |
| 158 const char* targ_name_in, | |
| 159 OM_uint32 lifetime_rec_in, | |
| 160 const gss_OID_desc& mech_type_in, | |
| 161 OM_uint32 ctx_flags_in, | |
| 162 int locally_initiated_in, | |
| 163 int open_in) | |
| 164 : src_name(src_name_in ? src_name_in : ""), | |
| 165 targ_name(targ_name_in ? targ_name_in : ""), | |
| 166 lifetime_rec(lifetime_rec_in), | |
| 167 ctx_flags(ctx_flags_in), | |
| 168 locally_initiated(locally_initiated_in), | |
| 169 open(open_in) { | |
| 170 CopyOid(&mech_type, &mech_type_in); | |
| 171 } | |
| 172 | |
| 173 GssContextMockImpl::~GssContextMockImpl() { | |
| 174 ClearOid(&mech_type); | |
| 175 } | |
| 176 | |
| 177 void GssContextMockImpl::Assign( | |
| 178 const GssContextMockImpl& other) { | |
| 179 if (&other == this) | |
| 180 return; | |
| 181 src_name = other.src_name; | |
| 182 targ_name = other.targ_name; | |
| 183 lifetime_rec = other.lifetime_rec; | |
| 184 CopyOid(&mech_type, &other.mech_type); | |
| 185 ctx_flags = other.ctx_flags; | |
| 186 locally_initiated = other.locally_initiated; | |
| 187 open = other.open; | |
| 188 } | |
| 189 | |
| 190 MockGSSAPILibrary::SecurityContextQuery::SecurityContextQuery() | |
| 191 : expected_package(), | |
| 192 response_code(0), | |
| 193 minor_response_code(0), | |
| 194 context_info() { | |
| 195 expected_input_token.length = 0; | |
| 196 expected_input_token.value = NULL; | |
| 197 output_token.length = 0; | |
| 198 output_token.value = NULL; | |
| 199 } | |
| 200 | |
| 201 MockGSSAPILibrary::SecurityContextQuery::SecurityContextQuery( | |
| 202 const std::string& in_expected_package, | |
| 203 OM_uint32 in_response_code, | |
| 204 OM_uint32 in_minor_response_code, | |
| 205 const test::GssContextMockImpl& in_context_info, | |
| 206 const char* in_expected_input_token, | |
| 207 const char* in_output_token) | |
| 208 : expected_package(in_expected_package), | |
| 209 response_code(in_response_code), | |
| 210 minor_response_code(in_minor_response_code), | |
| 211 context_info(in_context_info) { | |
| 212 if (in_expected_input_token) { | |
| 213 expected_input_token.length = strlen(in_expected_input_token); | |
| 214 expected_input_token.value = const_cast<char*>(in_expected_input_token); | |
| 215 } else { | |
| 216 expected_input_token.length = 0; | |
| 217 expected_input_token.value = NULL; | |
| 218 } | |
| 219 | |
| 220 if (in_output_token) { | |
| 221 output_token.length = strlen(in_output_token); | |
| 222 output_token.value = const_cast<char*>(in_output_token); | |
| 223 } else { | |
| 224 output_token.length = 0; | |
| 225 output_token.value = NULL; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 MockGSSAPILibrary::SecurityContextQuery::~SecurityContextQuery() {} | |
| 230 | |
| 231 MockGSSAPILibrary::MockGSSAPILibrary() { | |
| 232 } | |
| 233 | |
| 234 MockGSSAPILibrary::~MockGSSAPILibrary() { | |
| 235 } | |
| 236 | |
| 237 void MockGSSAPILibrary::ExpectSecurityContext( | |
| 238 const std::string& expected_package, | |
| 239 OM_uint32 response_code, | |
| 240 OM_uint32 minor_response_code, | |
| 241 const GssContextMockImpl& context_info, | |
| 242 const gss_buffer_desc& expected_input_token, | |
| 243 const gss_buffer_desc& output_token) { | |
| 244 SecurityContextQuery security_query; | |
| 245 security_query.expected_package = expected_package; | |
| 246 security_query.response_code = response_code; | |
| 247 security_query.minor_response_code = minor_response_code; | |
| 248 security_query.context_info.Assign(context_info); | |
| 249 security_query.expected_input_token = expected_input_token; | |
| 250 security_query.output_token = output_token; | |
| 251 expected_security_queries_.push_back(security_query); | |
| 252 } | |
| 253 | |
| 254 bool MockGSSAPILibrary::Init() { | |
| 255 return true; | |
| 256 } | |
| 257 | |
| 258 // These methods match the ones in the GSSAPI library. | |
| 259 OM_uint32 MockGSSAPILibrary::import_name( | |
| 260 OM_uint32* minor_status, | |
| 261 const gss_buffer_t input_name_buffer, | |
| 262 const gss_OID input_name_type, | |
| 263 gss_name_t* output_name) { | |
| 264 if (minor_status) | |
| 265 *minor_status = 0; | |
| 266 if (!output_name) | |
| 267 return GSS_S_BAD_NAME; | |
| 268 if (!input_name_buffer) | |
| 269 return GSS_S_CALL_BAD_STRUCTURE; | |
| 270 if (!input_name_type) | |
| 271 return GSS_S_BAD_NAMETYPE; | |
| 272 GssNameMockImpl* output = new GssNameMockImpl; | |
| 273 if (output == NULL) | |
| 274 return GSS_S_FAILURE; | |
| 275 output->name_type.length = 0; | |
| 276 output->name_type.elements = NULL; | |
| 277 | |
| 278 // Save the data. | |
| 279 output->name = BufferToString(input_name_buffer); | |
| 280 CopyOid(&output->name_type, input_name_type); | |
| 281 *output_name = reinterpret_cast<gss_name_t>(output); | |
| 282 | |
| 283 return GSS_S_COMPLETE; | |
| 284 } | |
| 285 | |
| 286 OM_uint32 MockGSSAPILibrary::release_name( | |
| 287 OM_uint32* minor_status, | |
| 288 gss_name_t* input_name) { | |
| 289 if (minor_status) | |
| 290 *minor_status = 0; | |
| 291 if (!input_name) | |
| 292 return GSS_S_BAD_NAME; | |
| 293 if (!*input_name) | |
| 294 return GSS_S_COMPLETE; | |
| 295 GssNameMockImpl* name = *reinterpret_cast<GssNameMockImpl**>(input_name); | |
| 296 ClearName(*input_name); | |
| 297 delete name; | |
| 298 *input_name = NULL; | |
| 299 return GSS_S_COMPLETE; | |
| 300 } | |
| 301 | |
| 302 OM_uint32 MockGSSAPILibrary::release_buffer( | |
| 303 OM_uint32* minor_status, | |
| 304 gss_buffer_t buffer) { | |
| 305 if (minor_status) | |
| 306 *minor_status = 0; | |
| 307 if (!buffer) | |
| 308 return GSS_S_BAD_NAME; | |
| 309 ClearBuffer(buffer); | |
| 310 return GSS_S_COMPLETE; | |
| 311 } | |
| 312 | |
| 313 OM_uint32 MockGSSAPILibrary::display_name( | |
| 314 OM_uint32* minor_status, | |
| 315 const gss_name_t input_name, | |
| 316 gss_buffer_t output_name_buffer, | |
| 317 gss_OID* output_name_type) { | |
| 318 if (minor_status) | |
| 319 *minor_status = 0; | |
| 320 if (!input_name) | |
| 321 return GSS_S_BAD_NAME; | |
| 322 if (!output_name_buffer) | |
| 323 return GSS_S_CALL_BAD_STRUCTURE; | |
| 324 if (!output_name_type) | |
| 325 return GSS_S_CALL_BAD_STRUCTURE; | |
| 326 std::string name(NameToString(input_name)); | |
| 327 BufferFromString(name, output_name_buffer); | |
| 328 GssNameMockImpl* internal_name = | |
| 329 *reinterpret_cast<GssNameMockImpl**>(input_name); | |
| 330 if (output_name_type) | |
| 331 *output_name_type = internal_name ? &internal_name->name_type : NULL; | |
| 332 return GSS_S_COMPLETE; | |
| 333 } | |
| 334 | |
| 335 OM_uint32 MockGSSAPILibrary::display_status( | |
| 336 OM_uint32* minor_status, | |
| 337 OM_uint32 status_value, | |
| 338 int status_type, | |
| 339 const gss_OID mech_type, | |
| 340 OM_uint32* message_context, | |
| 341 gss_buffer_t status_string) { | |
| 342 if (minor_status) | |
| 343 *minor_status = 0; | |
| 344 std::string msg = base::StringPrintf("Value: %u, Type %u", | |
| 345 status_value, | |
| 346 status_type); | |
| 347 if (message_context) | |
| 348 *message_context = 0; | |
| 349 BufferFromString(msg, status_string); | |
| 350 return GSS_S_COMPLETE; | |
| 351 } | |
| 352 | |
| 353 OM_uint32 MockGSSAPILibrary::init_sec_context( | |
| 354 OM_uint32* minor_status, | |
| 355 const gss_cred_id_t initiator_cred_handle, | |
| 356 gss_ctx_id_t* context_handle, | |
| 357 const gss_name_t target_name, | |
| 358 const gss_OID mech_type, | |
| 359 OM_uint32 req_flags, | |
| 360 OM_uint32 time_req, | |
| 361 const gss_channel_bindings_t input_chan_bindings, | |
| 362 const gss_buffer_t input_token, | |
| 363 gss_OID* actual_mech_type, | |
| 364 gss_buffer_t output_token, | |
| 365 OM_uint32* ret_flags, | |
| 366 OM_uint32* time_rec) { | |
| 367 if (minor_status) | |
| 368 *minor_status = 0; | |
| 369 if (!context_handle) | |
| 370 return GSS_S_CALL_BAD_STRUCTURE; | |
| 371 GssContextMockImpl** internal_context_handle = | |
| 372 reinterpret_cast<test::GssContextMockImpl**>(context_handle); | |
| 373 // Create it if necessary. | |
| 374 if (!*internal_context_handle) { | |
| 375 *internal_context_handle = new GssContextMockImpl; | |
| 376 } | |
| 377 EXPECT_TRUE(*internal_context_handle); | |
| 378 GssContextMockImpl& context = **internal_context_handle; | |
| 379 if (expected_security_queries_.empty()) { | |
| 380 return GSS_S_UNAVAILABLE; | |
| 381 } | |
| 382 SecurityContextQuery security_query = expected_security_queries_.front(); | |
| 383 expected_security_queries_.pop_front(); | |
| 384 EXPECT_EQ(std::string("Negotiate"), security_query.expected_package); | |
| 385 OM_uint32 major_status = security_query.response_code; | |
| 386 if (minor_status) | |
| 387 *minor_status = security_query.minor_response_code; | |
| 388 context.src_name = security_query.context_info.src_name; | |
| 389 context.targ_name = security_query.context_info.targ_name; | |
| 390 context.lifetime_rec = security_query.context_info.lifetime_rec; | |
| 391 CopyOid(&context.mech_type, &security_query.context_info.mech_type); | |
| 392 context.ctx_flags = security_query.context_info.ctx_flags; | |
| 393 context.locally_initiated = security_query.context_info.locally_initiated; | |
| 394 context.open = security_query.context_info.open; | |
| 395 if (!input_token) { | |
| 396 EXPECT_FALSE(security_query.expected_input_token.length); | |
| 397 } else { | |
| 398 EXPECT_EQ(input_token->length, security_query.expected_input_token.length); | |
| 399 if (input_token->length) { | |
| 400 EXPECT_EQ(0, memcmp(input_token->value, | |
| 401 security_query.expected_input_token.value, | |
| 402 input_token->length)); | |
| 403 } | |
| 404 } | |
| 405 CopyBuffer(output_token, &security_query.output_token); | |
| 406 if (actual_mech_type) | |
| 407 CopyOid(*actual_mech_type, mech_type); | |
| 408 if (ret_flags) | |
| 409 *ret_flags = req_flags; | |
| 410 return major_status; | |
| 411 } | |
| 412 | |
| 413 OM_uint32 MockGSSAPILibrary::wrap_size_limit( | |
| 414 OM_uint32* minor_status, | |
| 415 const gss_ctx_id_t context_handle, | |
| 416 int conf_req_flag, | |
| 417 gss_qop_t qop_req, | |
| 418 OM_uint32 req_output_size, | |
| 419 OM_uint32* max_input_size) { | |
| 420 if (minor_status) | |
| 421 *minor_status = 0; | |
| 422 ADD_FAILURE(); | |
| 423 return GSS_S_UNAVAILABLE; | |
| 424 } | |
| 425 | |
| 426 OM_uint32 MockGSSAPILibrary::delete_sec_context( | |
| 427 OM_uint32* minor_status, | |
| 428 gss_ctx_id_t* context_handle, | |
| 429 gss_buffer_t output_token) { | |
| 430 if (minor_status) | |
| 431 *minor_status = 0; | |
| 432 if (!context_handle) | |
| 433 return GSS_S_CALL_BAD_STRUCTURE; | |
| 434 GssContextMockImpl** internal_context_handle = | |
| 435 reinterpret_cast<GssContextMockImpl**>(context_handle); | |
| 436 if (*internal_context_handle) { | |
| 437 delete *internal_context_handle; | |
| 438 *internal_context_handle = NULL; | |
| 439 } | |
| 440 return GSS_S_COMPLETE; | |
| 441 } | |
| 442 | |
| 443 OM_uint32 MockGSSAPILibrary::inquire_context( | |
| 444 OM_uint32* minor_status, | |
| 445 const gss_ctx_id_t context_handle, | |
| 446 gss_name_t* src_name, | |
| 447 gss_name_t* targ_name, | |
| 448 OM_uint32* lifetime_rec, | |
| 449 gss_OID* mech_type, | |
| 450 OM_uint32* ctx_flags, | |
| 451 int* locally_initiated, | |
| 452 int* open) { | |
| 453 if (minor_status) | |
| 454 *minor_status = 0; | |
| 455 if (!context_handle) | |
| 456 return GSS_S_CALL_BAD_STRUCTURE; | |
| 457 GssContextMockImpl* internal_context_ptr = | |
| 458 reinterpret_cast<GssContextMockImpl*>(context_handle); | |
| 459 GssContextMockImpl& context = *internal_context_ptr; | |
| 460 if (src_name) | |
| 461 NameFromString(context.src_name, *src_name); | |
| 462 if (targ_name) | |
| 463 NameFromString(context.targ_name, *targ_name); | |
| 464 if (lifetime_rec) | |
| 465 *lifetime_rec = context.lifetime_rec; | |
| 466 if (mech_type) | |
| 467 CopyOid(*mech_type, &context.mech_type); | |
| 468 if (ctx_flags) | |
| 469 *ctx_flags = context.ctx_flags; | |
| 470 if (locally_initiated) | |
| 471 *locally_initiated = context.locally_initiated; | |
| 472 if (open) | |
| 473 *open = context.open; | |
| 474 return GSS_S_COMPLETE; | |
| 475 } | |
| 476 | |
| 477 } // namespace test | |
| 478 | |
| 479 } // namespace net | |
| 480 | |
| OLD | NEW |