mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 520607 - Remove use of "ntlm" auth module and replace with use of "sys-ntlm". r=wtc, cbiesinger. sr=bz.
This commit is contained in:
parent
7bc0b2bd75
commit
1e83668bfe
@ -20,6 +20,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@meer.net>
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -228,12 +229,8 @@ nsAuthSSPI::Init(const char *serviceName,
|
||||
{
|
||||
LOG((" nsAuthSSPI::Init\n"));
|
||||
|
||||
// we don't expect to be passed any user credentials
|
||||
NS_ASSERTION(!domain && !username && !password, "unexpected credentials");
|
||||
|
||||
// if we're configured for SPNEGO (Negotiate) or Kerberos, then it's critical
|
||||
// that the caller supply a service name to be used.
|
||||
// For NTLM, the service principal name can no longer be null. (Bug 487872)
|
||||
// The caller must supply a service name to be used. (For why we now require
|
||||
// a service name for NTLM, see bug 487872.)
|
||||
NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv;
|
||||
@ -266,18 +263,41 @@ nsAuthSSPI::Init(const char *serviceName,
|
||||
|
||||
TimeStamp useBefore;
|
||||
|
||||
SEC_WINNT_AUTH_IDENTITY_W ai;
|
||||
SEC_WINNT_AUTH_IDENTITY_W *pai = nsnull;
|
||||
|
||||
// domain, username, and password will be null if nsHttpNTLMAuth's ChallengeReceived
|
||||
// returns false for identityInvalid. Use default credentials in this case by passing
|
||||
// null for pai.
|
||||
if (username && password) {
|
||||
if (domain) {
|
||||
ai.Domain = const_cast<unsigned short*>(domain);
|
||||
ai.DomainLength = wcslen(domain);
|
||||
}
|
||||
else {
|
||||
ai.Domain = NULL;
|
||||
ai.DomainLength = 0;
|
||||
}
|
||||
ai.User = const_cast<unsigned short*>(username);
|
||||
ai.UserLength = wcslen(username);
|
||||
ai.Password = const_cast<unsigned short*>(password);
|
||||
ai.PasswordLength = wcslen(password);
|
||||
ai.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
pai = &ai;
|
||||
}
|
||||
|
||||
rc = (sspi->AcquireCredentialsHandleW)(NULL,
|
||||
package,
|
||||
SECPKG_CRED_OUTBOUND,
|
||||
NULL,
|
||||
NULL,
|
||||
pai,
|
||||
NULL,
|
||||
NULL,
|
||||
&mCred,
|
||||
&useBefore);
|
||||
if (rc != SEC_E_OK)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
LOG(("AcquireCredentialsHandle() succeeded.\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -351,6 +371,14 @@ nsAuthSSPI::GetNextToken(const void *inToken,
|
||||
&ctxAttr,
|
||||
&ignored);
|
||||
if (rc == SEC_I_CONTINUE_NEEDED || rc == SEC_E_OK) {
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (rc == SEC_E_OK)
|
||||
LOG(("InitializeSecurityContext: succeeded.\n"));
|
||||
else
|
||||
LOG(("InitializeSecurityContext: continue.\n"));
|
||||
#endif
|
||||
|
||||
if (!ob.cbBuffer) {
|
||||
nsMemory::Free(ob.pvBuffer);
|
||||
ob.pvBuffer = NULL;
|
||||
|
@ -257,15 +257,15 @@ nsHttpNegotiateAuth::GenerateCredentials(nsIHttpChannel *httpChannel,
|
||||
challenge++;
|
||||
len = strlen(challenge);
|
||||
|
||||
// strip off any padding (see bug 230351)
|
||||
while (challenge[len - 1] == '=')
|
||||
len--;
|
||||
|
||||
inTokenLen = (len * 3)/4;
|
||||
inToken = malloc(inTokenLen);
|
||||
if (!inToken)
|
||||
return (NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// strip off any padding (see bug 230351)
|
||||
while (challenge[len - 1] == '=')
|
||||
len--;
|
||||
|
||||
//
|
||||
// Decode the response that followed the "Negotiate" token
|
||||
//
|
||||
|
@ -822,6 +822,15 @@ pref("network.auth.use-sspi", true);
|
||||
|
||||
#endif
|
||||
|
||||
// Controls which NTLM authentication implementation we default to. True forces
|
||||
// the use of our generic (internal) NTLM authentication implementation vs. any
|
||||
// native implementation provided by the os. This pref is for diagnosing issues
|
||||
// with native NTLM. (See bug 520607 for details.) Using generic NTLM authentication
|
||||
// can expose the user to reflection attack vulnerabilities. Do not change this
|
||||
// unless you know what you're doing!
|
||||
// This pref should be removed 6 months after the release of firefox 3.6.
|
||||
pref("network.auth.force-generic-ntlm", false);
|
||||
|
||||
// The following prefs are used to enable automatic use of the operating
|
||||
// system's NTLM implementation to silently authenticate the user with their
|
||||
// Window's domain logon. The trusted-uris pref follows the format of the
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@meer.net>
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -54,6 +55,7 @@
|
||||
|
||||
static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
|
||||
static const char kTrustedURIs[] = "network.automatic-ntlm-auth.trusted-uris";
|
||||
static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
|
||||
|
||||
// XXX MatchesBaseURI and TestPref are duplicated in nsHttpNegotiateAuth.cpp,
|
||||
// but since that file lives in a separate library we cannot directly share it.
|
||||
@ -169,37 +171,48 @@ TestPref(nsIURI *uri, const char *pref)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Check to see if we should use our generic (internal) NTLM auth module.
|
||||
static PRBool
|
||||
CanUseSysNTLM(nsIHttpChannel *channel, PRBool isProxyAuth)
|
||||
ForceGenericNTLM()
|
||||
{
|
||||
// check prefs
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!prefs)
|
||||
return PR_FALSE;
|
||||
PRBool flag = PR_FALSE;
|
||||
|
||||
if (NS_FAILED(prefs->GetBoolPref(kForceGeneric, &flag)))
|
||||
flag = PR_FALSE;
|
||||
|
||||
LOG(("Force use of generic ntlm auth module: %d\n", flag));
|
||||
return flag;
|
||||
}
|
||||
|
||||
// Check to see if we should use default credentials for this host or proxy.
|
||||
static PRBool
|
||||
CanUseDefaultCredentials(nsIHttpChannel *channel, PRBool isProxyAuth)
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!prefs)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool val;
|
||||
if (isProxyAuth) {
|
||||
PRBool val;
|
||||
if (NS_FAILED(prefs->GetBoolPref(kAllowProxies, &val)))
|
||||
val = PR_FALSE;
|
||||
LOG(("sys-ntlm allowed for proxy: %d\n", val));
|
||||
LOG(("Default credentials allowed for proxy: %d\n", val));
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
if (uri && TestPref(uri, kTrustedURIs)) {
|
||||
LOG(("sys-ntlm allowed for host\n"));
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
PRBool isTrustedHost = (uri && TestPref(uri, kTrustedURIs));
|
||||
LOG(("Default credentials allowed for host: %d\n", isTrustedHost));
|
||||
return isTrustedHost;
|
||||
}
|
||||
|
||||
// Dummy class for session state object. This class doesn't hold any data.
|
||||
// Instead we use its existance as a flag. See ChallengeReceived.
|
||||
class nsNTLMSessionState : public nsISupports
|
||||
class nsNTLMSessionState : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -221,40 +234,58 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpChannel *channel,
|
||||
LOG(("nsHttpNTLMAuth::ChallengeReceived [ss=%p cs=%p]\n",
|
||||
*sessionState, *continuationState));
|
||||
|
||||
// NOTE: we don't define any session state
|
||||
// NOTE: we don't define any session state, but we do use the pointer.
|
||||
|
||||
*identityInvalid = PR_FALSE;
|
||||
// start new auth sequence if challenge is exactly "NTLM"
|
||||
|
||||
// Start a new auth sequence if the challenge is exactly "NTLM".
|
||||
// If native NTLM auth apis are available and enabled through prefs,
|
||||
// try to use them.
|
||||
if (PL_strcasecmp(challenge, "NTLM") == 0) {
|
||||
nsCOMPtr<nsISupports> module;
|
||||
//
|
||||
// our session state is non-null to indicate that we've flagged
|
||||
// this auth domain as not accepting the system's default login.
|
||||
//
|
||||
PRBool trySysNTLM = (*sessionState == nsnull);
|
||||
|
||||
//
|
||||
// we may have access to a built-in SSPI library,
|
||||
// which could be used to authenticate the user without prompting.
|
||||
//
|
||||
// if the continuationState is null, then we may want to try using
|
||||
// the SSPI NTLM module. however, we need to take care to only use
|
||||
// that module when speaking to a trusted host. because the SSPI
|
||||
// may send a weak LMv1 hash of the user's password, we cannot just
|
||||
// send it to any server.
|
||||
//
|
||||
if (trySysNTLM && !*continuationState && CanUseSysNTLM(channel, isProxyAuth)) {
|
||||
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
|
||||
// Check to see if we should default to our generic NTLM auth module
|
||||
// through UseGenericNTLM. (We use native auth by default if the
|
||||
// system provides it.) If *sessionState is non-null, we failed to
|
||||
// instantiate a native NTLM module the last time, so skip trying again.
|
||||
PRBool forceGeneric = ForceGenericNTLM();
|
||||
if (!forceGeneric && !*sessionState) {
|
||||
// Check for approved default credentials hosts and proxies. If
|
||||
// *continuationState is non-null, the last authentication attempt
|
||||
// failed so skip default credential use.
|
||||
if (!*continuationState && CanUseDefaultCredentials(channel, isProxyAuth)) {
|
||||
// Try logging in with the user's default credentials. If
|
||||
// successful, |identityInvalid| is false, which will trigger
|
||||
// a default credentials attempt once we return.
|
||||
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
else {
|
||||
// Try to use native NTLM and prompt the user for their domain,
|
||||
// username, and password. (only supported by windows nsAuthSSPI module.)
|
||||
// Note, for servers that use LMv1 a weak hash of the user's password
|
||||
// will be sent. We rely on windows internal apis to decide whether
|
||||
// we should support this older, less secure version of the protocol.
|
||||
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
|
||||
*identityInvalid = PR_TRUE;
|
||||
}
|
||||
#endif // XP_WIN
|
||||
#ifdef PR_LOGGING
|
||||
if (!module)
|
||||
LOG(("failed to load sys-ntlm module\n"));
|
||||
LOG(("Native sys-ntlm auth module not found.\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
// it's possible that there is no ntlm-sspi auth module...
|
||||
#ifdef XP_WIN
|
||||
// On windows, never fall back unless the user has specifically requested so.
|
||||
if (!forceGeneric && !module)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
#endif
|
||||
|
||||
// If no native support was available. Fall back on our internal NTLM implementation.
|
||||
if (!module) {
|
||||
if (!*sessionState) {
|
||||
// remember the fact that we cannot use the "sys-ntlm" module,
|
||||
// Remember the fact that we cannot use the "sys-ntlm" module,
|
||||
// so we don't ever bother trying again for this auth domain.
|
||||
*sessionState = new nsNTLMSessionState();
|
||||
if (!*sessionState)
|
||||
@ -262,18 +293,23 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpChannel *channel,
|
||||
NS_ADDREF(*sessionState);
|
||||
}
|
||||
|
||||
// Use our internal NTLM implementation. Note, this is less secure,
|
||||
// see bug 520607 for details.
|
||||
LOG(("Trying to fall back on internal ntlm auth.\n"));
|
||||
module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
|
||||
|
||||
// prompt user for domain, username, and password...
|
||||
// Prompt user for domain, username, and password.
|
||||
*identityInvalid = PR_TRUE;
|
||||
}
|
||||
|
||||
// if this fails, then it means that we cannot do NTLM auth.
|
||||
if (!module)
|
||||
// If this fails, then it means that we cannot do NTLM auth.
|
||||
if (!module) {
|
||||
LOG(("No ntlm auth modules available.\n"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// non-null continuation state implies that we failed to authenticate.
|
||||
// blow away the old authentication state, and use the new one.
|
||||
// A non-null continuation state implies that we failed to authenticate.
|
||||
// Blow away the old authentication state, and use the new one.
|
||||
module.swap(*continuationState);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -332,16 +368,16 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpChannel *httpChannel,
|
||||
challenge += 5;
|
||||
len -= 5;
|
||||
|
||||
// strip off any padding (see bug 230351)
|
||||
while (challenge[len - 1] == '=')
|
||||
len--;
|
||||
|
||||
// decode into the input secbuffer
|
||||
inBufLen = (len * 3)/4; // sufficient size (see plbase64.h)
|
||||
inBuf = nsMemory::Alloc(inBufLen);
|
||||
if (!inBuf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// strip off any padding (see bug 230351)
|
||||
while (challenge[len - 1] == '=')
|
||||
len--;
|
||||
|
||||
if (PL_Base64Decode(challenge, len, (char *) inBuf) == nsnull) {
|
||||
nsMemory::Free(inBuf);
|
||||
return NS_ERROR_UNEXPECTED; // improper base64 encoding
|
||||
|
@ -802,7 +802,6 @@ nsNTLMAuthModule::Init(const char *serviceName,
|
||||
const PRUnichar *username,
|
||||
const PRUnichar *password)
|
||||
{
|
||||
NS_ASSERTION(serviceName == nsnull, "unexpected service name");
|
||||
NS_ASSERTION(serviceFlags == nsIAuthModule::REQ_DEFAULT, "unexpected service flags");
|
||||
|
||||
mDomain = domain;
|
||||
|
Loading…
Reference in New Issue
Block a user