diff --git a/extensions/negotiateauth/Makefile.in b/extensions/negotiateauth/Makefile.in deleted file mode 100644 index 4b4330b22f7d..000000000000 --- a/extensions/negotiateauth/Makefile.in +++ /dev/null @@ -1,91 +0,0 @@ -# vim:set ts=8 sw=8 sts=8 noet: -# ***** 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 negotiateauth. -# -# The Initial Developer of the Original Code is -# Daniel Kouril -# -# Portions created by the Initial Developer are Copyright (C) 2003 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Daniel Kouril (original author) -# Wyllys Ingersoll -# Christopher Nebergall -# Darin Fisher -# -# 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 ***** - -DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -#undef USE_SSPI -GSSAPI_INCLUDES = -Ic:\inc\krb5\gssapi -include $(DEPTH)/config/autoconf.mk - -USE_GSSAPI = 1 -MOZILLA_INTERNAL_API = 1 - -MODULE = negotiateauth -LIBRARY_NAME = negotiateauth -IS_COMPONENT = 1 -EXPORT_LIBRARY = 1 -MODULE_NAME = nsNegotiateAuthModule - -REQUIRES = \ - xpcom \ - string \ - necko \ - pref \ - $(NULL) - -CPPSRCS = \ - nsNegotiateAuthFactory.cpp \ - nsHttpNegotiateAuth.cpp \ - $(NULL) - -EXTRA_DSO_LDOPTS = \ - $(MOZ_COMPONENT_LIBS) \ - $(NULL) - -LOCAL_INCLUDES += -Ic:/inc/krb5/gssapi - - -ifeq (1,$(USE_GSSAPI)) -LOCAL_INCLUDES += -Ic:\inc\krb5\gssapi -Ic:\inc\krb5 -LOCAL_INCLUDES += -DUSE_GSSAPI $(GSSAPI_INCLUDES) -CPPSRCS += nsNegotiateAuthGSSAPI.cpp -endif - -ifeq ($(OS_ARCH),WINNT) -#LOCAL_INCLUDES += -DUSE_SSPI -#CPPSRCS += nsNegotiateAuthSSPI.cpp -endif - -include $(topsrcdir)/config/rules.mk diff --git a/extensions/negotiateauth/nsHttpNegotiateAuth.cpp b/extensions/negotiateauth/nsHttpNegotiateAuth.cpp deleted file mode 100644 index 5e3d68af78dd..000000000000 --- a/extensions/negotiateauth/nsHttpNegotiateAuth.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* vim:set ts=4 sw=4 sts=4 et cindent: */ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is Daniel Kouril. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Daniel Kouril (original author) - * Wyllys Ingersoll - * Christopher Nebergall - * Darin Fisher - * - * 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 ***** */ - -// -// HTTP Negotiate Authentication Support Module -// -// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt -// (formerly draft-brezak-spnego-http-04.txt) -// -// Also described here: -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp -// - -#include -#include - -#include "nsNegotiateAuth.h" -#include "nsHttpNegotiateAuth.h" - -#include "nsIHttpChannel.h" -#include "nsIHttpChannelInternal.h" -#include "nsIAuthModule.h" -#include "nsIServiceManager.h" -#include "nsIPrefService.h" -#include "nsIPrefBranch.h" -#include "nsIProxyInfo.h" -#include "nsIURI.h" -#include "nsCOMPtr.h" -#include "nsString.h" -#include "nsNetCID.h" -#include "plbase64.h" -#include "plstr.h" -#include "prprf.h" -#include "prlog.h" -#include "prmem.h" - -//----------------------------------------------------------------------------- - -static const char kNegotiate[] = "Negotiate"; -static const char kNegotiateAuthTrustedURIs[] = "network.negotiate-auth.trusted-uris"; -static const char kNegotiateAuthDelegationURIs[] = "network.negotiate-auth.delegation-uris"; -static const char kNegotiateAuthAllowProxies[] = "network.negotiate-auth.allow-proxies"; - -#define kNegotiateLen (sizeof(kNegotiate)-1) - -//----------------------------------------------------------------------------- - -NS_IMETHODIMP -nsHttpNegotiateAuth::GetAuthFlags(PRUint32 *flags) -{ - // - // Negotiate Auth creds should not be reused across multiple requests. - // Only perform the negotiation when it is explicitly requested by the - // server. Thus, do *NOT* use the "REUSABLE_CREDENTIALS" flag here. - // - // CONNECTION_BASED is specified instead of REQUEST_BASED since we need - // to complete a sequence of transactions with the server over the same - // connection. - // - *flags = CONNECTION_BASED | IDENTITY_IGNORED; - return NS_OK; -} - -// -// Always set *identityInvalid == FALSE here. This -// will prevent the browser from popping up the authentication -// prompt window. Because GSSAPI does not have an API -// for fetching initial credentials (ex: A Kerberos TGT), -// there is no correct way to get the users credentials. -// -NS_IMETHODIMP -nsHttpNegotiateAuth::ChallengeReceived(nsIHttpChannel *httpChannel, - const char *challenge, - PRBool isProxyAuth, - nsISupports **sessionState, - nsISupports **continuationState, - PRBool *identityInvalid) -{ - nsIAuthModule *module = (nsIAuthModule *) *continuationState; - - *identityInvalid = PR_FALSE; - if (module) - return NS_OK; - - nsresult rv; - - nsCOMPtr uri; - rv = httpChannel->GetURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) - return rv; - - PRUint32 req_flags = nsIAuthModule::REQ_DEFAULT; - nsCAutoString service; - - if (isProxyAuth) { - if (!TestBoolPref(kNegotiateAuthAllowProxies)) { - LOG(("nsHttpNegotiateAuth::ChallengeReceived proxy auth blocked\n")); - return NS_ERROR_ABORT; - } - - nsCOMPtr httpInternal = - do_QueryInterface(httpChannel); - NS_ENSURE_STATE(httpInternal); - - nsCOMPtr proxyInfo; - httpInternal->GetProxyInfo(getter_AddRefs(proxyInfo)); - NS_ENSURE_STATE(proxyInfo); - - proxyInfo->GetHost(service); - } - else { - PRBool allowed = TestPref(uri, kNegotiateAuthTrustedURIs); - if (!allowed) { - LOG(("nsHttpNegotiateAuth::ChallengeReceived URI blocked\n")); - return NS_ERROR_ABORT; - } - - PRBool delegation = TestPref(uri, kNegotiateAuthDelegationURIs); - if (delegation) { - LOG((" using REQ_DELEGATE\n")); - req_flags |= nsIAuthModule::REQ_DELEGATE; - } - - rv = uri->GetAsciiHost(service); - if (NS_FAILED(rv)) - return rv; - } - - LOG((" service = %s\n", service.get())); - - // - // The correct service name for IIS servers is "HTTP/f.q.d.n", so - // construct the proper service name for passing to "gss_import_name". - // - // TODO: Possibly make this a configurable service name for use - // with non-standard servers that use stuff like "khttp/f.q.d.n" - // instead. - // - service.Insert("HTTP@", 0); - - rv = CallCreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate", &module); - if (NS_FAILED(rv)) - return rv; - - rv = module->Init(service.get(), req_flags, nsnull, nsnull, nsnull); - if (NS_FAILED(rv)) { - NS_RELEASE(module); - return rv; - } - - *continuationState = module; - return NS_OK; -} - -NS_IMPL_ISUPPORTS1(nsHttpNegotiateAuth, nsIHttpAuthenticator) - -// -// GenerateCredentials -// -// This routine is responsible for creating the correct authentication -// blob to pass to the server that requested "Negotiate" authentication. -// -NS_IMETHODIMP -nsHttpNegotiateAuth::GenerateCredentials(nsIHttpChannel *httpChannel, - const char *challenge, - PRBool isProxyAuth, - const PRUnichar *domain, - const PRUnichar *username, - const PRUnichar *password, - nsISupports **sessionState, - nsISupports **continuationState, - char **creds) -{ - // ChallengeReceived must have been called previously. - nsIAuthModule *module = (nsIAuthModule *) *continuationState; - NS_ENSURE_TRUE(module, NS_ERROR_NOT_INITIALIZED); - - LOG(("nsHttpNegotiateAuth::GenerateCredentials() [challenge=%s]\n", challenge)); - - NS_ASSERTION(creds, "null param"); - -#ifdef DEBUG - PRBool isGssapiAuth = - !PL_strncasecmp(challenge, kNegotiate, kNegotiateLen); - NS_ASSERTION(isGssapiAuth, "Unexpected challenge"); -#endif - - // - // If the "Negotiate:" header had some data associated with it, - // that data should be used as the input to this call. This may - // be a continuation of an earlier call because GSSAPI authentication - // often takes multiple round-trips to complete depending on the - // context flags given. We want to use MUTUAL_AUTHENTICATION which - // generally *does* require multiple round-trips. Don't assume - // auth can be completed in just 1 call. - // - unsigned int len = strlen(challenge); - - void *inToken, *outToken; - PRUint32 inTokenLen, outTokenLen; - - if (len > kNegotiateLen) { - challenge += kNegotiateLen; - while (*challenge == ' ') - challenge++; - len = strlen(challenge); - - inTokenLen = (len * 3)/4; - inToken = malloc(inTokenLen); - if (!inToken) - return (NS_ERROR_OUT_OF_MEMORY); - - // strip off any padding (see bug 230351) - while (challenge[len - 1] == '=') - len--; - - // - // Decode the response that followed the "Negotiate" token - // - if (PL_Base64Decode(challenge, len, (char *) inToken) == NULL) { - free(inToken); - return(NS_ERROR_UNEXPECTED); - } - } - else { - // - // Initializing, don't use an input token. - // - inToken = nsnull; - inTokenLen = 0; - } - - nsresult rv = module->GetNextToken(inToken, inTokenLen, &outToken, &outTokenLen); - - free(inToken); - - if (NS_FAILED(rv)) - return rv; - - if (outTokenLen == 0) { - LOG((" No output token to send, exiting")); - return NS_ERROR_FAILURE; - } - - // - // base64 encode the output token. - // - char *encoded_token = PL_Base64Encode((char *)outToken, outTokenLen, nsnull); - - nsMemory::Free(outToken); - - if (!encoded_token) - return NS_ERROR_OUT_OF_MEMORY; - - LOG((" Sending a token of length %d\n", outTokenLen)); - - // allocate a buffer sizeof("Negotiate" + " " + b64output_token + "\0") - *creds = (char *) nsMemory::Alloc(kNegotiateLen + 1 + strlen(encoded_token) + 1); - if (NS_UNLIKELY(!*creds)) - rv = NS_ERROR_OUT_OF_MEMORY; - else - sprintf(*creds, "%s %s", kNegotiate, encoded_token); - - PR_Free(encoded_token); - return rv; -} - -PRBool -nsHttpNegotiateAuth::TestBoolPref(const char *pref) -{ - nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); - if (!prefs) - return PR_FALSE; - - PRBool val; - nsresult rv = prefs->GetBoolPref(pref, &val); - if (NS_FAILED(rv)) - return PR_FALSE; - - return val; -} - -PRBool -nsHttpNegotiateAuth::TestPref(nsIURI *uri, const char *pref) -{ - nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); - if (!prefs) - return PR_FALSE; - - nsCAutoString scheme, host; - PRInt32 port; - - if (NS_FAILED(uri->GetScheme(scheme))) - return PR_FALSE; - if (NS_FAILED(uri->GetAsciiHost(host))) - return PR_FALSE; - if (NS_FAILED(uri->GetPort(&port))) - return PR_FALSE; - - char *hostList; - if (NS_FAILED(prefs->GetCharPref(pref, &hostList)) || !hostList) - return PR_FALSE; - - // pseudo-BNF - // ---------- - // - // url-list base-url ( base-url "," LWS )* - // base-url ( scheme-part | host-part | scheme-part host-part ) - // scheme-part scheme "://" - // host-part host [":" port] - // - // for example: - // "https://, http://office.foo.com" - // - - char *start = hostList, *end; - for (;;) { - // skip past any whitespace - while (*start == ' ' || *start == '\t') - ++start; - end = strchr(start, ','); - if (!end) - end = start + strlen(start); - if (start == end) - break; - if (MatchesBaseURI(scheme, host, port, start, end)) - return PR_TRUE; - if (*end == '\0') - break; - start = end + 1; - } - - nsMemory::Free(hostList); - return PR_FALSE; -} - -PRBool -nsHttpNegotiateAuth::MatchesBaseURI(const nsCSubstring &matchScheme, - const nsCSubstring &matchHost, - PRInt32 matchPort, - const char *baseStart, - const char *baseEnd) -{ - // check if scheme://host:port matches baseURI - - // parse the base URI - const char *hostStart, *schemeEnd = strstr(baseStart, "://"); - if (schemeEnd) { - // the given scheme must match the parsed scheme exactly - if (!matchScheme.Equals(Substring(baseStart, schemeEnd))) - return PR_FALSE; - hostStart = schemeEnd + 3; - } - else - hostStart = baseStart; - - // XXX this does not work for IPv6-literals - const char *hostEnd = strchr(hostStart, ':'); - if (hostEnd && hostEnd <= baseEnd) { - // the given port must match the parsed port exactly - int port = atoi(hostEnd + 1); - if (matchPort != (PRInt32) port) - return PR_FALSE; - } - else - hostEnd = baseEnd; - - - // if we didn't parse out a host, then assume we got a match. - if (hostStart == hostEnd) - return PR_TRUE; - - PRUint32 hostLen = hostEnd - hostStart; - - // matchHost must either equal host or be a subdomain of host - if (matchHost.Length() < hostLen) - return PR_FALSE; - - const char *end = matchHost.EndReading(); - if (PL_strncasecmp(end - hostLen, hostStart, hostLen) == 0) { - // if matchHost ends with host from the base URI, then make sure it is - // either an exact match, or prefixed with a dot. we don't want - // "foobar.com" to match "bar.com" - if (matchHost.Length() == hostLen || - *(end - hostLen) == '.' || - *(end - hostLen - 1) == '.') - return PR_TRUE; - } - - return PR_FALSE; -} diff --git a/extensions/negotiateauth/nsHttpNegotiateAuth.h b/extensions/negotiateauth/nsHttpNegotiateAuth.h deleted file mode 100644 index 7bde75f3760f..000000000000 --- a/extensions/negotiateauth/nsHttpNegotiateAuth.h +++ /dev/null @@ -1,70 +0,0 @@ -/* vim:set ts=4 sw=4 et cindent: */ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is Daniel Kouril. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Daniel Kouril (original author) - * Wyllys Ingersoll - * Christopher Nebergall - * Darin Fisher - * - * 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 nsHttpNegotiateAuth_h__ -#define nsHttpNegotiateAuth_h__ - -#include "nsIHttpAuthenticator.h" -#include "nsIURI.h" -#include "nsSubstring.h" - -// The nsGssapiAuth class provides responses for the GSS-API Negotiate method -// as specified by Microsoft in draft-brezak-spnego-http-04.txt - -class nsHttpNegotiateAuth : public nsIHttpAuthenticator -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIHTTPAUTHENTICATOR - -private: - // returns the value of the given boolean pref - PRBool TestBoolPref(const char *pref); - - // returns true if URI is accepted by the list of hosts in the pref - PRBool TestPref(nsIURI *, const char *pref); - - PRBool MatchesBaseURI(const nsCSubstring &scheme, - const nsCSubstring &host, - PRInt32 port, - const char *baseStart, - const char *baseEnd); -}; -#endif /* nsHttpNegotiateAuth_h__ */ diff --git a/extensions/negotiateauth/nsNegotiateAuth.h b/extensions/negotiateauth/nsNegotiateAuth.h deleted file mode 100644 index eeb8fa45a26e..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuth.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Darin Fisher - * - * 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 nsNegotiateAuth_h__ -#define nsNegotiateAuth_h__ - -#if defined( MOZ_LOGGING) -#define FORCE_PR_LOG -#endif - -#include "prlog.h" - -#if defined( PR_LOGGING ) -// -// in order to do logging, the following environment variables need to be set: -// -// set NSPR_LOG_MODULES=negotiateauth:4 -// set NSPR_LOG_FILE=negotiateauth.log -// -extern PRLogModuleInfo* gNegotiateLog; - -#define LOG(args) PR_LOG(gNegotiateLog, PR_LOG_DEBUG, args) -#else -#define LOG(args) -#endif - -#endif /* !defined( nsNegotiateAuth_h__ ) */ diff --git a/extensions/negotiateauth/nsNegotiateAuthFactory.cpp b/extensions/negotiateauth/nsNegotiateAuthFactory.cpp deleted file mode 100644 index fc285adbdd5b..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuthFactory.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Darin Fisher - * - * 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 "nsIGenericFactory.h" -#include "nsNegotiateAuth.h" - -//----------------------------------------------------------------------------- - -#define NS_HTTPNEGOTIATEAUTH_CID \ -{ /* 75c80fd0-accb-432c-af59-ec60668c3990 */ \ - 0x75c80fd0, \ - 0xaccb, \ - 0x432c, \ - {0xaf, 0x59, 0xec, 0x60, 0x66, 0x8c, 0x39, 0x90} \ -} - -#include "nsHttpNegotiateAuth.h" -NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpNegotiateAuth) - -//----------------------------------------------------------------------------- - -#define NS_NEGOTIATEAUTH_CID \ -{ /* 96ec4163-efc8-407a-8735-007fb26be4e8 */ \ - 0x96ec4163, \ - 0xefc8, \ - 0x407a, \ - {0x87, 0x35, 0x00, 0x7f, 0xb2, 0x6b, 0xe4, 0xe8} \ -} - -#if defined( USE_GSSAPI ) -#include "nsNegotiateAuthGSSAPI.h" - -#elif defined( USE_SSPI ) -#include "nsNegotiateAuthSSPI.h" - -static NS_METHOD -nsSysNTLMAuthConstructor(nsISupports *outer, REFNSIID iid, void **result) -{ - if (outer) - return NS_ERROR_NO_AGGREGATION; - - nsNegotiateAuth *auth = new nsNegotiateAuth(PR_TRUE); - if (!auth) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(auth); - nsresult rv = auth->QueryInterface(iid, result); - NS_RELEASE(auth); - return rv; -} - -#define NS_SYSNTLMAUTH_CID \ -{ /* dc195987-6e9a-47bc-b1fd-ab895d398833 */ \ - 0xdc195987, \ - 0x6e9a, \ - 0x47bc, \ - {0xb1, 0xfd, 0xab, 0x89, 0x5d, 0x39, 0x88, 0x33} \ -} - -#else -#error "missing implementation" -#endif - -NS_GENERIC_FACTORY_CONSTRUCTOR(nsNegotiateAuth) - - -//----------------------------------------------------------------------------- - -static nsModuleComponentInfo components[] = { - { "nsNegotiateAuth", - NS_NEGOTIATEAUTH_CID, - NS_AUTH_MODULE_CONTRACTID_PREFIX "negotiate", - nsNegotiateAuthConstructor - }, -#if defined( USE_SSPI ) - { "nsNegotiateAuthNTLM", - NS_SYSNTLMAUTH_CID, - NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm", - nsSysNTLMAuthConstructor - }, -#endif - { "nsHttpNegotiateAuth", - NS_HTTPNEGOTIATEAUTH_CID, - NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX "negotiate", - nsHttpNegotiateAuthConstructor - } -}; - -//----------------------------------------------------------------------------- - -#if defined( PR_LOGGING ) -PRLogModuleInfo *gNegotiateLog; - -// setup nspr logging ... -PR_STATIC_CALLBACK(nsresult) -InitNegotiateAuth(nsIModule *self) -{ - gNegotiateLog = PR_NewLogModule("negotiateauth"); - return NS_OK; -} -#else -#define InitNegotiateAuth nsnull -#endif - -NS_IMPL_NSGETMODULE_WITH_CTOR(nsNegotiateAuthModule, components, InitNegotiateAuth) diff --git a/extensions/negotiateauth/nsNegotiateAuthGSSAPI.cpp b/extensions/negotiateauth/nsNegotiateAuthGSSAPI.cpp deleted file mode 100644 index d6dec9c43702..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuthGSSAPI.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* vim:set ts=4 sw=4 sts=4 et cindent: */ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is Daniel Kouril. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Daniel Kouril (original author) - * Wyllys Ingersoll - * Christopher Nebergall - * Darin Fisher - * Mark Mentovai - * - * 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 ***** */ - -// -// GSSAPI Authentication Support Module -// -// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt -// (formerly draft-brezak-spnego-http-04.txt) -// -// Also described here: -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp -// -// - -#include "prlink.h" -#include "nsCOMPtr.h" -#include "nsIPrefService.h" -#include "nsIPrefBranch.h" -#include "nsIServiceManager.h" - -#include "nsNegotiateAuth.h" -#include "nsNegotiateAuthGSSAPI.h" - -#ifdef XP_MACOSX -#include -#endif - -// function pointers for gss functions -// -typedef OM_uint32 (*gss_display_status_type)( - OM_uint32 *, - OM_uint32, - int, - gss_OID, - OM_uint32 *, - gss_buffer_t); - -typedef OM_uint32 (*gss_init_sec_context_type)( - OM_uint32 *, - gss_cred_id_t, - gss_ctx_id_t *, - gss_name_t, - gss_OID, - OM_uint32, - OM_uint32, - gss_channel_bindings_t, - gss_buffer_t, - gss_OID *, - gss_buffer_t, - OM_uint32 *, - OM_uint32 *); - -typedef OM_uint32 (*gss_indicate_mechs_type)( - OM_uint32 *, - gss_OID_set *); - -typedef OM_uint32 (*gss_release_oid_set_type)( - OM_uint32 *, - gss_OID_set *); - -typedef OM_uint32 (*gss_delete_sec_context_type)( - OM_uint32 *, - gss_ctx_id_t *, - gss_buffer_t); - -typedef OM_uint32 (*gss_import_name_type)( - OM_uint32 *, - gss_buffer_t, - gss_OID, - gss_name_t *); - -typedef OM_uint32 (*gss_release_buffer_type)( - OM_uint32 *, - gss_buffer_t); - -typedef OM_uint32 (*gss_release_name_type)( - OM_uint32 *, - gss_name_t *); - -#ifdef XP_MACOSX -typedef KLStatus (*KLCacheHasValidTickets_type)( - KLPrincipal, - KLKerberosVersion, - KLBoolean *, - KLPrincipal *, - char **); -#endif - -//----------------------------------------------------------------------------- - -// We define GSS_C_NT_HOSTBASED_SERVICE explicitly since it may be referenced -// by by a different name depending on the implementation of gss but always -// has the same value - -static gss_OID_desc gss_c_nt_hostbased_service = - { 10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" }; - -static const char kNegotiateAuthGssLib[] = - "network.negotiate-auth.gsslib"; -static const char kNegotiateAuthNativeImp[] = - "network.negotiate-auth.using-native-gsslib"; - -static const char *gssFuncStr[] = { - "gss_display_status", - "gss_init_sec_context", - "gss_indicate_mechs", - "gss_release_oid_set", - "gss_delete_sec_context", - "gss_import_name", - "gss_release_buffer", - "gss_release_name" -}; - -#define gssFuncItems NS_ARRAY_LENGTH(gssFuncStr) - -static PRFuncPtr gssFunPtr[gssFuncItems]; -static PRBool gssNativeImp = PR_TRUE; -static PRBool gssFunInit = PR_FALSE; - -#define gss_display_status_ptr ((gss_display_status_type)*gssFunPtr[0]) -#define gss_init_sec_context_ptr ((gss_init_sec_context_type)*gssFunPtr[1]) -#define gss_indicate_mechs_ptr ((gss_indicate_mechs_type)*gssFunPtr[2]) -#define gss_release_oid_set_ptr ((gss_release_oid_set_type)*gssFunPtr[3]) -#define gss_delete_sec_context_ptr ((gss_delete_sec_context_type)*gssFunPtr[4]) -#define gss_import_name_ptr ((gss_import_name_type)*gssFunPtr[5]) -#define gss_release_buffer_ptr ((gss_release_buffer_type)*gssFunPtr[6]) -#define gss_release_name_ptr ((gss_release_name_type)*gssFunPtr[7]) - -#ifdef XP_MACOSX -static PRFuncPtr KLCacheHasValidTicketsPtr; -#define KLCacheHasValidTickets_ptr \ - ((KLCacheHasValidTickets_type)*KLCacheHasValidTicketsPtr) -#endif - -static nsresult -gssInit() -{ - nsXPIDLCString libPath; - nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); - if (prefs) { - prefs->GetCharPref(kNegotiateAuthGssLib, getter_Copies(libPath)); - prefs->GetBoolPref(kNegotiateAuthNativeImp, &gssNativeImp); - } - - PRLibrary *lib = NULL; - - if (!libPath.IsEmpty()) { - LOG(("Attempting to load user specified library [%s]\n", libPath.get())); - gssNativeImp = PR_FALSE; - lib = PR_LoadLibrary(libPath.get()); - } - else { - const char *const libNames[] = { - "gss", - "gssapi_krb5", - "gssapi" - }; - - for (size_t i = 0; i < NS_ARRAY_LENGTH(libNames) && !lib; ++i) { - char *libName = PR_GetLibraryName(NULL, libNames[i]); - if (libName) { - lib = PR_LoadLibrary(libName); - PR_FreeLibraryName(libName); - } - } - } - - if (!lib) { - LOG(("Fail to load gssapi library\n")); - return NS_ERROR_FAILURE; - } - - LOG(("Attempting to load gss functions\n")); - - for (size_t i = 0; i < gssFuncItems; ++i) { - gssFunPtr[i] = PR_FindFunctionSymbol(lib, gssFuncStr[i]); - if (!gssFunPtr[i]) { - LOG(("Fail to load %s function from gssapi library\n", gssFuncStr[i])); - PR_UnloadLibrary(lib); - return NS_ERROR_FAILURE; - } - } -#ifdef XP_MACOSX - if (gssNativeImp && - !(KLCacheHasValidTicketsPtr = - PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) { - LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n")); - PR_UnloadLibrary(lib); - return NS_ERROR_FAILURE; - } -#endif - - gssFunInit = PR_TRUE; - return NS_OK; -} - -#if defined( PR_LOGGING ) - -// Generate proper GSSAPI error messages from the major and -// minor status codes. -void -LogGssError(OM_uint32 maj_stat, OM_uint32 min_stat, const char *prefix) -{ - OM_uint32 new_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status1_string; - gss_buffer_desc status2_string; - OM_uint32 ret; - nsCAutoString error(prefix); - - if (!gssFunInit) - return; - - error += ": "; - do { - ret = gss_display_status_ptr(&new_stat, - maj_stat, - GSS_C_GSS_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status1_string); - error += (const char *) status1_string.value; - error += '\n'; - ret = gss_display_status_ptr(&new_stat, - min_stat, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status2_string); - error += (const char *) status2_string.value; - error += '\n'; - } while (!GSS_ERROR(ret) && msg_ctx != 0); - - LOG(("%s\n", error.get())); -} - -#else /* PR_LOGGING */ - -#define LogGssError(x,y,z) - -#endif /* PR_LOGGING */ - -//----------------------------------------------------------------------------- - -nsNegotiateAuth::nsNegotiateAuth() - : mServiceFlags(REQ_DEFAULT) -{ - OM_uint32 minstat, majstat; - gss_OID_set mech_set; - gss_OID item; - unsigned int i; - static gss_OID_desc gss_krb5_mech_oid_desc = - { 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; - static gss_OID_desc gss_spnego_mech_oid_desc = - { 6, (void *) "\x2b\x06\x01\x05\x05\x02" }; - - LOG(("entering nsNegotiateAuth::nsNegotiateAuth()\n")); - - if (!gssFunInit && NS_FAILED(gssInit())) - return; - - mCtx = GSS_C_NO_CONTEXT; - mMechOID = &gss_krb5_mech_oid_desc; - - // - // Now, look at the list of supported mechanisms, - // if SPNEGO is found, then use it. - // Otherwise, set the desired mechanism to - // GSS_C_NO_OID and let the system try to use - // the default mechanism. - // - // Using Kerberos directly (instead of negotiating - // with SPNEGO) may work in some cases depending - // on how smart the server side is. - // - majstat = gss_indicate_mechs_ptr(&minstat, &mech_set); - if (GSS_ERROR(majstat)) - return; - - for (i=0; icount; i++) { - item = &mech_set->elements[i]; - if (item->length == gss_spnego_mech_oid_desc.length && - !memcmp(item->elements, gss_spnego_mech_oid_desc.elements, - item->length)) { - // ok, we found it - mMechOID = &gss_spnego_mech_oid_desc; - break; - } - } - gss_release_oid_set_ptr(&minstat, &mech_set); -} - -void -nsNegotiateAuth::Reset() -{ - if (gssFunInit && mCtx != GSS_C_NO_CONTEXT) { - OM_uint32 minor_status; - gss_delete_sec_context_ptr(&minor_status, &mCtx, GSS_C_NO_BUFFER); - } - mCtx = GSS_C_NO_CONTEXT; -} - -NS_IMPL_ISUPPORTS1(nsNegotiateAuth, nsIAuthModule) - -NS_IMETHODIMP -nsNegotiateAuth::Init(const char *serviceName, - PRUint32 serviceFlags, - const PRUnichar *domain, - const PRUnichar *username, - const PRUnichar *password) -{ - // we don't expect to be passed any user credentials - NS_ASSERTION(!domain && !username && !password, "unexpected credentials"); - - // it's critial that the caller supply a service name to be used - NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG); - - LOG(("entering nsNegotiateAuth::Init()\n")); - - if (!gssFunInit) - return NS_ERROR_NOT_INITIALIZED; - - mServiceName = serviceName; - mServiceFlags = serviceFlags; - return NS_OK; -} - -NS_IMETHODIMP -nsNegotiateAuth::GetNextToken(const void *inToken, - PRUint32 inTokenLen, - void **outToken, - PRUint32 *outTokenLen) -{ - OM_uint32 major_status, minor_status; - OM_uint32 req_flags = 0; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER; - gss_name_t server; - - LOG(("entering nsNegotiateAuth::GetNextToken()\n")); - - if (!gssFunInit) - return NS_ERROR_NOT_INITIALIZED; - - if (mServiceFlags & REQ_DELEGATE) - req_flags |= GSS_C_DELEG_FLAG; - - input_token.value = (void *)mServiceName.get(); - input_token.length = mServiceName.Length() + 1; - - major_status = gss_import_name_ptr(&minor_status, - &input_token, - &gss_c_nt_hostbased_service, - &server); - input_token.value = NULL; - input_token.length = 0; - if (GSS_ERROR(major_status)) { - LogGssError(major_status, minor_status, "gss_import_name() failed"); - return NS_ERROR_FAILURE; - } - - if (inToken) { - input_token.length = inTokenLen; - input_token.value = (void *) inToken; - in_token_ptr = &input_token; - } - else if (mCtx != GSS_C_NO_CONTEXT) { - // If there is no input token, then we are starting a new - // authentication sequence. If we have already initialized our - // security context, then we're in trouble because it means that the - // first sequence failed. We need to bail or else we might end up in - // an infinite loop. - LOG(("Cannot restart authentication sequence!")); - return NS_ERROR_UNEXPECTED; - } - -#if defined(XP_MACOSX) - // Suppress Kerberos prompts to get credentials. See bug 240643. - // We can only use Mac OS X specific kerb functions if we are using - // the native lib - - KLBoolean found; - if (gssNativeImp && - (KLCacheHasValidTickets_ptr(NULL, kerberosVersion_V5, &found, NULL, - NULL) - != klNoErr || !found)) - { - major_status = GSS_S_FAILURE; - minor_status = 0; - } - else -#endif /* XP_MACOSX */ - major_status = gss_init_sec_context_ptr(&minor_status, - GSS_C_NO_CREDENTIAL, - &mCtx, - server, - mMechOID, - req_flags, - GSS_C_INDEFINITE, - GSS_C_NO_CHANNEL_BINDINGS, - in_token_ptr, - nsnull, - &output_token, - nsnull, - nsnull); - - nsresult rv; - if (GSS_ERROR(major_status)) { - LogGssError(major_status, minor_status, "gss_init_sec_context() failed"); - Reset(); - rv = NS_ERROR_FAILURE; - goto end; - } - if (major_status == GSS_S_COMPLETE) { - // - // We are done with this authentication, reset the context. - // - Reset(); - } - else if (major_status == GSS_S_CONTINUE_NEEDED) { - // - // The important thing is that we do NOT reset the - // context here because it will be needed on the - // next call. - // - } - - if (output_token.length == 0) { - LOG((" No GSS output token to send, exiting")); - rv = NS_ERROR_FAILURE; - goto end; - } - - *outTokenLen = output_token.length; - *outToken = nsMemory::Clone(output_token.value, output_token.length); - - gss_release_buffer_ptr(&minor_status, &output_token); - rv = NS_OK; - -end: - gss_release_name_ptr(&minor_status, &server); - - LOG((" leaving nsNegotiateAuth::GetNextToken [rv=%x]", rv)); - return rv; -} diff --git a/extensions/negotiateauth/nsNegotiateAuthGSSAPI.h b/extensions/negotiateauth/nsNegotiateAuthGSSAPI.h deleted file mode 100644 index 8ec9a3df1a58..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuthGSSAPI.h +++ /dev/null @@ -1,83 +0,0 @@ -/* vim:set ts=4 sw=4 et cindent: */ -/* ***** 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 the Negotiateauth - * - * The Initial Developer of the Original Code is Daniel Kouril. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Daniel Kouril (original author) - * Wyllys Ingersoll - * Christopher Nebergall - * Darin Fisher - * - * 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 nsGssapiAuth_h__ -#define nsGssapiAuth_h__ - -#include "nsIAuthModule.h" -#include "nsString.h" - -#if defined(HAVE_GSSAPI_H) -#include -#elif defined(HAVE_GSSAPI_GSSAPI_H) -#include -#endif - -#if defined(HAVE_GSSAPI_GENERIC_H) -#include -#elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) -#include -#endif - -// The nsNegotiateAuth class provides responses for the GSS-API Negotiate method -// as specified by Microsoft in draft-brezak-spnego-http-04.txt - -class nsNegotiateAuth : public nsIAuthModule -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIAUTHMODULE - - nsNegotiateAuth(); - -private: - ~nsNegotiateAuth() { Reset(); } - - void Reset(); - gss_OID GetOID() { return mMechOID; } - -private: - gss_ctx_id_t mCtx; - gss_OID mMechOID; - nsCString mServiceName; - PRUint32 mServiceFlags; -}; - -#endif /* nsGssapiAuth_h__ */ diff --git a/extensions/negotiateauth/nsNegotiateAuthSSPI.cpp b/extensions/negotiateauth/nsNegotiateAuthSSPI.cpp deleted file mode 100644 index 458fd3215228..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuthSSPI.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* vim:set ts=4 sw=4 sts=4 et cindent: */ -/* ***** 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 the SSPI NegotiateAuth Module - * - * The Initial Developer of the Original Code is IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Darin Fisher - * - * 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 ***** */ - -// -// Negotiate Authentication Support Module -// -// Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt -// (formerly draft-brezak-spnego-http-04.txt) -// -// Also described here: -// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp -// - -#include "nsNegotiateAuth.h" -#include "nsNegotiateAuthSSPI.h" -#include "nsIServiceManager.h" -#include "nsIDNSService.h" -#include "nsIDNSRecord.h" -#include "nsNetCID.h" -#include "nsCOMPtr.h" - -//----------------------------------------------------------------------------- - -#ifdef DEBUG -#define CASE_(_x) case _x: return # _x; -static const char *MapErrorCode(int rc) -{ - switch (rc) { - CASE_(SEC_E_OK) - CASE_(SEC_I_CONTINUE_NEEDED) - CASE_(SEC_I_COMPLETE_NEEDED) - CASE_(SEC_I_COMPLETE_AND_CONTINUE) - CASE_(SEC_E_INCOMPLETE_MESSAGE) - CASE_(SEC_I_INCOMPLETE_CREDENTIALS) - CASE_(SEC_E_INVALID_HANDLE) - CASE_(SEC_E_TARGET_UNKNOWN) - CASE_(SEC_E_LOGON_DENIED) - CASE_(SEC_E_INTERNAL_ERROR) - CASE_(SEC_E_NO_CREDENTIALS) - CASE_(SEC_E_NO_AUTHENTICATING_AUTHORITY) - CASE_(SEC_E_INSUFFICIENT_MEMORY) - CASE_(SEC_E_INVALID_TOKEN) - } - return ""; -} -#else -#define MapErrorCode(_rc) "" -#endif - -//----------------------------------------------------------------------------- - -static HINSTANCE sspi_lib; -static PSecurityFunctionTable sspi; - -static nsresult -InitSSPI() -{ - PSecurityFunctionTable (*initFun)(void); - - sspi_lib = LoadLibrary("secur32.dll"); - if (!sspi_lib) { - sspi_lib = LoadLibrary("security.dll"); - if (!sspi_lib) { - LOG(("SSPI library not found")); - return NS_ERROR_UNEXPECTED; - } - } - - initFun = (PSecurityFunctionTable (*)(void)) - GetProcAddress(sspi_lib, "InitSecurityInterfaceA"); - if (!initFun) { - LOG(("InitSecurityInterfaceA not found")); - return NS_ERROR_UNEXPECTED; - } - - sspi = initFun(); - if (!sspi) { - LOG(("InitSecurityInterfaceA failed")); - return NS_ERROR_UNEXPECTED; - } - - return NS_OK; -} - -//----------------------------------------------------------------------------- - -static nsresult -MakeSN(const char *principal, nsCString &result) -{ - nsresult rv; - - nsCAutoString buf(principal); - - // The service name looks like "protocol@hostname", we need to map - // this to a value that SSPI expects. To be consistent with IE, we - // need to map '@' to '/' and canonicalize the hostname. - PRInt32 index = buf.FindChar('@'); - if (index == kNotFound) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - - // This could be expensive if our DNS cache cannot satisfy the request. - // However, we should have at least hit the OS resolver once prior to - // reaching this code, so provided the OS resolver has this information - // cached, we should not have to worry about blocking on this function call - // for very long. NOTE: because we ask for the canonical hostname, we - // might end up requiring extra network activity in cases where the OS - // resolver might not have enough information to satisfy the request from - // its cache. This is not an issue in versions of Windows up to WinXP. - nsCOMPtr record; - rv = dns->Resolve(Substring(buf, index + 1), - nsIDNSService::RESOLVE_CANONICAL_NAME, - getter_AddRefs(record)); - if (NS_FAILED(rv)) - return rv; - - nsCAutoString cname; - rv = record->GetCanonicalName(cname); - if (NS_SUCCEEDED(rv)) { - result = StringHead(buf, index) + NS_LITERAL_CSTRING("/") + cname; - LOG(("Using SPN of [%s]\n", result.get())); - } - return rv; -} - -//----------------------------------------------------------------------------- - -nsNegotiateAuth::nsNegotiateAuth(PRBool useNTLM) - : mServiceFlags(REQ_DEFAULT) - , mMaxTokenLen(0) - , mUseNTLM(useNTLM) -{ - memset(&mCred, 0, sizeof(mCred)); - memset(&mCtxt, 0, sizeof(mCtxt)); -} - -nsNegotiateAuth::~nsNegotiateAuth() -{ - Reset(); - - if (mCred.dwLower || mCred.dwUpper) { -#ifdef __MINGW32__ - (sspi->FreeCredentialsHandle)(&mCred); -#else - (sspi->FreeCredentialHandle)(&mCred); -#endif - memset(&mCred, 0, sizeof(mCred)); - } -} - -void -nsNegotiateAuth::Reset() -{ - if (mCtxt.dwLower || mCtxt.dwUpper) { - (sspi->DeleteSecurityContext)(&mCtxt); - memset(&mCtxt, 0, sizeof(mCtxt)); - } -} - -NS_IMPL_ISUPPORTS1(nsNegotiateAuth, nsIAuthModule) - -NS_IMETHODIMP -nsNegotiateAuth::Init(const char *serviceName, - PRUint32 serviceFlags, - const PRUnichar *domain, - const PRUnichar *username, - const PRUnichar *password) -{ - // we don't expect to be passed any user credentials - NS_ASSERTION(!domain && !username && !password, "unexpected credentials"); - - // if we're configured for SPNEGO, then it's critial that the caller - // supply a service name to be used. - if (!mUseNTLM) - NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG); - - nsresult rv; - - // XXX lazy initialization like this assumes that we are single threaded - if (!sspi) { - rv = InitSSPI(); - if (NS_FAILED(rv)) - return rv; - } - - SEC_CHAR *package; - if (mUseNTLM) - package = "NTLM"; - else { - package = "Negotiate"; - - rv = MakeSN(serviceName, mServiceName); - if (NS_FAILED(rv)) - return rv; - mServiceFlags = serviceFlags; - } - - SECURITY_STATUS rc; - - PSecPkgInfo pinfo; - rc = (sspi->QuerySecurityPackageInfo)(package, &pinfo); - if (rc != SEC_E_OK) { - LOG(("%s package not found\n", package)); - return NS_ERROR_UNEXPECTED; - } - mMaxTokenLen = pinfo->cbMaxToken; - (sspi->FreeContextBuffer)(pinfo); - - TimeStamp useBefore; - - rc = (sspi->AcquireCredentialsHandle)(NULL, - package, - SECPKG_CRED_OUTBOUND, - NULL, - NULL, - NULL, - NULL, - &mCred, - &useBefore); - if (rc != SEC_E_OK) - return NS_ERROR_UNEXPECTED; - - return NS_OK; -} - -NS_IMETHODIMP -nsNegotiateAuth::GetNextToken(const void *inToken, - PRUint32 inTokenLen, - void **outToken, - PRUint32 *outTokenLen) -{ - SECURITY_STATUS rc; - - DWORD ctxAttr, ctxReq = 0; - CtxtHandle *ctxIn; - SecBufferDesc ibd, obd; - SecBuffer ib, ob; - - LOG(("entering nsNegotiateAuth::GetNextToken()\n")); - - if (mServiceFlags & REQ_DELEGATE) - ctxReq |= ISC_REQ_DELEGATE; - if (mServiceFlags & REQ_MUTUAL_AUTH) - ctxReq |= ISC_REQ_MUTUAL_AUTH; - - if (inToken) { - ib.BufferType = SECBUFFER_TOKEN; - ib.cbBuffer = inTokenLen; - ib.pvBuffer = (void *) inToken; - ibd.ulVersion = SECBUFFER_VERSION; - ibd.cBuffers = 1; - ibd.pBuffers = &ib; - ctxIn = &mCtxt; - } - else { - // If there is no input token, then we are starting a new - // authentication sequence. If we have already initialized our - // security context, then we're in trouble because it means that the - // first sequence failed. We need to bail or else we might end up in - // an infinite loop. - if (mCtxt.dwLower || mCtxt.dwUpper) { - LOG(("Cannot restart authentication sequence!")); - return NS_ERROR_UNEXPECTED; - } - - ctxIn = NULL; - } - - obd.ulVersion = SECBUFFER_VERSION; - obd.cBuffers = 1; - obd.pBuffers = &ob; - ob.BufferType = SECBUFFER_TOKEN; - ob.cbBuffer = mMaxTokenLen; - ob.pvBuffer = nsMemory::Alloc(ob.cbBuffer); - if (!ob.pvBuffer) - return NS_ERROR_OUT_OF_MEMORY; - memset(ob.pvBuffer, 0, ob.cbBuffer); - - SEC_CHAR *sn; - if (mUseNTLM) - sn = NULL; - else - sn = (SEC_CHAR *) mServiceName.get(); - - rc = (sspi->InitializeSecurityContext)(&mCred, - ctxIn, - sn, - ctxReq, - 0, - SECURITY_NATIVE_DREP, - inToken ? &ibd : NULL, - 0, - &mCtxt, - &obd, - &ctxAttr, - NULL); - if (rc == SEC_I_CONTINUE_NEEDED || rc == SEC_E_OK) { - *outToken = ob.pvBuffer; - *outTokenLen = ob.cbBuffer; - return NS_OK; - } - - LOG(("InitializeSecurityContext failed [rc=%d:%s]\n", rc, MapErrorCode(rc))); - Reset(); - nsMemory::Free(ob.pvBuffer); - return NS_ERROR_FAILURE; -} diff --git a/extensions/negotiateauth/nsNegotiateAuthSSPI.h b/extensions/negotiateauth/nsNegotiateAuthSSPI.h deleted file mode 100644 index 0131bfb200c6..000000000000 --- a/extensions/negotiateauth/nsNegotiateAuthSSPI.h +++ /dev/null @@ -1,81 +0,0 @@ -/* vim:set ts=4 sw=4 et cindent: */ -/* ***** 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 the SSPI NegotiateAuth Module. - * - * The Initial Developer of the Original Code is IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2004 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Darin Fisher - * - * 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 nsNegotiateAuthSSPI_h__ -#define nsNegotiateAuthSSPI_h__ - -#include "nsIAuthModule.h" -#include "nsString.h" - -#include - -#define SECURITY_WIN32 1 -#include -#include - -// The nsNegotiateAuth class provides responses for the GSS-API Negotiate method -// as specified by Microsoft in draft-brezak-spnego-http-04.txt - -// It can also be configured to talk raw NTLM. This implementation of NTLM has -// the advantage of being able to access the user's logon credentials. This -// implementation of NTLM should only be used for single-signon. It should be -// avoided when authenticating over the internet since it may use a lower-grade -// version of password hashing depending on the version of Windows being used. - -class nsNegotiateAuth : public nsIAuthModule -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIAUTHMODULE - - nsNegotiateAuth(PRBool useNTLM = PR_FALSE); - -private: - ~nsNegotiateAuth(); - - void Reset(); - -private: - CredHandle mCred; - CtxtHandle mCtxt; - nsCString mServiceName; - PRUint32 mServiceFlags; - PRUint32 mMaxTokenLen; - PRBool mUseNTLM; -}; - -#endif /* nsNegotiateAuthSSPI_h__ */