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

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

Issue 173528: Use SSPI for NTLM authentication on Windows.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Upload before checkin Created 11 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_handler_ntlm.cc ('k') | net/http/http_auth_handler_ntlm_win.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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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_handler_ntlm.h" 5 #include "net/http/http_auth_handler_ntlm.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 // For gethostname 8 // For gethostname
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <unistd.h> 10 #include <unistd.h>
11 #elif defined(OS_WIN) 11 #elif defined(OS_WIN)
12 #include <winsock2.h> 12 #include <winsock2.h>
13 #endif 13 #endif
14 14
15 #include "base/md5.h" 15 #include "base/md5.h"
16 #include "base/rand_util.h" 16 #include "base/rand_util.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/sys_string_conversions.h" 18 #include "base/sys_string_conversions.h"
19 #include "net/base/base64.h"
20 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
21 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
22 #include "net/http/des.h" 21 #include "net/http/des.h"
23 #include "net/http/md4.h" 22 #include "net/http/md4.h"
24 23
25 namespace net { 24 namespace net {
26 25
27 // Based on mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp, 26 // Based on mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp,
28 // CVS rev. 1.14. 27 // CVS rev. 1.14.
29 // 28 //
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() { 646 HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
648 // Wipe our copy of the password from memory, to reduce the chance of being 647 // Wipe our copy of the password from memory, to reduce the chance of being
649 // written to the paging file on disk. 648 // written to the paging file on disk.
650 ZapString(&password_); 649 ZapString(&password_);
651 } 650 }
652 651
653 bool HttpAuthHandlerNTLM::NeedsIdentity() { 652 bool HttpAuthHandlerNTLM::NeedsIdentity() {
654 return !auth_data_.empty(); 653 return !auth_data_.empty();
655 } 654 }
656 655
657 std::string HttpAuthHandlerNTLM::GenerateCredentials( 656 bool HttpAuthHandlerNTLM::IsFinalRound() {
658 const std::wstring& username, 657 return !auth_data_.empty();
659 const std::wstring& password,
660 const HttpRequestInfo* request,
661 const ProxyInfo* proxy) {
662 // TODO(wtc): See if we can use char* instead of void* for in_buf and
663 // out_buf. This change will need to propagate to GetNextToken,
664 // GenerateType1Msg, and GenerateType3Msg, and perhaps further.
665 const void* in_buf;
666 void* out_buf;
667 uint32 in_buf_len, out_buf_len;
668 std::string decoded_auth_data;
669
670 // |username| may be in the form "DOMAIN\user". Parse it into the two
671 // components.
672 std::wstring domain;
673 std::wstring user;
674 size_t backslash_idx = username.find(L'\\');
675 if (backslash_idx == std::wstring::npos) {
676 user = username;
677 } else {
678 domain = username.substr(0, backslash_idx);
679 user = username.substr(backslash_idx + 1);
680 }
681 domain_ = WideToUTF16(domain);
682 username_ = WideToUTF16(user);
683 password_ = WideToUTF16(password);
684
685 // Initial challenge.
686 if (auth_data_.empty()) {
687 in_buf_len = 0;
688 in_buf = NULL;
689 } else {
690 // Decode |auth_data_| into the input buffer.
691 int len = auth_data_.length();
692
693 // Strip off any padding.
694 // (See https://bugzilla.mozilla.org/show_bug.cgi?id=230351.)
695 //
696 // Our base64 decoder requires that the length be a multiple of 4.
697 while (len > 0 && len % 4 != 0 && auth_data_[len - 1] == '=')
698 len--;
699 auth_data_.erase(len);
700
701 if (!Base64Decode(auth_data_, &decoded_auth_data))
702 return std::string(); // Improper base64 encoding
703 in_buf_len = decoded_auth_data.length();
704 in_buf = decoded_auth_data.data();
705 }
706
707 int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len);
708 if (rv != OK)
709 return std::string();
710
711 // Base64 encode data in output buffer and prepend "NTLM ".
712 std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
713 std::string encode_output;
714 bool ok = Base64Encode(encode_input, &encode_output);
715 // OK, we are done with |out_buf|
716 free(out_buf);
717 if (!ok)
718 return std::string();
719 return std::string("NTLM ") + encode_output;
720 } 658 }
721 659
722 // static 660 // static
723 HttpAuthHandlerNTLM::GenerateRandomProc 661 HttpAuthHandlerNTLM::GenerateRandomProc
724 HttpAuthHandlerNTLM::SetGenerateRandomProc( 662 HttpAuthHandlerNTLM::SetGenerateRandomProc(
725 GenerateRandomProc proc) { 663 GenerateRandomProc proc) {
726 GenerateRandomProc old_proc = generate_random_proc_; 664 GenerateRandomProc old_proc = generate_random_proc_;
727 generate_random_proc_ = proc; 665 generate_random_proc_ = proc;
728 return old_proc; 666 return old_proc;
729 } 667 }
730 668
731 // static 669 // static
732 HttpAuthHandlerNTLM::HostNameProc HttpAuthHandlerNTLM::SetHostNameProc( 670 HttpAuthHandlerNTLM::HostNameProc HttpAuthHandlerNTLM::SetHostNameProc(
733 HostNameProc proc) { 671 HostNameProc proc) {
734 HostNameProc old_proc = get_host_name_proc_; 672 HostNameProc old_proc = get_host_name_proc_;
735 get_host_name_proc_ = proc; 673 get_host_name_proc_ = proc;
736 return old_proc; 674 return old_proc;
737 } 675 }
738 676
739 // The NTLM challenge header looks like:
740 // WWW-Authenticate: NTLM auth-data
741 bool HttpAuthHandlerNTLM::ParseChallenge(
742 std::string::const_iterator challenge_begin,
743 std::string::const_iterator challenge_end) {
744 scheme_ = "ntlm";
745 score_ = 3;
746 properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
747 auth_data_.clear();
748
749 // Verify the challenge's auth-scheme.
750 HttpAuth::ChallengeTokenizer challenge_tok(challenge_begin, challenge_end);
751 if (!challenge_tok.valid() ||
752 !LowerCaseEqualsASCII(challenge_tok.scheme(), "ntlm"))
753 return false;
754
755 // Extract the auth-data. We can't use challenge_tok.GetNext() because
756 // auth-data is base64-encoded and may contain '=' padding at the end,
757 // which would be mistaken for a name=value pair.
758 challenge_begin += 4; // Skip over "NTLM".
759 HttpUtil::TrimLWS(&challenge_begin, &challenge_end);
760
761 auth_data_.assign(challenge_begin, challenge_end);
762
763 return true;
764 }
765
766 int HttpAuthHandlerNTLM::GetNextToken(const void* in_token, 677 int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
767 uint32 in_token_len, 678 uint32 in_token_len,
768 void** out_token, 679 void** out_token,
769 uint32* out_token_len) { 680 uint32* out_token_len) {
770 int rv; 681 int rv;
771 682
772 // If in_token is non-null, then assume it contains a type 2 message... 683 // If in_token is non-null, then assume it contains a type 2 message...
773 if (in_token) { 684 if (in_token) {
774 LogToken("in-token", in_token, in_token_len); 685 LogToken("in-token", in_token, in_token_len);
775 std::string hostname = get_host_name_proc_(); 686 std::string hostname = get_host_name_proc_();
776 if (hostname.empty()) 687 if (hostname.empty())
777 return ERR_UNEXPECTED; 688 return ERR_UNEXPECTED;
778 uint8 rand_buf[8]; 689 uint8 rand_buf[8];
779 generate_random_proc_(rand_buf, 8); 690 generate_random_proc_(rand_buf, 8);
780 rv = GenerateType3Msg(domain_, username_, password_, hostname, rand_buf, 691 rv = GenerateType3Msg(domain_, username_, password_, hostname, rand_buf,
781 in_token, in_token_len, out_token, out_token_len); 692 in_token, in_token_len, out_token, out_token_len);
782 } else { 693 } else {
783 rv = GenerateType1Msg(out_token, out_token_len); 694 rv = GenerateType1Msg(out_token, out_token_len);
784 } 695 }
785 696
786 if (rv == OK) 697 if (rv == OK)
787 LogToken("out-token", *out_token, *out_token_len); 698 LogToken("out-token", *out_token, *out_token_len);
788 699
789 return rv; 700 return rv;
790 } 701 }
791 702
703 int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
704 return OK;
705 }
706
792 } // namespace net 707 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_ntlm.cc ('k') | net/http/http_auth_handler_ntlm_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698