File firefox-ntlm.patch of Package kompozer

diff --git a/mozilla/extensions/auth/Makefile.in b/mozilla/extensions/auth/Makefile.in
index f0aff40..46e5f5e 100644
--- a/mozilla/extensions/auth/Makefile.in
+++ b/mozilla/extensions/auth/Makefile.in
@@ -78,6 +78,8 @@ CPPSRCS		+= \
 ifeq ($(OS_ARCH),WINNT)
 LOCAL_INCLUDES	+= -DUSE_SSPI
 CPPSRCS		+= nsAuthSSPI.cpp
+else
+CPPSRCS         += nsAuthSambaNTLM.cpp
 endif
 
 include $(topsrcdir)/config/rules.mk
diff --git a/mozilla/extensions/auth/nsAuthFactory.cpp b/mozilla/extensions/auth/nsAuthFactory.cpp
index b3d515c..71705e5 100644
--- a/mozilla/extensions/auth/nsAuthFactory.cpp
+++ b/mozilla/extensions/auth/nsAuthFactory.cpp
@@ -127,6 +127,36 @@ nsKerbSSPIAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
   {0x8c, 0xd6, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66} \
 }
 
+#else
+
+#define NS_SAMBANTLMAUTH_CID                       \
+{ /* bc54f001-6eb0-4e32-9f49-7e064d8e70ef */       \
+  0xbc54f001,                                      \
+  0x6eb0,                                          \
+  0x4e32,                                          \
+  {0x9f, 0x49, 0x7e, 0x06, 0x4d, 0x8e, 0x70, 0xef} \
+}
+
+#include "nsAuthSambaNTLM.h"
+static NS_METHOD
+nsSambaNTLMAuthConstructor(nsISupports *outer, REFNSIID iid, void **result)
+{
+  if (outer)
+    return NS_ERROR_NO_AGGREGATION;
+
+  nsCOMPtr<nsAuthSambaNTLM> auth = new nsAuthSambaNTLM();
+  if (!auth)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  nsresult rv = auth->SpawnNTLMAuthHelper();
+  if (NS_FAILED(rv)) {
+    // Failure here probably means that cached credentials were not available
+    return rv;
+  }
+
+  return auth->QueryInterface(iid, result);
+}
+
 #endif
 
 static NS_METHOD
@@ -206,6 +236,12 @@ static nsModuleComponentInfo components[] = {
     NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm",
     nsSysNTLMAuthConstructor
   },
