/* vim:set ts=4 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Return false when the channel comes from a Private browsing window. staticbool TestNotInPBMode(nsIHttpAuthenticableChannel* authChannel, bool proxyAuth) { // Proxy should go all the time, it's not considered a privacy leak // to send default credentials to a proxy. if (proxyAuth) { returntrue;
}
if (!NS_UsePrivateBrowsing(bareChannel)) { returntrue;
}
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefs) { bool ssoInPb; if (NS_SUCCEEDED(prefs->GetBoolPref(kSSOinPBmode, &ssoInPb)) && ssoInPb) { returntrue;
}
// When the "Never remember history" option is set, all channels are // set PB mode flag, but here we want to make an exception, users // want their credentials go out. if (mozilla::StaticPrefs::browser_privatebrowsing_autostart()) { returntrue;
}
}
NS_IMETHODIMP
nsHttpNegotiateAuth::GetAuthFlags(uint32_t* flags) { // // Negotiate Auth creds should not be reused across multiple requests. // Only perform the negotiation when it is explicitly requested by the // server. Thus, do *NOT* use the "REUSABLE_CREDENTIALS" flag here. // // CONNECTION_BASED is specified instead of REQUEST_BASED since we need // to complete a sequence of transactions with the server over the same // connection. //
*flags = CONNECTION_BASED | IDENTITY_IGNORED; return NS_OK;
}
// // Always set *identityInvalid == FALSE here. This // will prevent the browser from popping up the authentication // prompt window. Because GSSAPI does not have an API // for fetching initial credentials (ex: A Kerberos TGT), // there is no correct way to get the users credentials. //
NS_IMETHODIMP
nsHttpNegotiateAuth::ChallengeReceived(nsIHttpAuthenticableChannel* authChannel, const nsACString& challenge, bool isProxyAuth,
nsISupports** sessionState,
nsISupports** continuationState, bool* identityInvalid) {
nsIAuthModule* rawModule = (nsIAuthModule*)*continuationState;
*identityInvalid = false; if (rawModule) { return NS_OK;
}
nsresult rv;
nsCOMPtr<nsIAuthModule> module;
nsCOMPtr<nsIURI> uri;
rv = authChannel->GetURI(getter_AddRefs(uri)); if (NS_FAILED(rv)) return rv;
bool delegation = mozilla::net::auth::URIMatchesPrefPattern(
uri, kNegotiateAuthDelegationURIs); if (delegation) {
LOG((" using REQ_DELEGATE\n"));
req_flags |= nsIAuthModule::REQ_DELEGATE;
}
rv = uri->GetAsciiHost(service); if (NS_FAILED(rv)) return rv;
}
LOG((" service = %s\n", service.get()));
// // The correct service name for IIS servers is "HTTP/f.q.d.n", so // construct the proper service name for passing to "gss_import_name". // // TODO: Possibly make this a configurable service name for use // with non-standard servers that use stuff like "khttp/f.q.d.n" // instead. //
service.InsertLiteral("HTTP@", 0);
constchar* authType; if (TestBoolPref(kNegotiateAuthSSPI)) {
LOG((" using negotiate-sspi\n"));
authType = "negotiate-sspi";
} else {
LOG((" using negotiate-gss\n"));
authType = "negotiate-gss";
}
// // GetNextTokenCompleteEvent // // This event is fired on main thread when async call of // nsHttpNegotiateAuth::GenerateCredentials is finished. During the Run() // method the nsIHttpAuthenticatorCallback::OnCredsAvailable is called with // obtained credentials, flags and NS_OK when successful, otherwise // NS_ERROR_FAILURE is returned as a result of failed operation. // class GetNextTokenCompleteEvent final : public nsIRunnable, public nsICancelable { public:
NS_DECL_THREADSAFE_ISUPPORTS
// // GetNextTokenRunnable // // This runnable is created by GenerateCredentialsAsync and it runs // on the background thread pool and calls GenerateCredentials. // class GetNextTokenRunnable final : public mozilla::Runnable {
~GetNextTokenRunnable() override = default;
// Passing session and continuation state this way to not touch // referencing of the object that may not be thread safe. // Not having a thread safe referencing doesn't mean the object // cannot be used on multiple threads (one example is nsAuthSSPI.) // This ensures state objects will be destroyed on the main thread // when not changed by GenerateCredentials. if (NS_FAILED(rv)) { return mCompleteEvent->DispatchError(mSessionState.forget(),
mContinuationState.forget());
}
// Use negotiate service to call GenerateCredentials outside of main thread
nsCOMPtr<nsIHttpAuthenticator> authenticator = new nsHttpNegotiateAuth();
nsISupports* sessionState = mSessionState;
nsISupports* continuationState = mContinuationState; // The continuationState is for the sake of completeness propagated // to the caller (despite it is not changed in any GenerateCredentials // implementation). // // The only implementation that use sessionState is the // nsHttpDigestAuth::GenerateCredentials. Since there's no reason // to implement nsHttpDigestAuth::GenerateCredentialsAsync // because digest auth does not block the main thread, we won't // propagate changes to sessionState to the caller because of // the change is too complicated on the caller side. // // Should any of the session or continuation states change inside // this method, they must be threadsafe.
rv = authenticator->GenerateCredentials(
mAuthChannel, mChallenge, mIsProxyAuth, mDomain, mUsername, mPassword,
&sessionState, &continuationState, aFlags, aCreds); if (mSessionState != sessionState) {
mSessionState = sessionState;
} if (mContinuationState != continuationState) {
mContinuationState = continuationState;
} return rv;
}
// // If the "Negotiate:" header had some data associated with it, // that data should be used as the input to this call. This may // be a continuation of an earlier call because GSSAPI authentication // often takes multiple round-trips to complete depending on the // context flags given. We want to use MUTUAL_AUTHENTICATION which // generally *does* require multiple round-trips. Don't assume // auth can be completed in just 1 call. //
// strip off any padding (see bug 230351)
uint32_t len = challenge.Length(); while (len > startPos && challenge[len - 1] == '=') {
len--;
}
// // Decode the response that followed the "Negotiate" token //
(void)Base64Decode(
nsDependentCSubstring(challenge, startPos, len - startPos), inToken);
}
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")); return NS_ERROR_FAILURE;
}
if (!TestBoolPref(kNegotiateAuthAllowNonFqdn)) { returnfalse;
}
if (NS_FAILED(uri->GetAsciiHost(host))) { returnfalse;
}
// return true if host does not contain a dot and is not an ip address return !host.IsEmpty() && !host.Contains('.') &&
!mozilla::net::HostIsIPLiteral(host);
}
¤ Dauer der Verarbeitung: 0.34 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.