Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Side by Side Diff: net/http/http_auth_gssapi_posix.cc

Issue 3360017: Fix multi-round authentication.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: SocketStream fix Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth_gssapi_posix.h ('k') | net/http/http_auth_gssapi_posix_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // msg_ctx needs to be outside the loop because it is invoked multiple times. 107 // msg_ctx needs to be outside the loop because it is invoked multiple times.
108 OM_uint32 msg_ctx = 0; 108 OM_uint32 msg_ctx = 0;
109 std::string rv = StringPrintf("(0x%08X)", status); 109 std::string rv = StringPrintf("(0x%08X)", status);
110 110
111 // This loop should continue iterating until msg_ctx is 0 after the first 111 // 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 112 // 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 113 // a finite number of iterations as well. As an added sanity check, no
114 // individual message may exceed |kMaxMsgLength|, and the final result 114 // individual message may exceed |kMaxMsgLength|, and the final result
115 // will not exceed |kMaxMsgLength|*2-1. 115 // will not exceed |kMaxMsgLength|*2-1.
116 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; 116 for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength;
117 ++i) { 117 ++i) {
118 OM_uint32 min_stat; 118 OM_uint32 min_stat;
119 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; 119 gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER;
120 OM_uint32 maj_stat = 120 OM_uint32 maj_stat =
121 gssapi_lib->display_status(&min_stat, status, status_code_type, 121 gssapi_lib->display_status(&min_stat, status, status_code_type,
122 GSS_C_NULL_OID, &msg_ctx, &msg); 122 GSS_C_NULL_OID, &msg_ctx, &msg);
123 if (maj_stat == GSS_S_COMPLETE) { 123 if (maj_stat == GSS_S_COMPLETE) {
124 int msg_len = (msg.length > kMaxMsgLength) ? 124 int msg_len = (msg.length > kMaxMsgLength) ?
125 static_cast<int>(kMaxMsgLength) : 125 static_cast<int>(kMaxMsgLength) :
126 static_cast<int>(msg.length); 126 static_cast<int>(msg.length);
127 if (msg_len > 0 && msg.value != NULL) { 127 if (msg_len > 0 && msg.value != NULL) {
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 // Only return this library if we can bind the functions we need. 475 // Only return this library if we can bind the functions we need.
476 if (BindMethods(lib)) 476 if (BindMethods(lib))
477 return lib; 477 return lib;
478 base::UnloadNativeLibrary(lib); 478 base::UnloadNativeLibrary(lib);
479 } 479 }
480 } 480 }
481 LOG(WARNING) << "Unable to find a compatible GSSAPI library"; 481 LOG(WARNING) << "Unable to find a compatible GSSAPI library";
482 return NULL; 482 return NULL;
483 } 483 }
484 484
485 #define BIND(lib, x) \ 485 #define BIND(lib, x) \
486 gss_##x##_type x = reinterpret_cast<gss_##x##_type>( \ 486 gss_##x##_type x = reinterpret_cast<gss_##x##_type>( \
487 base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x)); \ 487 base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x)); \
488 if (x == NULL) { \ 488 if (x == NULL) { \
489 LOG(WARNING) << "Unable to bind function \"" << "gss_" #x << "\""; \ 489 LOG(WARNING) << "Unable to bind function \"" << "gss_" #x << "\""; \
490 return false; \ 490 return false; \
491 } 491 }
492 492
493 bool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) { 493 bool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) {
494 DCHECK(lib != NULL); 494 DCHECK(lib != NULL);
495 495
496 BIND(lib, import_name) 496 BIND(lib, import_name);
497 BIND(lib, release_name) 497 BIND(lib, release_name);
498 BIND(lib, release_buffer) 498 BIND(lib, release_buffer);
499 BIND(lib, display_name) 499 BIND(lib, display_name);
500 BIND(lib, display_status) 500 BIND(lib, display_status);
501 BIND(lib, init_sec_context) 501 BIND(lib, init_sec_context);
502 BIND(lib, wrap_size_limit) 502 BIND(lib, wrap_size_limit);
503 BIND(lib, delete_sec_context) 503 BIND(lib, delete_sec_context);
504 BIND(lib, inquire_context) 504 BIND(lib, inquire_context);
505 505
506 import_name_ = import_name; 506 import_name_ = import_name;
507 release_name_ = release_name; 507 release_name_ = release_name;
508 release_buffer_ = release_buffer; 508 release_buffer_ = release_buffer;
509 display_name_ = display_name; 509 display_name_ = display_name;
510 display_status_ = display_status; 510 display_status_ = display_status;
511 init_sec_context_ = init_sec_context; 511 init_sec_context_ = init_sec_context;
512 wrap_size_limit_ = wrap_size_limit; 512 wrap_size_limit_ = wrap_size_limit;
513 delete_sec_context_ = delete_sec_context; 513 delete_sec_context_ = delete_sec_context;
514 inquire_context_ = inquire_context; 514 inquire_context_ = inquire_context;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 const gss_ctx_id_t context_handle, 631 const gss_ctx_id_t context_handle,
632 gss_name_t* src_name, 632 gss_name_t* src_name,
633 gss_name_t* targ_name, 633 gss_name_t* targ_name,
634 OM_uint32* lifetime_rec, 634 OM_uint32* lifetime_rec,
635 gss_OID* mech_type, 635 gss_OID* mech_type,
636 OM_uint32* ctx_flags, 636 OM_uint32* ctx_flags,
637 int* locally_initiated, 637 int* locally_initiated,
638 int* open) { 638 int* open) {
639 DCHECK(initialized_); 639 DCHECK(initialized_);
640 return inquire_context_(minor_status, 640 return inquire_context_(minor_status,
641 context_handle, 641 context_handle,
642 src_name, 642 src_name,
643 targ_name, 643 targ_name,
644 lifetime_rec, 644 lifetime_rec,
645 mech_type, 645 mech_type,
646 ctx_flags, 646 ctx_flags,
647 locally_initiated, 647 locally_initiated,
648 open); 648 open);
649 } 649 }
650 GSSAPILibrary* GSSAPILibrary::GetDefault() { 650 GSSAPILibrary* GSSAPILibrary::GetDefault() {
651 return Singleton<GSSAPISharedLibrary>::get(); 651 return Singleton<GSSAPISharedLibrary>::get();
652 } 652 }
653 653
654 ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib) 654 ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib)
655 : security_context_(GSS_C_NO_CONTEXT), 655 : security_context_(GSS_C_NO_CONTEXT),
656 gssapi_lib_(gssapi_lib) { 656 gssapi_lib_(gssapi_lib) {
657 DCHECK(gssapi_lib_); 657 DCHECK(gssapi_lib_);
658 } 658 }
(...skipping 29 matching lines...) Expand all
688 bool HttpAuthGSSAPI::Init() { 688 bool HttpAuthGSSAPI::Init() {
689 if (!library_) 689 if (!library_)
690 return false; 690 return false;
691 return library_->Init(); 691 return library_->Init();
692 } 692 }
693 693
694 bool HttpAuthGSSAPI::NeedsIdentity() const { 694 bool HttpAuthGSSAPI::NeedsIdentity() const {
695 return decoded_server_auth_token_.empty(); 695 return decoded_server_auth_token_.empty();
696 } 696 }
697 697
698 bool HttpAuthGSSAPI::IsFinalRound() const {
699 return !NeedsIdentity();
700 }
701
702 void HttpAuthGSSAPI::Delegate() { 698 void HttpAuthGSSAPI::Delegate() {
703 can_delegate_ = true; 699 can_delegate_ = true;
704 } 700 }
705 701
706 bool HttpAuthGSSAPI::ParseChallenge(HttpAuth::ChallengeTokenizer* tok) { 702 HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge(
703 HttpAuth::ChallengeTokenizer* tok) {
707 // Verify the challenge's auth-scheme. 704 // Verify the challenge's auth-scheme.
708 if (!tok->valid() || 705 if (!tok->valid() ||
709 !LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str())) 706 !LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str()))
710 return false; 707 return HttpAuth::AUTHORIZATION_RESULT_INVALID;
711 708
712 tok->set_expect_base64_token(true); 709 tok->set_expect_base64_token(true);
713 if (!tok->GetNext()) { 710 if (!tok->GetNext()) {
714 decoded_server_auth_token_.clear(); 711 // If a context has already been established, an empty Negotiate challenge
715 return true; 712 // should be treated as a rejection of the current attempt.
713 if (scoped_sec_context_.get() != GSS_C_NO_CONTEXT)
714 return HttpAuth::AUTHORIZATION_RESULT_REJECT;
715 DCHECK(decoded_server_auth_token_.empty());
716 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
717 } else {
718 // If a context has not already been established, additional tokens should
719 // not be present in the auth challenge.
720 if (scoped_sec_context_.get() == GSS_C_NO_CONTEXT)
721 return HttpAuth::AUTHORIZATION_RESULT_INVALID;
716 } 722 }
717 723
724 // Make sure the additional token is base64 encoded.
718 std::string encoded_auth_token = tok->value(); 725 std::string encoded_auth_token = tok->value();
719 std::string decoded_auth_token; 726 std::string decoded_auth_token;
720 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); 727 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
721 if (!base64_rv) { 728 if (!base64_rv)
722 LOG(ERROR) << "Base64 decoding of auth token failed."; 729 return HttpAuth::AUTHORIZATION_RESULT_INVALID;
723 return false;
724 }
725 decoded_server_auth_token_ = decoded_auth_token; 730 decoded_server_auth_token_ = decoded_auth_token;
726 return true; 731 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
727 } 732 }
728 733
729 int HttpAuthGSSAPI::GenerateAuthToken(const string16* username, 734 int HttpAuthGSSAPI::GenerateAuthToken(const string16* username,
730 const string16* password, 735 const string16* password,
731 const std::wstring& spn, 736 const std::wstring& spn,
732 std::string* auth_token) { 737 std::string* auth_token) {
733 DCHECK(auth_token); 738 DCHECK(auth_token);
734 DCHECK(username == NULL && password == NULL); 739 DCHECK(username == NULL && password == NULL);
735 740
736 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 741 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
737 input_token.length = decoded_server_auth_token_.length(); 742 input_token.length = decoded_server_auth_token_.length();
738 input_token.value = 743 input_token.value = (input_token.length > 0) ?
739 (input_token.length > 0) ? 744 const_cast<char*>(decoded_server_auth_token_.data()) :
740 const_cast<char*>(decoded_server_auth_token_.data()) : 745 NULL;
741 NULL;
742 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 746 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
743 ScopedBuffer scoped_output_token(&output_token, library_); 747 ScopedBuffer scoped_output_token(&output_token, library_);
744 int rv = GetNextSecurityToken(spn, &input_token, &output_token); 748 int rv = GetNextSecurityToken(spn, &input_token, &output_token);
745 if (rv != OK) 749 if (rv != OK)
746 return rv; 750 return rv;
747 751
748 // Base64 encode data in output buffer and prepend the scheme. 752 // Base64 encode data in output buffer and prepend the scheme.
749 std::string encode_input(static_cast<char*>(output_token.value), 753 std::string encode_input(static_cast<char*>(output_token.value),
750 output_token.length); 754 output_token.length);
751 std::string encode_output; 755 std::string encode_output;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 minor_status) 911 minor_status)
908 << std::endl 912 << std::endl
909 << DescribeContext(library_, scoped_sec_context_.get()); 913 << DescribeContext(library_, scoped_sec_context_.get());
910 return rv; 914 return rv;
911 } 915 }
912 916
913 return OK; 917 return OK;
914 } 918 }
915 919
916 } // namespace net 920 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_gssapi_posix.h ('k') | net/http/http_auth_gssapi_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698