Bug 265780 part I: Implement nsIAuthPrompt2 and related interfaces per the design at

http://wiki.mozilla.org/Necko:nsIAuthPrompt2
r=darin
This commit is contained in:
cbiesinger%web.de 2006-08-26 21:42:54 +00:00
Родитель 735380688b
Коммит 71105206f8
38 изменённых файлов: 1959 добавлений и 461 удалений

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

@ -1978,7 +1978,7 @@ MicrosummaryResource.prototype = {
get _httpAuthFailed() { return this.__httpAuthFailed },
set _httpAuthFailed(newValue) { this.__httpAuthFailed = newValue },
getAuthPrompt: function(aPromptReason) {
getAuthPrompt: function(aPromptReason, aIID) {
this._httpAuthFailed = true;
throw Components.results.NS_ERROR_NOT_AVAILABLE;
},

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

@ -76,6 +76,7 @@
#include "nsIObserverService.h"
#include "nsIPrompt.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
#include "nsTextFormatter.h"
#include "nsIChannelEventSink.h"
#include "nsIUploadChannel.h"
@ -127,6 +128,7 @@
#include "nsIHistoryEntry.h"
#include "nsISHistoryListener.h"
#include "nsIWindowWatcher.h"
#include "nsIPromptFactory.h"
#include "nsIObserver.h"
#include "nsINestedURI.h"
@ -455,11 +457,11 @@ NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink)
*aSink = prompt;
return NS_OK;
}
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
return NS_SUCCEEDED(
GetAuthPrompt(PROMPT_NORMAL, (nsIAuthPrompt **) aSink)) ?
GetAuthPrompt(PROMPT_NORMAL, aIID, aSink)) ?
NS_OK : NS_NOINTERFACE;
}
else if (aIID.Equals(NS_GET_IID(nsISHistory))) {
nsCOMPtr<nsISHistory> shistory;
@ -8820,8 +8822,9 @@ nsDocShell::SetBaseUrlForWyciwyg(nsIContentViewer * aContentViewer)
// nsDocShell::nsIAuthPromptProvider
//*****************************************************************************
nsresult
nsDocShell::GetAuthPrompt(PRUint32 aPromptReason, nsIAuthPrompt **aResult)
NS_IMETHODIMP
nsDocShell::GetAuthPrompt(PRUint32 aPromptReason, const nsIID& iid,
void** aResult)
{
// a priority prompt request will override a false mAllowAuth setting
PRBool priorityPrompt = (aPromptReason == PROMPT_PROXY);
@ -8831,7 +8834,7 @@ nsDocShell::GetAuthPrompt(PRUint32 aPromptReason, nsIAuthPrompt **aResult)
// we're either allowing auth, or it's a proxy request
nsresult rv;
nsCOMPtr<nsIWindowWatcher> wwatch =
nsCOMPtr<nsIPromptFactory> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
@ -8843,7 +8846,8 @@ nsDocShell::GetAuthPrompt(PRUint32 aPromptReason, nsIAuthPrompt **aResult)
// Get the an auth prompter for our window so that the parenting
// of the dialogs works as it should when using tabs.
return wwatch->GetNewAuthPrompter(window, aResult);
return wwatch->GetPrompt(window, iid,
NS_REINTERPRET_CAST(void**, aResult));
}
//*****************************************************************************

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

@ -67,6 +67,7 @@
*
* This contract implements the following interfaces:
* nsIPromptService
* nsIPromptService2 (optional)
*
* Embedders may override this ContractID with their own implementation if they
* want more control over the way prompts, alerts, and confirmation dialogs are
@ -87,4 +88,15 @@
#define NS_NONBLOCKINGALERTSERVICE_CONTRACTID \
"@mozilla.org/embedcomp/nbalert-service;1"
/**
* This contract ID should be implemented by password managers to be able to
* override the standard implementation of nsIAuthPrompt2. It will be used as
* a service.
*
* This contract implements the following interfaces:
* nsIPromptFactory
*/
#define NS_PWMGR_AUTHPROMPTFACTORY \
"@mozilla.org/passwordmanager/authpromptfactory;1"
#endif // NSEMBEDCID_H

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

@ -149,6 +149,7 @@ static const nsModuleComponentInfo gComponents[] = {
#endif
#endif
{ "Window Watcher", NS_WINDOWWATCHER_CID, NS_WINDOWWATCHER_CONTRACTID, nsWindowWatcherConstructor },
{ "Window Watcher", NS_WINDOWWATCHER_CID, NS_AUTHPROMPT_ADAPTER_FACTORY_CONTRACTID, nsWindowWatcherConstructor },
{ "Find", NS_FIND_CID, NS_FIND_CONTRACTID, nsFindConstructor },
{ "WebBrowserFind", NS_WEB_BROWSER_FIND_CID, NS_WEB_BROWSER_FIND_CONTRACTID, nsWebBrowserFindConstructor },
{ NS_APPSTARTUPNOTIFIER_CLASSNAME, NS_APPSTARTUPNOTIFIER_CID, NS_APPSTARTUPNOTIFIER_CONTRACTID, nsAppStartupNotifierConstructor },

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

@ -52,11 +52,16 @@ SDK_XPIDLSRCS = nsIWindowWatcher.idl \
$(NULL)
XPIDLSRCS = nsIDialogParamBlock.idl \
nsIPromptService2.idl \
nsPIPromptService.idl \
nsPIWindowWatcher.idl \
nsIAuthPromptWrapper.idl \
nsIPromptFactory.idl \
nsINonBlockingAlertService.idl \
$(NULL)
EXPORTS = nsPromptUtils.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,55 @@
/* ***** 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 embedding code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@web.de> (Original Author)
*
* 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 nsIDOMWindow;
/**
* This interface allows creating various prompts that have a specific parent.
*/
[scriptable, uuid(2532b748-75db-4732-9173-78d3bf34f694)]
interface nsIPromptFactory : nsISupports
{
/**
* Returns an object implementing the specified interface that creates
* prompts parented to aParent.
*/
void getPrompt(in nsIDOMWindow aParent, in nsIIDRef iid,
[iid_is(iid),retval] out nsQIResult result);
};

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

@ -0,0 +1,78 @@
/* ***** 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 embedding code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@web.de> (Original Author)
*
* 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 "nsIPromptService.idl"
interface nsIAuthInformation;
interface nsIAuthPromptCallback;
interface nsICancelable;
interface nsIChannel;
interface nsIDOMWindow;
/**
* This is an improved version of nsIPromptService that is less prescriptive
* about the resulting user interface.
*
* @status INCOMPLETE do not freeze before fixing bug 228207
*/
[scriptable, uuid(cf86d196-dbee-4482-9dfa-3477aa128319)]
interface nsIPromptService2 : nsIPromptService {
// NOTE: These functions differ from their nsIAuthPrompt counterparts by
// having additional checkbox parameters
// checkValue can be null meaning to show no checkbox
// checkboxLabel is a wstring so that it can be null from both JS and C++ in
// a convenient way
//
// See nsIAuthPrompt2 for documentation on the semantics of the other
// parameters.
boolean promptAuth(in nsIDOMWindow aParent,
in nsIChannel aChannel,
in PRUint32 level,
in nsIAuthInformation authInfo,
in wstring checkboxLabel,
inout boolean checkValue);
nsICancelable asyncPromptAuth(in nsIDOMWindow aParent,
in nsIChannel aChannel,
in nsIAuthPromptCallback aCallback,
in nsISupports aContext,
in PRUint32 level,
in nsIAuthInformation authInfo,
in wstring checkboxLabel,
inout boolean checkValue);
};

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

@ -36,6 +36,18 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsIObserver;
interface nsIPrompt;
interface nsIAuthPrompt;
interface nsISimpleEnumerator;
interface nsIWebBrowserChrome;
interface nsIWindowCreator;
/**
* nsIWindowWatcher is the keeper of Gecko/DOM Windows. It maintains
* a list of open top-level windows, and allows some operations on them.
@ -58,17 +70,6 @@
*
* @status FROZEN
*/
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsIObserver;
interface nsIPrompt;
interface nsIAuthPrompt;
interface nsISimpleEnumerator;
interface nsIWebBrowserChrome;
interface nsIWindowCreator;
[scriptable, uuid(002286a8-494b-43b3-8ddd-49e3fc50622b)]
interface nsIWindowWatcher : nsISupports {

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

@ -0,0 +1,161 @@
/* ***** 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 embedding code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@web.de> (Original Author)
*
* 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 ***** */
#ifndef NSPROMPTUTILS_H_
#define NSPROMPTUTILS_H_
/**
* @file
* This file defines some helper functions that simplify interaction
* with authentication prompts.
*/
/**
* Given a username (possibly in DOMAIN\user form) and password, parses the
* domain out of the username if necessary and sets domain, username and
* password on the auth information object.
*/
inline void
NS_SetAuthInfo(nsIAuthInformation* aAuthInfo, const nsString& user,
const nsString& password)
{
PRUint32 flags;
aAuthInfo->GetFlags(&flags);
if (flags & nsIAuthInformation::NEED_DOMAIN) {
// Domain is separated from username by a backslash
PRInt32 idx = user.FindChar(PRUnichar('\\'));
if (idx == kNotFound) {
aAuthInfo->SetUsername(user);
} else {
aAuthInfo->SetDomain(Substring(user, 0, idx));
aAuthInfo->SetUsername(Substring(user, idx + 1));
}
} else {
aAuthInfo->SetUsername(user);
}
aAuthInfo->SetPassword(password);
}
/**
* Gets the host and port from a channel and authentication info. This is the
* "logical" host and port for this authentication, i.e. for a proxy
* authentication it refers to the proxy, while for a host authentication it
* is the actual host.
*
* @param machineProcessing
* When this parameter is true, the host will be returned in ASCII
* (instead of UTF-8; this is relevant when IDN is used). In addition,
* the port will be returned as the real port even when it was not
* explicitly specified (when false, the port will be returned as -1 in
* this case)
*/
inline void
NS_GetAuthHostPort(nsIChannel* aChannel, nsIAuthInformation* aAuthInfo,
PRBool machineProcessing, nsCString& host, PRInt32* port)
{
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv))
return;
// Have to distinguish proxy auth and host auth here...
PRUint32 flags;
aAuthInfo->GetFlags(&flags);
if (flags & nsIAuthInformation::AUTH_PROXY) {
nsCOMPtr<nsIProxiedChannel> proxied(do_QueryInterface(aChannel));
NS_ASSERTION(proxied, "proxy auth needs nsIProxiedChannel");
nsCOMPtr<nsIProxyInfo> info;
proxied->GetProxyInfo(getter_AddRefs(info));
NS_ASSERTION(proxied, "proxy auth needs nsIProxyInfo");
nsCAutoString idnhost;
info->GetHost(idnhost);
info->GetPort(port);
if (machineProcessing) {
nsCOMPtr<nsIIDNService> idnService =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnService) {
idnService->ConvertUTF8toACE(idnhost, host);
} else {
// Not much we can do here...
host = idnhost;
}
} else {
host = idnhost;
}
} else {
if (machineProcessing) {
uri->GetAsciiHost(host);
*port = NS_GetRealPort(uri);
} else {
uri->GetHost(host);
uri->GetPort(port);
}
}
}
/**
* Creates the key for looking up passwords in the password manager. This
* function uses the same format that Gecko functions have always used, thus
* ensuring backwards compatibility.
*/
inline void
NS_GetAuthKey(nsIChannel* aChannel, nsIAuthInformation* aAuthInfo,
nsCString& key)
{
// NOTE: For backwards-compatibility reasons, this must be the ASCII host.
nsCString host;
PRInt32 port = -1;
NS_GetAuthHostPort(aChannel, aAuthInfo, PR_TRUE, host, &port);
nsAutoString realm;
aAuthInfo->GetRealm(realm);
// Now assemble the key: host:port (realm)
key.Append(host);
key.Append(':');
key.AppendInt(port);
key.AppendLiteral(" (");
AppendUTF16toUTF8(realm, key);
key.Append(')');
}
#endif

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

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sts=2 sw=2 et cin: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -20,6 +21,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Google Inc.
*
* 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
@ -37,16 +39,27 @@
#include "nsIServiceManager.h"
#include "nsIAuthPromptWrapper.h"
#include "nsIAuthInformation.h"
#include "nsPrompt.h"
#include "nsReadableUtils.h"
#include "nsDependentString.h"
#include "nsIStringBundle.h"
#include "nsIChannel.h"
#include "nsIURI.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMEvent.h"
#include "nsIPrivateDOMEvent.h"
#include "nsEmbedCID.h"
#include "nsNetCID.h"
#include "nsPIDOMWindow.h"
#include "nsIPromptFactory.h"
#include "nsIProxiedChannel.h"
#include "nsIProxyInfo.h"
#include "nsIIDNService.h"
#include "nsNetUtil.h"
#include "nsPromptUtils.h"
nsresult
NS_NewPrompter(nsIPrompt **result, nsIDOMWindow *aParent)
@ -104,7 +117,37 @@ NS_NewAuthPrompter(nsIAuthPrompt **result, nsIDOMWindow *aParent)
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsPrompt, nsIPrompt, nsIAuthPrompt)
nsresult
NS_NewAuthPrompter2(nsIAuthPrompt2 **result, nsIDOMWindow *aParent)
{
nsCOMPtr<nsIPromptFactory> factory =
do_GetService(NS_PWMGR_AUTHPROMPTFACTORY);
if (factory) {
// We just delegate everything to the pw mgr.
return factory->GetPrompt(aParent,
NS_GET_IID(nsIAuthPrompt2),
NS_REINTERPRET_CAST(void**, result));
}
nsresult rv;
*result = 0;
nsPrompt *prompter = new nsPrompt(aParent);
if (!prompter)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(prompter);
rv = prompter->Init();
if (NS_FAILED(rv)) {
NS_RELEASE(prompter);
return rv;
}
*result = prompter;
return NS_OK;
}
NS_IMPL_THREADSAFE_ISUPPORTS3(nsPrompt, nsIPrompt, nsIAuthPrompt, nsIAuthPrompt2)
nsPrompt::nsPrompt(nsIDOMWindow *aParent)
: mParent(aParent)
@ -123,6 +166,9 @@ nsresult
nsPrompt::Init()
{
mPromptService = do_GetService(NS_PROMPTSERVICE_CONTRACTID);
mPromptService2 = do_QueryInterface(mPromptService);
// A null mPromptService2 is not fatal, we have to deal with that
// (for compatibility with embeddors who only implement the old version)
return mPromptService ? NS_OK : NS_ERROR_FAILURE;
}
@ -476,4 +522,217 @@ nsPrompt::PromptPassword(const PRUnichar* dialogTitle,
return mPromptService->PromptPassword(mParent, dialogTitle, text, pwd,
nsnull, nsnull, _retval);
}
NS_IMETHODIMP
nsPrompt::PromptAuth(nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
PRBool* retval)
{
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!windowStateHelper.DefaultEnabled()) {
// Default to cancel
*retval = PR_FALSE;
return NS_OK;
}
if (mPromptService2) {
return mPromptService2->PromptAuth(mParent, aChannel,
aLevel, aAuthInfo,
nsnull, nsnull, retval);
}
return PromptPasswordAdapter(mPromptService, mParent, aChannel,
aLevel, aAuthInfo, nsnull, nsnull, retval);
}
NS_IMETHODIMP
nsPrompt::AsyncPromptAuth(nsIChannel* aChannel,
nsIAuthPromptCallback* aCallback,
nsISupports* aContext,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
nsICancelable** retval)
{
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!windowStateHelper.DefaultEnabled()) {
// XXX what to do?
return NS_ERROR_NOT_IMPLEMENTED;
}
if (mPromptService2) {
return mPromptService2->AsyncPromptAuth(mParent, aChannel,
aCallback, aContext,
aLevel, aAuthInfo,
nsnull, nsnull, retval);
}
// Tell the caller to use the sync version
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult
MakeDialogText(nsIChannel* aChannel, nsIAuthInformation* aAuthInfo,
nsXPIDLString& message)
{
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleSvc =
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleSvc->CreateBundle("chrome://necko/locale/necko.properties",
getter_AddRefs(bundle));
NS_ENSURE_SUCCESS(rv, rv);
// figure out what message to display...
nsCAutoString host;
PRInt32 port;
NS_GetAuthHostPort(aChannel, aAuthInfo, PR_FALSE, host, &port);
nsAutoString displayHost;
CopyUTF8toUTF16(host, displayHost);
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
nsCAutoString scheme;
uri->GetScheme(scheme);
PRUint32 flags;
aAuthInfo->GetFlags(&flags);
PRBool proxyAuth = (flags & nsIAuthInformation::AUTH_PROXY) != 0;
nsAutoString realm;
aAuthInfo->GetRealm(realm);
// Append the port if it was specified
if (port != -1) {
displayHost.Append(PRUnichar(':'));
displayHost.AppendInt(port);
}
NS_NAMED_LITERAL_STRING(proxyText, "EnterUserPasswordForProxy");
NS_NAMED_LITERAL_STRING(originText, "EnterUserPasswordForRealm");
const PRUnichar *text;
if (proxyAuth) {
text = proxyText.get();
} else {
text = originText.get();
// prepend "scheme://"
nsAutoString schemeU;
CopyASCIItoUTF16(scheme, schemeU);
schemeU.AppendLiteral("://");
displayHost.Insert(schemeU, 0);
}
const PRUnichar *strings[] = { realm.get(), displayHost.get() };
rv = bundle->FormatStringFromName(text, strings, 2, getter_Copies(message));
return rv;
}
/* static */ nsresult
nsPrompt::PromptPasswordAdapter(nsIPromptService* aService,
nsIDOMWindow* aParent,
nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
const PRUnichar* aCheckLabel,
PRBool* aCheckValue,
PRBool* retval)
{
// construct the message string
nsXPIDLString message;
MakeDialogText(aChannel, aAuthInfo, message);
nsAutoString defaultUser, defaultDomain, defaultPass;
aAuthInfo->GetUsername(defaultUser);
aAuthInfo->GetDomain(defaultDomain);
aAuthInfo->GetPassword(defaultPass);
PRUint32 flags;
aAuthInfo->GetFlags(&flags);
if ((flags & nsIAuthInformation::NEED_DOMAIN) && !defaultDomain.IsEmpty()) {
defaultDomain.Append(PRUnichar('\\'));
defaultUser.Insert(defaultDomain, 0);
}
// NOTE: Allocation failure is not fatal here (just default to empty string
// if allocation fails)
PRUnichar *user = ToNewUnicode(defaultUser),
*pass = ToNewUnicode(defaultPass);
nsresult rv;
rv = aService->PromptUsernameAndPassword(aParent, nsnull, message.get(),
&user, &pass, aCheckLabel,
aCheckValue, retval);
nsAdoptingString userStr(user);
nsAdoptingString passStr(pass);
NS_SetAuthInfo(aAuthInfo, userStr, passStr);
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(AuthPromptWrapper, nsIAuthPrompt2)
NS_IMETHODIMP
AuthPromptWrapper::PromptAuth(nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
PRBool* retval)
{
nsCAutoString keyUTF8;
NS_GetAuthKey(aChannel, aAuthInfo, keyUTF8);
NS_ConvertUTF8toUTF16 key(keyUTF8);
nsXPIDLString text;
MakeDialogText(aChannel, aAuthInfo, text);
PRUint32 flags;
aAuthInfo->GetFlags(&flags);
nsresult rv;
nsXPIDLString user, password;
if (flags & nsIAuthInformation::ONLY_PASSWORD) {
rv = mAuthPrompt->PromptPassword(nsnull, text.get(), key.get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
getter_Copies(password), retval);
if (NS_SUCCEEDED(rv) && *retval) {
NS_ASSERTION(password, "password must not be null if retval is true");
aAuthInfo->SetPassword(password);
}
} else {
rv = mAuthPrompt->PromptUsernameAndPassword(nsnull, text.get(), key.get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
getter_Copies(user),
getter_Copies(password),
retval);
if (NS_SUCCEEDED(rv) && *retval) {
NS_ASSERTION(user && password, "out params must be nonnull");
NS_SetAuthInfo(aAuthInfo, user, password);
}
}
return rv;
}
NS_IMETHODIMP
AuthPromptWrapper::AsyncPromptAuth(nsIChannel*,
nsIAuthPromptCallback*,
nsISupports*,
PRUint32,
nsIAuthInformation*,
nsICancelable**)
{
// There is no way to implement this here. Just tell the caller
// to fall back to the synchronous version.
return NS_ERROR_NOT_IMPLEMENTED;
}

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

@ -39,24 +39,63 @@
#include "nsIDOMWindow.h"
#include "nsIPrompt.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
#include "nsIPromptService.h"
#include "nsIPromptService2.h"
class nsPrompt : public nsIPrompt,
public nsIAuthPrompt {
public nsIAuthPrompt,
public nsIAuthPrompt2 {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPROMPT
NS_DECL_NSIAUTHPROMPT
NS_DECL_NSIAUTHPROMPT2
nsPrompt(nsIDOMWindow *window);
virtual ~nsPrompt() {}
nsresult Init();
/**
* This helper method can be used to implement nsIAuthPrompt2's
* PromptPassword function using nsIPromptService (as opposed to
* nsIPromptService2).
*/
static nsresult PromptPasswordAdapter(nsIPromptService* aService,
nsIDOMWindow* aParent,
nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
const PRUnichar* aCheckLabel,
PRBool* aCheckValue,
PRBool* retval);
protected:
nsCOMPtr<nsIDOMWindow> mParent;
nsCOMPtr<nsIPromptService> mPromptService;
// This is the new prompt service version. May be null.
nsCOMPtr<nsIPromptService2> mPromptService2;
};
/**
* A class that wraps an nsIAuthPrompt so that it can be used as an
* nsIAuthPrompt2.
*/
class AuthPromptWrapper : public nsIAuthPrompt2
{
public:
AuthPromptWrapper(nsIAuthPrompt* aAuthPrompt) :
mAuthPrompt(aAuthPrompt) {}
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPT2
private:
~AuthPromptWrapper() {}
nsCOMPtr<nsIAuthPrompt> mAuthPrompt;
};
nsresult
@ -64,3 +103,6 @@ NS_NewPrompter(nsIPrompt **result, nsIDOMWindow *aParent);
nsresult
NS_NewAuthPrompter(nsIAuthPrompt **result, nsIDOMWindow *aParent);
nsresult
NS_NewAuthPrompter2(nsIAuthPrompt2 **result, nsIDOMWindow *aParent);

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

@ -36,6 +36,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsPromptService.h"
#include "nsPrompt.h"
#include "nsDialogParamBlock.h"
#include "nsIComponentManager.h"
@ -83,7 +84,7 @@ private:
************************ nsPromptService ***********************
****************************************************************/
NS_IMPL_ISUPPORTS3(nsPromptService, nsIPromptService,
NS_IMPL_ISUPPORTS4(nsPromptService, nsIPromptService, nsIPromptService2,
nsPIPromptService, nsINonBlockingAlertService)
nsPromptService::nsPromptService() {
@ -558,6 +559,36 @@ NS_IMETHODIMP nsPromptService::PromptPassword(nsIDOMWindow *parent,
return rv;
}
NS_IMETHODIMP
nsPromptService::PromptAuth(nsIDOMWindow* aParent,
nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
const PRUnichar* aCheckLabel,
PRBool* aCheckValue,
PRBool *retval)
{
return nsPrompt::PromptPasswordAdapter(this, aParent, aChannel,
aLevel, aAuthInfo,
aCheckLabel, aCheckValue,
retval);
}
NS_IMETHODIMP
nsPromptService::AsyncPromptAuth(nsIDOMWindow* aParent,
nsIChannel* aChannel,
nsIAuthPromptCallback* aCallback,
nsISupports* aContext,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
const PRUnichar* aCheckLabel,
PRBool* aCheckValue,
nsICancelable** retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPromptService::Select(nsIDOMWindow *parent, const PRUnichar *dialogTitle,
const PRUnichar* text, PRUint32 count,

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

@ -46,7 +46,7 @@
{0x150e7415, 0x72d7, 0x11da, {0xa9, 0x24, 0x00, 0x03, 0x93, 0x86, 0x35, 0x7a}}
#include "nsCOMPtr.h"
#include "nsIPromptService.h"
#include "nsIPromptService2.h"
#include "nsPIPromptService.h"
#include "nsINonBlockingAlertService.h"
#include "nsIWindowWatcher.h"
@ -54,7 +54,7 @@
class nsIDOMWindow;
class nsIDialogParamBlock;
class nsPromptService: public nsIPromptService,
class nsPromptService: public nsIPromptService2,
public nsPIPromptService,
public nsINonBlockingAlertService {
@ -66,6 +66,7 @@ public:
nsresult Init();
NS_DECL_NSIPROMPTSERVICE
NS_DECL_NSIPROMPTSERVICE2
NS_DECL_NSPIPROMPTSERVICE
NS_DECL_NSINONBLOCKINGALERTSERVICE
NS_DECL_ISUPPORTS

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

@ -324,7 +324,11 @@ nsresult JSContextAutoPopper::Push(JSContext *cx)
NS_IMPL_ADDREF(nsWindowWatcher)
NS_IMPL_RELEASE(nsWindowWatcher)
NS_IMPL_QUERY_INTERFACE2(nsWindowWatcher, nsIWindowWatcher, nsPIWindowWatcher)
NS_IMPL_QUERY_INTERFACE4(nsWindowWatcher,
nsIWindowWatcher,
nsIPromptFactory,
nsIAuthPromptAdapterFactory,
nsPIWindowWatcher)
nsWindowWatcher::nsWindowWatcher() :
mEnumeratorList(),
@ -962,6 +966,47 @@ nsWindowWatcher::GetNewAuthPrompter(nsIDOMWindow *aParent, nsIAuthPrompt **_retv
return NS_NewAuthPrompter(_retval, aParent);
}
NS_IMETHODIMP
nsWindowWatcher::GetPrompt(nsIDOMWindow *aParent, const nsIID& aIID,
void **_retval)
{
if (aIID.Equals(NS_GET_IID(nsIPrompt)))
return NS_NewPrompter(NS_REINTERPRET_CAST(nsIPrompt**, _retval), aParent);
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)))
return NS_NewAuthPrompter(NS_REINTERPRET_CAST(nsIAuthPrompt**, _retval),
aParent);
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
nsresult rv = NS_NewAuthPrompter2(NS_REINTERPRET_CAST(nsIAuthPrompt2**,
_retval),
aParent);
if (rv == NS_NOINTERFACE) {
// Return an wrapped nsIAuthPrompt (if we can)
nsCOMPtr<nsIAuthPrompt> prompt;
rv = NS_NewAuthPrompter(getter_AddRefs(prompt), aParent);
if (NS_SUCCEEDED(rv)) {
NS_WrapAuthPrompt(prompt,
NS_REINTERPRET_CAST(nsIAuthPrompt2**, _retval));
if (!*_retval)
rv = NS_ERROR_NOT_AVAILABLE;
}
return rv;
}
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsWindowWatcher::CreateAdapter(nsIAuthPrompt* aPrompt, nsIAuthPrompt2** _retval)
{
*_retval = new AuthPromptWrapper(aPrompt);
if (!*_retval)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*_retval);
return NS_OK;
}
NS_IMETHODIMP
nsWindowWatcher::SetWindowCreator(nsIWindowCreator *creator)
{

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

@ -46,6 +46,8 @@
#include "jspubtd.h"
#include "nsIWindowCreator.h" // for stupid compilers
#include "nsIWindowWatcher.h"
#include "nsIPromptFactory.h"
#include "nsIAuthPromptAdapterFactory.h"
#include "nsPIWindowWatcher.h"
#include "nsVoidArray.h"
@ -64,7 +66,9 @@ struct SizeSpec;
class nsWindowWatcher :
public nsIWindowWatcher,
public nsPIWindowWatcher
public nsPIWindowWatcher,
public nsIPromptFactory,
public nsIAuthPromptAdapterFactory
{
friend class nsWatcherWindowEnumerator;
@ -78,6 +82,8 @@ public:
NS_DECL_NSIWINDOWWATCHER
NS_DECL_NSPIWINDOWWATCHER
NS_DECL_NSIPROMPTFACTORY
NS_DECL_NSIAUTHPROMPTADAPTERFACTORY
private:
PRBool AddEnumerator(nsWatcherWindowEnumerator* inEnumerator);

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

@ -66,6 +66,7 @@ REQUIRES = xpcom \
intl \
unicharutil \
windowwatcher \
embed_base \
$(NULL)
CPPSRCS = \

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

@ -42,6 +42,7 @@
#include "nsWalletService.h"
#include "nsPasswordManager.h"
#include "nsCPasswordManager.h"
#include "nsEmbedCID.h"
// Define the constructor function for the nsWalletlibService
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWalletlibService, Init)
@ -55,6 +56,11 @@ static const nsModuleComponentInfo components[] = {
nsWalletlibService::RegisterProc,
nsWalletlibService::UnregisterProc
},
{ NS_WALLETSERVICE_CLASSNAME, NS_WALLETSERVICE_CID,
NS_PWMGR_AUTHPROMPTFACTORY, nsWalletlibServiceConstructor,
nsWalletlibService::RegisterProc,
nsWalletlibService::UnregisterProc
},
{ NS_PASSWORDMANAGER_CLASSNAME, NS_PASSWORDMANAGER_CID,
NS_PASSWORDMANAGER_CONTRACTID, nsPasswordManagerConstructor },
{ NS_SINGLESIGNONPROMPT_CLASSNAME, NS_SINGLESIGNONPROMPT_CID,

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

@ -62,6 +62,7 @@
#include "nsReadableUtils.h"
#include "nsICategoryManager.h"
#include "nsNetUtil.h"
#include "nsEmbedCID.h"
// for making the leap from nsIDOMWindowInternal -> nsIPresShell
@ -84,11 +85,12 @@ nsWalletlibService::~nsWalletlibService()
SI_ClearUserData();
}
NS_IMPL_THREADSAFE_ISUPPORTS5(nsWalletlibService,
NS_IMPL_THREADSAFE_ISUPPORTS6(nsWalletlibService,
nsIWalletService,
nsIObserver,
nsIFormSubmitObserver,
nsIWebProgressListener,
nsIPromptFactory,
nsISupportsWeakReference)
NS_IMETHODIMP nsWalletlibService::WALLET_PreEdit(nsAString& walletList) {
@ -535,6 +537,60 @@ nsWalletlibService::WALLET_Decrypt (const char *crypt, PRUnichar **text) {
return rv;
}
NS_IMETHODIMP
nsWalletlibService::GetPrompt(nsIDOMWindow* aParent,
const nsIID& aIID,
void** _retval) {
if (!aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
NS_WARNING("Wallet asked for unexpected interface");
return NS_NOINTERFACE;
}
// NOTE: It is important to return the specific return value here. The
// caller cares.
nsresult rv;
nsCOMPtr<nsIPromptService2> service =
do_GetService(NS_PROMPTSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsWalletAuthPromptWrapper* wrapper =
new nsWalletAuthPromptWrapper(service, aParent);
if (!wrapper)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(wrapper);
*_retval = NS_STATIC_CAST(nsIAuthPrompt2*, wrapper);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsWalletAuthPromptWrapper
NS_IMPL_ISUPPORTS1(nsWalletAuthPromptWrapper, nsIAuthPrompt2)
NS_IMETHODIMP
nsWalletAuthPromptWrapper::PromptAuth(nsIChannel* aChannel,
PRUint32 aLevel,
nsIAuthInformation* aAuthInfo,
PRBool* retval)
{
return SINGSIGN_PromptAuth(mService, mParent, aChannel,
aLevel, aAuthInfo, retval);
}
NS_IMETHODIMP
nsWalletAuthPromptWrapper::AsyncPromptAuth(nsIChannel*,
nsIAuthPromptCallback*,
nsISupports*,
PRUint32,
nsIAuthInformation*,
nsICancelable**)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsSingleSignOnPrompt

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

@ -43,17 +43,22 @@
#include "nsIFormSubmitObserver.h"
#include "nsWeakReference.h"
#include "nsIPrompt.h"
#include "nsIPromptService2.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIURI.h"
#include "nsIWebProgressListener.h"
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsIAuthPromptWrapper.h"
#include "nsIAuthPrompt2.h"
#include "nsIPromptFactory.h"
class nsWalletlibService : public nsIWalletService,
public nsIObserver,
public nsIFormSubmitObserver,
public nsIWebProgressListener,
public nsIPromptFactory,
public nsSupportsWeakReference {
public:
@ -61,6 +66,7 @@ public:
NS_DECL_NSIWALLETSERVICE
NS_DECL_NSIOBSERVER
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIPROMPTFACTORY
// NS_DECL_NSSUPPORTSWEAKREFERENCE
nsWalletlibService();
@ -105,4 +111,21 @@ protected:
////////////////////////////////////////////////////////////////////////////////
class nsWalletAuthPromptWrapper : public nsIAuthPrompt2
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPT2
nsWalletAuthPromptWrapper(nsIPromptService2* aService,
nsIDOMWindow* aParent)
: mService(aService), mParent(aParent) {}
private:
~nsWalletAuthPromptWrapper() {}
nsCOMPtr<nsIPromptService2> mService;
nsCOMPtr<nsIDOMWindow> mParent;
};
#endif /* nsWalletService_h___ */

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

@ -65,7 +65,15 @@
#include "nsReadableUtils.h"
#include "nsIObserverService.h"
#include "nsIObserver.h"
#include "nsIPromptService2.h"
#include "nsIWindowWatcher.h"
#include "nsIAuthInformation.h"
#include "nsIProxiedChannel.h"
#include "nsIProxyInfo.h"
#include "nsIIDNService.h"
#include "nsNetCID.h"
#include "nsCRT.h"
#include "nsPromptUtils.h"
//#define SINGSIGN_LOGGING
#ifdef SINGSIGN_LOGGING
@ -577,6 +585,36 @@ si_CheckGetUsernamePassword
}
}
static nsresult
si_CheckPromptAuth
(nsIPromptService2* aService, nsIDOMWindow* aParent, nsIChannel* aChannel,
PRUint32 aLevel, nsIAuthInformation* aAuthInfo, PRBool* remembered)
{
PRUnichar* check_string;
if (SI_GetBoolPref(pref_Crypto, PR_FALSE)) {
check_string = Wallet_Localize("SaveTheseValuesEncrypted");
} else {
check_string = Wallet_Localize("SaveTheseValuesObscured");
}
PRBool confirmed = PR_FALSE;
nsresult rv = aService->PromptAuth(aParent, aChannel, aLevel,
aAuthInfo, check_string,
remembered, &confirmed);
if (check_string)
Recycle(check_string);
if (NS_FAILED(rv))
return rv;
if (confirmed) {
return NS_OK;
} else {
return NS_ERROR_FAILURE; /* user pressed cancel */
}
}
/********************
* Utility Routines *
@ -2493,7 +2531,7 @@ si_RememberSignonDataFromBrowser(const char* passwordRealm, const nsString& user
* Check for remembered data from a previous browser-generated password dialog
* restore it if so
*/
static void
static PRBool
si_RestoreOldSignonDataFromBrowser
(nsIPrompt* dialog, const char* passwordRealm, PRBool pickFirstUser, nsString& username, nsString& password) {
si_SignonUserStruct* user;
@ -2512,7 +2550,7 @@ si_RestoreOldSignonDataFromBrowser
/* username = 0; */
/* *password = 0; */
si_unlock_signon_list();
return;
return PR_FALSE;
}
/* restore the data from previous time this URL was visited */
@ -2529,6 +2567,7 @@ si_RestoreOldSignonDataFromBrowser
}
}
si_unlock_signon_list();
return PR_TRUE;
}
PRBool
@ -2777,6 +2816,81 @@ SINGSIGN_Prompt
return NS_OK;
}
nsresult
SINGSIGN_PromptAuth
(nsIPromptService2* aService, nsIDOMWindow* aParent, nsIChannel* aChannel,
PRUint32 aLevel, nsIAuthInformation* aAuthInfo, PRBool* retval) {
nsCAutoString key;
NS_GetAuthKey(aChannel, aAuthInfo, key);
/* do only the dialog if signon preference is not enabled */
if (!si_GetSignonRememberingPref()){
return aService->PromptAuth(aParent, aChannel, aLevel,
aAuthInfo, nsnull, nsnull,
retval);
}
/* prefill with previous username/password if any */
/* this needs a dialog to choose between multiple usernames */
nsCOMPtr<nsIPrompt> prompt;
nsresult rv;
nsCOMPtr<nsIWindowWatcher> wwatcher =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
wwatcher->GetNewPrompter(aParent, getter_AddRefs(prompt));
// If we have a domain, insert a "domain\" in front of the username
// for the lookup
nsAutoString domain, username, password;
aAuthInfo->GetDomain(domain);
aAuthInfo->GetUsername(username);
if (!domain.IsEmpty()) {
domain.Append(PRUnichar('\\'));
username.Insert(domain, 0);
}
// Offer saving the data iff we had previously stored information
PRBool checked = si_RestoreOldSignonDataFromBrowser(prompt,
key.get(),
PR_FALSE,
username,
password);
if (checked) {
NS_SetAuthInfo(aAuthInfo, username, password);
}
PRBool remembered = checked;
rv = si_CheckPromptAuth(aService, aParent, aChannel, aLevel,
aAuthInfo, &checked);
if (NS_FAILED(rv)) {
/* user pressed Cancel */
*retval = PR_FALSE;
return NS_OK;
}
/* Get the newly entered data back */
aAuthInfo->GetDomain(domain);
aAuthInfo->GetUsername(username);
aAuthInfo->GetPassword(password);
if (!domain.IsEmpty()) {
domain.Append(PRUnichar('\\'));
username.Insert(domain, 0);
}
if (checked) {
Wallet_GiveCaveat(nsnull, prompt);
si_RememberSignonDataFromBrowser (key.get(), username, password);
} else if (remembered) {
/* a login was remembered but user unchecked the box; we forget the remembered login */
si_RemoveUser(key.get(), username, PR_TRUE, PR_FALSE, PR_TRUE);
}
/* cleanup and return */
*retval = PR_TRUE;
return NS_OK;
}
/*****************
* Signon Viewer *
*****************/

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

@ -50,6 +50,9 @@
#include "nsIDOMWindowInternal.h"
class nsIURI;
class nsIPromptService2;
class nsIChannel;
class nsIAuthInformation;
/* Duplicates defines as in nsIPrompt.idl -- keep in sync! */
#define SINGSIGN_SAVE_PASSWORD_NEVER 0
@ -96,6 +99,11 @@ SINGSIGN_Prompt
const char* passwordRealm, nsIPrompt* dialog, PRBool *returnValue,
PRUint32 savePassword = SINGSIGN_SAVE_PASSWORD_PERMANENTLY);
extern nsresult
SINGSIGN_PromptAuth
(nsIPromptService2* aService, nsIDOMWindow* aParent, nsIChannel* aChannel,
PRUint32 aLevel, nsIAuthInformation* aAuthInfo, PRBool* retval);
extern nsresult
SINGSIGN_RemoveUser
(const char* passwordRealm, const PRUnichar *userName, PRBool notify);

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

@ -61,7 +61,11 @@ SDK_XPIDLSRCS = \
$(NULL)
XPIDLSRCS = \
nsIAuthInformation.idl \
nsIAuthPrompt.idl \
nsIAuthPrompt2.idl \
nsIAuthPromptAdapterFactory.idl \
nsIAuthPromptCallback.idl \
nsIAsyncStreamCopier.idl \
nsISafeOutputStream.idl \
nsIBufferedStreams.idl \

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

@ -0,0 +1,133 @@
/* ***** 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 Necko code.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Google Inc.
*
* 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"
/**
* A object that hold authentication information. The caller of
* nsIAuthPrompt2::promptUsernameAndPassword or
* nsIAuthPrompt2::promptPasswordAsync provides an object implementing this
* interface; the prompt implementation can then read the values here to prefill
* the dialog. After the user entered the authentication information, it should
* set the attributes of this object to indicate to the caller what was entered
* by the user.
*/
[scriptable, uuid(0d73639c-2a92-4518-9f92-28f71fea5f20)]
interface nsIAuthInformation : nsISupports
{
/** @name Flags */
/* @{ */
/**
* This dialog belongs to a network host.
*/
const PRUint32 AUTH_HOST = 1;
/**
* This dialog belongs to a proxy.
*/
const PRUint32 AUTH_PROXY = 2;
/**
* This dialog needs domain information. The user interface should show a
* domain field, prefilled with the domain attribute's value.
*/
const PRUint32 NEED_DOMAIN = 4;
/**
* This dialog only asks for password information. The implementation SHOULD
* NOT show a username field. It MUST NOT modify the user attribute,
* although it should show its initial value to the user in some form. For
* example, a paragraph in the dialog might say "Please enter your password
* for user jsmith at server intranet".
*
* This flag is mutually exclusive with #NEED_DOMAIN.
*/
const PRUint32 ONLY_PASSWORD = 8;
/* @} */
/**
* Flags describing this dialog. A bitwise OR of the flag values
* above.
*
* It is possible that neither #AUTH_HOST nor #AUTH_PROXY are set.
*
* Implementations should ignore flags they don't understand; especially, they
* should not throw an exception because of an unsupported flag.
*/
readonly attribute unsigned long flags;
/**
* The server-supplied realm of the authentication as defined in RFC 2617.
* Can be the empty string if the protocol does not support realms.
* Otherwise, this is a human-readable string like "Secret files".
*/
readonly attribute AString realm;
/**
* The authentication scheme used for this request, if applicable. If the
* protocol for this authentication does not support schemes, this will be
* the empty string. Otherwise, this will be a string such as "basic" or
* "digest". This string will always be in lowercase.
*/
readonly attribute AUTF8String authenticationScheme;
/**
* The initial value should be used to prefill the dialog.
* Implementations should not show the password in clear.
* On return, this parameter should contain the username entered by
* the user.
*/
attribute AString username;
/**
* The initial value should be used to prefill the dialog or show it
* in some other way to the user.
* On return, this parameter should contain the username entered by
* the user.
*/
attribute AString password;
/**
* The initial value should be used to prefill the dialog or show it
* in some other way to the user.
* On return, this parameter should contain the domain entered by
* the user.
* This attribute is only used if flags include #NEED_DOMAIN.
*/
attribute AString domain;
};

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

@ -0,0 +1,124 @@
/* ***** 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 Necko code.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Google Inc.
*
* 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 nsIAuthPromptCallback;
interface nsIChannel;
interface nsICancelable;
interface nsIAuthInformation;
/**
* An interface allowing to prompt for a username and password. This interface
* is usually acquired using getInterface on notification callbacks or similar.
* It can be used to prompt users for authentication information, either
* synchronously or asynchronously.
*/
[scriptable, uuid(447fc780-1d28-412a-91a1-466d48129c65)]
interface nsIAuthPrompt2 : nsISupports
{
/** @name Security Levels */
/* @{ */
/**
* The password will be sent unencrypted. No security provided.
*/
const PRUint32 LEVEL_NONE = 0;
/**
* Password will be sent encrypted, but the connection is otherwise
* insecure.
*/
const PRUint32 LEVEL_PW_ENCRYPTED = 1;
/**
* The connection, both for password and data, is secure.
*/
const PRUint32 LEVEL_SECURE = 2;
/* @} */
/**
* Requests a username and a password. Implementations will commonly show a
* dialog with a username and password field, depending on flags also a
* domain field.
*
* @param aChannel
* The channel that requires authentication.
* @param level
* One of the level constants from above. See there for descriptions
* of the levels.
* @param authInfo
* Authentication information object. The implementation should fill in
* this object with the information entered by the user before
* returning.
*
* @retval true
* Authentication can proceed using the values in the authInfo
* object.
* @retval false
* Authentication should be cancelled, usually because the user did
* not provide username/password.
*
* @note Exceptions thrown from this function will be treated like a
* return value of false.
*/
boolean promptAuth(in nsIChannel aChannel,
in PRUint32 level,
in nsIAuthInformation authInfo);
/**
* Asynchronously prompt the user for a username and password.
* This has largely the same semantics as promptUsernameAndPassword(),
* but must return immediately after calling and return the entered
* data in a callback.
*
* If the user closes the dialog using a cancel button or similar,
* the callback's nsIAuthPromptCallback::onAuthCancelled method must be
* called.
* Calling nsICancelable::cancel on the returned object SHOULD close the
* dialog and MUST call nsIAuthPromptCallback::onAuthCancelled on the provided
* callback.
*
* @throw NS_ERROR_NOT_IMPLEMENTED
* Asynchronous authentication prompts are not supported;
* the caller should fall back to promptUsernameAndPassword().
*/
nsICancelable asyncPromptAuth(in nsIChannel aChannel,
in nsIAuthPromptCallback aCallback,
in nsISupports aContext,
in PRUint32 level,
in nsIAuthInformation authInfo);
};

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

@ -0,0 +1,55 @@
/* ***** 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 Necko code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@web.de> (Original Author)
*
* 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;
interface nsIAuthPrompt2;
/**
* An interface for wrapping nsIAuthPrompt interfaces to make
* them usable via an nsIAuthPrompt2 interface.
*/
[scriptable, uuid(60e46383-bb9a-4860-8962-80d9c5c05ddc)]
interface nsIAuthPromptAdapterFactory : nsISupports
{
/**
* Wrap an object implementing nsIAuthPrompt so that it's usable via
* nsIAuthPrompt2.
*/
nsIAuthPrompt2 createAdapter(in nsIAuthPrompt aPrompt);
};

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

@ -0,0 +1,77 @@
/* ***** 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 Necko code.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Google Inc.
*
* 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 nsIAuthInformation;
/**
* Interface for callback methods for the asynchronous nsIAuthPrompt2 method.
* Callers MUST call exactly one method if nsIAuthPrompt2::promptPasswordAsync
* returns successfully. They MUST NOT call any method on this interface before
* promptPasswordAsync returns.
*/
[scriptable, uuid(bdc387d7-2d29-4cac-92f1-dd75d786631d)]
interface nsIAuthPromptCallback : nsISupports
{
/**
* Authentication information is available.
*
* @param aContext
* The context as passed to promptPasswordAsync
* @param aAuthInfo
* Authentication information. Must be the same object that was passed
* to promptPasswordAsync.
*
* @note Any exceptions thrown from this method should be ignored.
*/
void onAuthAvailable(in nsISupports aContext,
in nsIAuthInformation aAuthInfo);
/**
* Notification that the prompt was cancelled.
*
* @param aContext
* The context that was passed to promptPasswordAsync.
* @param userCancel
* If false, this prompt was cancelled by calling the
* the cancel method on the nsICancelable; otherwise,
* it was cancelled by the user.
*/
void onAuthCancelled(in nsISupports aContext, in boolean userCancel);
};

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

@ -37,9 +37,7 @@
#include "nsISupports.idl"
interface nsIAuthPrompt;
[scriptable, uuid(129d3bd5-8a26-4b0b-b8a0-19fdea029196)]
[scriptable, uuid(bd9dc0fa-68ce-47d0-8859-6418c2ae8576)]
interface nsIAuthPromptProvider : nsISupports
{
/**
@ -53,13 +51,16 @@ interface nsIAuthPromptProvider : nsISupports
const PRUint32 PROMPT_PROXY = 1;
/**
* Request a nsIAuthPrompt interface for the given prompt reason;
* Request a prompt 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
* one of #PROMPT_NORMAL or #PROMPT_PROXY
* @param iid The desired interface, e.g.
* NS_GET_IID(nsIAuthPrompt2).
* @returns an nsIAuthPrompt2 interface, or throws NS_ERROR_NOT_AVAILABLE
*/
nsIAuthPrompt getAuthPrompt(in PRUint32 aPromptReason);
void getAuthPrompt(in PRUint32 aPromptReason, in nsIIDRef iid,
[iid_is(iid),retval] out nsQIResult result);
};

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

@ -85,6 +85,9 @@
#include "nsInterfaceRequestorAgg.h"
#include "nsInt64.h"
#include "nsINetUtil.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
#include "nsIAuthPromptAdapterFactory.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsINestedURI.h"
@ -289,6 +292,46 @@ NS_MakeAbsoluteURI(nsAString &result,
return rv;
}
/**
* This function is a helper function to get a protocol's default port if the
* URI does not specify a port explicitly. Returns -1 if this protocol has no
* concept of ports or if there was an error getting the port.
*/
inline PRInt32
NS_GetRealPort(nsIURI* aURI,
nsIIOService* ioService = nsnull) // pass in nsIIOService to optimize callers
{
PRInt32 port;
nsresult rv = aURI->GetPort(&port);
if (NS_FAILED(rv))
return -1;
if (port != -1)
return port; // explicitly specified
// Otherwise, we have to get the default port from the protocol handler
// Need the scheme first
nsCAutoString scheme;
rv = aURI->GetScheme(scheme);
if (NS_FAILED(rv))
return -1;
nsCOMPtr<nsIIOService> grip;
rv = net_EnsureIOService(&ioService, grip);
if (!ioService)
return -1;
nsCOMPtr<nsIProtocolHandler> handler;
rv = ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
if (NS_FAILED(rv))
return -1;
NS_ASSERTION(handler, "IO Service lied");
rv = handler->GetDefaultPort(&port);
return NS_SUCCEEDED(rv) ? port : -1;
}
inline nsresult
NS_NewInputStreamChannel(nsIChannel **result,
nsIURI *uri,
@ -983,6 +1026,78 @@ NS_QueryNotificationCallbacks(nsIInterfaceRequestor *callbacks,
}
}
/**
* Wraps an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2. This
* method is provided mainly for use by other methods in this file.
*
* *aAuthPrompt2 should be set to null before calling this function.
*/
inline void
NS_WrapAuthPrompt(nsIAuthPrompt *aAuthPrompt, nsIAuthPrompt2** aAuthPrompt2)
{
nsCOMPtr<nsIAuthPromptAdapterFactory> factory =
do_GetService(NS_AUTHPROMPT_ADAPTER_FACTORY_CONTRACTID);
if (!factory)
return;
NS_WARNING("Using deprecated nsIAuthPrompt");
factory->CreateAdapter(aAuthPrompt, aAuthPrompt2);
}
/**
* Gets an auth prompt from an interface requestor. This takes care of wrapping
* an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2.
*/
inline void
NS_QueryAuthPrompt2(nsIInterfaceRequestor *aCallbacks,
nsIAuthPrompt2 **aAuthPrompt)
{
CallGetInterface(aCallbacks, aAuthPrompt);
if (*aAuthPrompt)
return;
// Maybe only nsIAuthPrompt is provided and we have to wrap it.
nsCOMPtr<nsIAuthPrompt> prompt(do_GetInterface(aCallbacks));
if (!prompt)
return;
NS_WrapAuthPrompt(prompt, aAuthPrompt);
}
/**
* Gets an nsIAuthPrompt2 from a channel. Use this instead of
* NS_QueryNotificationCallbacks for better backwards compatibility.
*/
inline void
NS_QueryAuthPrompt2(nsIChannel *aChannel,
nsIAuthPrompt2 **aAuthPrompt)
{
*aAuthPrompt = nsnull;
// We want to use any auth prompt we can find on the channel's callbacks,
// and if that fails use the loadgroup's prompt (if any)
// Therefore, we can't just use NS_QueryNotificationCallbacks, because
// that would prefer a loadgroup's nsIAuthPrompt2 over a channel's
// nsIAuthPrompt.
nsCOMPtr<nsIInterfaceRequestor> callbacks;
aChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks) {
NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
if (*aAuthPrompt)
return;
}
nsCOMPtr<nsILoadGroup> group;
aChannel->GetLoadGroup(getter_AddRefs(group));
if (!group)
return;
group->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (!callbacks)
return;
NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
}
/* template helper */
template <class T> inline void
NS_QueryNotificationCallbacks(nsIInterfaceRequestor *callbacks,

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

@ -796,6 +796,8 @@
/**
* This contract ID will be gotten as a service and gets the opportunity to look
* at and veto all redirects that are processed by necko.
*
* Must implement nsIChannelEventSink
*/
#define NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID \
"@mozilla.org/netwerk/global-channel-event-sink;1"
@ -803,10 +805,22 @@
/**
* This contract ID will be gotten as a service implementing nsINetworkLinkService
* and monitored by IOService for automatic online/offline management.
*
* Must implement nsINetworkLinkService
*/
#define NS_NETWORK_LINK_SERVICE_CONTRACTID \
"@mozilla.org/network/network-link-service;1"
/**
* This contract ID is used when Necko needs to wrap an nsIAuthPrompt as
* nsIAuthPrompt2. Implementing it is required for backwards compatibility
* with Versions before 1.9.
*
* Must implement nsIAuthPromptAdapterFactory
*/
#define NS_AUTHPROMPT_ADAPTER_FACTORY_CONTRACTID \
"@mozilla.org/network/authprompt-adapter-factory;1"
/******************************************************************************
* Categories
*/

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

@ -23,6 +23,7 @@
* Contributor(s):
* Darin Fisher <darin@meer.net> (original author)
* Christian Biesinger <cbiesinger@web.de>
* Google Inc.
*
* 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
@ -46,7 +47,8 @@
#include "nsHttpResponseHead.h"
#include "nsHttp.h"
#include "nsIHttpAuthenticator.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthInformation.h"
#include "nsIAuthPrompt2.h"
#include "nsIAuthPromptProvider.h"
#include "nsIStringBundle.h"
#include "nsXPCOM.h"
@ -2117,7 +2119,7 @@ SetIdent(nsHttpAuthIdentity &ident,
// helper function for getting an auth prompt from an interface requestor
static void
GetAuthPrompt(nsIInterfaceRequestor *ifreq, PRBool proxyAuth,
nsIAuthPrompt **result)
nsIAuthPrompt2 **result)
{
if (!ifreq)
return;
@ -2130,9 +2132,11 @@ GetAuthPrompt(nsIInterfaceRequestor *ifreq, PRBool proxyAuth,
nsCOMPtr<nsIAuthPromptProvider> promptProvider = do_GetInterface(ifreq);
if (promptProvider)
promptProvider->GetAuthPrompt(promptReason, result);
promptProvider->GetAuthPrompt(promptReason,
NS_GET_IID(nsIAuthPrompt2),
NS_REINTERPRET_CAST(void**, result));
else
CallGetInterface(ifreq, result);
NS_QueryAuthPrompt2(ifreq, result);
}
// generate credentials for the given challenge, and update the auth cache.
@ -2655,6 +2659,101 @@ nsHttpChannel::ParseRealm(const char *challenge, nsACString &realm)
}
}
class nsAuthInformationHolder : public nsIAuthInformation {
public:
// aAuthType must be ASCII
nsAuthInformationHolder(PRUint32 aFlags, const nsString& aRealm,
const nsCString& aAuthType)
: mFlags(aFlags), mRealm(aRealm), mAuthType(aAuthType) {}
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHINFORMATION
void SetToHttpAuthIdentity(PRUint32 authFlags, nsHttpAuthIdentity& identity);
private:
nsString mUser;
nsString mPassword;
nsString mDomain;
PRUint32 mFlags;
nsString mRealm;
nsCString mAuthType;
};
NS_IMPL_ISUPPORTS1(nsAuthInformationHolder, nsIAuthInformation)
NS_IMETHODIMP
nsAuthInformationHolder::GetFlags(PRUint32* aFlags)
{
*aFlags = mFlags;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::GetRealm(nsAString& aRealm)
{
aRealm = mRealm;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::GetAuthenticationScheme(nsACString& aScheme)
{
aScheme = mAuthType;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::GetUsername(nsAString& aUserName)
{
aUserName = mUser;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::SetUsername(const nsAString& aUserName)
{
if (!(mFlags & ONLY_PASSWORD))
mUser = aUserName;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::GetPassword(nsAString& aPassword)
{
aPassword = mPassword;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::SetPassword(const nsAString& aPassword)
{
mPassword = aPassword;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::GetDomain(nsAString& aDomain)
{
aDomain = mDomain;
return NS_OK;
}
NS_IMETHODIMP
nsAuthInformationHolder::SetDomain(const nsAString& aDomain)
{
if (mFlags & NEED_DOMAIN)
mDomain = aDomain;
return NS_OK;
}
void
nsAuthInformationHolder::SetToHttpAuthIdentity(PRUint32 authFlags, nsHttpAuthIdentity& identity)
{
SetIdent(identity, authFlags, ToNewUnicode(mUser), ToNewUnicode(mPassword));
identity.Set(mDomain.get(), mUser.get(), mPassword.get());
}
nsresult
nsHttpChannel::PromptForIdentity(const char *scheme,
const char *host,
@ -2667,11 +2766,7 @@ nsHttpChannel::PromptForIdentity(const char *scheme,
{
LOG(("nsHttpChannel::PromptForIdentity [this=%x]\n", this));
// XXX authType should be included in the prompt
// XXX i18n: IDN not supported.
nsCOMPtr<nsIAuthPrompt> authPrompt;
nsCOMPtr<nsIAuthPrompt2> authPrompt;
GetAuthPrompt(mCallbacks, proxyAuth, getter_AddRefs(authPrompt));
if (!authPrompt && mLoadGroup) {
nsCOMPtr<nsIInterfaceRequestor> cbs;
@ -2684,93 +2779,38 @@ nsHttpChannel::PromptForIdentity(const char *scheme,
// XXX i18n: need to support non-ASCII realm strings (see bug 41489)
NS_ConvertASCIItoUTF16 realmU(realm);
//
// construct the single signon key
//
// we always add the port to domain since it is used as the key for storing
// in password maanger. THE FORMAT OF THIS KEY IS SACROSANCT!! do not
// even think about changing the format of this key.
//
// XXX we need to prefix this with "scheme://" at some point. however, that
// has to be done very carefully and probably with some cooperation from the
// password manager to ensure that passwords remembered under the old key
// format are not lost.
//
nsAutoString key;
CopyASCIItoUTF16(host, key); // XXX IDN?
key.Append(PRUnichar(':'));
key.AppendInt(port);
key.AppendLiteral(" (");
key.Append(realmU);
key.Append(PRUnichar(')'));
nsresult rv;
// construct the message string
nsCOMPtr<nsIStringBundleService> bundleSvc =
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleSvc->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(bundle));
if (NS_FAILED(rv)) return rv;
// figure out what message to display...
nsAutoString displayHost;
CopyASCIItoUTF16(host, displayHost); // XXX IDN?
// If not proxy auth then add port only if it was originally specified
// in the URI.
PRInt32 uriPort = -1;
if (proxyAuth || (NS_SUCCEEDED(mURI->GetPort(&uriPort)) && uriPort != -1)) {
displayHost.Append(PRUnichar(':'));
displayHost.AppendInt(port);
}
nsXPIDLString message;
{
NS_NAMED_LITERAL_STRING(proxyText, "EnterUserPasswordForProxy");
NS_NAMED_LITERAL_STRING(originText, "EnterUserPasswordForRealm");
const PRUnichar *text;
if (proxyAuth) {
text = proxyText.get();
} else {
text = originText.get();
// prepend "scheme://"
nsAutoString schemeU;
CopyASCIItoUTF16(scheme, schemeU);
schemeU.AppendLiteral("://");
displayHost.Insert(schemeU, 0);
}
const PRUnichar *strings[] = { realmU.get(), displayHost.get() };
rv = bundle->FormatStringFromName(text, strings, 2,
getter_Copies(message));
}
if (NS_FAILED(rv)) return rv;
// prompt the user...
PRUint32 promptFlags = 0;
if (proxyAuth)
promptFlags |= nsIAuthInformation::AUTH_PROXY;
else
promptFlags |= nsIAuthInformation::AUTH_HOST;
if (authFlags & nsIHttpAuthenticator::IDENTITY_INCLUDES_DOMAIN)
promptFlags |= nsIAuthInformation::NEED_DOMAIN;
nsRefPtr<nsAuthInformationHolder> holder =
new nsAuthInformationHolder(promptFlags, realmU, nsDependentCString(authType));
if (!holder)
return NS_ERROR_OUT_OF_MEMORY;
PRBool retval = PR_FALSE;
PRUnichar *user = nsnull, *pass = nsnull;
rv = authPrompt->PromptUsernameAndPassword(nsnull, message.get(),
key.get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
&user, &pass, &retval);
if (NS_FAILED(rv)) return rv;
rv = authPrompt->PromptAuth(this,
nsIAuthPrompt2::LEVEL_NONE,
holder, &retval);
if (NS_FAILED(rv))
return rv;
// remember that we successfully showed the user an auth dialog
if (!proxyAuth)
mSuppressDefensiveAuth = PR_TRUE;
if (!retval || !user || !pass)
if (!retval)
rv = NS_ERROR_ABORT;
else
SetIdent(ident, authFlags, user, pass);
holder->SetToHttpAuthIdentity(authFlags, ident);
if (user) nsMemory::Free(user);
if (pass) nsMemory::Free(pass);
return rv;
}

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

@ -83,6 +83,16 @@ nsTestServ.prototype =
// fall through to failure response
}
stream.write(failedResponse, failedResponse.length);
},
"/auth/ntlm/simple": function(stream) {
var response = this.headers("401 Unauthorized") +
"WWW-Authenticate: NTLM\r\n" + // realm=\"secret\"\r\n" +
"\r\n" +
"NOTE: This just sends an NTLM challenge, it never\n" +
"accepts the authentication. It also closes\n" +
"the connection after sending the challenge\n";
stream.write(response, response.length);
}
},

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

@ -3,6 +3,9 @@
const FLAG_RETURN_FALSE = 1 << 0;
const FLAG_WRONG_PASSWORD = 1 << 1;
const nsIAuthPrompt2 = Components.interfaces.nsIAuthPrompt2;
const nsIAuthInformation = Components.interfaces.nsIAuthInformation;
function AuthPrompt1(flags) {
this.flags = flags;
}
@ -58,10 +61,81 @@ AuthPrompt1.prototype = {
};
function Requestor(flags) {
function AuthPrompt2(flags) {
this.flags = flags;
}
AuthPrompt2.prototype = {
user: "guest",
pass: "guest",
expectedRealm: "secret",
QueryInterface: function authprompt2_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIAuthPrompt2))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
promptAuth:
function ap2_promptAuth(channel, level, authInfo)
{
var isNTLM = channel.URI.path.indexOf("ntlm") != -1;
if (isNTLM)
this.expectedRealm = ""; // NTLM knows no realms
do_check_eq(this.expectedRealm, authInfo.realm);
// This would be nice but isn't currently implemented,
// so we can't test it
// var expectedLevel = isNTLM ?
// nsIAuthPrompt2.LEVEL_PW_ENCRYPTED :
// nsIAuthPrompt2.LEVEL_NONE;
var expectedLevel = nsIAuthPrompt2.LEVEL_NONE;
do_check_eq(expectedLevel, level);
var expectedFlags = nsIAuthInformation.AUTH_HOST;
if (isNTLM)
expectedFlags |= nsIAuthInformation.NEED_DOMAIN;
do_check_eq(expectedFlags, authInfo.flags);
var expectedScheme = isNTLM ? "ntlm" : "basic";
do_check_eq(expectedScheme, authInfo.authenticationScheme);
// No passwords in the URL -> nothing should be prefilled
do_check_eq(authInfo.username, "");
do_check_eq(authInfo.password, "");
do_check_eq(authInfo.domain, "");
if (this.flags & FLAG_RETURN_FALSE)
return false;
authInfo.username = this.user;
if (this.flags & FLAG_WRONG_PASSWORD) {
authInfo.password = this.pass + ".wrong";
// Now clear the flag to avoid an infinite loop
this.flags &= ~FLAG_WRONG_PASSWORD;
} else {
authInfo.password = this.pass;
}
return true;
},
asyncPromptAuth: function ap2_async(chan, cb, ctx, lvl, info) {
do_throw("not implemented yet")
}
};
function Requestor(flags, versions) {
this.flags = flags;
this.versions = versions;
}
Requestor.prototype = {
QueryInterface: function requestor_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
@ -71,16 +145,26 @@ Requestor.prototype = {
},
getInterface: function requestor_gi(iid) {
if (iid.equals(Components.interfaces.nsIAuthPrompt)) {
if (this.versions & 1 &&
iid.equals(Components.interfaces.nsIAuthPrompt)) {
// Allow the prompt to store state by caching it here
if (!this.prompt1)
this.prompt1 = new AuthPrompt1(this.flags);
return this.prompt1;
}
if (this.versions & 2 &&
iid.equals(Components.interfaces.nsIAuthPrompt2)) {
// Allow the prompt to store state by caching it here
if (!this.prompt2)
this.prompt2 = new AuthPrompt2(this.flags);
return this.prompt2;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
prompt1: null
prompt1: null,
prompt2: null
};
var listener = {
@ -137,7 +221,8 @@ function makeChan(url) {
return chan;
}
var tests = [test_noauth, test_returnfalse1, test_wrongpw1, test_prompt1];
var tests = [test_noauth, test_returnfalse1, test_wrongpw1, test_prompt1,
test_returnfalse2, test_wrongpw2, test_prompt2, test_ntlm];
var current_test = 0;
var httpserv = null;
@ -159,7 +244,7 @@ function test_noauth() {
function test_returnfalse1() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE);
chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 1);
listener.expectedCode = 401; // Unauthorized
chan.asyncOpen(listener, null);
@ -169,7 +254,7 @@ function test_returnfalse1() {
function test_wrongpw1() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD);
chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD, 1);
listener.expectedCode = 200; // OK
chan.asyncOpen(listener, null);
@ -179,10 +264,50 @@ function test_wrongpw1() {
function test_prompt1() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(0);
chan.notificationCallbacks = new Requestor(0, 1);
listener.expectedCode = 200; // OK
chan.asyncOpen(listener, null);
do_test_pending();
}
function test_returnfalse2() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2);
listener.expectedCode = 401; // Unauthorized
chan.asyncOpen(listener, null);
do_test_pending();
}
function test_wrongpw2() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD, 2);
listener.expectedCode = 200; // OK
chan.asyncOpen(listener, null);
do_test_pending();
}
function test_prompt2() {
var chan = makeChan("http://localhost:4444/auth");
chan.notificationCallbacks = new Requestor(0, 2);
listener.expectedCode = 200; // OK
chan.asyncOpen(listener, null);
do_test_pending();
}
function test_ntlm() {
var chan = makeChan("http://localhost:4444/auth/ntlm/simple");
chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2);
listener.expectedCode = 401; // Unauthorized
chan.asyncOpen(listener, null);
do_test_pending();
}

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

@ -0,0 +1,181 @@
// NOTE: This tests code outside of Necko. The test still lives here because
// the contract is part of Necko.
const nsIAuthInformation = Components.interfaces.nsIAuthInformation;
const nsIAuthPromptAdapterFactory = Components.interfaces.nsIAuthPromptAdapterFactory;
function run_test() {
const contractID = "@mozilla.org/network/authprompt-adapter-factory;1";
if (!(contractID in Components.classes)) {
print("No adapter factory found, skipping testing");
return;
}
var adapter = Components.classes[contractID].getService();
do_check_eq(adapter instanceof nsIAuthPromptAdapterFactory, true);
// NOTE: xpconnect lets us get away with passing an empty object here
// For this part of the test, we only care that this function returns
// success
do_check_neq(adapter.createAdapter({}), null);
const host = "www.mozilla.org";
var info = {
username: "",
password: "",
domain: "",
flags: nsIAuthInformation.AUTH_HOST,
authenticationScheme: "basic",
realm: "secretrealm"
};
const CALLED_PROMPT = 1 << 0;
const CALLED_PROMPTUP = 1 << 1;
const CALLED_PROMPTP = 1 << 2;
function Prompt1() {}
Prompt1.prototype = {
called: 0,
rv: true,
user: "foo\\bar",
pw: "bar",
QueryInterface: function authprompt_qi(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIAuthPrompt))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
prompt: function ap1_prompt(title, text, realm, save, defaultText, result) {
this.called |= CALLED_PROMPT;
this.doChecks(text, realm);
return this.rv;
},
promptUsernameAndPassword:
function ap1_promptUP(title, text, realm, savePW, user, pw)
{
this.called |= CALLED_PROMPTUP;
this.doChecks(text, realm);
user.value = this.user;
pw.value = this.pw;
return this.rv;
},
promptPassword: function ap1_promptPW(title, text, realm, save, pwd) {
this.called |= CALLED_PROMPTP;
this.doChecks(text, realm);
pwd.value = this.pw;
return this.rv;
},
doChecks: function ap1_check(text, realm) {
do_check_eq(host + ":80 (" + info.realm + ")", realm);
do_check_neq(text.indexOf(host), -1);
do_check_neq(text.indexOf(info.realm), -1);
// No explicit port in the URL; message should not contain -1
// for those cases
do_check_eq(text.indexOf("-1"), -1);
}
};
var prompt1 = new Prompt1();
var wrapper = adapter.createAdapter(prompt1);
// Also have to make up a channel
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var chan = ios.newChannel("http://" + host, "", null);
function do_tests(expectedRV) {
// 1: The simple case
prompt1.rv = expectedRV;
var rv = wrapper.promptAuth(chan, 0, info);
do_check_eq(rv, prompt1.rv);
do_check_eq(prompt1.called, CALLED_PROMPTUP);
if (rv) {
do_check_eq(info.domain, "");
do_check_eq(info.username, prompt1.user);
do_check_eq(info.password, prompt1.pw);
}
info.domain = "";
info.username = "";
info.password = "";
// 2: Only ask for a PW
prompt1 = new Prompt1();
prompt1.rv = expectedRV;
info.flags |= nsIAuthInformation.ONLY_PASSWORD;
wrapper = adapter.createAdapter(prompt1);
rv = wrapper.promptAuth(chan, 0, info);
do_check_eq(rv, prompt1.rv);
do_check_eq(prompt1.called, CALLED_PROMPTP);
if (rv) {
do_check_eq(info.domain, "");
do_check_eq(info.username, "");
do_check_eq(info.password, prompt1.pw);
}
info.flags &= ~nsIAuthInformation.ONLY_PASSWORD;
info.domain = "";
info.username = "";
info.password = "";
// 3: user, pw and domain
prompt1 = new Prompt1();
prompt1.rv = expectedRV;
info.flags |= nsIAuthInformation.NEED_DOMAIN;
wrapper = adapter.createAdapter(prompt1);
rv = wrapper.promptAuth(chan, 0, info);
do_check_eq(rv, prompt1.rv);
do_check_eq(prompt1.called, CALLED_PROMPTUP);
if (rv) {
do_check_eq(info.domain, "foo");
do_check_eq(info.username, "bar");
do_check_eq(info.password, prompt1.pw);
}
info.flags &= ~nsIAuthInformation.ONLY_PASSWORD;
info.domain = "";
info.username = "";
info.password = "";
// 4: username that doesn't contain a domain
prompt1 = new Prompt1();
prompt1.rv = expectedRV;
info.flags |= nsIAuthInformation.NEED_DOMAIN;
prompt1.user = "foo";
wrapper = adapter.createAdapter(prompt1);
rv = wrapper.promptAuth(chan, 0, info);
do_check_eq(rv, prompt1.rv);
do_check_eq(prompt1.called, CALLED_PROMPTUP);
if (rv) {
do_check_eq(info.domain, "");
do_check_eq(info.username, prompt1.user);
do_check_eq(info.password, prompt1.pw);
}
info.flags &= ~nsIAuthInformation.ONLY_PASSWORD;
info.domain = "";
info.username = "";
info.password = "";
}
do_tests(true);
do_tests(false);
}

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

@ -37,6 +37,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsPasswordManager.h"
#include "nsSingleSignonPrompt.h"
#include "nsIFile.h"
#include "nsNetUtil.h"
#include "nsILineInputStream.h"
@ -44,6 +45,7 @@
#include "nsISecretDecoderRing.h"
#include "nsIPasswordInternal.h"
#include "nsIPrompt.h"
#include "nsIPromptService2.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranch2.h"
@ -72,6 +74,7 @@
#include "nsIPK11Token.h"
#include "nsUnicharUtils.h"
#include "nsCOMArray.h"
#include "nsEmbedCID.h"
static const char kPMPropertiesURL[] = "chrome://passwordmgr/locale/passwordmgr.properties";
static PRBool sRememberPasswords = PR_FALSE;
@ -209,6 +212,7 @@ NS_INTERFACE_MAP_BEGIN(nsPasswordManager)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMFocusListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPasswordManager)
NS_INTERFACE_MAP_ENTRY(nsIPromptFactory)
NS_INTERFACE_MAP_END
nsPasswordManager::nsPasswordManager()
@ -1226,6 +1230,35 @@ nsPasswordManager::HandleEvent(nsIDOMEvent* aEvent)
return NS_OK;
}
// nsIPromptFactory implementation
NS_IMETHODIMP
nsPasswordManager::GetPrompt(nsIDOMWindow* aParent, const nsIID& aIID,
void** _retval)
{
if (!aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
NS_WARNING("asked for unknown IID");
return NS_NOINTERFACE;
}
// NOTE: It is important to return the specific return value here. The
// caller cares.
nsresult rv;
nsCOMPtr<nsIPromptService2> service =
do_GetService(NS_PROMPTSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
nsSingleSignonPrompt2* wrapper = new nsSingleSignonPrompt2(service, aParent);
if (!wrapper)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(wrapper);
*_retval = NS_STATIC_CAST(nsIAuthPrompt2*, wrapper);
return NS_OK;
}
// Autocomplete implementation
class UserAutoComplete : public nsIAutoCompleteResult

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

@ -47,6 +47,7 @@
#include "nsIDOMFocusListener.h"
#include "nsIStringBundle.h"
#include "nsIPrefBranch.h"
#include "nsIPromptFactory.h"
/* 360565c4-2ef3-4f6a-bab9-94cca891b2a7 */
#define NS_PASSWORDMANAGER_CID \
@ -68,6 +69,7 @@ class nsPasswordManager : public nsIPasswordManager,
public nsIFormSubmitObserver,
public nsIWebProgressListener,
public nsIDOMFocusListener,
public nsIPromptFactory,
public nsSupportsWeakReference
{
public:
@ -114,6 +116,7 @@ public:
NS_DECL_NSIPASSWORDMANAGERINTERNAL
NS_DECL_NSIOBSERVER
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIPROMPTFACTORY
// nsIFormSubmitObserver
NS_IMETHOD Notify(nsIContent* aFormNode,

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

@ -1,270 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Password Manager.
*
* The Initial Developer of the Original Code is
* Brian Ryner.
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* 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 "nsSingleSignonPrompt.h"
#include "nsPasswordManager.h"
#include "nsIServiceManager.h"
NS_IMPL_ISUPPORTS2(nsSingleSignonPrompt,
nsIAuthPromptWrapper,
nsIAuthPrompt)
// nsIAuthPrompt
NS_IMETHODIMP
nsSingleSignonPrompt::Prompt(const PRUnichar* aDialogTitle,
const PRUnichar* aText,
const PRUnichar* aPasswordRealm,
PRUint32 aSavePassword,
const PRUnichar* aDefaultText,
PRUnichar** aResult,
PRBool* aConfirm)
{
nsAutoString checkMsg;
nsString emptyString;
PRBool checkValue = PR_FALSE;
PRBool *checkPtr = nsnull;
PRUnichar* value = nsnull;
nsCOMPtr<nsIPasswordManagerInternal> mgrInternal;
if (nsPasswordManager::SingleSignonEnabled() && aPasswordRealm) {
if (aSavePassword == SAVE_PASSWORD_PERMANENTLY) {
nsPasswordManager::GetLocalizedString(NS_LITERAL_STRING("rememberValue"),
checkMsg);
checkPtr = &checkValue;
}
mgrInternal = do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
nsCAutoString outHost;
nsAutoString outUser, outPassword;
mgrInternal->FindPasswordEntry(NS_ConvertUTF16toUTF8(aPasswordRealm),
emptyString,
emptyString,
outHost,
outUser,
outPassword);
if (!outUser.IsEmpty()) {
value = ToNewUnicode(outUser);
checkValue = PR_TRUE;
}
}
if (!value && aDefaultText)
value = ToNewUnicode(nsDependentString(aDefaultText));
mPrompt->Prompt(aDialogTitle,
aText,
&value,
checkMsg.get(),
checkPtr,
aConfirm);
if (*aConfirm) {
if (checkValue && value && value[0] != '\0') {
// The user requested that we save the value
// TODO: support SAVE_PASSWORD_FOR_SESSION
nsCOMPtr<nsIPasswordManager> manager = do_QueryInterface(mgrInternal);
manager->AddUser(NS_ConvertUTF16toUTF8(aPasswordRealm),
nsDependentString(value),
emptyString);
}
*aResult = value;
} else {
if (value)
nsMemory::Free(value);
*aResult = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsSingleSignonPrompt::PromptUsernameAndPassword(const PRUnichar* aDialogTitle,
const PRUnichar* aText,
const PRUnichar* aPasswordRealm,
PRUint32 aSavePassword,
PRUnichar** aUser,
PRUnichar** aPassword,
PRBool* aConfirm)
{
nsAutoString checkMsg;
nsString emptyString;
PRBool checkValue = PR_FALSE;
PRBool *checkPtr = nsnull;
PRUnichar *user = nsnull, *password = nsnull;
nsCOMPtr<nsIPasswordManagerInternal> mgrInternal;
if (nsPasswordManager::SingleSignonEnabled() && aPasswordRealm) {
if (aSavePassword == SAVE_PASSWORD_PERMANENTLY) {
nsPasswordManager::GetLocalizedString(NS_LITERAL_STRING("rememberPassword"),
checkMsg);
checkPtr = &checkValue;
}
mgrInternal = do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
nsCAutoString outHost;
nsAutoString outUser, outPassword;
mgrInternal->FindPasswordEntry(NS_ConvertUTF16toUTF8(aPasswordRealm),
emptyString,
emptyString,
outHost,
outUser,
outPassword);
user = ToNewUnicode(outUser);
password = ToNewUnicode(outPassword);
if (!outUser.IsEmpty() || !outPassword.IsEmpty())
checkValue = PR_TRUE;
}
mPrompt->PromptUsernameAndPassword(aDialogTitle,
aText,
&user,
&password,
checkMsg.get(),
checkPtr,
aConfirm);
if (*aConfirm) {
if (checkValue && user && password && (user[0] != '\0' || password[0] != '\0')) {
// The user requested that we save the values
// TODO: support SAVE_PASSWORD_FOR_SESSION
nsCOMPtr<nsIPasswordManager> manager = do_QueryInterface(mgrInternal);
manager->AddUser(NS_ConvertUTF16toUTF8(aPasswordRealm),
nsDependentString(user),
nsDependentString(password));
}
*aUser = user;
*aPassword = password;
} else {
if (user)
nsMemory::Free(user);
if (password)
nsMemory::Free(password);
*aUser = *aPassword = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsSingleSignonPrompt::PromptPassword(const PRUnichar* aDialogTitle,
const PRUnichar* aText,
const PRUnichar* aPasswordRealm,
PRUint32 aSavePassword,
PRUnichar** aPassword,
PRBool* aConfirm)
{
nsAutoString checkMsg;
nsString emptyString;
PRBool checkValue = PR_FALSE;
PRBool *checkPtr = nsnull;
PRUnichar* password = nsnull;
nsCOMPtr<nsIPasswordManagerInternal> mgrInternal;
if (nsPasswordManager::SingleSignonEnabled() && aPasswordRealm) {
if (aSavePassword == SAVE_PASSWORD_PERMANENTLY) {
nsPasswordManager::GetLocalizedString(NS_LITERAL_STRING("rememberPassword"),
checkMsg);
checkPtr = &checkValue;
}
mgrInternal = do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
nsCAutoString outHost;
nsAutoString outUser, outPassword;
mgrInternal->FindPasswordEntry(NS_ConvertUTF16toUTF8(aPasswordRealm),
emptyString,
emptyString,
outHost,
outUser,
outPassword);
password = ToNewUnicode(outPassword);
if (!outPassword.IsEmpty())
checkValue = PR_TRUE;
}
mPrompt->PromptPassword(aDialogTitle,
aText,
&password,
checkMsg.get(),
checkPtr,
aConfirm);
if (*aConfirm) {
if (checkValue && password && password[0] != '\0') {
// The user requested that we save the password
// TODO: support SAVE_PASSWORD_FOR_SESSION
nsCOMPtr<nsIPasswordManager> manager = do_QueryInterface(mgrInternal);
manager->AddUser(NS_ConvertUTF16toUTF8(aPasswordRealm),
emptyString,
nsDependentString(password));
}
*aPassword = password;
} else {
if (password)
nsMemory::Free(password);
*aPassword = nsnull;
}
return NS_OK;
}
// nsIAuthPromptWrapper
NS_IMETHODIMP
nsSingleSignonPrompt::SetPromptDialogs(nsIPrompt* aDialogs)
{
mPrompt = aDialogs;
return NS_OK;
}

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

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Password Manager.
*
* The Initial Developer of the Original Code is
* Brian Ryner.
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Ryner <bryner@brianryner.com>
*
* 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 "nsIAuthPromptWrapper.h"
#include "nsCOMPtr.h"
#include "nsIPrompt.h"
/* 1baf3398-f759-4a72-a21f-0abdc9cc9960 */
#define NS_SINGLE_SIGNON_PROMPT_CID \
{0x1baf3398, 0xf759, 0x4a72, {0xa2, 0x1f, 0x0a, 0xbd, 0xc9, 0xcc, 0x99, 0x60}}
// Our wrapper for username/password prompts - this allows us to prefill
// the password dialog and add a "remember this password" checkbox.
class nsSingleSignonPrompt : public nsIAuthPromptWrapper
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPT
NS_DECL_NSIAUTHPROMPTWRAPPER
nsSingleSignonPrompt() { }
virtual ~nsSingleSignonPrompt() { }
protected:
void GetLocalizedString(const nsAString& aKey, nsAString& aResult);
nsCOMPtr<nsIPrompt> mPrompt;
};

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

@ -75,6 +75,7 @@
#include "nsIDOMMouseEvent.h"
#include "nsIGenericFactory.h"
#include "nsToolkitCompsCID.h"
#include "nsEmbedCID.h"
NS_INTERFACE_MAP_BEGIN(nsFormFillController)
NS_INTERFACE_MAP_ENTRY(nsIFormFillController)
@ -1150,6 +1151,13 @@ static const nsModuleComponentInfo components[] =
nsPasswordManager::Register,
nsPasswordManager::Unregister },
{ "Password Manager",
NS_PASSWORDMANAGER_CID,
NS_PWMGR_AUTHPROMPTFACTORY,
nsPasswordManagerConstructor,
nsPasswordManager::Register,
nsPasswordManager::Unregister },
{ "Single Signon Prompt",
NS_SINGLE_SIGNON_PROMPT_CID,
"@mozilla.org/wallet/single-sign-on-prompt;1",