зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b874482b5b
Коммит
b3d74be7b8
|
@ -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");
|
||||
|
|
Загрузка…
Ссылка в новой задаче