+#else
+  { "nsAuthSambaNTLM", 
+    NS_SAMBANTLMAUTH_CID,
+    NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm",
+    nsSambaNTLMAuthConstructor
+  },
 #endif
   { "nsHttpNegotiateAuth", 
     NS_HTTPNEGOTIATEAUTH_CID,
diff --git a/mozilla/extensions/auth/nsAuthSambaNTLM.cpp b/mozilla/extensions/auth/nsAuthSambaNTLM.cpp
new file mode 100644
index 0000000..05d00f2
--- /dev/null
+++ b/mozilla/extensions/auth/nsAuthSambaNTLM.cpp
@@ -0,0 +1,323 @@
+/* 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 Samba NTLM Authentication.
+ *
+ * The Initial Developer of the Original Code is Novell.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert O'Callahan (rocallahan@novell.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 "nsAuth.h"
+#include "nsAuthSambaNTLM.h"
+#include "prenv.h"
+#include "plbase64.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+nsAuthSambaNTLM::nsAuthSambaNTLM()
+    : mInitialMessage(nsnull), mChildPID(0), mFromChildFD(-1), mToChildFD(-1)
+{
+}
+
+nsAuthSambaNTLM::~nsAuthSambaNTLM()
+{
+    // ntlm_auth reads from stdin regularly so closing our file handles
+    // should cause it to exit. Trying to kill it with a signal would be
+    // problematic because another process could have spawned with that pid
+    // if it has unexpectedly quit.
+    Shutdown();
+    free(mInitialMessage);
+}
+
+void
+nsAuthSambaNTLM::Shutdown()
+{
+    if (mFromChildFD >= 0) {
+        close(mFromChildFD);
+        mFromChildFD = -1;
+    }
+    if (mToChildFD >= 0) {
+        close(mToChildFD);
+        mToChildFD = -1;
+    }
+    if (mChildPID) {
+        waitpid(mChildPID, nsnull, 0);
+        mChildPID = 0;
+    }
+}
+
+NS_IMPL_ISUPPORTS1(nsAuthSambaNTLM, nsIAuthModule)
+
+static PRBool
+SpawnIOChild(char** aArgs, pid_t* aPID, int* aFromChildFD, int* aToChildFD)
+{
+    int toChildPipe[2];
+    if (pipe(toChildPipe) < 0)
+        return PR_FALSE;
+    int fromChildPipe[2];
+    if (pipe(fromChildPipe) < 0) {
+        close(toChildPipe[0]);
+        close(toChildPipe[1]);
+        return PR_FALSE;
+    }
+
+    pid_t pid = fork();
+    if (pid < 0) {
+        PRInt32 i;
+        for (i = 0; i < 2; ++i) {
+            close(fromChildPipe[i]);
+            close(toChildPipe[i]);
+        } 
+        NS_WARNING("fork() failed");
+        return PR_FALSE;
+    }
+
+    if (pid > 0) {
+        // We are the parent
+        close(toChildPipe[0]);
+        close(fromChildPipe[1]);
+        *aPID = pid;
+        *aFromChildFD = fromChildPipe[0];
+        *aToChildFD = toChildPipe[1];
+        return PR_TRUE;
+    }
+    
+    // We are the child
+    close(toChildPipe[1]);
+    close(fromChildPipe[0]);
+    // Make stdin read from toChildPipe
+    int result0 = dup2(toChildPipe[0], 0);
+    // Make stdout write to fromChildPipe
+    int result1 = dup2(fromChildPipe[1], 1);
+    if (result0 >= 0 && result1 >= 0) {
+        execvp(aArgs[0], aArgs);
+    }
+    
+    // Guess an error occurred! Just exit, the parent will notice
+    // that we're not responding correctly.
+    LOG(("ntlm_auth exec failure, errno=%d", errno));
+    exit(0);
+    // ... satisfy the compiler
+    return PR_FALSE;
+}
+
+static PRBool WriteString(int aFD, const nsACString& aString)
+{
+    PRInt32 length = aString.Length();
+    nsPromiseFlatCString flat(aString);
+    const char* s = flat.get();
+    LOG(("Writing to ntlm_auth: %s", s));
+
+    while (length > 0) {
+        int result = write(aFD, s, length);
+        if (result <= 0)
+            return PR_FALSE;
+        s += result;
+        length -= result;
+    }
+    return PR_TRUE;
+}
+
+static PRBool ReadLine(int aFD, nsACString& aString)
+{
+    // ntlm_auth is defined to only send one line in response to each of our
+    // input lines. So this simple unbuffered strategy works as long as we
+    // read the response immediately after sending one request.
+    aString.Truncate();
+    for (;;) {
+        char buf[1024];
+        int result = read(aFD, buf, sizeof(buf));
+        if (result <= 0)
+            return PR_FALSE;
+        aString.Append(buf, result);
+        if (buf[result - 1] == '\n') {
+            LOG(("Read from ntlm_auth: %s", nsPromiseFlatCString(aString).get()));
+            return PR_TRUE;
+        }
+    }
+}
+
+/**
+ * Returns a heap-allocated array of PRUint8s, and stores the length in aLen.
+ * Returns nsnull if there's an error of any kind.
+ */
+static PRUint8* ExtractMessage(const nsACString& aLine, PRUint32* aLen)
+{
+    // ntlm_auth sends blobs to us as base64-encoded strings after the "xx "
+    // preamble on the response line.
+    PRInt32 length = aLine.Length();
+    // The caller should verify there is a valid "xx " prefix and the line
+    // is terminated with a \n
+    NS_ASSERTION(length >= 4, "Line too short...");
+    nsPromiseFlatCString flat(aLine);
+    const char* s = flat.get() + 3;
+    length -= 4; // lose first 3 chars plus trailing \n
+    NS_ASSERTION(s[length] == '\n', "aLine not newline-terminated");
+    
+    if (length & 3) {
+        // The base64 encoded block must be multiple of 4. If not, something
+        // screwed up.
+        NS_WARNING("Base64 encoded block should be a multiple of 4 chars");
+        return nsnull; 
+    } 
+
+    // Calculate the exact length. I wonder why there isn't a function for this
+    // in plbase64.
+    PRInt32 numEquals;
+    for (numEquals = 0; numEquals < length; ++numEquals) {
+        if (flat.get()[length - 1 - numEquals] != '=')
+            break;
+    }
+    *aLen = (length/4)*3 - numEquals;
+    return NS_REINTERPRET_CAST(PRUint8*, PL_Base64Decode(flat.get() + 3, length - 4, nsnull));
+}
+
+nsresult
+nsAuthSambaNTLM::SpawnNTLMAuthHelper()
+{
+    const char* username = PR_GetEnv("USER");
+    if (!username)
+        return NS_ERROR_FAILURE;
+
+    char* args[] = {
+        "ntlm_auth",
+        "--helper-protocol", "ntlmssp-client-1",
+        "--use-cached-creds",
+        "--username", NS_CONST_CAST(char*, username),
+        nsnull
+    };
+
+    PRBool isOK = SpawnIOChild(args, &mChildPID, &mFromChildFD, &mToChildFD);
+    if (!isOK)  
+        return NS_ERROR_FAILURE;
+
+    if (!WriteString(mToChildFD, NS_LITERAL_CSTRING("YR\n")))
+        return NS_ERROR_FAILURE;
+    nsCString line;
+    if (!ReadLine(mFromChildFD, line))
+        return NS_ERROR_FAILURE;
+    if (!StringBeginsWith(line, NS_LITERAL_CSTRING("YR "))) {
+        // Something went wrong. Perhaps no credentials are accessible.
+        return NS_ERROR_FAILURE;
+    }
+
+    // It gave us an initial client-to-server request packet. Save that
+    // because we'll need it later.
+    mInitialMessage = ExtractMessage(line, &mInitialMessageLen);
+    if (!mInitialMessage)
+        return NS_ERROR_FAILURE;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Init(const char *serviceName,
+                      PRUint32    serviceFlags,
+                      const PRUnichar *domain,
+                      const PRUnichar *username,
+                      const PRUnichar *password)
+{
+    NS_ASSERTION(!username && !domain && !password, "unexpected credentials");
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::GetNextToken(const void *inToken,
+                              PRUint32    inTokenLen,
+                              void      **outToken,
+                              PRUint32   *outTokenLen)
+{
+    if (!inToken) {
+        /* someone wants our initial message */
+        *outToken = nsMemory::Clone(mInitialMessage, mInitialMessageLen);
+        if (!*outToken)
+            return NS_ERROR_OUT_OF_MEMORY;
+        *outTokenLen = mInitialMessageLen;
+        return NS_OK;
+    }
+
+    /* inToken must be a type 2 message. Get ntlm_auth to generate our response */
+    char* encoded = PL_Base64Encode(NS_STATIC_CAST(const char*, inToken), inTokenLen, nsnull);
+    if (!encoded)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    nsCString request;
+    request.AssignLiteral("TT ");
+    request.Append(encoded);
+    free(encoded);
+    request.Append('\n');
+
+    if (!WriteString(mToChildFD, request))
+        return NS_ERROR_FAILURE;
+    nsCString line;
+    if (!ReadLine(mFromChildFD, line))
+        return NS_ERROR_FAILURE;
+    if (!StringBeginsWith(line, NS_LITERAL_CSTRING("KK "))) {
+        // Something went wrong. Perhaps no credentials are accessible.
+        return NS_ERROR_FAILURE;
+    }
+    PRUint8* buf = ExtractMessage(line, outTokenLen);
+    if (!buf)
+        return NS_ERROR_FAILURE;
+    // *outToken has to be freed by nsMemory::Free, which may not be free() 
+    *outToken = nsMemory::Clone(buf, *outTokenLen);
+    if (!*outToken) {
+        free(buf);
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    
+    // We're done. Close our file descriptors now and reap the helper
+    // process.
+    Shutdown();
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Unwrap(const void *inToken,
+                        PRUint32    inTokenLen,
+                        void      **outToken,
+                        PRUint32   *outTokenLen)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsAuthSambaNTLM::Wrap(const void *inToken,
+                      PRUint32    inTokenLen,
+                      PRBool      confidential,
+                      void      **outToken,
+                      PRUint32   *outTokenLen)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/mozilla/extensions/auth/nsAuthSambaNTLM.h b/mozilla/extensions/auth/nsAuthSambaNTLM.h
new file mode 100644
index 0000000..6034f03
--- /dev/null
+++ b/mozilla/extensions/auth/nsAuthSambaNTLM.h
@@ -0,0 +1,78 @@
+/* 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 Samba NTLM Authentication.
+ *
+ * The Initial Developer of the Original Code is Novell.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert O'Callahan (rocallahan@novell.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 ***** */
+
+#ifndef nsAuthSambaNTLM_h__
+#define nsAuthSambaNTLM_h__
+
+#include "nsIAuthModule.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+
+/**
+ * This is an implementation of NTLM authentication that does single-signon
+ * by obtaining the user's Unix username and then asking Samba's
+ * ntlm_auth tool to do the authentication for us
+ * using the user's password cached in winbindd, if available. If the
+ * password is not available then this component fails to instantiate so
+ * nsHttpNTLMAuth will fall back to a different NTLM implementation.
+ */
+class nsAuthSambaNTLM : public nsIAuthModule
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIAUTHMODULE
+
+    nsAuthSambaNTLM();
+
+    // We spawn the ntlm_auth helper from the module constructor, because
+    // that lets us fail to instantiate the module if ntlm_auth isn't
+    // available, triggering fallback to the built-in NTLM support (which
+    // doesn't support single signon, of course)
+    nsresult SpawnNTLMAuthHelper();
+
+private:
+    ~nsAuthSambaNTLM();
+
+    void Shutdown();
+
+    PRUint8* mInitialMessage; /* free with free() */
+    PRUint32 mInitialMessageLen;
+    PRInt32  mChildPID;
+    PRInt32  mFromChildFD, mToChildFD;
+};
+
+#endif /* nsAuthSambaNTLM_h__ */
diff --git a/mozilla/netwerk/protocol/http/src/nsHttpNTLMAuth.cpp b/mozilla/netwerk/protocol/http/src/nsHttpNTLMAuth.cpp
index 9c25334..cde2695 100644
--- a/mozilla/netwerk/protocol/http/src/nsHttpNTLMAuth.cpp
+++ b/mozilla/netwerk/protocol/http/src/nsHttpNTLMAuth.cpp
@@ -46,8 +46,6 @@
 
 //-----------------------------------------------------------------------------
 
-#ifdef XP_WIN
-
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIServiceManager.h"
@@ -208,8 +206,6 @@ public:
 };
 NS_IMPL_ISUPPORTS0(nsNTLMSessionState)
 
-#endif
-
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS1(nsHttpNTLMAuth, nsIHttpAuthenticator)
@@ -231,7 +227,6 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpChannel *channel,
     // start new auth sequence if challenge is exactly "NTLM"
     if (PL_strcasecmp(challenge, "NTLM") == 0) {
         nsCOMPtr<nsISupports> module;
-#ifdef XP_WIN
         //
         // our session state is non-null to indicate that we've flagged
         // this auth domain as not accepting the system's default login.
@@ -239,7 +234,7 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpChannel *channel,
         PRBool trySysNTLM = (*sessionState == nsnull);
 
         //
-        // on windows, we may have access to the built-in SSPI library,
+        // we may have access to a built-in SSPI library,
         // which could be used to authenticate the user without prompting.
         // 
         // if the continuationState is null, then we may want to try using
@@ -266,9 +261,7 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHttpChannel *channel,
                     return NS_ERROR_OUT_OF_MEMORY;
                 NS_ADDREF(*sessionState);
             }
-#else
-        {
-#endif 
+
             module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
 
             // prompt user for domain, username, and password...
openSUSE Build Service is sponsored by