15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See "SSPI Sample Application" at 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://msdn.microsoft.com/en-us/library/aa918273.aspx 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_sspi_win.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_auth_challenge_tokenizer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MapAcquireCredentialsStatusToError(SECURITY_STATUS status, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SEC_WCHAR* package) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "AcquireCredentialsHandle returned 0x" << std::hex << status; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_OK: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INSUFFICIENT_MEMORY: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_OUT_OF_MEMORY; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INTERNAL_ERROR: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "AcquireCredentialsHandle returned unexpected status 0x" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_NO_CREDENTIALS: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_NOT_OWNER: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_UNKNOWN_CREDENTIALS: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_INVALID_AUTH_CREDENTIALS; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_SECPKG_NOT_FOUND: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This indicates that the SSPI configuration does not match expectations 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNSUPPORTED_AUTH_SCHEME; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "AcquireCredentialsHandle returned undocumented status 0x" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AcquireExplicitCredentials(SSPILibrary* library, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SEC_WCHAR* package, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& domain, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& user, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::string16& password, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CredHandle* cred) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEC_WINNT_AUTH_IDENTITY identity; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.User = 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str())); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.UserLength = user.size(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.Domain = 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str())); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.DomainLength = domain.size(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.Password = 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(password.c_str())); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity.PasswordLength = password.size(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeStamp expiry; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pass the username/password to get the credentials handle. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_STATUS status = library->AcquireCredentialsHandle( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pszPrincipal 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<SEC_WCHAR*>(package), // pszPackage 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECPKG_CRED_OUTBOUND, // fCredentialUse 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pvLogonID 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &identity, // pAuthData 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pGetKeyFn (not used) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pvGetKeyArgument (not used) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cred, // phCredential 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &expiry); // ptsExpiry 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MapAcquireCredentialsStatusToError(status, package); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AcquireDefaultCredentials(SSPILibrary* library, const SEC_WCHAR* package, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CredHandle* cred) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeStamp expiry; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pass the username/password to get the credentials handle. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: Since the 5th argument is NULL, it uses the default 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cached credentials for the logged in user, which can be used 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for a single sign-on. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_STATUS status = library->AcquireCredentialsHandle( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pszPrincipal 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<SEC_WCHAR*>(package), // pszPackage 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECPKG_CRED_OUTBOUND, // fCredentialUse 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pvLogonID 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pAuthData 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pGetKeyFn (not used) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, // pvGetKeyArgument (not used) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cred, // phCredential 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &expiry); // ptsExpiry 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MapAcquireCredentialsStatusToError(status, package); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MapInitializeSecurityContextStatusToError(SECURITY_STATUS status) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "InitializeSecurityContext returned 0x" << std::hex << status; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_OK: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_I_CONTINUE_NEEDED: 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_I_COMPLETE_AND_CONTINUE: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_I_COMPLETE_NEEDED: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_I_INCOMPLETE_CREDENTIALS: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INCOMPLETE_MESSAGE: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INTERNAL_ERROR: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These are return codes reported by InitializeSecurityContext 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but not expected by Chrome (for example, INCOMPLETE_CREDENTIALS 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and INCOMPLETE_MESSAGE are intended for schannel). 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "InitializeSecurityContext returned unexpected status 0x" 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INSUFFICIENT_MEMORY: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_OUT_OF_MEMORY; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_UNSUPPORTED_FUNCTION: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INVALID_HANDLE: 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_INVALID_HANDLE; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_INVALID_TOKEN: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_INVALID_RESPONSE; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_LOGON_DENIED: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_ACCESS_DENIED; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_NO_CREDENTIALS: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_WRONG_PRINCIPAL: 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_INVALID_AUTH_CREDENTIALS; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_NO_AUTHENTICATING_AUTHORITY: 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_TARGET_UNKNOWN: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_MISCONFIGURED_AUTH_ENVIRONMENT; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "InitializeSecurityContext returned undocumented status 0x" 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MapQuerySecurityPackageInfoStatusToError(SECURITY_STATUS status) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "QuerySecurityPackageInfo returned 0x" << std::hex << status; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_OK: 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_SECPKG_NOT_FOUND: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This isn't a documented return code, but has been encountered 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // during testing. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNSUPPORTED_AUTH_SCHEME; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "QuerySecurityPackageInfo returned undocumented status 0x" 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MapFreeContextBufferStatusToError(SECURITY_STATUS status) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "FreeContextBuffer returned 0x" << std::hex << status; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (status) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SEC_E_OK: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The documentation at 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://msdn.microsoft.com/en-us/library/aa375416(VS.85).aspx 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only mentions that a non-zero (or non-SEC_E_OK) value is returned 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the function fails, and does not indicate what the failure 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conditions are. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "FreeContextBuffer returned undocumented status 0x" 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::hex << status; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme, 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SEC_WCHAR* security_package, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG max_token_length) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : library_(library), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheme_(scheme), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) security_package_(security_package), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_token_length_(max_token_length), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) can_delegate_(false) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(library_); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecInvalidateHandle(&cred_); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecInvalidateHandle(&ctxt_); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthSSPI::~HttpAuthSSPI() { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetSecurityContext(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SecIsValidHandle(&cred_)) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) library_->FreeCredentialsHandle(&cred_); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecInvalidateHandle(&cred_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpAuthSSPI::NeedsIdentity() const { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decoded_server_auth_token_.empty(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpAuthSSPI::AllowsExplicitCredentials() const { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpAuthSSPI::Delegate() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) can_delegate_ = true; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpAuthSSPI::ResetSecurityContext() { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SecIsValidHandle(&ctxt_)) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) library_->DeleteSecurityContext(&ctxt_); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecInvalidateHandle(&ctxt_); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuth::AuthorizationResult HttpAuthSSPI::ParseChallenge( 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HttpAuthChallengeTokenizer* tok) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the challenge's auth-scheme. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str())) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_INVALID; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encoded_auth_token = tok->base64_param(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (encoded_auth_token.empty()) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a context has already been established, an empty challenge 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be treated as a rejection of the current attempt. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SecIsValidHandle(&ctxt_)) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_REJECT; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(decoded_server_auth_token_.empty()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a context has not already been established, additional tokens should 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not be present in the auth challenge. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SecIsValidHandle(&ctxt_)) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_INVALID; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string decoded_auth_token; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base64_rv) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_INVALID; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_server_auth_token_ = decoded_auth_token; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials, 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& spn, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* auth_token) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial challenge. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SecIsValidHandle(&cred_)) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = OnFirstRound(credentials); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(SecIsValidHandle(&cred_)); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* out_buf; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int out_buf_len; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = GetNextSecurityToken( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spn, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<void *>(const_cast<char *>( 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_server_auth_token_.c_str())), 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoded_server_auth_token_.length(), 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &out_buf, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &out_buf_len); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Base64 encode data in output buffer and prepend the scheme. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encode_input(static_cast<char*>(out_buf), out_buf_len); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encode_output; 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Base64Encode(encode_input, &encode_output); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OK, we are done with |out_buf| 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(out_buf); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *auth_token = scheme_ + " " + encode_output; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpAuthSSPI::OnFirstRound(const AuthCredentials* credentials) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!SecIsValidHandle(&cred_)); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = OK; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (credentials) { 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 domain; 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 user; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SplitDomainAndUser(credentials->username(), &domain, &user); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AcquireExplicitCredentials(library_, security_package_, domain, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user, credentials->password(), &cred_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AcquireDefaultCredentials(library_, security_package_, &cred_); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpAuthSSPI::GetNextSecurityToken( 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& spn, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* in_token, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int in_token_len, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void** out_token, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* out_token_len) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CtxtHandle* ctxt_ptr; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecBufferDesc in_buffer_desc, out_buffer_desc; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecBufferDesc* in_buffer_desc_ptr; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecBuffer in_buffer, out_buffer; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (in_token_len > 0) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare input buffer. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc.ulVersion = SECBUFFER_VERSION; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc.cBuffers = 1; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc.pBuffers = &in_buffer; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer.BufferType = SECBUFFER_TOKEN; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer.cbBuffer = in_token_len; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer.pvBuffer = const_cast<void*>(in_token); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt_ptr = &ctxt_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc_ptr = &in_buffer_desc; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is no input token, then we are starting a new authentication 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sequence. If we have already initialized our security context, then 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're incorrectly reusing the auth handler for a new sequence. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SecIsValidHandle(&ctxt_)) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_UNEXPECTED; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt_ptr = NULL; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc_ptr = NULL; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare output buffer. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer_desc.ulVersion = SECBUFFER_VERSION; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer_desc.cBuffers = 1; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer_desc.pBuffers = &out_buffer; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer.BufferType = SECBUFFER_TOKEN; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer.cbBuffer = max_token_length_; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer.pvBuffer = malloc(out_buffer.cbBuffer); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!out_buffer.pvBuffer) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_OUT_OF_MEMORY; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD context_flags = 0; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox only sets ISC_REQ_DELEGATE, but MSDN documentation indicates that 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ISC_REQ_MUTUAL_AUTH must also be set. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (can_delegate_) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This returns a token that is passed to the remote server. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD context_attribute; 362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::wstring spn_wide = base::ASCIIToWide(spn); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_STATUS status = library_->InitializeSecurityContext( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cred_, // phCredential 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt_ptr, // phContext 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const_cast<wchar_t *>(spn_wide.c_str()), // pszTargetName 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_flags, // fContextReq 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Reserved1 (must be 0) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_NATIVE_DREP, // TargetDataRep 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_buffer_desc_ptr, // pInput 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, // Reserved2 (must be 0) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ctxt_, // phNewContext 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &out_buffer_desc, // pOutput 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &context_attribute, // pfContextAttr 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); // ptsExpiry 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = MapInitializeSecurityContextStatusToError(status); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetSecurityContext(); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(out_buffer.pvBuffer); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!out_buffer.cbBuffer) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(out_buffer.pvBuffer); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_buffer.pvBuffer = NULL; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_token = out_buffer.pvBuffer; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_token_len = out_buffer.cbBuffer; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SplitDomainAndUser(const base::string16& combined, 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* domain, 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* user) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |combined| may be in the form "user" or "DOMAIN\user". 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separate the two parts if they exist. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(cbentzel): I believe user@domain is also a valid form. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t backslash_idx = combined.find(L'\\'); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (backslash_idx == base::string16::npos) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) domain->clear(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *user = combined; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *domain = combined.substr(0, backslash_idx); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *user = combined.substr(backslash_idx + 1); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DetermineMaxTokenLength(SSPILibrary* library, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring& package, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG* max_token_length) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(library); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(max_token_length); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PSecPkgInfo pkg_info = NULL; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECURITY_STATUS status = library->QuerySecurityPackageInfo( 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<wchar_t *>(package.c_str()), &pkg_info); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = MapQuerySecurityPackageInfoStatusToError(status); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int token_length = pkg_info->cbMaxToken; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = library->FreeContextBuffer(pkg_info); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = MapFreeContextBufferStatusToError(status); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != OK) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *max_token_length = token_length; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 428