Bug 1705659 - Make GetAuthenticator work with nsACString r=necko-reviewers,dragana

Depends on D112602

Differential Revision: https://phabricator.services.mozilla.com/D112597
This commit is contained in:
Valentin Gosu 2021-08-12 12:39:22 +00:00
Родитель b874482b5b
Коммит b3d74be7b8
19 изменённых файлов: 402 добавлений и 526 удалений

Просмотреть файл

@ -324,14 +324,15 @@ void nsAuthGSSAPI::Shutdown() {
NS_IMPL_ISUPPORTS(nsAuthGSSAPI, nsIAuthModule)
NS_IMETHODIMP
nsAuthGSSAPI::Init(const char* serviceName, uint32_t serviceFlags,
const char16_t* domain, const char16_t* username,
const char16_t* password) {
nsAuthGSSAPI::Init(const nsACString& serviceName, uint32_t serviceFlags,
const nsAString& domain, const nsAString& username,
const nsAString& password) {
// we don't expect to be passed any user credentials
NS_ASSERTION(!domain && !username && !password, "unexpected credentials");
NS_ASSERTION(domain.IsEmpty() && username.IsEmpty() && password.IsEmpty(),
"unexpected credentials");
// it's critial that the caller supply a service name to be used
NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG);
NS_ENSURE_TRUE(!serviceName.IsEmpty(), NS_ERROR_INVALID_ARG);
LOG(("entering nsAuthGSSAPI::Init()\n"));

Просмотреть файл

@ -20,13 +20,14 @@ void nsAuthSASL::Reset() { mSASLReady = false; }
NS_IMPL_ISUPPORTS(nsAuthSASL, nsIAuthModule)
NS_IMETHODIMP
nsAuthSASL::Init(const char* serviceName, uint32_t serviceFlags,
const char16_t* domain, const char16_t* username,
const char16_t* password) {
nsAuthSASL::Init(const nsACString& serviceName, uint32_t serviceFlags,
const nsAString& domain, const nsAString& username,
const nsAString& password) {
nsresult rv;
NS_ASSERTION(username, "SASL requires a username");
NS_ASSERTION(!domain && !password, "unexpected credentials");
NS_ASSERTION(!username.IsEmpty(), "SASL requires a username");
NS_ASSERTION(domain.IsEmpty() && password.IsEmpty(),
"unexpected credentials");
mUsername = username;
@ -45,7 +46,7 @@ nsAuthSASL::Init(const char* serviceName, uint32_t serviceFlags,
MOZ_ALWAYS_TRUE(mInnerModule = nsIAuthModule::CreateInstance(authType));
mInnerModule->Init(serviceName, serviceFlags, nullptr, nullptr, nullptr);
mInnerModule->Init(serviceName, serviceFlags, u""_ns, u""_ns, u""_ns);
return NS_OK;
}

Просмотреть файл

@ -90,7 +90,7 @@ static nsresult InitSSPI() {
//-----------------------------------------------------------------------------
nsresult nsAuthSSPI::MakeSN(const char* principal, nsCString& result) {
nsresult nsAuthSSPI::MakeSN(const nsACString& principal, nsCString& result) {
nsresult rv;
nsAutoCString buf(principal);
@ -174,9 +174,9 @@ void nsAuthSSPI::Reset() {
NS_IMPL_ISUPPORTS(nsAuthSSPI, nsIAuthModule)
NS_IMETHODIMP
nsAuthSSPI::Init(const char* serviceName, uint32_t serviceFlags,
const char16_t* domain, const char16_t* username,
const char16_t* password) {
nsAuthSSPI::Init(const nsACString& aServiceName, uint32_t aServiceFlags,
const nsAString& aDomain, const nsAString& aUsername,
const nsAString& aPassword) {
LOG((" nsAuthSSPI::Init\n"));
mIsFirst = true;
@ -185,7 +185,7 @@ nsAuthSSPI::Init(const char* serviceName, uint32_t serviceFlags,
// 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);
NS_ENSURE_TRUE(!aServiceName.IsEmpty(), NS_ERROR_INVALID_ARG);
nsresult rv;
@ -203,18 +203,18 @@ nsAuthSSPI::Init(const char* serviceName, uint32_t serviceFlags,
// lookups. The incoming serviceName is in the format: "protocol@hostname",
// SSPI expects
// "<service class>/<hostname>", so swap the '@' for a '/'.
mServiceName.Assign(serviceName);
mServiceName = aServiceName;
int32_t index = mServiceName.FindChar('@');
if (index == kNotFound) return NS_ERROR_UNEXPECTED;
mServiceName.Replace(index, 1, '/');
} else {
// Kerberos requires the canonical host, MakeSN takes care of this through a
// DNS lookup.
rv = MakeSN(serviceName, mServiceName);
rv = MakeSN(aServiceName, mServiceName);
if (NS_FAILED(rv)) return rv;
}
mServiceFlags = serviceFlags;
mServiceFlags = aServiceFlags;
SECURITY_STATUS rc;
@ -235,11 +235,11 @@ nsAuthSSPI::Init(const char* serviceName, uint32_t serviceFlags,
// 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 (!aUsername.IsEmpty() && !aPassword.IsEmpty()) {
// Keep a copy of these strings for the duration
mUsername.Assign(username);
mPassword.Assign(password);
mDomain.Assign(domain);
mUsername = aUsername;
mPassword = aPassword;
mDomain = aDomain;
ai.Domain = reinterpret_cast<unsigned short*>(mDomain.BeginWriting());
ai.DomainLength = mDomain.Length();
ai.User = reinterpret_cast<unsigned short*>(mUsername.BeginWriting());
@ -258,7 +258,7 @@ nsAuthSSPI::Init(const char* serviceName, uint32_t serviceFlags,
static bool sTelemetrySent = false;
if (!sTelemetrySent) {
mozilla::Telemetry::Accumulate(mozilla::Telemetry::NTLM_MODULE_USED_2,
serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
aServiceFlags & nsIAuthModule::REQ_PROXY_AUTH
? NTLM_MODULE_WIN_API_PROXY
: NTLM_MODULE_WIN_API_DIRECT);
sTelemetrySent = true;

Просмотреть файл

@ -41,7 +41,7 @@ class nsAuthSSPI final : public nsIAuthModule {
typedef ::TimeStamp MS_TimeStamp;
private:
nsresult MakeSN(const char* principal, nsCString& result);
nsresult MakeSN(const nsACString& principal, nsCString& result);
CredHandle mCred;
CtxtHandle mCtxt;

Просмотреть файл

@ -188,10 +188,11 @@ nsresult nsAuthSambaNTLM::SpawnNTLMAuthHelper() {
}
NS_IMETHODIMP
nsAuthSambaNTLM::Init(const char* serviceName, uint32_t serviceFlags,
const char16_t* domain, const char16_t* username,
const char16_t* password) {
NS_ASSERTION(!username && !domain && !password, "unexpected credentials");
nsAuthSambaNTLM::Init(const nsACString& serviceName, uint32_t serviceFlags,
const nsAString& domain, const nsAString& username,
const nsAString& password) {
NS_ASSERTION(username.IsEmpty() && domain.IsEmpty() && password.IsEmpty(),
"unexpected credentials");
static bool sTelemetrySent = false;
if (!sTelemetrySent) {

Просмотреть файл

@ -148,7 +148,8 @@ nsHttpNegotiateAuth::GetAuthFlags(uint32_t* flags) {
//
NS_IMETHODIMP
nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
const char* challenge, bool isProxyAuth,
const nsACString& challenge,
bool isProxyAuth,
nsISupports** sessionState,
nsISupports** continuationState,
bool* identityInvalid) {
@ -225,7 +226,7 @@ nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
MOZ_ALWAYS_TRUE(module = nsIAuthModule::CreateInstance(authType));
rv = module->Init(service.get(), req_flags, nullptr, nullptr, nullptr);
rv = module->Init(service, req_flags, u""_ns, u""_ns, u""_ns);
if (NS_FAILED(rv)) {
return rv;
@ -250,22 +251,15 @@ namespace {
//
class GetNextTokenCompleteEvent final : public nsIRunnable,
public nsICancelable {
virtual ~GetNextTokenCompleteEvent() {
if (mCreds) {
free(mCreds);
}
};
public:
NS_DECL_THREADSAFE_ISUPPORTS
explicit GetNextTokenCompleteEvent(nsIHttpAuthenticatorCallback* aCallback)
: mCallback(aCallback), mCreds(nullptr), mCancelled(false) {}
: mCallback(aCallback) {}
NS_IMETHODIMP DispatchSuccess(
char* aCreds, uint32_t aFlags,
already_AddRefed<nsISupports> aSessionState,
already_AddRefed<nsISupports> aContinuationState) {
nsresult DispatchSuccess(const nsACString& aCreds, uint32_t aFlags,
already_AddRefed<nsISupports> aSessionState,
already_AddRefed<nsISupports> aContinuationState) {
// Called from worker thread
MOZ_ASSERT(!NS_IsMainThread());
@ -277,9 +271,8 @@ class GetNextTokenCompleteEvent final : public nsIRunnable,
return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
}
NS_IMETHODIMP DispatchError(
already_AddRefed<nsISupports> aSessionState,
already_AddRefed<nsISupports> aContinuationState) {
nsresult DispatchError(already_AddRefed<nsISupports> aSessionState,
already_AddRefed<nsISupports> aContinuationState) {
// Called from worker thread
MOZ_ASSERT(!NS_IsMainThread());
@ -315,11 +308,13 @@ class GetNextTokenCompleteEvent final : public nsIRunnable,
}
private:
virtual ~GetNextTokenCompleteEvent() = default;
nsCOMPtr<nsIHttpAuthenticatorCallback> mCallback;
char* mCreds; // This class owns it, freed in destructor
uint32_t mFlags;
nsresult mResult;
bool mCancelled;
nsCString mCreds;
uint32_t mFlags = 0;
nsresult mResult = NS_OK;
bool mCancelled = false;
nsCOMPtr<nsISupports> mSessionState;
nsCOMPtr<nsISupports> mContinuationState;
};
@ -338,8 +333,8 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
public:
GetNextTokenRunnable(
nsMainThreadPtrHandle<nsIHttpAuthenticableChannel>& authChannel,
const char* challenge, bool isProxyAuth, const char16_t* domain,
const char16_t* username, const char16_t* password,
const nsACString& challenge, bool isProxyAuth, const nsAString& domain,
const nsAString& username, const nsAString& password,
nsISupports* sessionState, nsISupports* continuationState,
GetNextTokenCompleteEvent* aCompleteEvent)
: mozilla::Runnable("GetNextTokenRunnable"),
@ -357,9 +352,9 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
// Runs on worker thread
MOZ_ASSERT(!NS_IsMainThread());
char* creds;
nsCString creds;
uint32_t flags;
nsresult rv = ObtainCredentialsAndFlags(&creds, &flags);
nsresult rv = ObtainCredentialsAndFlags(creds, &flags);
// Passing session and continuation state this way to not touch
// referencing of the object that may not be thread safe.
@ -376,7 +371,7 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
mContinuationState.forget());
}
NS_IMETHODIMP ObtainCredentialsAndFlags(char** aCreds, uint32_t* aFlags) {
NS_IMETHODIMP ObtainCredentialsAndFlags(nsCString& aCreds, uint32_t* aFlags) {
nsresult rv;
// Use negotiate service to call GenerateCredentials outside of main thread
@ -398,9 +393,8 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
// Should any of the session or continuation states change inside
// this method, they must be threadsafe.
rv = authenticator->GenerateCredentials(
mAuthChannel, mChallenge.get(), mIsProxyAuth, mDomain.get(),
mUsername.get(), mPassword.get(), &sessionState, &continuationState,
aFlags, aCreds);
mAuthChannel, mChallenge, mIsProxyAuth, mDomain, mUsername, mPassword,
&sessionState, &continuationState, aFlags, aCreds);
if (mSessionState != sessionState) {
mSessionState = sessionState;
}
@ -427,9 +421,9 @@ class GetNextTokenRunnable final : public mozilla::Runnable {
NS_IMETHODIMP
nsHttpNegotiateAuth::GenerateCredentialsAsync(
nsIHttpAuthenticableChannel* authChannel,
nsIHttpAuthenticatorCallback* aCallback, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* username,
const char16_t* password, nsISupports* sessionState,
nsIHttpAuthenticatorCallback* aCallback, const nsACString& challenge,
bool isProxyAuth, const nsAString& domain, const nsAString& username,
const nsAString& password, nsISupports* sessionState,
nsISupports* continuationState, nsICancelable** aCancelable) {
NS_ENSURE_ARG(aCallback);
NS_ENSURE_ARG_POINTER(aCancelable);
@ -460,10 +454,10 @@ nsHttpNegotiateAuth::GenerateCredentialsAsync(
//
NS_IMETHODIMP
nsHttpNegotiateAuth::GenerateCredentials(
nsIHttpAuthenticableChannel* authChannel, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* username,
const char16_t* password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* flags, char** creds) {
nsIHttpAuthenticableChannel* authChannel, const nsACString& aChallenge,
bool isProxyAuth, const nsAString& domain, const nsAString& username,
const nsAString& password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* flags, nsACString& creds) {
// ChallengeReceived must have been called previously.
nsIAuthModule* module = (nsIAuthModule*)*continuationState;
NS_ENSURE_TRUE(module, NS_ERROR_NOT_INITIALIZED);
@ -471,12 +465,11 @@ nsHttpNegotiateAuth::GenerateCredentials(
*flags = USING_INTERNAL_IDENTITY;
LOG(("nsHttpNegotiateAuth::GenerateCredentials() [challenge=%s]\n",
challenge));
NS_ASSERTION(creds, "null param");
aChallenge.BeginReading()));
#ifdef DEBUG
bool isGssapiAuth = !PL_strncasecmp(challenge, kNegotiate, kNegotiateLen);
bool isGssapiAuth = StringBeginsWith(aChallenge, "Negotiate"_ns,
nsCaseInsensitiveCStringComparator);
NS_ASSERTION(isGssapiAuth, "Unexpected challenge");
#endif
@ -489,15 +482,14 @@ nsHttpNegotiateAuth::GenerateCredentials(
// generally *does* require multiple round-trips. Don't assume
// auth can be completed in just 1 call.
//
unsigned int len = strlen(challenge);
void *inToken = nullptr, *outToken;
uint32_t inTokenLen, outTokenLen;
if (len > kNegotiateLen) {
nsAutoCString inToken;
if (aChallenge.Length() > kNegotiateLen) {
const nsCString& flatChallenge = PromiseFlatCString(aChallenge);
const char* challenge = flatChallenge.get();
challenge += kNegotiateLen;
while (*challenge == ' ') challenge++;
len = strlen(challenge);
unsigned int len = strlen(challenge);
if (!len) return NS_ERROR_UNEXPECTED;
@ -507,25 +499,21 @@ nsHttpNegotiateAuth::GenerateCredentials(
//
// Decode the response that followed the "Negotiate" token
//
nsresult rv = Base64Decode(challenge, len, (char**)&inToken, &inTokenLen);
if (NS_FAILED(rv)) {
free(inToken);
return rv;
}
} else {
//
// Initializing, don't use an input token.
//
inTokenLen = 0;
(void)Base64Decode(nsDependentCSubstring(challenge, len), inToken);
}
nsresult rv =
module->GetNextToken(inToken, inTokenLen, &outToken, &outTokenLen);
free(inToken);
if (NS_FAILED(rv)) return rv;
void* outToken = nullptr;
uint32_t outTokenLen = 0;
nsresult rv = module->GetNextToken(inToken.get(), inToken.Length(), &outToken,
&outTokenLen);
if (NS_FAILED(rv)) {
if (outToken) {
// Technically if the call fails we shouln't have allocated, but
// Coverity doesn't know that.
free(outToken);
}
return rv;
}
if (outTokenLen == 0) {
LOG((" No output token to send, exiting"));
@ -535,20 +523,17 @@ nsHttpNegotiateAuth::GenerateCredentials(
//
// base64 encode the output token.
//
char* encoded_token = PL_Base64Encode((char*)outToken, outTokenLen, nullptr);
nsAutoCString encodedToken;
rv = mozilla::Base64Encode(
nsDependentCSubstring((char*)outToken, outTokenLen), encodedToken);
free(outToken);
if (!encoded_token) return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(rv)) {
return rv;
}
LOG((" Sending a token of length %d\n", outTokenLen));
// allocate a buffer sizeof("Negotiate" + " " + b64output_token + "\0")
const int bufsize = kNegotiateLen + 1 + strlen(encoded_token) + 1;
*creds = (char*)moz_xmalloc(bufsize);
snprintf(*creds, bufsize, "%s %s", kNegotiate, encoded_token);
PR_Free(encoded_token); // PL_Base64Encode() uses PR_Malloc().
creds = nsPrintfCString("%s %s", kNegotiate, encodedToken.get());
return rv;
}

Просмотреть файл

@ -15,7 +15,7 @@ class nsAuthInformationHolder : public nsIAuthInformation {
public:
// aAuthType must be ASCII
nsAuthInformationHolder(uint32_t aFlags, const nsString& aRealm,
const nsCString& aAuthType)
const nsACString& aAuthType)
: mFlags(aFlags), mRealm(aRealm), mAuthType(aAuthType) {}
NS_DECL_ISUPPORTS

Просмотреть файл

@ -60,11 +60,11 @@ interface nsIAuthModule : nsISupports
* @param aPassword
* the user's password
*/
void init(in string aServiceName,
void init(in ACString aServiceName,
in unsigned long aServiceFlags,
in wstring aDomain,
in wstring aUsername,
in wstring aPassword);
in AString aDomain,
in AString aUsername,
in AString aPassword);
/**
* Called to get the next token in a sequence of authentication steps.

Просмотреть файл

@ -21,7 +21,7 @@ interface nsIHttpAuthenticatorCallback : nsISupports
* @param aContinuationState
* Modified continuation state to be passed to caller
*/
void onCredsGenerated(in string aCreds,
void onCredsGenerated(in ACString aCreds,
in unsigned long aFlags,
in nsresult aResult,
in nsISupports aSessionsState,

Просмотреть файл

@ -22,7 +22,7 @@
namespace mozilla {
namespace net {
static inline void GetAuthKey(const char* scheme, const char* host,
static inline void GetAuthKey(const nsACString& scheme, const nsACString& host,
int32_t port, nsACString const& originSuffix,
nsCString& key) {
key.Truncate();
@ -35,17 +35,6 @@ static inline void GetAuthKey(const char* scheme, const char* host,
key.AppendInt(port);
}
// return true if the two strings are equal or both empty. an empty string
// is either null or zero length.
static bool StrEquivalent(const char16_t* a, const char16_t* b) {
static const char16_t emptyStr[] = {0};
if (!a) a = emptyStr;
if (!b) b = emptyStr;
return nsCRT::strcmp(a, b) == 0;
}
//-----------------------------------------------------------------------------
// nsHttpAuthCache <public>
//-----------------------------------------------------------------------------
@ -71,12 +60,14 @@ nsHttpAuthCache::~nsHttpAuthCache() {
}
}
nsresult nsHttpAuthCache::GetAuthEntryForPath(const char* scheme,
const char* host, int32_t port,
const char* path,
nsresult nsHttpAuthCache::GetAuthEntryForPath(const nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& path,
nsACString const& originSuffix,
nsHttpAuthEntry** entry) {
LOG(("nsHttpAuthCache::GetAuthEntryForPath %p [path=%s]\n", this, path));
LOG(("nsHttpAuthCache::GetAuthEntryForPath %p [path=%s]\n", this,
path.BeginReading()));
nsAutoCString key;
nsHttpAuthNode* node = LookupAuthNode(scheme, host, port, originSuffix, key);
@ -87,14 +78,16 @@ nsresult nsHttpAuthCache::GetAuthEntryForPath(const char* scheme,
return *entry ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
nsresult nsHttpAuthCache::GetAuthEntryForDomain(const char* scheme,
const char* host, int32_t port,
const char* realm,
nsresult nsHttpAuthCache::GetAuthEntryForDomain(const nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& realm,
nsACString const& originSuffix,
nsHttpAuthEntry** entry)
{
LOG(("nsHttpAuthCache::GetAuthEntryForDomain %p [realm=%s]\n", this, realm));
LOG(("nsHttpAuthCache::GetAuthEntryForDomain %p [realm=%s]\n", this,
realm.BeginReading()));
nsAutoCString key;
nsHttpAuthNode* node = LookupAuthNode(scheme, host, port, originSuffix, key);
@ -105,17 +98,15 @@ nsresult nsHttpAuthCache::GetAuthEntryForDomain(const char* scheme,
return *entry ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
nsresult nsHttpAuthCache::SetAuthEntry(const char* scheme, const char* host,
int32_t port, const char* path,
const char* realm, const char* creds,
const char* challenge,
nsACString const& originSuffix,
const nsHttpAuthIdentity* ident,
nsISupports* metadata) {
nsresult nsHttpAuthCache::SetAuthEntry(
const nsACString& scheme, const nsACString& host, int32_t port,
const nsACString& path, const nsACString& realm, const nsACString& creds,
const nsACString& challenge, nsACString const& originSuffix,
const nsHttpAuthIdentity* ident, nsISupports* metadata) {
nsresult rv;
LOG(("nsHttpAuthCache::SetAuthEntry %p [realm=%s path=%s metadata=%p]\n",
this, realm, path, metadata));
this, realm.BeginReading(), path.BeginReading(), metadata));
nsAutoCString key;
nsHttpAuthNode* node = LookupAuthNode(scheme, host, port, originSuffix, key);
@ -136,8 +127,9 @@ nsresult nsHttpAuthCache::SetAuthEntry(const char* scheme, const char* host,
return node->SetAuthEntry(path, realm, creds, challenge, ident, metadata);
}
void nsHttpAuthCache::ClearAuthEntry(const char* scheme, const char* host,
int32_t port, const char* realm,
void nsHttpAuthCache::ClearAuthEntry(const nsACString& scheme,
const nsACString& host, int32_t port,
const nsACString& realm,
nsACString const& originSuffix) {
nsAutoCString key;
GetAuthKey(scheme, host, port, originSuffix, key);
@ -154,8 +146,9 @@ void nsHttpAuthCache::ClearAll() {
// nsHttpAuthCache <private>
//-----------------------------------------------------------------------------
nsHttpAuthNode* nsHttpAuthCache::LookupAuthNode(const char* scheme,
const char* host, int32_t port,
nsHttpAuthNode* nsHttpAuthCache::LookupAuthNode(const nsACString& scheme,
const nsACString& host,
int32_t port,
nsACString const& originSuffix,
nsCString& key) {
GetAuthKey(scheme, host, port, originSuffix, key);
@ -215,52 +208,16 @@ void nsHttpAuthCache::CollectKeys(nsTArray<nsCString>& aValue) {
// nsHttpAuthIdentity
//-----------------------------------------------------------------------------
nsresult nsHttpAuthIdentity::Set(const char16_t* domain, const char16_t* user,
const char16_t* pass) {
char16_t *newUser, *newPass, *newDomain;
int domainLen = domain ? NS_strlen(domain) : 0;
int userLen = user ? NS_strlen(user) : 0;
int passLen = pass ? NS_strlen(pass) : 0;
int len = userLen + 1 + passLen + 1 + domainLen + 1;
newUser = (char16_t*)malloc(len * sizeof(char16_t));
if (!newUser) return NS_ERROR_OUT_OF_MEMORY;
if (user) memcpy(newUser, user, userLen * sizeof(char16_t));
newUser[userLen] = 0;
newPass = &newUser[userLen + 1];
if (pass) memcpy(newPass, pass, passLen * sizeof(char16_t));
newPass[passLen] = 0;
newDomain = &newPass[passLen + 1];
if (domain) memcpy(newDomain, domain, domainLen * sizeof(char16_t));
newDomain[domainLen] = 0;
// wait until the end to clear member vars in case input params
// reference our members!
if (mUser) free(mUser);
mUser = newUser;
mPass = newPass;
mDomain = newDomain;
return NS_OK;
}
void nsHttpAuthIdentity::Clear() {
if (mUser) {
free(mUser);
mUser = nullptr;
mPass = nullptr;
mDomain = nullptr;
}
mUser.Truncate();
mPass.Truncate();
mDomain.Truncate();
}
bool nsHttpAuthIdentity::Equals(const nsHttpAuthIdentity& ident) const {
// we could probably optimize this with a single loop, but why bother?
return StrEquivalent(mUser, ident.mUser) &&
StrEquivalent(mPass, ident.mPass) &&
StrEquivalent(mDomain, ident.mDomain);
return mUser == ident.mUser && mPass == ident.mPass &&
mDomain == ident.mDomain;
}
//-----------------------------------------------------------------------------
@ -268,8 +225,6 @@ bool nsHttpAuthIdentity::Equals(const nsHttpAuthIdentity& ident) const {
//-----------------------------------------------------------------------------
nsHttpAuthEntry::~nsHttpAuthEntry() {
if (mRealm) free(mRealm);
while (mRoot) {
nsHttpAuthPath* ap = mRoot;
mRoot = mRoot->mNext;
@ -277,14 +232,10 @@ nsHttpAuthEntry::~nsHttpAuthEntry() {
}
}
nsresult nsHttpAuthEntry::AddPath(const char* aPath) {
// null path matches empty path
if (!aPath) aPath = "";
nsresult nsHttpAuthEntry::AddPath(const nsACString& aPath) {
nsHttpAuthPath* tempPtr = mRoot;
while (tempPtr) {
const char* curpath = tempPtr->mPath;
if (strncmp(aPath, curpath, strlen(curpath)) == 0) {
if (StringBeginsWith(aPath, nsDependentCString(tempPtr->mPath))) {
return NS_OK; // subpath already exists in the list
}
@ -293,11 +244,12 @@ nsresult nsHttpAuthEntry::AddPath(const char* aPath) {
// Append the aPath
nsHttpAuthPath* newAuthPath;
int newpathLen = strlen(aPath);
int newpathLen = aPath.Length();
newAuthPath = (nsHttpAuthPath*)malloc(sizeof(nsHttpAuthPath) + newpathLen);
if (!newAuthPath) return NS_ERROR_OUT_OF_MEMORY;
memcpy(newAuthPath->mPath, aPath, newpathLen + 1);
memcpy(newAuthPath->mPath, aPath.BeginReading(), newpathLen);
newAuthPath->mPath[aPath.Length()] = '\0';
newAuthPath->mNext = nullptr;
if (!mRoot) {
@ -311,59 +263,28 @@ nsresult nsHttpAuthEntry::AddPath(const char* aPath) {
return NS_OK;
}
nsresult nsHttpAuthEntry::Set(const char* path, const char* realm,
const char* creds, const char* chall,
nsresult nsHttpAuthEntry::Set(const nsACString& path, const nsACString& realm,
const nsACString& creds, const nsACString& chall,
const nsHttpAuthIdentity* ident,
nsISupports* metadata) {
char *newRealm, *newCreds, *newChall;
int realmLen = realm ? strlen(realm) : 0;
int credsLen = creds ? strlen(creds) : 0;
int challLen = chall ? strlen(chall) : 0;
int len = realmLen + 1 + credsLen + 1 + challLen + 1;
newRealm = (char*)malloc(len);
if (!newRealm) return NS_ERROR_OUT_OF_MEMORY;
if (realm) memcpy(newRealm, realm, realmLen);
newRealm[realmLen] = 0;
newCreds = &newRealm[realmLen + 1];
if (creds) memcpy(newCreds, creds, credsLen);
newCreds[credsLen] = 0;
newChall = &newCreds[credsLen + 1];
if (chall) memcpy(newChall, chall, challLen);
newChall[challLen] = 0;
nsresult rv = NS_OK;
if (ident) {
rv = mIdent.Set(*ident);
mIdent = *ident;
} else if (mIdent.IsEmpty()) {
// If we are not given an identity and our cached identity has not been
// initialized yet (so is currently empty), initialize it now by
// filling it with nulls. We need to do that because consumers expect
// that mIdent is initialized after this function returns.
rv = mIdent.Set(nullptr, nullptr, nullptr);
mIdent.Clear();
}
nsresult rv = AddPath(path);
if (NS_FAILED(rv)) {
free(newRealm);
return rv;
}
rv = AddPath(path);
if (NS_FAILED(rv)) {
free(newRealm);
return rv;
}
// wait until the end to clear member vars in case input params
// reference our members!
if (mRealm) free(mRealm);
mRealm = newRealm;
mCreds = newCreds;
mChallenge = newChall;
mRealm = realm;
mCreds = creds;
mChallenge = chall;
mMetaData = metadata;
return NS_OK;
@ -383,10 +304,7 @@ nsHttpAuthNode::~nsHttpAuthNode() {
mList.Clear();
}
nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByPath(const char* path) {
// null path matches empty path
if (!path) path = "";
nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByPath(const nsACString& path) {
// look for an entry that either matches or contains this directory.
// ie. we'll give out credentials if the given directory is a sub-
// directory of an existing entry.
@ -398,10 +316,10 @@ nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByPath(const char* path) {
// proxy auth entries have no path, so require exact match on
// empty path string.
if (entryPath[0] == '\0') {
if (path[0] == '\0') {
if (path.IsEmpty()) {
return entry.get();
}
} else if (strncmp(path, entryPath, strlen(entryPath)) == 0) {
} else if (StringBeginsWith(path, nsDependentCString(entryPath))) {
return entry.get();
}
@ -412,16 +330,13 @@ nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByPath(const char* path) {
}
nsHttpAuthNode::EntryList::const_iterator nsHttpAuthNode::LookupEntryItrByRealm(
const char* realm) const {
// null realm matches empty realm
if (!realm) realm = "";
const nsACString& realm) const {
return std::find_if(mList.cbegin(), mList.cend(), [&realm](const auto& val) {
return strcmp(realm, val->Realm()) == 0;
return realm.Equals(val->Realm());
});
}
nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByRealm(const char* realm) {
nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByRealm(const nsACString& realm) {
auto itr = LookupEntryItrByRealm(realm);
if (itr != mList.cend()) {
return itr->get();
@ -430,8 +345,10 @@ nsHttpAuthEntry* nsHttpAuthNode::LookupEntryByRealm(const char* realm) {
return nullptr;
}
nsresult nsHttpAuthNode::SetAuthEntry(const char* path, const char* realm,
const char* creds, const char* challenge,
nsresult nsHttpAuthNode::SetAuthEntry(const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident,
nsISupports* metadata) {
// look for an entry with a matching realm
@ -452,7 +369,7 @@ nsresult nsHttpAuthNode::SetAuthEntry(const char* path, const char* realm,
return NS_OK;
}
void nsHttpAuthNode::ClearAuthEntry(const char* realm) {
void nsHttpAuthNode::ClearAuthEntry(const nsACString& realm) {
auto idx = LookupEntryItrByRealm(realm);
if (idx != mList.cend()) {
mList.RemoveElementAt(idx);

Просмотреть файл

@ -32,33 +32,26 @@ struct nsHttpAuthPath {
class nsHttpAuthIdentity {
public:
nsHttpAuthIdentity() = default;
nsHttpAuthIdentity(const char16_t* domain, const char16_t* user,
const char16_t* password)
: mUser(nullptr), mPass{nullptr}, mDomain{nullptr} {
DebugOnly<nsresult> rv = Set(domain, user, password);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
nsHttpAuthIdentity(const nsAString& domain, const nsAString& user,
const nsAString& password)
: mUser(user), mPass(password), mDomain(domain) {}
~nsHttpAuthIdentity() { Clear(); }
const char16_t* Domain() const { return mDomain; }
const char16_t* User() const { return mUser; }
const char16_t* Password() const { return mPass; }
const nsString& Domain() const { return mDomain; }
const nsString& User() const { return mUser; }
const nsString& Password() const { return mPass; }
[[nodiscard]] nsresult Set(const char16_t* domain, const char16_t* user,
const char16_t* password);
[[nodiscard]] nsresult Set(const nsHttpAuthIdentity& other) {
return Set(other.mDomain, other.mUser, other.mPass);
}
void Clear();
bool Equals(const nsHttpAuthIdentity& ident) const;
bool IsEmpty() const { return !mUser; }
bool IsEmpty() const {
return mUser.IsEmpty() && mPass.IsEmpty() && mDomain.IsEmpty();
}
private:
// allocated as one contiguous blob, starting at mUser.
char16_t* mUser{nullptr};
char16_t* mPass{nullptr};
char16_t* mDomain{nullptr};
nsString mUser;
nsString mPass;
nsString mDomain;
};
//-----------------------------------------------------------------------------
@ -67,37 +60,34 @@ class nsHttpAuthIdentity {
class nsHttpAuthEntry {
public:
const char* Realm() const { return mRealm; }
const char* Creds() const { return mCreds; }
const char* Challenge() const { return mChallenge; }
const char16_t* Domain() const { return mIdent.Domain(); }
const char16_t* User() const { return mIdent.User(); }
const char16_t* Pass() const { return mIdent.Password(); }
const nsCString& Realm() const { return mRealm; }
const nsCString& Creds() const { return mCreds; }
const nsCString& Challenge() const { return mChallenge; }
const nsString& Domain() const { return mIdent.Domain(); }
const nsString& User() const { return mIdent.User(); }
const nsString& Pass() const { return mIdent.Password(); }
nsHttpAuthPath* RootPath() { return mRoot; }
const nsHttpAuthIdentity& Identity() const { return mIdent; }
[[nodiscard]] nsresult AddPath(const char* aPath);
[[nodiscard]] nsresult AddPath(const nsACString& aPath);
nsCOMPtr<nsISupports> mMetaData;
private:
nsHttpAuthEntry(const char* path, const char* realm, const char* creds,
const char* challenge, const nsHttpAuthIdentity* ident,
nsISupports* metadata)
: mRoot(nullptr),
mTail(nullptr),
mRealm(nullptr),
mCreds{nullptr},
mChallenge{nullptr} {
nsHttpAuthEntry(const nsACString& path, const nsACString& realm,
const nsACString& creds, const nsACString& challenge,
const nsHttpAuthIdentity* ident, nsISupports* metadata)
: mRoot(nullptr), mTail(nullptr) {
DebugOnly<nsresult> rv =
Set(path, realm, creds, challenge, ident, metadata);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
~nsHttpAuthEntry();
[[nodiscard]] nsresult Set(const char* path, const char* realm,
const char* creds, const char* challenge,
[[nodiscard]] nsresult Set(const nsACString& path, const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident,
nsISupports* metadata);
@ -106,10 +96,9 @@ class nsHttpAuthEntry {
nsHttpAuthPath* mRoot; // root pointer
nsHttpAuthPath* mTail; // tail pointer
// allocated together in one blob, starting with mRealm.
char* mRealm;
char* mCreds;
char* mChallenge;
nsCString mRealm;
nsCString mCreds;
nsCString mChallenge;
friend class nsHttpAuthNode;
friend class nsHttpAuthCache;
@ -130,19 +119,22 @@ class nsHttpAuthNode {
// path can be null, in which case we'll search for an entry
// with a null path.
nsHttpAuthEntry* LookupEntryByPath(const char* path);
nsHttpAuthEntry* LookupEntryByPath(const nsACString& path);
// realm must not be null
nsHttpAuthEntry* LookupEntryByRealm(const char* realm);
EntryList::const_iterator LookupEntryItrByRealm(const char* realm) const;
nsHttpAuthEntry* LookupEntryByRealm(const nsACString& realm);
EntryList::const_iterator LookupEntryItrByRealm(
const nsACString& realm) const;
// if a matching entry is found, then credentials will be changed.
[[nodiscard]] nsresult SetAuthEntry(const char* path, const char* realm,
const char* creds, const char* challenge,
[[nodiscard]] nsresult SetAuthEntry(const nsACString& path,
const nsACString& realm,
const nsACString& creds,
const nsACString& challenge,
const nsHttpAuthIdentity* ident,
nsISupports* metadata);
void ClearAuthEntry(const char* realm);
void ClearAuthEntry(const nsACString& realm);
uint32_t EntryCount() { return mList.Length(); }
@ -167,18 +159,20 @@ class nsHttpAuthCache {
// |scheme|, |host|, and |port| are required
// |path| can be null
// |entry| is either null or a weak reference
[[nodiscard]] nsresult GetAuthEntryForPath(const char* scheme,
const char* host, int32_t port,
const char* path,
[[nodiscard]] nsresult GetAuthEntryForPath(const nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& path,
nsACString const& originSuffix,
nsHttpAuthEntry** entry);
// |scheme|, |host|, and |port| are required
// |realm| must not be null
// |entry| is either null or a weak reference
[[nodiscard]] nsresult GetAuthEntryForDomain(const char* scheme,
const char* host, int32_t port,
const char* realm,
[[nodiscard]] nsresult GetAuthEntryForDomain(const nsACString& scheme,
const nsACString& host,
int32_t port,
const nsACString& realm,
nsACString const& originSuffix,
nsHttpAuthEntry** entry);
@ -187,16 +181,16 @@ class nsHttpAuthCache {
// |realm| must not be null
// if |credentials|, |user|, |pass|, and |challenge| are each
// null, then the entry is deleted.
[[nodiscard]] nsresult SetAuthEntry(const char* scheme, const char* host,
int32_t port, const char* path,
const char* realm, const char* creds,
const char* challenge,
nsACString const& originSuffix,
const nsHttpAuthIdentity* ident,
nsISupports* metadata);
[[nodiscard]] nsresult SetAuthEntry(
const nsACString& scheme, const nsACString& host, int32_t port,
const nsACString& directory, const nsACString& realm,
const nsACString& credentials, const nsACString& challenge,
nsACString const& originSuffix, const nsHttpAuthIdentity* ident,
nsISupports* metadata);
void ClearAuthEntry(const char* scheme, const char* host, int32_t port,
const char* realm, nsACString const& originSuffix);
void ClearAuthEntry(const nsACString& scheme, const nsACString& host,
int32_t port, const nsACString& realm,
nsACString const& originSuffix);
// expire all existing auth list entries including proxy auths.
void ClearAll();
@ -205,8 +199,9 @@ class nsHttpAuthCache {
void CollectKeys(nsTArray<nsCString>& aValue);
private:
nsHttpAuthNode* LookupAuthNode(const char* scheme, const char* host,
int32_t port, nsACString const& originSuffix,
nsHttpAuthNode* LookupAuthNode(const nsACString& scheme,
const nsACString& host, int32_t port,
nsACString const& originSuffix,
nsCString& key);
class OriginClearObserver : public nsIObserver {

Просмотреть файл

@ -81,9 +81,7 @@ nsHttpAuthManager::SetAuthIdentity(
const nsACString& aPath, const nsAString& aUserDomain,
const nsAString& aUserName, const nsAString& aUserPassword, bool aIsPrivate,
nsIPrincipal* aPrincipal) {
nsHttpAuthIdentity ident(PromiseFlatString(aUserDomain).get(),
PromiseFlatString(aUserName).get(),
PromiseFlatString(aUserPassword).get());
nsHttpAuthIdentity ident(aUserDomain, aUserName, aUserPassword);
nsAutoCString originSuffix;
if (aPrincipal) {
@ -91,13 +89,11 @@ nsHttpAuthManager::SetAuthIdentity(
}
nsHttpAuthCache* auth_cache = aIsPrivate ? mPrivateAuthCache : mAuthCache;
return auth_cache->SetAuthEntry(
PromiseFlatCString(aScheme).get(), PromiseFlatCString(aHost).get(), aPort,
PromiseFlatCString(aPath).get(), PromiseFlatCString(aRealm).get(),
nullptr, // credentials
nullptr, // challenge
originSuffix, &ident,
nullptr); // metadata
return auth_cache->SetAuthEntry(aScheme, aHost, aPort, aPath, aRealm,
""_ns, // credentials
""_ns, // challenge
originSuffix, &ident,
nullptr); // metadata
}
NS_IMETHODIMP

Просмотреть файл

@ -43,8 +43,8 @@ NS_IMPL_ISUPPORTS(nsHttpBasicAuth, nsIHttpAuthenticator)
NS_IMETHODIMP
nsHttpBasicAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
const char* challenge, bool isProxyAuth,
nsISupports** sessionState,
const nsACString& challenge,
bool isProxyAuth, nsISupports** sessionState,
nsISupports** continuationState,
bool* identityInvalid) {
// if challenged, then the username:password that was sent must
@ -55,42 +55,40 @@ nsHttpBasicAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
NS_IMETHODIMP
nsHttpBasicAuth::GenerateCredentialsAsync(
nsIHttpAuthenticableChannel* authChannel,
nsIHttpAuthenticatorCallback* aCallback, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* username,
const char16_t* password, nsISupports* sessionState,
nsIHttpAuthenticatorCallback* aCallback, const nsACString& aChallenge,
bool isProxyAuth, const nsAString& domain, const nsAString& username,
const nsAString& password, nsISupports* sessionState,
nsISupports* continuationState, nsICancelable** aCancellable) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHttpBasicAuth::GenerateCredentials(
nsIHttpAuthenticableChannel* authChannel, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* user,
const char16_t* password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* aFlags, char** creds)
{
LOG(("nsHttpBasicAuth::GenerateCredentials [challenge=%s]\n", challenge));
NS_ENSURE_ARG_POINTER(creds);
nsIHttpAuthenticableChannel* authChannel, const nsACString& aChallenge,
bool isProxyAuth, const nsAString& domain, const nsAString& user,
const nsAString& password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* aFlags, nsACString& creds) {
LOG(("nsHttpBasicAuth::GenerateCredentials [challenge=%s]\n",
aChallenge.BeginReading()));
*aFlags = 0;
// we only know how to deal with Basic auth for http.
bool isBasicAuth = !nsCRT::strncasecmp(challenge, "basic", 5);
bool isBasicAuth = StringBeginsWith(aChallenge, "basic"_ns,
nsCaseInsensitiveCStringComparator);
NS_ENSURE_TRUE(isBasicAuth, NS_ERROR_UNEXPECTED);
// we work with UTF-8 around here
nsAutoCString userpass;
CopyUTF16toUTF8(mozilla::MakeStringSpan(user), userpass);
CopyUTF16toUTF8(user, userpass);
userpass.Append(':'); // always send a ':' (see bug 129565)
AppendUTF16toUTF8(mozilla::MakeStringSpan(password), userpass);
AppendUTF16toUTF8(password, userpass);
nsAutoCString authString{"Basic "_ns};
nsresult rv = Base64EncodeAppend(userpass, authString);
NS_ENSURE_SUCCESS(rv, rv);
*creds = ToNewCString(authString);
creds = authString;
return NS_OK;
}

Просмотреть файл

@ -223,9 +223,9 @@ nsHttpChannelAuthProvider::AddAuthorizationHeaders(
// check if proxy credentials should be sent
const char* proxyHost = ProxyHost();
if (proxyHost && UsingHttpProxy()) {
SetAuthorizationHeader(authCache, nsHttp::Proxy_Authorization, "http",
proxyHost, ProxyPort(),
nullptr, // proxy has no path
SetAuthorizationHeader(authCache, nsHttp::Proxy_Authorization, "http"_ns,
nsDependentCString(proxyHost), ProxyPort(),
""_ns, // proxy has no path
mProxyIdent);
}
@ -245,8 +245,8 @@ nsHttpChannelAuthProvider::AddAuthorizationHeaders(
nsAutoCString path, scheme;
if (NS_SUCCEEDED(GetCurrentPath(path)) &&
NS_SUCCEEDED(mURI->GetScheme(scheme))) {
SetAuthorizationHeader(authCache, nsHttp::Authorization, scheme.get(),
Host(), Port(), path.get(), mIdent);
SetAuthorizationHeader(authCache, nsHttp::Authorization, scheme,
nsDependentCString(Host()), Port(), path, mIdent);
}
return NS_OK;
@ -311,31 +311,6 @@ nsHttpChannelAuthProvider::Disconnect(nsresult status) {
return NS_OK;
}
// buf contains "domain\user"
static void ParseUserDomain(char16_t* buf, const char16_t** user,
const char16_t** domain) {
char16_t* p = buf;
while (*p && *p != '\\') ++p;
if (!*p) return;
*p = '\0';
*domain = buf;
*user = p + 1;
}
// helper function for setting identity from raw user:pass
static void SetIdent(nsHttpAuthIdentity& ident, uint32_t authFlags,
char16_t* userBuf, char16_t* passBuf) {
const char16_t* user = userBuf;
const char16_t* domain = nullptr;
if (authFlags & nsIHttpAuthenticator::IDENTITY_INCLUDES_DOMAIN) {
ParseUserDomain(userBuf, &user, &domain);
}
DebugOnly<nsresult> rv = ident.Set(domain, user, passBuf);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
// helper function for getting an auth prompt from an interface requestor
static void GetAuthPrompt(nsIInterfaceRequestor* ifreq, bool proxyAuth,
nsIAuthPrompt2** result) {
@ -359,10 +334,11 @@ static void GetAuthPrompt(nsIInterfaceRequestor* ifreq, bool proxyAuth,
// generate credentials for the given challenge, and update the auth cache.
nsresult nsHttpChannelAuthProvider::GenCredsAndSetEntry(
nsIHttpAuthenticator* auth, bool proxyAuth, const char* scheme,
const char* host, int32_t port, const char* directory, const char* realm,
const char* challenge, const nsHttpAuthIdentity& ident,
nsCOMPtr<nsISupports>& sessionState, char** result) {
nsIHttpAuthenticator* auth, bool proxyAuth, const nsACString& scheme,
const nsACString& host, int32_t port, const nsACString& directory,
const nsACString& realm, const nsACString& challenge,
const nsHttpAuthIdentity& ident, nsCOMPtr<nsISupports>& sessionState,
nsACString& result) {
nsresult rv;
nsISupports* ss = sessionState;
@ -397,17 +373,18 @@ nsresult nsHttpChannelAuthProvider::GenCredsAndSetEntry(
// don't log this in release build since it could contain sensitive info.
#ifdef DEBUG
LOG(("generated creds: %s\n", *result));
LOG(("generated creds: %s\n", result.BeginReading()));
#endif
return UpdateCache(auth, scheme, host, port, directory, realm, challenge,
ident, *result, generateFlags, sessionState, proxyAuth);
ident, result, generateFlags, sessionState, proxyAuth);
}
nsresult nsHttpChannelAuthProvider::UpdateCache(
nsIHttpAuthenticator* auth, const char* scheme, const char* host,
int32_t port, const char* directory, const char* realm,
const char* challenge, const nsHttpAuthIdentity& ident, const char* creds,
nsIHttpAuthenticator* auth, const nsACString& scheme,
const nsACString& host, int32_t port, const nsACString& directory,
const nsACString& realm, const nsACString& challenge,
const nsHttpAuthIdentity& ident, const nsACString& creds,
uint32_t generateFlags, nsISupports* sessionState, bool aProxyAuth) {
nsresult rv;
@ -443,8 +420,8 @@ nsresult nsHttpChannelAuthProvider::UpdateCache(
// if the credentials are not reusable, then we don't bother sticking
// them in the auth cache.
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
saveCreds ? creds : nullptr,
saveChallenge ? challenge : nullptr, suffix,
saveCreds ? creds : ""_ns,
saveChallenge ? challenge : ""_ns, suffix,
saveIdentity ? &ident : nullptr, sessionState);
return rv;
}
@ -477,7 +454,7 @@ nsresult nsHttpChannelAuthProvider::PrepareForAuthentication(bool proxyAuth) {
nsresult rv;
nsCOMPtr<nsIHttpAuthenticator> precedingAuth;
nsCString proxyAuthType;
rv = GetAuthenticator(mProxyAuthType.get(), proxyAuthType,
rv = GetAuthenticator(mProxyAuthType, proxyAuthType,
getter_AddRefs(precedingAuth));
if (NS_FAILED(rv)) return rv;
@ -528,7 +505,8 @@ nsresult nsHttpChannelAuthProvider::GetCredentials(
nsAutoCString realm, domain, nonce, opaque;
bool stale = false;
uint16_t qop = 0;
if (StringBeginsWith(ac.challenge, "Digest"_ns, nsCaseInsensitiveCStringComparator)) {
if (StringBeginsWith(ac.challenge, "Digest"_ns,
nsCaseInsensitiveCStringComparator)) {
Unused << nsHttpDigestAuth::ParseChallenge(ac.challenge, realm, domain,
nonce, opaque, &stale,
&ac.algorithm, &qop);
@ -573,8 +551,8 @@ nsresult nsHttpChannelAuthProvider::GetCredentials(
// figure out which challenge we can handle and which authenticator to use.
for (size_t i = 0; i < cc.Length(); i++) {
rv = GetAuthenticator(nsCString(cc[i].challenge).get(), authType,
getter_AddRefs(auth));
rv = GetAuthenticator(cc[i].challenge, authType, getter_AddRefs(auth));
LOG(("trying auth for %s", authType.get()));
if (NS_SUCCEEDED(rv)) {
//
// if we've already selected an auth type from a previous challenge
@ -642,7 +620,7 @@ nsresult nsHttpChannelAuthProvider::GetCredentials(
}
nsresult nsHttpChannelAuthProvider::GetAuthorizationMembers(
bool proxyAuth, nsACString& scheme, const char*& host, int32_t& port,
bool proxyAuth, nsACString& scheme, nsCString& host, int32_t& port,
nsACString& path, nsHttpAuthIdentity*& ident,
nsISupports**& continuationState) {
if (proxyAuth) {
@ -676,8 +654,6 @@ nsresult nsHttpChannelAuthProvider::GetAuthorizationMembers(
nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
const nsACString& aChallenge, const nsACString& aAuthType, bool proxyAuth,
nsIHttpAuthenticator* auth, nsCString& creds) {
const nsCString& flatAuthType = PromiseFlatCString(aAuthType);
const char* authType = flatAuthType.get();
LOG(
("nsHttpChannelAuthProvider::GetCredentialsForChallenge "
"[this=%p channel=%p proxyAuth=%d challenges=%s]\n",
@ -707,7 +683,7 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// set informations that depend on whether
// we're authenticating against a proxy
// or a webserver
const char* host;
nsAutoCString host;
int32_t port;
nsHttpAuthIdentity* ident;
nsAutoCString path, scheme;
@ -755,8 +731,8 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// try instead.
//
nsHttpAuthEntry* entry = nullptr;
Unused << authCache->GetAuthEntryForDomain(scheme.get(), host, port,
realm.get(), suffix, &entry);
Unused << authCache->GetAuthEntryForDomain(scheme, host, port, realm, suffix,
&entry);
// hold reference to the auth session state (in case we clear our
// reference to the entry).
@ -771,9 +747,9 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// for digest auth, maybe our cached nonce value simply timed out...
bool identityInvalid;
nsISupports* sessionState = sessionStateGrip;
rv =
auth->ChallengeReceived(mAuthChannel, challenge, proxyAuth, &sessionState,
&*continuationState, &identityInvalid);
rv = auth->ChallengeReceived(mAuthChannel, aChallenge, proxyAuth,
&sessionState, &*continuationState,
&identityInvalid);
sessionStateGrip.swap(sessionState);
if (NS_FAILED(rv)) return rv;
@ -817,13 +793,12 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
LOG((" clearing bad auth cache entry\n"));
// ok, we've already tried this user identity, so clear the
// corresponding entry from the auth cache.
authCache->ClearAuthEntry(scheme.get(), host, port, realm.get(),
suffix);
authCache->ClearAuthEntry(scheme, host, port, realm, suffix);
entry = nullptr;
ident->Clear();
}
} else if (!identFromURI ||
(nsCRT::strcmp(ident->User(), entry->Identity().User()) == 0 &&
(ident->User() == entry->Identity().User() &&
!(loadFlags & (nsIChannel::LOAD_ANONYMOUS |
nsIChannel::LOAD_EXPLICIT_CREDENTIALS)))) {
LOG((" taking identity from auth cache\n"));
@ -833,13 +808,12 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// to distinguish logons based on the supplied password alone,
// but that would be quite unusual... and i don't think we need
// to worry about such unorthodox cases.
rv = ident->Set(entry->Identity());
MOZ_ASSERT(NS_SUCCEEDED(rv));
*ident = entry->Identity();
identFromURI = false;
if (entry->Creds()[0] != '\0') {
LOG((" using cached credentials!\n"));
creds.Assign(entry->Creds());
return entry->AddPath(path.get());
return entry->AddPath(path);
}
}
} else if (!identFromURI) {
@ -859,19 +833,22 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// Collect statistics on how frequently the various types of HTTP
// authentication are used over SSL and non-SSL connections.
if (Telemetry::CanRecordPrereleaseData()) {
if ("basic"_ns.LowerCaseEqualsASCII(authType)) {
if ("basic"_ns.Equals(aAuthType, nsCaseInsensitiveCStringComparator)) {
Telemetry::Accumulate(
Telemetry::HTTP_AUTH_TYPE_STATS,
UsingSSL() ? HTTP_AUTH_BASIC_SECURE : HTTP_AUTH_BASIC_INSECURE);
} else if ("digest"_ns.LowerCaseEqualsASCII(authType)) {
} else if ("digest"_ns.Equals(aAuthType,
nsCaseInsensitiveCStringComparator)) {
Telemetry::Accumulate(
Telemetry::HTTP_AUTH_TYPE_STATS,
UsingSSL() ? HTTP_AUTH_DIGEST_SECURE : HTTP_AUTH_DIGEST_INSECURE);
} else if ("ntlm"_ns.LowerCaseEqualsASCII(authType)) {
} else if ("ntlm"_ns.Equals(aAuthType,
nsCaseInsensitiveCStringComparator)) {
Telemetry::Accumulate(
Telemetry::HTTP_AUTH_TYPE_STATS,
UsingSSL() ? HTTP_AUTH_NTLM_SECURE : HTTP_AUTH_NTLM_INSECURE);
} else if ("negotiate"_ns.LowerCaseEqualsASCII(authType)) {
} else if ("negotiate"_ns.Equals(aAuthType,
nsCaseInsensitiveCStringComparator)) {
Telemetry::Accumulate(Telemetry::HTTP_AUTH_TYPE_STATS,
UsingSSL() ? HTTP_AUTH_NEGOTIATE_SECURE
: HTTP_AUTH_NEGOTIATE_INSECURE);
@ -898,7 +875,7 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// at this point we are forced to interact with the user to get
// their username and password for this domain.
rv = PromptForIdentity(level, proxyAuth, realm.get(), authType, authFlags,
rv = PromptForIdentity(level, proxyAuth, realm, aAuthType, authFlags,
*ident);
if (NS_FAILED(rv)) return rv;
identFromURI = false;
@ -932,10 +909,8 @@ nsresult nsHttpChannelAuthProvider::GetCredentialsForChallenge(
// expecting to authenticate as.
//
nsCString result;
rv = GenCredsAndSetEntry(auth, proxyAuth, scheme.get(), host, port,
path.get(), realm.get(), challenge, *ident,
sessionStateGrip, getter_Copies(result));
if (NS_SUCCEEDED(rv)) creds = result;
rv = GenCredsAndSetEntry(auth, proxyAuth, scheme, host, port, path, realm,
aChallenge, *ident, sessionStateGrip, creds);
return rv;
}
@ -1060,26 +1035,20 @@ bool nsHttpChannelAuthProvider::BlockPrompt(bool proxyAuth) {
return false;
}
inline void GetAuthType(const char* challenge, nsCString& authType) {
const char* p;
// get the challenge type
if ((p = strchr(challenge, ' ')) != nullptr) {
authType.Assign(challenge, p - challenge);
} else {
authType.Assign(challenge);
}
inline void GetAuthType(const nsACString& aChallenge, nsCString& authType) {
auto spaceIndex = aChallenge.FindChar(' ');
authType = Substring(aChallenge, 0, spaceIndex);
// normalize to lowercase
ToLowerCase(authType);
}
nsresult nsHttpChannelAuthProvider::GetAuthenticator(
const char* challenge, nsCString& authType, nsIHttpAuthenticator** auth) {
const nsACString& aChallenge, nsCString& authType,
nsIHttpAuthenticator** auth) {
LOG(("nsHttpChannelAuthProvider::GetAuthenticator [this=%p channel=%p]\n",
this, mAuthChannel));
GetAuthType(challenge, authType);
// normalize to lowercase
ToLowerCase(authType);
GetAuthType(aChallenge, authType);
nsCOMPtr<nsIHttpAuthenticator> authenticator;
if (authType.EqualsLiteral("negotiate")) {
@ -1100,6 +1069,16 @@ nsresult nsHttpChannelAuthProvider::GetAuthenticator(
return NS_OK;
}
// buf contains "domain\user"
static void ParseUserDomain(const nsAString& buf, nsDependentSubstring& user,
nsDependentSubstring& domain) {
auto backslashPos = buf.FindChar(u'\\');
if (backslashPos != kNotFound) {
domain.Rebind(buf, 0, backslashPos);
user.Rebind(buf, backslashPos + 1);
}
}
void nsHttpChannelAuthProvider::GetIdentityFromURI(uint32_t authFlags,
nsHttpAuthIdentity& ident) {
LOG(("nsHttpChannelAuthProvider::GetIdentityFromURI [this=%p channel=%p]\n",
@ -1122,8 +1101,14 @@ void nsHttpChannelAuthProvider::GetIdentityFromURI(uint32_t authFlags,
}
if (!userBuf.IsEmpty()) {
SetIdent(ident, authFlags, (char16_t*)userBuf.get(),
(char16_t*)passBuf.get());
nsDependentSubstring user(userBuf, 0);
nsDependentSubstring domain(u""_ns, 0);
if (authFlags & nsIHttpAuthenticator::IDENTITY_INCLUDES_DOMAIN) {
ParseUserDomain(userBuf, user, domain);
}
ident = nsHttpAuthIdentity(domain, user, passBuf);
}
}
@ -1181,7 +1166,7 @@ void nsHttpChannelAuthProvider::ParseRealm(const nsACString& aChallenge,
class nsHTTPAuthInformation : public nsAuthInformationHolder {
public:
nsHTTPAuthInformation(uint32_t aFlags, const nsString& aRealm,
const nsCString& aAuthType)
const nsACString& aAuthType)
: nsAuthInformationHolder(aFlags, aRealm, aAuthType) {}
void SetToHttpAuthIdentity(uint32_t authFlags, nsHttpAuthIdentity& identity);
@ -1189,14 +1174,12 @@ class nsHTTPAuthInformation : public nsAuthInformationHolder {
void nsHTTPAuthInformation::SetToHttpAuthIdentity(
uint32_t authFlags, nsHttpAuthIdentity& identity) {
DebugOnly<nsresult> rv =
identity.Set(Domain().get(), User().get(), Password().get());
MOZ_ASSERT(NS_SUCCEEDED(rv));
identity = nsHttpAuthIdentity(Domain(), User(), Password());
}
nsresult nsHttpChannelAuthProvider::PromptForIdentity(
uint32_t level, bool proxyAuth, const char* realm, const char* authType,
uint32_t authFlags, nsHttpAuthIdentity& ident) {
uint32_t level, bool proxyAuth, const nsACString& realm,
const nsACString& authType, uint32_t authFlags, nsHttpAuthIdentity& ident) {
LOG(("nsHttpChannelAuthProvider::PromptForIdentity [this=%p channel=%p]\n",
this, mAuthChannel));
@ -1242,8 +1225,8 @@ nsresult nsHttpChannelAuthProvider::PromptForIdentity(
promptFlags |= nsIAuthInformation::CROSS_ORIGIN_SUB_RESOURCE;
}
RefPtr<nsHTTPAuthInformation> holder = new nsHTTPAuthInformation(
promptFlags, realmU, nsDependentCString(authType));
RefPtr<nsHTTPAuthInformation> holder =
new nsHTTPAuthInformation(promptFlags, realmU, authType);
if (!holder) return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIChannel> channel(do_QueryInterface(mAuthChannel, &rv));
@ -1298,7 +1281,7 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthAvailable(
nsresult rv;
const char* host;
nsAutoCString host;
int32_t port;
nsHttpAuthIdentity* ident;
nsAutoCString path, scheme;
@ -1319,21 +1302,20 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthAvailable(
nsHttpAuthCache* authCache = gHttpHandler->AuthCache(mIsPrivate);
nsHttpAuthEntry* entry = nullptr;
Unused << authCache->GetAuthEntryForDomain(scheme.get(), host, port,
realm.get(), suffix, &entry);
Unused << authCache->GetAuthEntryForDomain(scheme, host, port, realm, suffix,
&entry);
nsCOMPtr<nsISupports> sessionStateGrip;
if (entry) sessionStateGrip = entry->mMetaData;
nsAuthInformationHolder* holder =
static_cast<nsAuthInformationHolder*>(aAuthInfo);
rv = ident->Set(holder->Domain().get(), holder->User().get(),
holder->Password().get());
MOZ_ASSERT(NS_SUCCEEDED(rv));
*ident =
nsHttpAuthIdentity(holder->Domain(), holder->User(), holder->Password());
nsAutoCString unused;
nsCOMPtr<nsIHttpAuthenticator> auth;
rv = GetAuthenticator(mCurrentChallenge.get(), unused, getter_AddRefs(auth));
rv = GetAuthenticator(mCurrentChallenge, unused, getter_AddRefs(auth));
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "GetAuthenticator failed");
OnAuthCancelled(aContext, true);
@ -1341,9 +1323,8 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthAvailable(
}
nsCString creds;
rv = GenCredsAndSetEntry(auth, mProxyAuth, scheme.get(), host, port,
path.get(), realm.get(), mCurrentChallenge.get(),
*ident, sessionStateGrip, getter_Copies(creds));
rv = GenCredsAndSetEntry(auth, mProxyAuth, scheme, host, port, path, realm,
mCurrentChallenge, *ident, sessionStateGrip, creds);
mCurrentChallenge.Truncate();
if (NS_FAILED(rv)) {
@ -1424,7 +1405,7 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthCancelled(nsISupports* aContext,
}
NS_IMETHODIMP nsHttpChannelAuthProvider::OnCredsGenerated(
const char* aGeneratedCreds, uint32_t aFlags, nsresult aResult,
const nsACString& aGeneratedCreds, uint32_t aFlags, nsresult aResult,
nsISupports* aSessionState, nsISupports* aContinuationState) {
nsresult rv;
@ -1452,10 +1433,10 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnCredsGenerated(
nsCOMPtr<nsIHttpAuthenticator> auth;
nsAutoCString unused;
rv = GetAuthenticator(mCurrentChallenge.get(), unused, getter_AddRefs(auth));
rv = GetAuthenticator(mCurrentChallenge, unused, getter_AddRefs(auth));
NS_ENSURE_SUCCESS(rv, rv);
const char* host;
nsAutoCString host;
int32_t port;
nsHttpAuthIdentity* ident;
nsAutoCString directory, scheme;
@ -1469,13 +1450,13 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnCredsGenerated(
unusedContinuationState);
if (NS_FAILED(rv)) return rv;
rv = UpdateCache(auth, scheme.get(), host, port, directory.get(), realm.get(),
mCurrentChallenge.get(), *ident, aGeneratedCreds, aFlags,
aSessionState, mProxyAuth);
rv =
UpdateCache(auth, scheme, host, port, directory, realm, mCurrentChallenge,
*ident, aGeneratedCreds, aFlags, aSessionState, mProxyAuth);
MOZ_ASSERT(NS_SUCCEEDED(rv));
mCurrentChallenge.Truncate();
rv = ContinueOnAuthAvailable(nsDependentCString(aGeneratedCreds));
rv = ContinueOnAuthAvailable(aGeneratedCreds);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return NS_OK;
}
@ -1634,9 +1615,9 @@ bool nsHttpChannelAuthProvider::ConfirmAuth(const char* bundleKey,
}
void nsHttpChannelAuthProvider::SetAuthorizationHeader(
nsHttpAuthCache* authCache, const nsHttpAtom& header, const char* scheme,
const char* host, int32_t port, const char* path,
nsHttpAuthIdentity& ident) {
nsHttpAuthCache* authCache, const nsHttpAtom& header,
const nsACString& scheme, const nsACString& host, int32_t port,
const nsACString& path, nsHttpAuthIdentity& ident) {
nsHttpAuthEntry* entry = nullptr;
nsresult rv;
@ -1683,7 +1664,7 @@ void nsHttpChannelAuthProvider::SetAuthorizationHeader(
// up the one from the auth cache instead.
// when this is undesired, specify LOAD_EXPLICIT_CREDENTIALS load
// flag.
if (nsCRT::strcmp(ident.User(), entry->User()) == 0) {
if (ident.User() == entry->User()) {
uint32_t loadFlags;
if (NS_SUCCEEDED(mAuthChannel->GetLoadFlags(&loadFlags)) &&
!(loadFlags & nsIChannel::LOAD_EXPLICIT_CREDENTIALS)) {
@ -1693,43 +1674,41 @@ void nsHttpChannelAuthProvider::SetAuthorizationHeader(
}
bool identFromURI;
if (ident.IsEmpty()) {
rv = ident.Set(entry->Identity());
MOZ_ASSERT(NS_SUCCEEDED(rv));
ident = entry->Identity();
identFromURI = false;
} else {
identFromURI = true;
}
nsCString temp; // this must have the same lifetime as creds
const char* creds = entry->Creds();
const char* challenge = entry->Challenge();
nsAutoCString creds(entry->Creds());
// we can only send a preemptive Authorization header if we have either
// stored credentials or a stored challenge from which to derive
// credentials. if the identity is from the URI, then we cannot use
// the stored credentials.
if ((!creds[0] || identFromURI) && challenge[0]) {
if ((creds.IsEmpty() || identFromURI) && !entry->Challenge().IsEmpty()) {
nsCOMPtr<nsIHttpAuthenticator> auth;
nsAutoCString unused;
rv = GetAuthenticator(challenge, unused, getter_AddRefs(auth));
rv = GetAuthenticator(entry->Challenge(), unused, getter_AddRefs(auth));
if (NS_SUCCEEDED(rv)) {
bool proxyAuth = (header == nsHttp::Proxy_Authorization);
rv = GenCredsAndSetEntry(auth, proxyAuth, scheme, host, port, path,
entry->Realm(), challenge, ident,
entry->mMetaData, getter_Copies(temp));
if (NS_SUCCEEDED(rv)) creds = temp.get();
entry->Realm(), entry->Challenge(), ident,
entry->mMetaData, temp);
if (NS_SUCCEEDED(rv)) creds = temp;
// make sure the continuation state is null since we do not
// support mixing preemptive and 'multirequest' authentication.
NS_IF_RELEASE(*continuationState);
}
}
if (creds[0]) {
if (!creds.IsEmpty()) {
LOG((" adding \"%s\" request header\n", header.get()));
if (header == nsHttp::Proxy_Authorization) {
rv = mAuthChannel->SetProxyCredentials(nsDependentCString(creds));
rv = mAuthChannel->SetProxyCredentials(creds);
MOZ_ASSERT(NS_SUCCEEDED(rv));
} else {
rv = mAuthChannel->SetWWWCredentials(nsDependentCString(creds));
rv = mAuthChannel->SetWWWCredentials(creds);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}

Просмотреть файл

@ -58,11 +58,12 @@ class nsHttpChannelAuthProvider final : public nsIHttpChannelAuthProvider,
[[nodiscard]] nsresult PrepareForAuthentication(bool proxyAuth);
[[nodiscard]] nsresult GenCredsAndSetEntry(
nsIHttpAuthenticator*, bool proxyAuth, const char* scheme,
const char* host, int32_t port, const char* dir, const char* realm,
const char* challenge, const nsHttpAuthIdentity& ident,
nsCOMPtr<nsISupports>& session, char** result);
[[nodiscard]] nsresult GetAuthenticator(const char* challenge,
nsIHttpAuthenticator*, bool proxyAuth, const nsACString& scheme,
const nsACString& host, int32_t port, const nsACString& dir,
const nsACString& realm, const nsACString& challenge,
const nsHttpAuthIdentity& ident, nsCOMPtr<nsISupports>& session,
nsACString& result);
[[nodiscard]] nsresult GetAuthenticator(const nsACString& aChallenge,
nsCString& authType,
nsIHttpAuthenticator** auth);
void ParseRealm(const nsACString&, nsACString& realm);
@ -80,15 +81,15 @@ class nsHttpChannelAuthProvider final : public nsIHttpChannelAuthProvider,
const nsACString& aChallenge, const nsACString& aAuthType, bool proxyAuth,
nsIHttpAuthenticator* auth, nsCString& creds);
[[nodiscard]] nsresult PromptForIdentity(uint32_t level, bool proxyAuth,
const char* realm,
const char* authType,
const nsACString& realm,
const nsACString& authType,
uint32_t authFlags,
nsHttpAuthIdentity&);
bool ConfirmAuth(const char* bundleKey, bool doYesNoPrompt);
void SetAuthorizationHeader(nsHttpAuthCache*, const nsHttpAtom& header,
const char* scheme, const char* host,
int32_t port, const char* path,
const nsACString& scheme, const nsACString& host,
int32_t port, const nsACString& path,
nsHttpAuthIdentity& ident);
[[nodiscard]] nsresult GetCurrentPath(nsACString&);
/**
@ -97,7 +98,7 @@ class nsHttpChannelAuthProvider final : public nsIHttpChannelAuthProvider,
* with what authorization we work (WWW or proxy).
*/
[[nodiscard]] nsresult GetAuthorizationMembers(
bool proxyAuth, nsACString& scheme, const char*& host, int32_t& port,
bool proxyAuth, nsACString& scheme, nsCString& host, int32_t& port,
nsACString& path, nsHttpAuthIdentity*& ident,
nsISupports**& continuationState);
/**
@ -125,11 +126,11 @@ class nsHttpChannelAuthProvider final : public nsIHttpChannelAuthProvider,
// Store credentials to the cache when appropriate aFlags are set.
[[nodiscard]] nsresult UpdateCache(
nsIHttpAuthenticator* aAuth, const char* aScheme, const char* aHost,
int32_t aPort, const char* aDirectory, const char* aRealm,
const char* aChallenge, const nsHttpAuthIdentity& aIdent,
const char* aCreds, uint32_t aGenerateFlags, nsISupports* aSessionState,
bool aProxyAuth);
nsIHttpAuthenticator* aAuth, const nsACString& aScheme,
const nsACString& aHost, int32_t aPort, const nsACString& aDirectory,
const nsACString& aRealm, const nsACString& aChallenge,
const nsHttpAuthIdentity& aIdent, const nsACString& aCreds,
uint32_t aGenerateFlags, nsISupports* aSessionState, bool aProxyAuth);
private:
nsIHttpAuthenticableChannel* mAuthChannel{nullptr}; // weak ref

Просмотреть файл

@ -154,7 +154,8 @@ nsresult nsHttpDigestAuth::GetMethodAndPath(
NS_IMETHODIMP
nsHttpDigestAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
const char* challenge, bool isProxyAuth,
const nsACString& challenge,
bool isProxyAuth,
nsISupports** sessionState,
nsISupports** continuationState,
bool* result) {
@ -162,8 +163,8 @@ nsHttpDigestAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
bool stale;
uint16_t algorithm, qop;
nsresult rv = ParseChallenge(nsCString(challenge), realm, domain, nonce,
opaque, &stale, &algorithm, &qop);
nsresult rv = ParseChallenge(challenge, realm, domain, nonce, opaque, &stale,
&algorithm, &qop);
if (!(algorithm &
(ALGO_MD5 | ALGO_MD5_SESS | ALGO_SHA256 | ALGO_SHA256_SESS))) {
@ -187,28 +188,28 @@ nsHttpDigestAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel,
NS_IMETHODIMP
nsHttpDigestAuth::GenerateCredentialsAsync(
nsIHttpAuthenticableChannel* authChannel,
nsIHttpAuthenticatorCallback* aCallback, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* username,
const char16_t* password, nsISupports* sessionState,
nsIHttpAuthenticatorCallback* aCallback, const nsACString& challenge,
bool isProxyAuth, const nsAString& domain, const nsAString& username,
const nsAString& password, nsISupports* sessionState,
nsISupports* continuationState, nsICancelable** aCancellable) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHttpDigestAuth::GenerateCredentials(
nsIHttpAuthenticableChannel* authChannel, const char* challenge,
bool isProxyAuth, const char16_t* userdomain, const char16_t* username,
const char16_t* password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* aFlags, char** creds)
nsIHttpAuthenticableChannel* authChannel, const nsACString& aChallenge,
bool isProxyAuth, const nsAString& userdomain, const nsAString& username,
const nsAString& password, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* aFlags, nsACString& creds)
{
LOG(("nsHttpDigestAuth::GenerateCredentials [challenge=%s]\n", challenge));
NS_ENSURE_ARG_POINTER(creds);
LOG(("nsHttpDigestAuth::GenerateCredentials [challenge=%s]\n",
aChallenge.BeginReading()));
*aFlags = 0;
bool isDigestAuth = !nsCRT::strncasecmp(challenge, "digest ", 7);
bool isDigestAuth = StringBeginsWith(aChallenge, "digest "_ns,
nsCaseInsensitiveCStringComparator);
NS_ENSURE_TRUE(isDigestAuth, NS_ERROR_UNEXPECTED);
// IIS implementation requires extra quotes
@ -232,8 +233,8 @@ nsHttpDigestAuth::GenerateCredentials(
bool stale;
uint16_t algorithm, qop;
rv = ParseChallenge(nsCString(challenge), realm, domain, nonce, opaque,
&stale, &algorithm, &qop);
rv = ParseChallenge(aChallenge, realm, domain, nonce, opaque, &stale,
&algorithm, &qop);
if (NS_FAILED(rv)) {
LOG(
("nsHttpDigestAuth::GenerateCredentials [ParseChallenge failed "
@ -406,7 +407,7 @@ nsHttpDigestAuth::GenerateCredentials(
NS_ENSURE_SUCCESS(rv, rv);
}
*creds = ToNewCString(authString);
creds = authString;
return NS_OK;
}

Просмотреть файл

@ -155,7 +155,7 @@ NS_IMPL_ISUPPORTS(nsHttpNTLMAuth, nsIHttpAuthenticator)
NS_IMETHODIMP
nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel* channel,
const char* challenge, bool isProxyAuth,
const nsACString& challenge, bool isProxyAuth,
nsISupports** sessionState,
nsISupports** continuationState,
bool* identityInvalid) {
@ -172,7 +172,7 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel* channel,
// 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 (nsCRT::strcasecmp(challenge, "NTLM") == 0) {
if (challenge.Equals("NTLM"_ns, nsCaseInsensitiveCStringComparator)) {
nsCOMPtr<nsIAuthModule> module;
// Check to see if we should default to our generic NTLM auth module
@ -249,33 +249,31 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel* channel,
NS_IMETHODIMP
nsHttpNTLMAuth::GenerateCredentialsAsync(
nsIHttpAuthenticableChannel* authChannel,
nsIHttpAuthenticatorCallback* aCallback, const char* challenge,
bool isProxyAuth, const char16_t* domain, const char16_t* username,
const char16_t* password, nsISupports* sessionState,
nsIHttpAuthenticatorCallback* aCallback, const nsACString& challenge,
bool isProxyAuth, const nsAString& domain, const nsAString& username,
const nsAString& password, nsISupports* sessionState,
nsISupports* continuationState, nsICancelable** aCancellable) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel* authChannel,
const char* challenge, bool isProxyAuth,
const char16_t* domain,
const char16_t* user, const char16_t* pass,
nsISupports** sessionState,
nsISupports** continuationState,
uint32_t* aFlags, char** creds)
nsHttpNTLMAuth::GenerateCredentials(
nsIHttpAuthenticableChannel* authChannel, const nsACString& aChallenge,
bool isProxyAuth, const nsAString& domain, const nsAString& user,
const nsAString& pass, nsISupports** sessionState,
nsISupports** continuationState, uint32_t* aFlags, nsACString& creds)
{
LOG(("nsHttpNTLMAuth::GenerateCredentials\n"));
*creds = nullptr;
creds.Truncate();
*aFlags = 0;
// if user or password is empty, ChallengeReceived returned
// identityInvalid = false, that means we are using default user
// credentials; see nsAuthSSPI::Init method for explanation of this
// condition
if (!user || !pass) *aFlags = USING_INTERNAL_IDENTITY;
if (user.IsEmpty() || pass.IsEmpty()) *aFlags = USING_INTERNAL_IDENTITY;
nsresult rv;
nsCOMPtr<nsIAuthModule> module = do_QueryInterface(*continuationState, &rv);
@ -285,6 +283,9 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel* authChannel,
uint32_t inBufLen, outBufLen;
Maybe<nsTArray<uint8_t>> certArray;
const nsCString& flatChallenge = PromiseFlatCString(aChallenge);
const char* challenge = flatChallenge.get();
// initial challenge
if (nsCRT::strcasecmp(challenge, "NTLM") == 0) {
// NTLM service name format is 'HTTP@host' for both http and https
@ -300,7 +301,7 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel* authChannel,
uint32_t reqFlags = nsIAuthModule::REQ_DEFAULT;
if (isProxyAuth) reqFlags |= nsIAuthModule::REQ_PROXY_AUTH;
rv = module->Init(serviceName.get(), reqFlags, domain, user, pass);
rv = module->Init(serviceName, reqFlags, domain, user, pass);
if (NS_FAILED(rv)) return rv;
// This update enables updated Windows machines (Win7 or patched previous
@ -377,10 +378,10 @@ nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel* authChannel,
if (!credsLen.isValid()) {
rv = NS_ERROR_FAILURE;
} else {
*creds = (char*)moz_xmalloc(credsLen.value());
memcpy(*creds, "NTLM ", 5);
PL_Base64Encode((char*)outBuf, outBufLen, *creds + 5);
(*creds)[credsLen.value() - 1] = '\0'; // null terminate
nsAutoCString encoded;
(void)Base64Encode(nsDependentCSubstring((char*)outBuf, outBufLen),
encoded);
creds = nsPrintfCString("NTLM %s", encoded.get());
}
// OK, we are done with |outBuf|

Просмотреть файл

@ -49,7 +49,7 @@ interface nsIHttpAuthenticator : nsISupports
*/
[must_use]
void challengeReceived(in nsIHttpAuthenticableChannel aChannel,
in string aChallenge,
in ACString aChallenge,
in boolean aProxyAuth,
inout nsISupports aSessionState,
inout nsISupports aContinuationState,
@ -96,11 +96,11 @@ interface nsIHttpAuthenticator : nsISupports
[must_use]
void generateCredentialsAsync(in nsIHttpAuthenticableChannel aChannel,
in nsIHttpAuthenticatorCallback aCallback,
in string aChallenge,
in ACString aChallenge,
in boolean aProxyAuth,
in wstring aDomain,
in wstring aUser,
in wstring aPassword,
in AString aDomain,
in AString aUser,
in AString aPassword,
in nsISupports aSessionState,
in nsISupports aContinuationState,
out nsICancelable aCancel);
@ -141,12 +141,12 @@ interface nsIHttpAuthenticator : nsISupports
* authenticator may return one of the generate flags bellow.
*/
[must_use]
string generateCredentials(in nsIHttpAuthenticableChannel aChannel,
in string aChallenge,
ACString generateCredentials(in nsIHttpAuthenticableChannel aChannel,
in ACString aChallenge,
in boolean aProxyAuth,
in wstring aDomain,
in wstring aUser,
in wstring aPassword,
in AString aDomain,
in AString aUser,
in AString aPassword,
inout nsISupports aSessionState,
inout nsISupports aContinuationState,
out unsigned long aFlags);

Просмотреть файл

@ -916,9 +916,9 @@ nsresult nsNTLMAuthModule::InitTest() {
}
NS_IMETHODIMP
nsNTLMAuthModule::Init(const char* /*serviceName*/, uint32_t serviceFlags,
const char16_t* domain, const char16_t* username,
const char16_t* password) {
nsNTLMAuthModule::Init(const nsACString& serviceName, uint32_t serviceFlags,
const nsAString& domain, const nsAString& username,
const nsAString& password) {
MOZ_ASSERT((serviceFlags & ~nsIAuthModule::REQ_PROXY_AUTH) ==
nsIAuthModule::REQ_DEFAULT,
"Unexpected service flags");