diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 226e5153b69..137e76dcabe 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -349,6 +349,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocShell) NS_INTERFACE_MAP_ENTRY(nsIContentViewerContainer) NS_INTERFACE_MAP_ENTRY(nsIEditorDocShell) NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor) + NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider) NS_INTERFACE_MAP_END_THREADSAFE ///***************************************************************************** @@ -7249,3 +7250,26 @@ nsDocShell::SetBaseUrlForWyciwyg(nsIContentViewer * aContentViewer) } return rv; } + +//***************************************************************************** +// nsDocShell::nsIAuthPromptProvider +//***************************************************************************** + +nsresult +nsDocShell::GetAuthPrompt(PRUint32 aPromptReason, nsIAuthPrompt **aResult) +{ + // a priority prompt request will override a false mAllowAuth setting + PRBool priorityPrompt = (aPromptReason == nsIAuthPromptProvider::PROMPT_PROXY); + + if (!mAllowAuth && !priorityPrompt) + return NS_ERROR_NOT_AVAILABLE; + + // we're either allowing auth, or it's a proxy request + nsCOMPtr authPrompter(do_GetInterface(mTreeOwner)); + if (!authPrompter) + return NS_ERROR_NOT_AVAILABLE; + + *aResult = authPrompter; + NS_ADDREF(*aResult); + return NS_OK; +} diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index c2501973f1f..0806e5541c5 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -98,6 +98,7 @@ #include "nsIWebBrowserFind.h" #include "nsIHttpChannel.h" #include "nsDocShellTransferableHooks.h" +#include "nsIAuthPromptProvider.h" #define MAKE_LOAD_TYPE(type, flags) ((type) | ((flags) << 16)) @@ -194,6 +195,7 @@ class nsDocShell : public nsIDocShell, public nsIWebProgressListener, public nsIEditorDocShell, public nsIWebPageDescriptor, + public nsIAuthPromptProvider, public nsSupportsWeakReference { friend class nsDSURIContentListener; @@ -219,6 +221,7 @@ public: NS_DECL_NSICONTENTVIEWERCONTAINER NS_DECL_NSIEDITORDOCSHELL NS_DECL_NSIWEBPAGEDESCRIPTOR + NS_DECL_NSIAUTHPROMPTPROVIDER nsresult SetLoadCookie(nsISupports * aCookie); nsresult GetLoadCookie(nsISupports ** aResult); diff --git a/mozilla/netwerk/base/public/Makefile.in b/mozilla/netwerk/base/public/Makefile.in index ac4b06fb573..016a4d77f6f 100644 --- a/mozilla/netwerk/base/public/Makefile.in +++ b/mozilla/netwerk/base/public/Makefile.in @@ -105,6 +105,7 @@ XPIDLSRCS = \ nsIExternalProtocolHandler.idl \ nsIAuthModule.idl \ nsIContentSniffer.idl \ + nsIAuthPromptProvider.idl \ $(NULL) EXPORTS = \ diff --git a/mozilla/netwerk/base/public/nsIAuthPromptProvider.idl b/mozilla/netwerk/base/public/nsIAuthPromptProvider.idl new file mode 100644 index 00000000000..8fc045bfb88 --- /dev/null +++ b/mozilla/netwerk/base/public/nsIAuthPromptProvider.idl @@ -0,0 +1,65 @@ +/* -*- Mode: idl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Vladimir Vukicevic + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIAuthPrompt; + +[scriptable, uuid(129d3bd5-8a26-4b0b-b8a0-19fdea029196)] +interface nsIAuthPromptProvider : nsISupports +{ + /** + * Normal (non-proxy) prompt request. + */ + const PRUint32 PROMPT_NORMAL = 0; + + /** + * Proxy auth request. + */ + const PRUint32 PROMPT_PROXY = 1; + + /** + * Request a nsIAuthPrompt interface for the given prompt reason; + * @throws NS_ERROR_NOT_AVAILABLE if no prompt is allowed or + * available for the given reason. + * + * @param aPromptReason The reason for the auth prompt; + * one of @PROMPT_NORMAL or @PROMPT_PROXY + * @returns a nsIAuthPrompt interface, or throws NS_ERROR_NOT_AVAILABLE + */ + nsIAuthPrompt getAuthPrompt(in PRUint32 aPromptReason); +}; diff --git a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp index e061cf9780d..6878af0b767 100644 --- a/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp +++ b/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp @@ -47,6 +47,7 @@ #include "nsHttp.h" #include "nsIHttpAuthenticator.h" #include "nsIAuthPrompt.h" +#include "nsIAuthPromptProvider.h" #include "nsIStringBundle.h" #include "nsXPCOM.h" #include "nsISupportsPrimitives.h" @@ -2063,8 +2064,19 @@ nsHttpChannel::ProcessAuthentication(PRUint32 httpStatus) const char *challenges; PRBool proxyAuth = (httpStatus == 407); - if (proxyAuth) + if (proxyAuth) { + // only allow a proxy challenge if we have a proxy server configured. + // otherwise, we could inadvertantly 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 (!mConnectionInfo->UsingHttpProxy()) { + LOG(("rejecting 407 when proxy server not configured!\n")); + return NS_ERROR_UNEXPECTED; + } challenges = mResponseHead->PeekHeader(nsHttp::Proxy_Authenticate); + } else challenges = mResponseHead->PeekHeader(nsHttp::WWW_Authenticate); NS_ENSURE_TRUE(challenges, NS_ERROR_UNEXPECTED); @@ -2168,12 +2180,9 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge, nsCAutoString path, scheme; PRBool identFromURI = PR_FALSE; - // it is possible for the origin server to fake a proxy challenge. if - // that happens we need to be sure to use the origin server as the auth - // domain. otherwise, we could inadvertantly expose the user's proxy - // credentials to an origin server. + if (proxyAuth) { + NS_ASSERTION (mConnectionInfo->UsingHttpProxy(), "proxyAuth is true, but no HTTP proxy is configured!"); - if (proxyAuth && mConnectionInfo->UsingHttpProxy()) { host = mConnectionInfo->ProxyHost(); port = mConnectionInfo->ProxyPort(); ident = &mProxyIdent; @@ -2396,8 +2405,19 @@ nsHttpChannel::PromptForIdentity(const char *scheme, // XXX i18n: IDN not supported. + nsCOMPtr authPromptProvider; nsCOMPtr authPrompt; - GetCallback(NS_GET_IID(nsIAuthPrompt), getter_AddRefs(authPrompt)); + + GetCallback(NS_GET_IID(nsIAuthPromptProvider), getter_AddRefs(authPromptProvider)); + if (authPromptProvider) { + PRUint32 promptReason = (proxyAuth ? + nsIAuthPromptProvider::PROMPT_PROXY : + nsIAuthPromptProvider::PROMPT_NORMAL); + (void) authPromptProvider->GetAuthPrompt(promptReason, getter_AddRefs(authPrompt)); + } + else + GetCallback(NS_GET_IID(nsIAuthPrompt), getter_AddRefs(authPrompt)); + if (!authPrompt) return NS_ERROR_NO_INTERFACE;