| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_auth_gssapi_posix.h" | 5 #include "net/http/http_auth_gssapi_posix.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
| 12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/singleton.h" | 14 #include "base/singleton.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/stringprintf.h" |
| 16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 17 #include "net/base/net_util.h" | 18 #include "net/base/net_util.h" |
| 18 | 19 |
| 19 // These are defined for the GSSAPI library: | 20 // These are defined for the GSSAPI library: |
| 20 // Paraphrasing the comments from gssapi.h: | 21 // Paraphrasing the comments from gssapi.h: |
| 21 // "The implementation must reserve static storage for a | 22 // "The implementation must reserve static storage for a |
| 22 // gss_OID_desc object for each constant. That constant | 23 // gss_OID_desc object for each constant. That constant |
| 23 // should be initialized to point to that gss_OID_desc." | 24 // should be initialized to point to that gss_OID_desc." |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 gss_OID CHROME_GSS_KRB5_MECH_OID_DESC = | 90 gss_OID CHROME_GSS_KRB5_MECH_OID_DESC = |
| 90 &CHROME_GSS_KRB5_MECH_OID_DESC_VAL; | 91 &CHROME_GSS_KRB5_MECH_OID_DESC_VAL; |
| 91 | 92 |
| 92 // Debugging helpers. | 93 // Debugging helpers. |
| 93 namespace { | 94 namespace { |
| 94 | 95 |
| 95 std::string DisplayStatus(OM_uint32 major_status, | 96 std::string DisplayStatus(OM_uint32 major_status, |
| 96 OM_uint32 minor_status) { | 97 OM_uint32 minor_status) { |
| 97 if (major_status == GSS_S_COMPLETE) | 98 if (major_status == GSS_S_COMPLETE) |
| 98 return "OK"; | 99 return "OK"; |
| 99 return StringPrintf("0x%08X 0x%08X", major_status, minor_status); | 100 return base::StringPrintf("0x%08X 0x%08X", major_status, minor_status); |
| 100 } | 101 } |
| 101 | 102 |
| 102 std::string DisplayCode(GSSAPILibrary* gssapi_lib, | 103 std::string DisplayCode(GSSAPILibrary* gssapi_lib, |
| 103 OM_uint32 status, | 104 OM_uint32 status, |
| 104 OM_uint32 status_code_type) { | 105 OM_uint32 status_code_type) { |
| 105 const int kMaxDisplayIterations = 8; | 106 const int kMaxDisplayIterations = 8; |
| 106 const size_t kMaxMsgLength = 4096; | 107 const size_t kMaxMsgLength = 4096; |
| 107 // msg_ctx needs to be outside the loop because it is invoked multiple times. | 108 // msg_ctx needs to be outside the loop because it is invoked multiple times. |
| 108 OM_uint32 msg_ctx = 0; | 109 OM_uint32 msg_ctx = 0; |
| 109 std::string rv = StringPrintf("(0x%08X)", status); | 110 std::string rv = base::StringPrintf("(0x%08X)", status); |
| 110 | 111 |
| 111 // This loop should continue iterating until msg_ctx is 0 after the first | 112 // This loop should continue iterating until msg_ctx is 0 after the first |
| 112 // iteration. To be cautious and prevent an infinite loop, it stops after | 113 // iteration. To be cautious and prevent an infinite loop, it stops after |
| 113 // a finite number of iterations as well. As an added sanity check, no | 114 // a finite number of iterations as well. As an added sanity check, no |
| 114 // individual message may exceed |kMaxMsgLength|, and the final result | 115 // individual message may exceed |kMaxMsgLength|, and the final result |
| 115 // will not exceed |kMaxMsgLength|*2-1. | 116 // will not exceed |kMaxMsgLength|*2-1. |
| 116 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; | 117 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; |
| 117 ++i) { | 118 ++i) { |
| 118 OM_uint32 min_stat; | 119 OM_uint32 min_stat; |
| 119 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; | 120 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; |
| 120 OM_uint32 maj_stat = | 121 OM_uint32 maj_stat = |
| 121 gssapi_lib->display_status(&min_stat, status, status_code_type, | 122 gssapi_lib->display_status(&min_stat, status, status_code_type, |
| 122 GSS_C_NULL_OID, &msg_ctx, &msg); | 123 GSS_C_NULL_OID, &msg_ctx, &msg); |
| 123 if (maj_stat == GSS_S_COMPLETE) { | 124 if (maj_stat == GSS_S_COMPLETE) { |
| 124 int msg_len = (msg.length > kMaxMsgLength) ? | 125 int msg_len = (msg.length > kMaxMsgLength) ? |
| 125 static_cast<int>(kMaxMsgLength) : | 126 static_cast<int>(kMaxMsgLength) : |
| 126 static_cast<int>(msg.length); | 127 static_cast<int>(msg.length); |
| 127 if (msg_len > 0 && msg.value != NULL) { | 128 if (msg_len > 0 && msg.value != NULL) { |
| 128 rv += StringPrintf(" %.*s", msg_len, | 129 rv += base::StringPrintf(" %.*s", msg_len, |
| 129 static_cast<char*>(msg.value)); | 130 static_cast<char*>(msg.value)); |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 gssapi_lib->release_buffer(&min_stat, &msg); | 133 gssapi_lib->release_buffer(&min_stat, &msg); |
| 133 if (!msg_ctx) | 134 if (!msg_ctx) |
| 134 break; | 135 break; |
| 135 } | 136 } |
| 136 return rv; | 137 return rv; |
| 137 } | 138 } |
| 138 | 139 |
| 139 std::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib, | 140 std::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib, |
| 140 OM_uint32 major_status, | 141 OM_uint32 major_status, |
| 141 OM_uint32 minor_status) { | 142 OM_uint32 minor_status) { |
| 142 if (major_status == GSS_S_COMPLETE) | 143 if (major_status == GSS_S_COMPLETE) |
| 143 return "OK"; | 144 return "OK"; |
| 144 std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE); | 145 std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE); |
| 145 std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE); | 146 std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE); |
| 146 return StringPrintf("Major: %s | Minor: %s", major.c_str(), minor.c_str()); | 147 return base::StringPrintf("Major: %s | Minor: %s", major.c_str(), |
| 148 minor.c_str()); |
| 147 } | 149 } |
| 148 | 150 |
| 149 // ScopedName releases a gss_name_t when it goes out of scope. | 151 // ScopedName releases a gss_name_t when it goes out of scope. |
| 150 class ScopedName { | 152 class ScopedName { |
| 151 public: | 153 public: |
| 152 ScopedName(gss_name_t name, | 154 ScopedName(gss_name_t name, |
| 153 GSSAPILibrary* gssapi_lib) | 155 GSSAPILibrary* gssapi_lib) |
| 154 : name_(name), | 156 : name_(name), |
| 155 gssapi_lib_(gssapi_lib) { | 157 gssapi_lib_(gssapi_lib) { |
| 156 DCHECK(gssapi_lib_); | 158 DCHECK(gssapi_lib_); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 size_t str_length = 0; | 248 size_t str_length = 0; |
| 247 for ( ; str_length < kMaxCharsToPrint; ++str_length) { | 249 for ( ; str_length < kMaxCharsToPrint; ++str_length) { |
| 248 if (!str[str_length]) | 250 if (!str[str_length]) |
| 249 break; | 251 break; |
| 250 if (!isprint(str[str_length])) { | 252 if (!isprint(str[str_length])) { |
| 251 is_printable = false; | 253 is_printable = false; |
| 252 break; | 254 break; |
| 253 } | 255 } |
| 254 } | 256 } |
| 255 if (!str[str_length]) { | 257 if (!str[str_length]) { |
| 256 output += StringPrintf("\"%s\"", str); | 258 output += base::StringPrintf("\"%s\"", str); |
| 257 return output; | 259 return output; |
| 258 } | 260 } |
| 259 } | 261 } |
| 260 output = StringPrintf("(%u) \"", byte_length); | 262 output = base::StringPrintf("(%u) \"", byte_length); |
| 261 if (!oid->elements) { | 263 if (!oid->elements) { |
| 262 output += "<NULL>"; | 264 output += "<NULL>"; |
| 263 return output; | 265 return output; |
| 264 } | 266 } |
| 265 const unsigned char* elements = | 267 const unsigned char* elements = |
| 266 reinterpret_cast<const unsigned char*>(oid->elements); | 268 reinterpret_cast<const unsigned char*>(oid->elements); |
| 267 // Don't print more than |kMaxCharsToPrint| characters. | 269 // Don't print more than |kMaxCharsToPrint| characters. |
| 268 size_t i = 0; | 270 size_t i = 0; |
| 269 for ( ; (i < byte_length) && (i < kMaxCharsToPrint); ++i) { | 271 for ( ; (i < byte_length) && (i < kMaxCharsToPrint); ++i) { |
| 270 output += StringPrintf("\\x%02X", elements[i]); | 272 output += base::StringPrintf("\\x%02X", elements[i]); |
| 271 } | 273 } |
| 272 if (i >= kMaxCharsToPrint) | 274 if (i >= kMaxCharsToPrint) |
| 273 output += "..."; | 275 output += "..."; |
| 274 output += "\""; | 276 output += "\""; |
| 275 | 277 |
| 276 // Check if the OID is one of the predefined values. | 278 // Check if the OID is one of the predefined values. |
| 277 output += AppendIfPredefinedValue(oid, | 279 output += AppendIfPredefinedValue(oid, |
| 278 GSS_C_NT_USER_NAME, | 280 GSS_C_NT_USER_NAME, |
| 279 "GSS_C_NT_USER_NAME"); | 281 "GSS_C_NT_USER_NAME"); |
| 280 output += AppendIfPredefinedValue(oid, | 282 output += AppendIfPredefinedValue(oid, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 305 gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER; | 307 gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER; |
| 306 gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER; | 308 gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER; |
| 307 gss_OID output_name_type = &output_name_type_desc; | 309 gss_OID output_name_type = &output_name_type_desc; |
| 308 major_status = gssapi_lib->display_name(&minor_status, | 310 major_status = gssapi_lib->display_name(&minor_status, |
| 309 name, | 311 name, |
| 310 &output_name_buffer, | 312 &output_name_buffer, |
| 311 &output_name_type); | 313 &output_name_type); |
| 312 ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib); | 314 ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib); |
| 313 if (major_status != GSS_S_COMPLETE) { | 315 if (major_status != GSS_S_COMPLETE) { |
| 314 std::string error = | 316 std::string error = |
| 315 StringPrintf("Unable to describe name 0x%p, %s", | 317 base::StringPrintf("Unable to describe name 0x%p, %s", |
| 316 name, | 318 name, |
| 317 DisplayExtendedStatus(gssapi_lib, | 319 DisplayExtendedStatus(gssapi_lib, |
| 318 major_status, | 320 major_status, |
| 319 minor_status).c_str()); | 321 minor_status).c_str()); |
| 320 return error; | 322 return error; |
| 321 } | 323 } |
| 322 int len = output_name_buffer.length; | 324 int len = output_name_buffer.length; |
| 323 std::string description = | 325 std::string description = base::StringPrintf( |
| 324 StringPrintf("%*s (Type %s)", | 326 "%*s (Type %s)", |
| 325 len, | 327 len, |
| 326 reinterpret_cast<const char*>(output_name_buffer.value), | 328 reinterpret_cast<const char*>(output_name_buffer.value), |
| 327 DescribeOid(gssapi_lib, output_name_type).c_str()); | 329 DescribeOid(gssapi_lib, output_name_type).c_str()); |
| 328 return description; | 330 return description; |
| 329 } | 331 } |
| 330 | 332 |
| 331 std::string DescribeContext(GSSAPILibrary* gssapi_lib, | 333 std::string DescribeContext(GSSAPILibrary* gssapi_lib, |
| 332 const gss_ctx_id_t context_handle) { | 334 const gss_ctx_id_t context_handle) { |
| 333 OM_uint32 major_status = 0; | 335 OM_uint32 major_status = 0; |
| 334 OM_uint32 minor_status = 0; | 336 OM_uint32 minor_status = 0; |
| 335 gss_name_t src_name = GSS_C_NO_NAME; | 337 gss_name_t src_name = GSS_C_NO_NAME; |
| 336 gss_name_t targ_name = GSS_C_NO_NAME; | 338 gss_name_t targ_name = GSS_C_NO_NAME; |
| 337 OM_uint32 lifetime_rec = 0; | 339 OM_uint32 lifetime_rec = 0; |
| 338 gss_OID mech_type = GSS_C_NO_OID; | 340 gss_OID mech_type = GSS_C_NO_OID; |
| 339 OM_uint32 ctx_flags = 0; | 341 OM_uint32 ctx_flags = 0; |
| 340 int locally_initiated = 0; | 342 int locally_initiated = 0; |
| 341 int open = 0; | 343 int open = 0; |
| 342 major_status = gssapi_lib->inquire_context(&minor_status, | 344 major_status = gssapi_lib->inquire_context(&minor_status, |
| 343 context_handle, | 345 context_handle, |
| 344 &src_name, | 346 &src_name, |
| 345 &targ_name, | 347 &targ_name, |
| 346 &lifetime_rec, | 348 &lifetime_rec, |
| 347 &mech_type, | 349 &mech_type, |
| 348 &ctx_flags, | 350 &ctx_flags, |
| 349 &locally_initiated, | 351 &locally_initiated, |
| 350 &open); | 352 &open); |
| 351 ScopedName(src_name, gssapi_lib); | 353 ScopedName(src_name, gssapi_lib); |
| 352 ScopedName(targ_name, gssapi_lib); | 354 ScopedName(targ_name, gssapi_lib); |
| 353 if (major_status != GSS_S_COMPLETE) { | 355 if (major_status != GSS_S_COMPLETE) { |
| 354 std::string error = | 356 std::string error = |
| 355 StringPrintf("Unable to describe context 0x%p, %s", | 357 base::StringPrintf("Unable to describe context 0x%p, %s", |
| 356 context_handle, | 358 context_handle, |
| 357 DisplayExtendedStatus(gssapi_lib, | 359 DisplayExtendedStatus(gssapi_lib, |
| 358 major_status, | 360 major_status, |
| 359 minor_status).c_str()); | 361 minor_status).c_str()); |
| 360 return error; | 362 return error; |
| 361 } | 363 } |
| 362 std::string source(DescribeName(gssapi_lib, src_name)); | 364 std::string source(DescribeName(gssapi_lib, src_name)); |
| 363 std::string target(DescribeName(gssapi_lib, targ_name)); | 365 std::string target(DescribeName(gssapi_lib, targ_name)); |
| 364 std::string description = StringPrintf("Context 0x%p: " | 366 std::string description = base::StringPrintf("Context 0x%p: " |
| 365 "Source \"%s\", " | 367 "Source \"%s\", " |
| 366 "Target \"%s\", " | 368 "Target \"%s\", " |
| 367 "lifetime %d, " | 369 "lifetime %d, " |
| 368 "mechanism %s, " | 370 "mechanism %s, " |
| 369 "flags 0x%08X, " | 371 "flags 0x%08X, " |
| 370 "local %d, " | 372 "local %d, " |
| 371 "open %d", | 373 "open %d", |
| 372 context_handle, | 374 context_handle, |
| 373 source.c_str(), | 375 source.c_str(), |
| 374 target.c_str(), | 376 target.c_str(), |
| 375 lifetime_rec, | 377 lifetime_rec, |
| 376 DescribeOid(gssapi_lib, | 378 DescribeOid(gssapi_lib, |
| 377 mech_type).c_str(), | 379 mech_type).c_str(), |
| 378 ctx_flags, | 380 ctx_flags, |
| 379 locally_initiated, | 381 locally_initiated, |
| 380 open); | 382 open); |
| 381 return description; | 383 return description; |
| 382 } | 384 } |
| 383 | 385 |
| 384 } // namespace | 386 } // namespace |
| 385 | 387 |
| 386 GSSAPISharedLibrary::GSSAPISharedLibrary() | 388 GSSAPISharedLibrary::GSSAPISharedLibrary() |
| 387 : initialized_(false), | 389 : initialized_(false), |
| 388 gssapi_library_(NULL), | 390 gssapi_library_(NULL), |
| 389 import_name_(NULL), | 391 import_name_(NULL), |
| 390 release_name_(NULL), | 392 release_name_(NULL), |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 minor_status) | 877 minor_status) |
| 876 << std::endl | 878 << std::endl |
| 877 << DescribeContext(library_, scoped_sec_context_.get()); | 879 << DescribeContext(library_, scoped_sec_context_.get()); |
| 878 return rv; | 880 return rv; |
| 879 } | 881 } |
| 880 | 882 |
| 881 return OK; | 883 return OK; |
| 882 } | 884 } |
| 883 | 885 |
| 884 } // namespace net | 886 } // namespace net |
| OLD | NEW |