Index: src/java/org/apache/commons/httpclient/HostConfiguration.java
===================================================================
--- src/java/org/apache/commons/httpclient/HostConfiguration.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 915934)
+++ src/java/org/apache/commons/httpclient/HostConfiguration.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(working copy)
@@ -31,7 +31,9 @@
 package org.apache.commons.httpclient;
 
 import org.apache.commons.httpclient.params.HostParams;
+import org.apache.commons.httpclient.params.HttpClientParams;
 import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolFactory;
 import org.apache.commons.httpclient.util.LangUtils;
 
 import java.net.InetAddress;
@@ -250,7 +252,10 @@
      * @param protocol The protocol.
      */
     public synchronized void setHost(final String host, int port, final String protocol) {
-        this.host = new HttpHost(host, port, Protocol.getProtocol(protocol));
+        if (this.params.getParameter(HttpClientParams.PROTOCOL_FACTORY) != null)
+            this.host = new HttpHost(host, port, ((ProtocolFactory)this.params.getParameter(HttpClientParams.PROTOCOL_FACTORY)).getProtocol(protocol));
+        else
+            this.host = new HttpHost(host, port, Protocol.getProtocol(protocol));
     }
     
     /**
@@ -293,7 +298,7 @@
      * @param port The port
      */
     public synchronized void setHost(final String host, int port) {
-        setHost(host, port, Protocol.getProtocol("http"));
+        setHost(host, port, "http");
     }
     
     /**
@@ -302,7 +307,11 @@
      * @param host The host(IP or DNS name).
      */
     public synchronized void setHost(final String host) {
-        Protocol defaultProtocol = Protocol.getProtocol("http"); 
+        Protocol defaultProtocol;
+        if (this.params.getParameter(HttpClientParams.PROTOCOL_FACTORY) != null)
+            defaultProtocol = ((ProtocolFactory)this.params.getParameter(HttpClientParams.PROTOCOL_FACTORY)).getProtocol("http");
+        else
+            defaultProtocol = Protocol.getProtocol("http"); 
         setHost(host, defaultProtocol.getDefaultPort(), defaultProtocol);
     }
     
Index: src/java/org/apache/commons/httpclient/protocol/ProtocolFactory.java
===================================================================
--- src/java/org/apache/commons/httpclient/protocol/ProtocolFactory.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 0)
+++ src/java/org/apache/commons/httpclient/protocol/ProtocolFactory.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(revision 1308601)
@@ -0,0 +1,150 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/protocol/Protocol.java,v 1.10 2004/04/18 23:51:38 jsdever Exp $
+ * $Revision: 157457 $
+ * $Date: 2005-03-14 15:23:16 -0500 (Mon, 14 Mar 2005) $
+ *
+ * ====================================================================
+ *
+ *  Copyright 2002-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.commons.httpclient.protocol;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.httpclient.util.LangUtils;
+
+/**
+ * A class to encapsulate the specifics of a protocol.  This class class also
+ * provides the ability to customize the set and characteristics of the
+ * protocols used.
+ * 
+ * <p>One use case for modifying the default set of protocols would be to set a
+ * custom SSL socket factory.  This would look something like the following:
+ * <pre> 
+ * Protocol myHTTPS = new Protocol( "https", new MySSLSocketFactory(), 443 );
+ * 
+ * Protocol.registerProtocol( "https", myHTTPS );
+ * </pre>
+ *
+ * @author Michael Becke 
+ * @author Jeff Dever
+ * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
+ *  
+ * @since 2.0 
+ */
+public class ProtocolFactory {
+
+    /** The available protocols */
+    private Map PROTOCOLS = Collections.synchronizedMap(new HashMap());
+
+    /**
+     * Registers a new protocol with the given identifier.  If a protocol with
+     * the given ID already exists it will be overridden.  This ID is the same
+     * one used to retrieve the protocol from getProtocol(String).
+     * 
+     * @param id the identifier for this protocol
+     * @param protocol the protocol to register
+     * 
+     * @see #getProtocol(String)
+     */
+    public void registerProtocol(String id, Protocol protocol) {
+
+        if (id == null) {
+            throw new IllegalArgumentException("id is null");
+        }
+        if (protocol == null) {
+            throw new IllegalArgumentException("protocol is null");
+        }
+
+        PROTOCOLS.put(id, protocol);
+    }
+
+    /**
+     * Unregisters the protocol with the given ID.
+     * 
+     * @param id the ID of the protocol to remove
+     */
+    public void unregisterProtocol(String id) {
+
+        if (id == null) {
+            throw new IllegalArgumentException("id is null");
+        }
+
+        PROTOCOLS.remove(id);
+    }
+
+    /**
+     * Gets the protocol with the given ID.
+     * 
+     * @param id the protocol ID
+     * 
+     * @return Protocol a protocol
+     * 
+     * @throws IllegalStateException if a protocol with the ID cannot be found
+     */
+    public Protocol getProtocol(String id) 
+        throws IllegalStateException {
+
+        if (id == null) {
+            throw new IllegalArgumentException("id is null");
+        }
+
+        Protocol protocol = (Protocol) PROTOCOLS.get(id);
+
+        if (protocol == null) {
+            protocol = lazyRegisterProtocol(id);
+        }
+
+        return protocol;
+    } 
+
+    /**
+     * Lazily registers the protocol with the given id.
+     * 
+     * @param id the protocol ID
+     * 
+     * @return the lazily registered protocol
+     * 
+     * @throws IllegalStateException if the protocol with id is not recognized
+     */
+    private Protocol lazyRegisterProtocol(String id) 
+        throws IllegalStateException {
+
+        if ("http".equals(id)) {
+            final Protocol http 
+                = new Protocol("http", DefaultProtocolSocketFactory.getSocketFactory(), 80);
+            Protocol.registerProtocol("http", http);
+            return http;
+        }
+
+        if ("https".equals(id)) {
+            final Protocol https 
+                = new Protocol("https", SSLProtocolSocketFactory.getSocketFactory(), 443);
+            Protocol.registerProtocol("https", https);
+            return https;
+        }
+
+        throw new IllegalStateException("unsupported protocol: '" + id + "'");
+    }
+}

Property changes on: src/java/org/apache/commons/httpclient/protocol/ProtocolFactory.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
Index: src/java/org/apache/commons/httpclient/auth/NTLMScheme.java
===================================================================
--- src/java/org/apache/commons/httpclient/auth/NTLMScheme.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 915934)
+++ src/java/org/apache/commons/httpclient/auth/NTLMScheme.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(working copy)
@@ -336,18 +336,23 @@
         NTLM ntlm = new NTLM();
         ntlm.setCredentialCharset(method.getParams().getCredentialCharset());
         String response = null;
+
         if (this.state == INITIATED || this.state == FAILED) {
             response = ntlm.getType1Message(
                 ntcredentials.getHost(), 
                 ntcredentials.getDomain());
             this.state = TYPE1_MSG_GENERATED;
         } else {
+	    NTLM.Type2Message t2m = new NTLM.Type2Message(this.ntlmchallenge);
             response = ntlm.getType3Message(
                 ntcredentials.getUserName(), 
                 ntcredentials.getPassword(),
                 ntcredentials.getHost(), 
                 ntcredentials.getDomain(),
-                ntlm.parseType2Message(this.ntlmchallenge));
+                t2m.getChallenge(),
+		t2m.getFlags(),
+		t2m.getTarget(),
+		t2m.getTargetInfo());
             this.state = TYPE3_MSG_GENERATED;
         }
         return "NTLM " + response;
Index: src/java/org/apache/commons/httpclient/auth/NTLM.java
===================================================================
--- src/java/org/apache/commons/httpclient/auth/NTLM.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 915934)
+++ src/java/org/apache/commons/httpclient/auth/NTLM.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(working copy)
@@ -32,6 +32,9 @@
 
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
+import java.security.Key;
+import java.security.MessageDigest;
+
 import java.util.Locale;
 
 import javax.crypto.BadPaddingException;
@@ -52,9 +55,13 @@
  * exists for it.  This class is based upon the reverse engineering
  * efforts of a wide range of people.</p>
  *
+ * THIS IS A VERY HELPFUL REFERENCE: http://en.wikipedia.org/wiki/NTLM
+ *
  * <p>Please note that an implementation of JCE must be correctly installed and configured when
  * using NTLM support.</p>
  *
+ * NTLMv2 protocol description provided by Michael B Allen <jcifs at samba.org>
+ *
  * <p>This class should not be used externally to HttpClient as it's API is specifically
  * designed to work with HttpClient's use case, in particular it's connection management.</p>
  *
@@ -67,18 +74,52 @@
  */
 final class NTLM {
 
+    // Flags we use
+    protected final static int FLAG_UNICODE_ENCODING = 0x00000001;
+    protected final static int FLAG_TARGET_DESIRED = 0x00000004;
+    protected final static int FLAG_NEGOTIATE_SIGN = 0x00000010;
+    protected final static int FLAG_NEGOTIATE_SEAL = 0x00000020;
+    protected final static int FLAG_NEGOTIATE_NTLM = 0x00000200;
+    protected final static int FLAG_NEGOTIATE_ALWAYS_SIGN = 0x00008000;
+    protected final static int FLAG_NEGOTIATE_NTLM2 = 0x00080000;
+    protected final static int FLAG_NEGOTIATE_128 = 0x20000000;
+    protected final static int FLAG_NEGOTIATE_KEY_EXCH = 0x40000000;
+
+    /** Secure random generator */
+    private static java.security.SecureRandom randomGenerator;
+    static
+    {
+	try
+	{
+		randomGenerator = java.security.SecureRandom.getInstance("SHA1PRNG");
+	}
+	catch (Exception e)
+	{
+		// If exception, nothing we can really do about it - can't even count on log being initialized
+		System.err.println("Couldn't initialize random generator: "+e.getMessage());
+		e.printStackTrace(System.err);
+	}
+    }
+
+    /** Signature string for NTLM messages */
+    private static final String signatureString = "NTLMSSP";
+
     /** Character encoding */
     public static final String DEFAULT_CHARSET = "ASCII";
 
-    /** The current response */
-    private byte[] currentResponse;
-
-    /** The current position */
-    private int currentPosition = 0;
-
     /** The character set to use for encoding the credentials */
     private String credentialCharset = DEFAULT_CHARSET;
     
+    /** The signature string as bytes in the default encoding */
+    private static byte[] signatureBytes;
+    static
+    {
+	byte[] bytesWithoutNull = EncodingUtil.getBytes(signatureString, "ASCII");
+	signatureBytes = new byte[bytesWithoutNull.length + 1];
+	System.arraycopy(bytesWithoutNull,0,signatureBytes,0,bytesWithoutNull.length);
+	signatureBytes[bytesWithoutNull.length] = (byte) 0x00;
+    }
+
     /**
      * Returns the response for the given message.
      *
@@ -98,469 +139,1268 @@
         if (message == null || message.trim().equals("")) {
             response = getType1Message(host, domain);
         } else {
-            response = getType3Message(username, password, host, domain,
-                    parseType2Message(message));
+	    Type2Message t2m = new Type2Message(message);
+	    response = getType3Message(username, password, host, domain,
+                t2m.getChallenge(), t2m.getFlags(), t2m.getTarget(), t2m.getTargetInfo());
         }
         return response;
     }
 
     /**
-     * Return the cipher for the specified key.
-     * @param key The key.
-     * @return Cipher The cipher.
-     * @throws AuthenticationException If the cipher cannot be retrieved.
+     * Creates the first message (type 1 message) in the NTLM authentication sequence.
+     * This message includes the user name, domain and host for the authentication session.
+     *
+     * @param host the computer name of the host requesting authentication.
+     * @param domain The domain to authenticate with.
+     * @return String the message to add to the HTTP request header.
      */
-    private Cipher getCipher(byte[] key) throws AuthenticationException {
-        try {
-            final Cipher ecipher = Cipher.getInstance("DES/ECB/NoPadding");
-            key = setupKey(key);
-            ecipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DES"));
-            return ecipher;
-        } catch (NoSuchAlgorithmException e) {
-            throw new AuthenticationException("DES encryption is not available.", e);
-        } catch (InvalidKeyException e) {
-            throw new AuthenticationException("Invalid key for DES encryption.", e);
-        } catch (NoSuchPaddingException e) {
-            throw new AuthenticationException(
-                "NoPadding option for DES is not available.", e);
-        }
+    public String getType1Message(String host, String domain)
+        throws AuthenticationException {
+        return new Type1Message(domain,host).getResponse();
     }
 
     /** 
-     * Adds parity bits to the key.
-     * @param key56 The key
-     * @return The modified key.
+     * Creates the type 3 message using the given server nonce.  The type 3 message includes all the
+     * information for authentication, host, domain, username and the result of encrypting the
+     * nonce sent by the server using the user's password as the key.
+     *
+     * @param user The user name.  This should not include the domain name.
+     * @param password The password.
+     * @param host The host that is originating the authentication request.
+     * @param domain The domain to authenticate within.
+     * @param nonce the 8 byte array the server sent.
+     * @return The type 3 message.
+     * @throws AuthenticationException If {@encrypt(byte[],byte[])} fails.
      */
-    private byte[] setupKey(byte[] key56) {
-        byte[] key = new byte[8];
-        key[0] = (byte) ((key56[0] >> 1) & 0xff);
-        key[1] = (byte) ((((key56[0] & 0x01) << 6) 
-            | (((key56[1] & 0xff) >> 2) & 0xff)) & 0xff);
-        key[2] = (byte) ((((key56[1] & 0x03) << 5) 
-            | (((key56[2] & 0xff) >> 3) & 0xff)) & 0xff);
-        key[3] = (byte) ((((key56[2] & 0x07) << 4) 
-            | (((key56[3] & 0xff) >> 4) & 0xff)) & 0xff);
-        key[4] = (byte) ((((key56[3] & 0x0f) << 3) 
-            | (((key56[4] & 0xff) >> 5) & 0xff)) & 0xff);
-        key[5] = (byte) ((((key56[4] & 0x1f) << 2) 
-            | (((key56[5] & 0xff) >> 6) & 0xff)) & 0xff);
-        key[6] = (byte) ((((key56[5] & 0x3f) << 1) 
-            | (((key56[6] & 0xff) >> 7) & 0xff)) & 0xff);
-        key[7] = (byte) (key56[6] & 0x7f);
-        
-        for (int i = 0; i < key.length; i++) {
-            key[i] = (byte) (key[i] << 1);
-        }
-        return key;
+    public String getType3Message(String user, String password,
+            String host, String domain, byte[] nonce, int type2Flags, String target, byte[] targetInformation)
+    throws AuthenticationException {
+        return new Type3Message(domain,host,user,password,nonce,type2Flags,target,targetInformation).getResponse();
     }
 
     /**
-     * Encrypt the data.
-     * @param key The key.
-     * @param bytes The data
-     * @return byte[] The encrypted data
-     * @throws HttpException If {@link Cipher.doFinal(byte[])} fails
+     * @return Returns the credentialCharset.
      */
-    private byte[] encrypt(byte[] key, byte[] bytes)
-        throws AuthenticationException {
-        Cipher ecipher = getCipher(key);
-        try {
-            byte[] enc = ecipher.doFinal(bytes);
-            return enc;
-        } catch (IllegalBlockSizeException e) {
-            throw new AuthenticationException("Invalid block size for DES encryption.", e);
-        } catch (BadPaddingException e) {
-            throw new AuthenticationException("Data not padded correctly for DES encryption.", e);
-        }
+    public String getCredentialCharset() {
+        return credentialCharset;
     }
 
     /** 
-     * Prepares the object to create a response of the given length.
-     * @param length the length of the response to prepare.
+     * @param credentialCharset The credentialCharset to set.
      */
-    private void prepareResponse(int length) {
-        currentResponse = new byte[length];
-        currentPosition = 0;
+    public void setCredentialCharset(String credentialCharset) {
+        this.credentialCharset = credentialCharset;
     }
 
-    /** 
-     * Adds the given byte to the response.
-     * @param b the byte to add.
-     */
-    private void addByte(byte b) {
-        currentResponse[currentPosition] = b;
-        currentPosition++;
+    /** Strip dot suffix from a name */
+    private static String stripDotSuffix(String value)
+    {
+	int index = value.indexOf(".");
+	if (index != -1)
+            return value.substring(0,index);
+	return value;
     }
 
-    /** 
-     * Adds the given bytes to the response.
-     * @param bytes the bytes to add.
-     */
-    private void addBytes(byte[] bytes) {
-        for (int i = 0; i < bytes.length; i++) {
-            currentResponse[currentPosition] = bytes[i];
-            currentPosition++;
-        }
+    /** Convert host to standard form */
+    private static String convertHost(String host)
+    {
+	return stripDotSuffix(host);
     }
 
-    /** 
-     * Returns the response that has been generated after shrinking the array if
-     * required and base64 encodes the response.
-     * @return The response as above.
-     */
-    private String getResponse() {
-        byte[] resp;
-        if (currentResponse.length > currentPosition) {
-            byte[] tmp = new byte[currentPosition];
-            for (int i = 0; i < currentPosition; i++) {
-                tmp[i] = currentResponse[i];
-            }
-            resp = tmp;
-        } else {
-            resp = currentResponse;
+    /** Convert domain to standard form */
+    private static String convertDomain(String domain)
+    {
+        return stripDotSuffix(domain);
+    }
+
+    private static int readULong(byte[] src, int index)
+        throws AuthenticationException {
+        if (src.length < index + 4)
+            throw new AuthenticationException("NTLM authentication - buffer too small for DWORD");
+        return (src[index] & 0xff) |
+                ((src[index + 1] & 0xff) << 8) |
+                ((src[index + 2] & 0xff) << 16) |
+                ((src[index + 3] & 0xff) << 24);
+    }
+
+    private static int readUShort(byte[] src, int index)
+        throws AuthenticationException {
+        if (src.length < index + 2)
+            throw new AuthenticationException("NTLM authentication - buffer too small for WORD");
+        return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8);
+    }
+
+    private static byte[] readSecurityBuffer(byte[] src, int index) 
+        throws AuthenticationException {
+        int length = readUShort(src, index);
+        int offset = readULong(src, index + 4);
+	if (src.length < offset + length)
+            throw new AuthenticationException("NTLM authentication - buffer too small for data item");
+        byte[] buffer = new byte[length];
+        System.arraycopy(src, offset, buffer, 0, length);
+        return buffer;
+    }
+
+    /** Calculate a challenge block */
+    private static byte[] makeRandomChallenge()
+    {
+        byte[] rval = new byte[8];
+        synchronized (randomGenerator)
+        {
+            randomGenerator.nextBytes(rval);
         }
-        return EncodingUtil.getAsciiString(Base64.encodeBase64(resp));
+        return rval;
     }
+     
+    /** Calculate an NTLM2 challenge block */
+    private static byte[] makeNTLM2RandomChallenge()
+    {
+        byte[] rval = new byte[24];
+        synchronized (randomGenerator)
+        {
+            randomGenerator.nextBytes(rval);
+        }
+        // 8-byte challenge, padded with zeros to 24 bytes.
+        java.util.Arrays.fill(rval,8,24,(byte)0x00);
+        return rval;
+    }
     
+    
     /**
-     * Creates the first message (type 1 message) in the NTLM authentication sequence.
-     * This message includes the user name, domain and host for the authentication session.
+     * Calculates the LM Response for the given challenge, using the specified
+     * password.
      *
-     * @param host the computer name of the host requesting authentication.
-     * @param domain The domain to authenticate with.
-     * @return String the message to add to the HTTP request header.
+     * @param password The user's password.
+     * @param challenge The Type 2 challenge from the server.
+     *
+     * @return The LM Response.
      */
-    public String getType1Message(String host, String domain) {
-        host = host.toUpperCase(Locale.ENGLISH);
-        domain = domain.toUpperCase(Locale.ENGLISH);
-        byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET);
-        byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET);
+    public static byte[] getLMResponse(String password, byte[] challenge)
+        throws AuthenticationException {
+        byte[] lmHash = lmHash(password);
+        return lmResponse(lmHash, challenge);
+    }
 
-        int finalLength = 32 + hostBytes.length + domainBytes.length;
-        prepareResponse(finalLength);
-        
-        // The initial id string.
-        byte[] protocol = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET);
-        addBytes(protocol);
-        addByte((byte) 0);
+    /**
+     * Calculates the NTLM Response for the given challenge, using the
+     * specified password.
+     *
+     * @param password The user's password.
+     * @param challenge The Type 2 challenge from the server.
+     *
+     * @return The NTLM Response.
+     */
+    public static byte[] getNTLMResponse(String password, byte[] challenge)
+        throws AuthenticationException {
+        byte[] ntlmHash = ntlmHash(password);
+        return lmResponse(ntlmHash, challenge);
+    }
 
-        // Type
-        addByte((byte) 1);
-        addByte((byte) 0);
-        addByte((byte) 0);
-        addByte((byte) 0);
+    /**
+     * Calculates the NTLMv2 Response for the given challenge, using the
+     * specified authentication target, username, password, target information
+     * block, and client challenge.
+     *
+     * @param target The authentication target (i.e., domain).
+     * @param user The username. 
+     * @param password The user's password.
+     * @param targetInformation The target information block from the Type 2
+     * message.
+     * @param challenge The Type 2 challenge from the server.
+     * @param clientChallenge The random 8-byte client challenge. 
+     *
+     * @return The NTLMv2 Response.
+     */
+    public static byte[] getNTLMv2Response(String target, String user,
+        String password, byte[] challenge,
+        byte[] clientChallenge, byte[] targetInformation)
+            throws AuthenticationException {
+        byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+        byte[] blob = createBlob(clientChallenge, targetInformation);
+        return lmv2Response(ntlmv2Hash, challenge, blob);
+    }
 
-        // Flags
-        addByte((byte) 6);
-        addByte((byte) 82);
-        addByte((byte) 0);
-        addByte((byte) 0);
+    /**
+     * Calculates the LMv2 Response for the given challenge, using the
+     * specified authentication target, username, password, and client
+     * challenge.
+     *
+     * @param target The authentication target (i.e., domain).
+     * @param user The username.
+     * @param password The user's password.
+     * @param challenge The Type 2 challenge from the server.
+     * @param clientChallenge The random 8-byte client challenge.
+     *
+     * @return The LMv2 Response. 
+     */
+    public static byte[] getLMv2Response(String target, String user,
+        String password, byte[] challenge, byte[] clientChallenge)
+            throws AuthenticationException {
+        byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+        return lmv2Response(ntlmv2Hash, challenge, clientChallenge);
+    }
 
-        // Domain length (first time).
-        int iDomLen = domainBytes.length;
-        byte[] domLen = convertShort(iDomLen);
-        addByte(domLen[0]);
-        addByte(domLen[1]);
+    /**
+     * Calculates the NTLM2 Session Response for the given challenge, using the
+     * specified password and client challenge.
+     *
+     * @param password The user's password.
+     * @param challenge The Type 2 challenge from the server.
+     * @param clientChallenge The random 8-byte client challenge.
+     *
+     * @return The NTLM2 Session Response.  This is placed in the NTLM
+     * response field of the Type 3 message; the LM response field contains
+     * the client challenge, null-padded to 24 bytes.
+     */
+    public static byte[] getNTLM2SessionResponse(String password,
+        byte[] challenge, byte[] clientChallenge) throws AuthenticationException
+    {
+        try
+        {
+            byte[] ntlmHash = ntlmHash(password);
 
-        // Domain length (second time).
-        addByte(domLen[0]);
-        addByte(domLen[1]);
+            // Look up MD5 algorithm (was necessary on jdk 1.4.2)
+            // This used to be needed, but java 1.5.0_07 includes the MD5 algorithm (finally)
+            //Class x = Class.forName("gnu.crypto.hash.MD5");
+            //Method updateMethod = x.getMethod("update",new Class[]{byte[].class});
+            //Method digestMethod = x.getMethod("digest",new Class[0]);
+            //Object mdInstance = x.newInstance();
+            //updateMethod.invoke(mdInstance,new Object[]{challenge});
+            //updateMethod.invoke(mdInstance,new Object[]{clientChallenge});
+            //byte[] digest = (byte[])digestMethod.invoke(mdInstance,new Object[0]);
+	
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            md5.update(challenge);
+            md5.update(clientChallenge);
+            byte[] digest = md5.digest();
+	
+            byte[] sessionHash = new byte[8];
+            System.arraycopy(digest, 0, sessionHash, 0, 8);
+            return lmResponse(ntlmHash, sessionHash);
+        }
+        catch (Exception e)
+        {
+            if (e instanceof AuthenticationException)
+                throw (AuthenticationException)e;
+            throw new AuthenticationException(e.getMessage(),e);
+	}
+    }
 
-        // Domain offset.
-        byte[] domOff = convertShort(hostBytes.length + 32);
-        addByte(domOff[0]);
-        addByte(domOff[1]);
-        addByte((byte) 0);
-        addByte((byte) 0);
+    /**
+     * Creates the LM Hash of the user's password.
+     *
+     * @param password The password.
+     *
+     * @return The LM Hash of the given password, used in the calculation
+     * of the LM Response.
+     */
+    private static byte[] lmHash(String password) throws AuthenticationException
+    {
+        try
+        {
+            byte[] oemPassword = password.toUpperCase().getBytes("US-ASCII");
+            int length = Math.min(oemPassword.length, 14);
+            byte[] keyBytes = new byte[14];
+            System.arraycopy(oemPassword, 0, keyBytes, 0, length);
+            Key lowKey = createDESKey(keyBytes, 0);
+            Key highKey = createDESKey(keyBytes, 7);
+            byte[] magicConstant = "KGS!@#$%".getBytes("US-ASCII");
+            Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+            des.init(Cipher.ENCRYPT_MODE, lowKey);
+            byte[] lowHash = des.doFinal(magicConstant);
+            des.init(Cipher.ENCRYPT_MODE, highKey);
+            byte[] highHash = des.doFinal(magicConstant);
+            byte[] lmHash = new byte[16];
+            System.arraycopy(lowHash, 0, lmHash, 0, 8);
+            System.arraycopy(highHash, 0, lmHash, 8, 8);
+            return lmHash;
+        }
+        catch (Exception e)
+        {
+            throw new AuthenticationException(e.getMessage(),e);
+        }
+    }
 
-        // Host length (first time).
-        byte[] hostLen = convertShort(hostBytes.length);
-        addByte(hostLen[0]);
-        addByte(hostLen[1]);
+    /**
+     * Creates the NTLM Hash of the user's password.
+     *
+     * @param password The password.
+     *
+     * @return The NTLM Hash of the given password, used in the calculation
+     * of the NTLM Response and the NTLMv2 and LMv2 Hashes.
+     */
+    private static byte[] ntlmHash(String password) throws AuthenticationException
+    {
+        try
+        {
+            byte[] unicodePassword = password.getBytes("UnicodeLittleUnmarked");
+            MD4 md4 = new MD4();
+            md4.update(unicodePassword);
+            return md4.getOutput();
+        }
+        catch (java.io.UnsupportedEncodingException e)
+        {
+            throw new AuthenticationException("Unicode not supported: "+e.getMessage(),e);
+        }
+    }
 
-        // Host length (second time).
-        addByte(hostLen[0]);
-        addByte(hostLen[1]);
+    /**
+     * Creates the NTLMv2 Hash of the user's password.
+     *
+     * @param target The authentication target (i.e., domain).
+     * @param user The username.
+     * @param password The password.
+     *
+     * @return The NTLMv2 Hash, used in the calculation of the NTLMv2
+     * and LMv2 Responses. 
+     */
+    private static byte[] ntlmv2Hash(String target, String user,
+        String password) throws AuthenticationException
+    {
+        try
+        {
+            byte[] ntlmHash = ntlmHash(password);
+            HMACMD5 hmacMD5 = new HMACMD5(ntlmHash);
+            // Upper case username, mixed case target!!
+            hmacMD5.update(user.toUpperCase().getBytes("UnicodeLittleUnmarked"));
+            hmacMD5.update(target.getBytes("UnicodeLittleUnmarked"));
+            return hmacMD5.getOutput();
+        }
+        catch (java.io.UnsupportedEncodingException e)
+        {
+            throw new AuthenticationException("Unicode not supported! "+e.getMessage(),e);
+        }
+    }
 
-        // Host offset (always 32).
-        byte[] hostOff = convertShort(32);
-        addByte(hostOff[0]);
-        addByte(hostOff[1]);
-        addByte((byte) 0);
-        addByte((byte) 0);
+    /**
+     * Creates the LM Response from the given hash and Type 2 challenge.
+     *
+     * @param hash The LM or NTLM Hash.
+     * @param challenge The server challenge from the Type 2 message.
+     *
+     * @return The response (either LM or NTLM, depending on the provided
+     * hash).
+     */
+    private static byte[] lmResponse(byte[] hash, byte[] challenge)
+        throws AuthenticationException
+    {
+        try
+        {
+            byte[] keyBytes = new byte[21];
+            System.arraycopy(hash, 0, keyBytes, 0, 16);
+            Key lowKey = createDESKey(keyBytes, 0);
+            Key middleKey = createDESKey(keyBytes, 7);
+            Key highKey = createDESKey(keyBytes, 14);
+            Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+            des.init(Cipher.ENCRYPT_MODE, lowKey);
+            byte[] lowResponse = des.doFinal(challenge);
+            des.init(Cipher.ENCRYPT_MODE, middleKey);
+            byte[] middleResponse = des.doFinal(challenge);
+            des.init(Cipher.ENCRYPT_MODE, highKey);
+            byte[] highResponse = des.doFinal(challenge);
+            byte[] lmResponse = new byte[24];
+            System.arraycopy(lowResponse, 0, lmResponse, 0, 8);
+            System.arraycopy(middleResponse, 0, lmResponse, 8, 8);
+            System.arraycopy(highResponse, 0, lmResponse, 16, 8);
+            return lmResponse;
+        }
+        catch (Exception e)
+        {
+            throw new AuthenticationException(e.getMessage(),e);
+        }
+    }
 
-        // Host String.
-        addBytes(hostBytes);
-
-        // Domain String.
-        addBytes(domainBytes);
-
-        return getResponse();
+    /**
+     * Creates the LMv2 Response from the given hash, client data, and
+     * Type 2 challenge.
+     *
+     * @param hash The NTLMv2 Hash.
+     * @param clientData The client data (blob or client challenge).
+     * @param challenge The server challenge from the Type 2 message.
+     *
+     * @return The response (either NTLMv2 or LMv2, depending on the
+     * client data).
+     */
+    private static byte[] lmv2Response(byte[] hash, byte[] challenge,
+        byte[] clientData) throws AuthenticationException
+    {
+        HMACMD5 hmacMD5 = new HMACMD5(hash);
+        hmacMD5.update(challenge);
+        hmacMD5.update(clientData);
+        byte[] mac = hmacMD5.getOutput();
+        byte[] lmv2Response = new byte[mac.length + clientData.length];
+        System.arraycopy(mac, 0, lmv2Response, 0, mac.length);
+        System.arraycopy(clientData, 0, lmv2Response, mac.length,
+            clientData.length);
+        return lmv2Response;
     }
 
-    /** 
-     * Extracts the server nonce out of the given message type 2.
-     * 
-     * @param message the String containing the base64 encoded message.
-     * @return an array of 8 bytes that the server sent to be used when
-     * hashing the password.
+    /**
+     * Creates the NTLMv2 blob from the given target information block and
+     * client challenge.
+     *
+     * @param targetInformation The target information block from the Type 2
+     * message.
+     * @param clientChallenge The random 8-byte client challenge.
+     *
+     * @return The blob, used in the calculation of the NTLMv2 Response.
      */
-    public byte[] parseType2Message(String message) {
-        // Decode the message first.
-        byte[] msg = Base64.decodeBase64(EncodingUtil.getBytes(message, DEFAULT_CHARSET));
-        byte[] nonce = new byte[8];
-        // The nonce is the 8 bytes starting from the byte in position 24.
+    private static byte[] createBlob(byte[] clientChallenge, byte[] targetInformation) {
+        byte[] blobSignature = new byte[] {
+            (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00
+        };
+        byte[] reserved = new byte[] {
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+        };
+        byte[] unknown1 = new byte[] {
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+        };
+        long time = System.currentTimeMillis();
+        time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch.
+        time *= 10000; // tenths of a microsecond.
+        // convert to little-endian byte array.
+        byte[] timestamp = new byte[8];
         for (int i = 0; i < 8; i++) {
-            nonce[i] = msg[i + 24];
+            timestamp[i] = (byte) time;
+            time >>>= 8;
         }
-        return nonce;
+        byte[] blob = new byte[blobSignature.length + reserved.length+ timestamp.length + 8 +
+            unknown1.length + targetInformation.length];
+        int offset = 0;
+        System.arraycopy(blobSignature, 0, blob, offset, blobSignature.length);
+        offset += blobSignature.length;
+        System.arraycopy(reserved, 0, blob, offset, reserved.length);
+        offset += reserved.length;
+        System.arraycopy(timestamp, 0, blob, offset, timestamp.length);
+        offset += timestamp.length;
+        System.arraycopy(clientChallenge, 0, blob, offset,8);
+        offset += 8;
+        System.arraycopy(unknown1, 0, blob, offset, unknown1.length);
+        offset += unknown1.length;
+        System.arraycopy(targetInformation, 0, blob, offset,
+            targetInformation.length);
+        return blob;
     }
 
     /** 
-     * Creates the type 3 message using the given server nonce.  The type 3 message includes all the
-     * information for authentication, host, domain, username and the result of encrypting the
-     * nonce sent by the server using the user's password as the key.
+     * Creates a DES encryption key from the given key material.
      *
-     * @param user The user name.  This should not include the domain name.
-     * @param password The password.
-     * @param host The host that is originating the authentication request.
-     * @param domain The domain to authenticate within.
-     * @param nonce the 8 byte array the server sent.
-     * @return The type 3 message.
-     * @throws AuthenticationException If {@encrypt(byte[],byte[])} fails.
+     * @param bytes A byte array containing the DES key material.
+     * @param offset The offset in the given byte array at which
+     * the 7-byte key material starts.
+     *
+     * @return A DES encryption key created from the key material
+     * starting at the specified offset in the given byte array.
      */
-    public String getType3Message(String user, String password,
-            String host, String domain, byte[] nonce)
-    throws AuthenticationException {
+    private static Key createDESKey(byte[] bytes, int offset) {
+        byte[] keyBytes = new byte[7];
+        System.arraycopy(bytes, offset, keyBytes, 0, 7);
+        byte[] material = new byte[8];
+        material[0] = keyBytes[0];
+        material[1] = (byte) (keyBytes[0] << 7 | (keyBytes[1] & 0xff) >>> 1);
+        material[2] = (byte) (keyBytes[1] << 6 | (keyBytes[2] & 0xff) >>> 2);
+        material[3] = (byte) (keyBytes[2] << 5 | (keyBytes[3] & 0xff) >>> 3);
+        material[4] = (byte) (keyBytes[3] << 4 | (keyBytes[4] & 0xff) >>> 4);
+        material[5] = (byte) (keyBytes[4] << 3 | (keyBytes[5] & 0xff) >>> 5);
+        material[6] = (byte) (keyBytes[5] << 2 | (keyBytes[6] & 0xff) >>> 6);
+        material[7] = (byte) (keyBytes[6] << 1);
+        oddParity(material);
+        return new SecretKeySpec(material, "DES");
+    }
 
-        int ntRespLen = 0;
-        int lmRespLen = 24;
-        domain = domain.toUpperCase(Locale.ENGLISH);
-        host = host.toUpperCase(Locale.ENGLISH);
-        user = user.toUpperCase(Locale.ENGLISH);
-        byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET);
-        byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET);
-        byte[] userBytes = EncodingUtil.getBytes(user, credentialCharset);
-        int domainLen = domainBytes.length;
-        int hostLen = hostBytes.length;
-        int userLen = userBytes.length;
-        int finalLength = 64 + ntRespLen + lmRespLen + domainLen 
-            + userLen + hostLen;
-        prepareResponse(finalLength);
-        byte[] ntlmssp = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET);
-        addBytes(ntlmssp);
-        addByte((byte) 0);
-        addByte((byte) 3);
-        addByte((byte) 0);
-        addByte((byte) 0);
-        addByte((byte) 0);
+    /**
+     * Applies odd parity to the given byte array.
+     *
+     * @param bytes The data whose parity bits are to be adjusted for
+     * odd parity.
+     */
+    private static void oddParity(byte[] bytes) {
+        for (int i = 0; i < bytes.length; i++) {
+            byte b = bytes[i];
+            boolean needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^
+                                    (b >>> 4) ^ (b >>> 3) ^ (b >>> 2) ^
+                                    (b >>> 1)) & 0x01) == 0;
+            if (needsParity) {
+                bytes[i] |= (byte) 0x01;
+            } else {
+                bytes[i] &= (byte) 0xfe;
+            }
+        }
+    }
+    
+    /** NTLM message generation, base class */
+    protected static class NTLMMessage
+    {
+        /** The current response */
+        private byte[] messageContents = null;
 
-        // LM Resp Length (twice)
-        addBytes(convertShort(24));
-        addBytes(convertShort(24));
+        /** The current output position */
+        private int currentOutputPosition = 0;
 
-        // LM Resp Offset
-        addBytes(convertShort(finalLength - 24));
-        addByte((byte) 0);
-        addByte((byte) 0);
+        /** Constructor to use when message contents are not yet known */
+        public NTLMMessage()
+        {
+        }
+	
+        /** Constructor to use when message contents are known */
+        public NTLMMessage(String messageBody, int expectedType)
+            throws AuthenticationException
+        {
+            messageContents = Base64.decodeBase64(EncodingUtil.getBytes(messageBody, DEFAULT_CHARSET));
+            // Look for NTLM message
+            if (messageContents.length < signatureBytes.length)
+                throw new AuthenticationException("NTLM message decoding error - packet too short");
+            int i = 0;
+            while (i < signatureBytes.length)
+            {
+                if (messageContents[i] != signatureBytes[i])
+                    throw new AuthenticationException("NTLM message expected - instead got unrecognized bytes");
+                i++;
+            }
 
-        // NT Resp Length (twice)
-        addBytes(convertShort(0));
-        addBytes(convertShort(0));
+            // Check to be sure there's a type 2 message indicator next
+            int type = readULong(signatureBytes.length);
+            if (type != expectedType)
+                throw new AuthenticationException("NTLM type "+Integer.toString(expectedType)+" message expected - instead got type "+Integer.toString(type));
+		
+            currentOutputPosition = messageContents.length;
+        }
 
-        // NT Resp Offset
-        addBytes(convertShort(finalLength));
-        addByte((byte) 0);
-        addByte((byte) 0);
-
-        // Domain length (twice)
-        addBytes(convertShort(domainLen));
-        addBytes(convertShort(domainLen));
+        /** Get the length of the signature and flags, so calculations can adjust offsets accordingly.
+        */
+        protected int getPreambleLength()
+        {
+            return signatureBytes.length + 4;
+        }
+	
+        /** Get the message length */
+        protected int getMessageLength()
+        {
+            return currentOutputPosition;
+        }
         
-        // Domain offset.
-        addBytes(convertShort(64));
-        addByte((byte) 0);
-        addByte((byte) 0);
+        /** Read a byte from a position within the message buffer */
+        protected byte readByte(int position) throws AuthenticationException
+        {
+            if (messageContents.length < position + 1)
+                throw new AuthenticationException("NTLM: Message too short");
+            return messageContents[position];
+        }
 
-        // User Length (twice)
-        addBytes(convertShort(userLen));
-        addBytes(convertShort(userLen));
+        /** Read a bunch of bytes from a position in the message buffer */
+        protected void readBytes(byte[] buffer, int position)
+            throws AuthenticationException
+        {
+            if (messageContents.length < position + buffer.length)
+                throw new AuthenticationException("NTLM: Message too short");
+            System.arraycopy(messageContents,position,buffer,0,buffer.length);
+        }
+	
+        /** Read a ushort from a position within the message buffer */
+        protected int readUShort(int position) throws AuthenticationException
+        {
+            return NTLM.readUShort(messageContents,position);
+        }
+	
+        /** Read a ulong from a position within the message buffer */
+        protected int readULong(int position) throws AuthenticationException
+        {
+            return NTLM.readULong(messageContents,position);
+        }
+	
+        /** Read a security buffer from a position within the message buffer */
+        protected byte[] readSecurityBuffer(int position) throws AuthenticationException
+        {
+            return NTLM.readSecurityBuffer(messageContents,position);
+        }
+	
+        /** 
+        * Prepares the object to create a response of the given length.
+        * @param length the maximum length of the response to prepare, not including the type and the signature (which this method adds).
+        */
+        protected void prepareResponse(int maxlength, int messageType) {
+            messageContents = new byte[maxlength];
+            currentOutputPosition = 0;
+            addBytes(signatureBytes);
+            addULong(messageType);
+        }
 
-        // User offset
-        addBytes(convertShort(64 + domainLen));
-        addByte((byte) 0);
-        addByte((byte) 0);
+        /** 
+        * Adds the given byte to the response.
+        * @param b the byte to add.
+        */
+        protected void addByte(byte b) {
+            messageContents[currentOutputPosition] = b;
+            currentOutputPosition++;
+        }
 
-        // Host length (twice)
-        addBytes(convertShort(hostLen));
-        addBytes(convertShort(hostLen));
+        /** 
+        * Adds the given bytes to the response.
+        * @param bytes the bytes to add.
+        */
+        protected void addBytes(byte[] bytes) {
+            for (int i = 0; i < bytes.length; i++) {
+                messageContents[currentOutputPosition] = bytes[i];
+                currentOutputPosition++;
+            }
+        }
 
-        // Host offset
-        addBytes(convertShort(64 + domainLen + userLen));
+        /** Adds a USHORT to the response */
+        protected void addUShort(int value) {
+            addByte((byte) (value & 0xff));
+            addByte((byte) (value >> 8 & 0xff));
+        }
+	
+        /** Adds a ULong to the response */
+        protected void addULong(int value) {
+            addByte((byte) (value & 0xff));
+            addByte((byte) (value >> 8 & 0xff));
+            addByte((byte) (value >> 16 & 0xff));
+            addByte((byte) (value >> 24 & 0xff));
+        }
 
-        for (int i = 0; i < 6; i++) {
-            addByte((byte) 0);
+        /** 
+        * Returns the response that has been generated after shrinking the array if
+        * required and base64 encodes the response.
+        * @return The response as above.
+        */
+        public String getResponse() {
+            byte[] resp;
+            if (messageContents.length > currentOutputPosition) {
+                byte[] tmp = new byte[currentOutputPosition];
+                for (int i = 0; i < currentOutputPosition; i++) {
+                    tmp[i] = messageContents[i];
+                }
+                resp = tmp;
+            } else {
+                resp = messageContents;
+            }
+            return EncodingUtil.getAsciiString(Base64.encodeBase64(resp));
         }
 
-        // Message length
-        addBytes(convertShort(finalLength));
-        addByte((byte) 0);
-        addByte((byte) 0);
+    }
+    
+    /** Type 1 message assembly class */
+    public static class Type1Message extends NTLMMessage
+    {
+	protected byte[] hostBytes;
+	protected byte[] domainBytes;
 
-        // Flags
-        addByte((byte) 6);
-        addByte((byte) 82);
-        addByte((byte) 0);
-        addByte((byte) 0);
+        /** Constructor.  Include the arguments the message will need */
+        public Type1Message(String domain, String host)
+	    throws AuthenticationException
+        {
+            super();
+            try
+            {
+                // Strip off domain name from the host!
+                host = convertHost(host);
+                // Use only the base domain name!
+                domain = convertDomain(domain);
+	
+                hostBytes = host.getBytes("UnicodeLittleUnmarked");
+                domainBytes = domain.toUpperCase().getBytes("UnicodeLittleUnmarked");
+            }
+            catch (java.io.UnsupportedEncodingException e)
+            {
+                throw new AuthenticationException("Unicode unsupported: "+e.getMessage(),e);
+            }
+        }
+	
+        /** Getting the response involves building the message before returning it */
+        public String getResponse()
+        {
+            // Now, build the message.  Calculate its length first, including signature or type.
+            int finalLength = 32 + hostBytes.length + domainBytes.length;
+            
+            // Set up the response.  This will initialize the signature, message type, and flags.
+            prepareResponse(finalLength,1);
+		
+            // Flags.  These are the complete set of flags we support.
+            addULong(FLAG_NEGOTIATE_NTLM |
+                FLAG_NEGOTIATE_NTLM2 |
+                FLAG_NEGOTIATE_SIGN |
+                FLAG_NEGOTIATE_SEAL |
+                /* FLAG_NEGOTIATE_ALWAYS_SIGN |
+                    FLAG_NEGOTIATE_KEY_EXCH | */
+                FLAG_UNICODE_ENCODING |
+                FLAG_TARGET_DESIRED |
+                FLAG_NEGOTIATE_128);
 
-        addBytes(domainBytes);
-        addBytes(userBytes);
-        addBytes(hostBytes);
-        addBytes(hashPassword(password, nonce));
-        return getResponse();
-    }
+            // Domain length (two times).
+            addUShort(domainBytes.length);
+            addUShort(domainBytes.length);
 
-    /** 
-     * Creates the LANManager and NT response for the given password using the
-     * given nonce.
-     * @param password the password to create a hash for.
-     * @param nonce the nonce sent by the server.
-     * @return The response.
-     * @throws HttpException If {@link #encrypt(byte[],byte[])} fails.
-     */
-    private byte[] hashPassword(String password, byte[] nonce)
-        throws AuthenticationException {
-        byte[] passw = EncodingUtil.getBytes(password.toUpperCase(Locale.ENGLISH), credentialCharset);
-        byte[] lmPw1 = new byte[7];
-        byte[] lmPw2 = new byte[7];
+            // Domain offset.
+            addULong(hostBytes.length + 32);
 
-        int len = passw.length;
-        if (len > 7) {
-            len = 7;
+            // Host length (two times).
+            addUShort(hostBytes.length);
+            addUShort(hostBytes.length);
+
+            // Host offset (always 32).
+            addULong(32);
+		
+            // Host String.
+            addBytes(hostBytes);
+
+            // Domain String.
+            addBytes(domainBytes);
+
+            return super.getResponse();
         }
 
-        int idx;
-        for (idx = 0; idx < len; idx++) {
-            lmPw1[idx] = passw[idx];
+    }
+
+    /** Type 2 message class */
+    public static class Type2Message extends NTLMMessage
+    {
+        protected byte[] challenge;
+        protected String target;
+        protected byte[] targetInfo;
+        protected int flags;
+
+        public Type2Message(String message)
+	    throws AuthenticationException
+        {
+            super(message,2);
+		
+            // Parse out the rest of the info we need from the message
+            // The nonce is the 8 bytes starting from the byte in position 24.
+            challenge = new byte[8];
+            readBytes(challenge,24);
+
+            flags = readULong(20);
+            if ((flags & FLAG_UNICODE_ENCODING) == 0)
+                throw new AuthenticationException("NTLM type 2 message has flags that make no sense: "+Integer.toString(flags));
+            // Do the target!
+            target = null;
+            // The TARGET_DESIRED flag is said to not have understood semantics in Type2 messages, so use the length of the packet to decide
+            // how to proceed instead
+            if (getMessageLength() >= 12 + 8)
+            {
+                byte[] bytes = readSecurityBuffer(12);
+                if (bytes.length != 0)
+                {
+                    try
+                    {
+                        target = new String(bytes,"UnicodeLittleUnmarked");
+                    }
+                    catch (java.io.UnsupportedEncodingException e)
+                    {
+                        throw new AuthenticationException(e.getMessage(),e);
+                    }
+                }
+            }
+
+            // Do the target info!
+            targetInfo = null;
+            // TARGET_DESIRED flag cannot be relied on, so use packet length
+            if (getMessageLength() >= 40 + 8)
+            {
+                byte[] bytes = readSecurityBuffer(40);
+                if (bytes.length != 0)
+                {
+                    targetInfo = bytes;
+                }
+            }
         }
-        for (; idx < 7; idx++) {
-            lmPw1[idx] = (byte) 0;
+	
+        /** Retrieve the challenge */
+        public byte[] getChallenge()
+        {
+            return challenge;
         }
-
-        len = passw.length;
-        if (len > 14) {
-            len = 14;
+	
+        /** Retrieve the target */
+        public String getTarget()
+        {
+            return target;
         }
-        for (idx = 7; idx < len; idx++) {
-            lmPw2[idx - 7] = passw[idx];
+	
+        /** Retrieve the target info */
+        public byte[] getTargetInfo()
+        {
+            return targetInfo;
         }
-        for (; idx < 14; idx++) {
-            lmPw2[idx - 7] = (byte) 0;
+	
+        /** Retrieve the response flags */
+        public int getFlags()
+        {
+            return flags;
         }
 
-        // Create LanManager hashed Password
-        byte[] magic = {
-            (byte) 0x4B, (byte) 0x47, (byte) 0x53, (byte) 0x21, 
-            (byte) 0x40, (byte) 0x23, (byte) 0x24, (byte) 0x25
-        };
+    }
 
-        byte[] lmHpw1;
-        lmHpw1 = encrypt(lmPw1, magic);
+    /** Type 3 message assembly class */
+    public static class Type3Message extends NTLMMessage
+    {
+        // Response flags from the type2 message
+        protected int type2Flags;
 
-        byte[] lmHpw2 = encrypt(lmPw2, magic);
+        protected byte[] domainBytes;
+        protected byte[] hostBytes;
+        protected byte[] userBytes;
+	
+        protected byte[] lmResp;
+        protected byte[] ntResp;
 
-        byte[] lmHpw = new byte[21];
-        for (int i = 0; i < lmHpw1.length; i++) {
-            lmHpw[i] = lmHpw1[i];
+        /** Constructor.  Pass the arguments we will need */
+        public Type3Message(String domain, String host, String user, String password,
+            byte[] nonce, int type2Flags, String target, byte[] targetInformation)
+	    throws AuthenticationException
+        {
+            // Save the flags
+            this.type2Flags = type2Flags;
+		
+            // Strip off domain name from the host!
+            host = convertHost(host);
+            // Use only the base domain name!
+            domain = convertDomain(domain);
+
+            // Use the new code to calculate the responses, including v2 if that seems warranted.
+            try
+            {
+                if (targetInformation != null && target != null)
+                {
+                    byte[] clientChallenge = makeRandomChallenge();
+                    ntResp = getNTLMv2Response(target,user,password,nonce,clientChallenge,targetInformation);
+                    lmResp = getLMv2Response(target,user,password,nonce,clientChallenge);
+                }
+                else
+                {
+                    if ((type2Flags & FLAG_NEGOTIATE_NTLM2) != 0)
+                    {
+                        // NTLM2 session stuff is requested
+                        byte[] clientChallenge = makeNTLM2RandomChallenge();
+				
+                        ntResp = getNTLM2SessionResponse(password,nonce,clientChallenge);
+                        lmResp = clientChallenge;
+				
+                        // All the other flags we send (signing, sealing, key exchange) are supported, but they don't do anything at all in an
+                        // NTLM2 context!  So we're done at this point.
+                    }
+                    else
+                    {
+                        ntResp = getNTLMResponse(password,nonce);
+                        lmResp = getLMResponse(password,nonce);
+                    }
+                }
+            }
+            catch (AuthenticationException e)
+            {
+                // This likely means we couldn't find the MD4 hash algorithm - fail back to just using LM
+                ntResp = new byte[0];
+                lmResp = getLMResponse(password,nonce);
+            }
+
+            try
+            {
+                domainBytes = domain.toUpperCase().getBytes("UnicodeLittleUnmarked");
+                hostBytes = host.getBytes("UnicodeLittleUnmarked");
+                userBytes = user.getBytes("UnicodeLittleUnmarked");
+            }
+            catch (java.io.UnsupportedEncodingException e)
+            {
+                throw new AuthenticationException("Unicode not supported: "+e.getMessage(),e);
+            }
         }
-        for (int i = 0; i < lmHpw2.length; i++) {
-            lmHpw[i + 8] = lmHpw2[i];
+	
+        /** Assemble the response */
+        public String getResponse()
+        {
+            int ntRespLen = ntResp.length;
+            int lmRespLen = lmResp.length;
+
+            int domainLen = domainBytes.length;
+            int hostLen = hostBytes.length;
+            int userLen = userBytes.length;
+		    
+            // Calculate the layout within the packet
+            int lmRespOffset = 64;
+            int ntRespOffset = lmRespOffset + lmRespLen;
+            int domainOffset = ntRespOffset + ntRespLen;
+            int userOffset = domainOffset + domainLen;
+            int hostOffset = userOffset + userLen;
+            int sessionKeyOffset = hostOffset + hostLen;
+            int finalLength = sessionKeyOffset + 0;
+		
+            // Start the response.  Length includes signature and type
+            prepareResponse(finalLength,3);
+		
+            // LM Resp Length (twice)
+            addUShort(lmRespLen);
+            addUShort(lmRespLen);
+
+            // LM Resp Offset
+            addULong(lmRespOffset);
+
+            // NT Resp Length (twice)
+            addUShort(ntRespLen);
+            addUShort(ntRespLen);
+
+            // NT Resp Offset
+            addULong(ntRespOffset);
+
+            // Domain length (twice)
+            addUShort(domainLen);
+            addUShort(domainLen);
+		
+            // Domain offset.
+            addULong(domainOffset);
+
+            // User Length (twice)
+            addUShort(userLen);
+            addUShort(userLen);
+
+            // User offset
+            addULong(userOffset);
+
+            // Host length (twice)
+            addUShort(hostLen);
+            addUShort(hostLen);
+
+            // Host offset
+            addULong(hostOffset);
+		
+            // 4 bytes of zeros - not sure what this is
+            addULong(0);
+
+            // Message length
+            addULong(finalLength);
+		
+            // Flags.  Currently:  NEGOTIATE_NTLM + UNICODE_ENCODING + TARGET_DESIRED + NEGOTIATE_128
+            addULong(FLAG_NEGOTIATE_NTLM | FLAG_UNICODE_ENCODING | FLAG_TARGET_DESIRED | FLAG_NEGOTIATE_128 |
+                (type2Flags & FLAG_NEGOTIATE_NTLM2) |
+                (type2Flags & FLAG_NEGOTIATE_SIGN) |
+                (type2Flags & FLAG_NEGOTIATE_SEAL) |
+                (type2Flags & FLAG_NEGOTIATE_KEY_EXCH) |
+                (type2Flags & FLAG_NEGOTIATE_ALWAYS_SIGN));
+
+            // Add the actual data
+            addBytes(lmResp);
+            addBytes(ntResp);
+            addBytes(domainBytes);
+            addBytes(userBytes);
+            addBytes(hostBytes);
+
+            return super.getResponse();
         }
-        for (int i = 0; i < 5; i++) {
-            lmHpw[i + 16] = (byte) 0;
-        }
+    }
 
-        // Create the responses.
-        byte[] lmResp = new byte[24];
-        calcResp(lmHpw, nonce, lmResp);
+    protected static void writeULong(byte[] buffer, int value, int offset)
+    {
+        buffer[offset] = (byte) (value & 0xff);
+        buffer[offset+1] = (byte) (value >> 8 & 0xff);
+        buffer[offset+2] = (byte) (value >> 16 & 0xff);
+        buffer[offset+3] = (byte) (value >> 24 & 0xff);
+    }
+    
+    protected static int F(int x, int y, int z) {
+        return((x & y) | (~x & z));
+    }
+    protected static int G(int x, int y, int z) {
+        return((x & y) | (x & z) | (y & z));
+    }
+    protected static int H(int x, int y, int z) {
+        return(x ^ y ^ z);
+    }
 
-        return lmResp;
+    protected static int rotintlft(int val, int numbits) {
+        return((val << numbits) | (val >>> (32 - numbits)));
     }
 
-    /** 
-     * Takes a 21 byte array and treats it as 3 56-bit DES keys.  The 8 byte
-     * plaintext is encrypted with each key and the resulting 24 bytes are
-     * stored in the results array.
-     * 
-     * @param keys The keys.
-     * @param plaintext The plain text to encrypt.
-     * @param results Where the results are stored.
-     * @throws AuthenticationException If {@link #encrypt(byte[],byte[])} fails.
-     */
-    private void calcResp(byte[] keys, byte[] plaintext, byte[] results)
-        throws AuthenticationException {
-        byte[] keys1 = new byte[7];
-        byte[] keys2 = new byte[7];
-        byte[] keys3 = new byte[7];
-        for (int i = 0; i < 7; i++) {
-            keys1[i] = keys[i];
+    /** Cryptography support - MD4.
+    * The following class was based loosely on the RFC and on code found at http://www.cs.umd.edu/~harry/jotp/src/md.java.
+    * Code correctness was verified by looking at MD4.java from the jcifs library (http://jcifs.samba.org).
+    * It was massaged extensively to the final form found here by Karl Wright (kwright@metacarta.com).
+    */
+    protected static class MD4
+    {
+        protected int A = 0x67452301;
+        protected int B = 0xefcdab89;
+        protected int C = 0x98badcfe;
+        protected int D = 0x10325476;
+        protected long count = 0L;
+        protected byte[] dataBuffer = new byte[64];
+	
+        public MD4()
+        {
         }
+	
+        public void update(byte[] input)
+        {
+            // We always deal with 512 bits at a time.  Correspondingly, there is a buffer 64 bytes long that we write data into until it gets full.
+            int curBufferPos = (int)(count & 63L);
+            int inputIndex = 0;
+            while (input.length - inputIndex + curBufferPos >= dataBuffer.length)
+            {
+                // We have enough data to do the next step.  Do a partial copy and a transform, updating inputIndex and curBufferPos accordingly
+                int transferAmt = dataBuffer.length - curBufferPos;
+                System.arraycopy(input,inputIndex,dataBuffer,curBufferPos,transferAmt);
+                count += transferAmt;
+                curBufferPos = 0;
+                inputIndex += transferAmt;
+                processBuffer();
+            }
+		
+            // If there's anything left, copy it into the buffer and leave it.  We know there's not enough left to process.
+            if (inputIndex < input.length)
+            {
+                int transferAmt = input.length - inputIndex;
+                System.arraycopy(input,inputIndex,dataBuffer,curBufferPos,transferAmt);
+                count += transferAmt;
+                curBufferPos += transferAmt;
+            }
+        }
+	
+        public byte[] getOutput()
+        {
+            // Feed pad/length data into engine.  This must round out the input to a multiple of 512 bits.
+            int bufferIndex = (int)(count & 63L);
+            int padLen = (bufferIndex < 56) ? (56 - bufferIndex) : (120 - bufferIndex);
+            byte[] postBytes = new byte[padLen + 8];
+            // Leading 0x80, specified amount of zero padding, then length in bits.
+            postBytes[0] = (byte)0x80;
+            // Fill out the last 8 bytes with the length
+            for (int i = 0; i < 8; i++)
+            {
+                postBytes[padLen + i] = (byte)((count * 8) >>> (8 * i));
+            }
+		
+            // Update the engine
+            update(postBytes);
 
-        for (int i = 0; i < 7; i++) {
-            keys2[i] = keys[i + 7];
+            // Calculate final result
+            byte[] result = new byte[16];
+            writeULong(result,A,0);
+            writeULong(result,B,4);
+            writeULong(result,C,8);
+            writeULong(result,D,12);
+            return result;
         }
 
-        for (int i = 0; i < 7; i++) {
-            keys3[i] = keys[i + 14];
+        protected void processBuffer()
+        {
+            // Convert current buffer to 16 ulongs
+            int[] d = new int[16];
+
+            for (int i = 0; i < 16; i++)
+            {
+                d[i] = (dataBuffer[i*4] & 0xff) + ((dataBuffer[i*4+1] & 0xff) << 8) + 
+                    ((dataBuffer[i*4+2] & 0xff) << 16) + ((dataBuffer[i*4+3] & 0xff) << 24);
+            }
+		
+            // Do a round of processing
+            int AA = A; int BB = B; int CC = C; int DD = D;
+            round1(d);
+            round2(d);
+            round3(d);
+            A += AA; B+= BB; C+= CC; D+= DD;
+
         }
-        byte[] results1 = encrypt(keys1, plaintext);
 
-        byte[] results2 = encrypt(keys2, plaintext);
+        protected void round1(int[] d) {
+            A = rotintlft((A + F(B, C, D) + d[0]), 3);
+            D = rotintlft((D + F(A, B, C) + d[1]), 7);
+            C = rotintlft((C + F(D, A, B) + d[2]), 11);
+            B = rotintlft((B + F(C, D, A) + d[3]), 19);
 
-        byte[] results3 = encrypt(keys3, plaintext);
+            A = rotintlft((A + F(B, C, D) + d[4]), 3);
+            D = rotintlft((D + F(A, B, C) + d[5]), 7);
+            C = rotintlft((C + F(D, A, B) + d[6]), 11);
+            B = rotintlft((B + F(C, D, A) + d[7]), 19);
 
-        for (int i = 0; i < 8; i++) {
-            results[i] = results1[i];
+            A = rotintlft((A + F(B, C, D) + d[8]), 3);
+            D = rotintlft((D + F(A, B, C) + d[9]), 7);
+            C = rotintlft((C + F(D, A, B) + d[10]), 11);
+            B = rotintlft((B + F(C, D, A) + d[11]), 19);
+
+            A = rotintlft((A + F(B, C, D) + d[12]), 3);
+            D = rotintlft((D + F(A, B, C) + d[13]), 7);
+            C = rotintlft((C + F(D, A, B) + d[14]), 11);
+            B = rotintlft((B + F(C, D, A) + d[15]), 19);
+	}
+	    
+        protected void round2(int[] d) {
+            A = rotintlft((A + G(B, C, D) + d[0] + 0x5a827999), 3);
+            D = rotintlft((D + G(A, B, C) + d[4] + 0x5a827999), 5);
+            C = rotintlft((C + G(D, A, B) + d[8] + 0x5a827999), 9);
+            B = rotintlft((B + G(C, D, A) + d[12] + 0x5a827999), 13);
+
+            A = rotintlft((A + G(B, C, D) + d[1] + 0x5a827999), 3);
+            D = rotintlft((D + G(A, B, C) + d[5] + 0x5a827999), 5);
+            C = rotintlft((C + G(D, A, B) + d[9] + 0x5a827999), 9);
+            B = rotintlft((B + G(C, D, A) + d[13] + 0x5a827999), 13);
+
+            A = rotintlft((A + G(B, C, D) + d[2] + 0x5a827999), 3);
+            D = rotintlft((D + G(A, B, C) + d[6] + 0x5a827999), 5);
+            C = rotintlft((C + G(D, A, B) + d[10] + 0x5a827999), 9);
+            B = rotintlft((B + G(C, D, A) + d[14] + 0x5a827999), 13);
+
+            A = rotintlft((A + G(B, C, D) + d[3] + 0x5a827999), 3);
+            D = rotintlft((D + G(A, B, C) + d[7] + 0x5a827999), 5);
+            C = rotintlft((C + G(D, A, B) + d[11] + 0x5a827999), 9);
+            B = rotintlft((B + G(C, D, A) + d[15] + 0x5a827999), 13);
+
         }
-        for (int i = 0; i < 8; i++) {
-            results[i + 8] = results2[i];
+
+        protected void round3(int[] d) {
+            A = rotintlft((A + H(B, C, D) + d[0] + 0x6ed9eba1), 3);
+            D = rotintlft((D + H(A, B, C) + d[8] + 0x6ed9eba1), 9);
+            C = rotintlft((C + H(D, A, B) + d[4] + 0x6ed9eba1), 11);
+            B = rotintlft((B + H(C, D, A) + d[12] + 0x6ed9eba1), 15);
+
+            A = rotintlft((A + H(B, C, D) + d[2] + 0x6ed9eba1), 3);
+            D = rotintlft((D + H(A, B, C) + d[10] + 0x6ed9eba1), 9);
+            C = rotintlft((C + H(D, A, B) + d[6] + 0x6ed9eba1), 11);
+            B = rotintlft((B + H(C, D, A) + d[14] + 0x6ed9eba1), 15);
+
+            A = rotintlft((A + H(B, C, D) + d[1] + 0x6ed9eba1), 3);
+            D = rotintlft((D + H(A, B, C) + d[9] + 0x6ed9eba1), 9);
+            C = rotintlft((C + H(D, A, B) + d[5] + 0x6ed9eba1), 11);
+            B = rotintlft((B + H(C, D, A) + d[13] + 0x6ed9eba1), 15);
+
+            A = rotintlft((A + H(B, C, D) + d[3] + 0x6ed9eba1), 3);
+            D = rotintlft((D + H(A, B, C) + d[11] + 0x6ed9eba1), 9);
+            C = rotintlft((C + H(D, A, B) + d[7] + 0x6ed9eba1), 11);
+            B = rotintlft((B + H(C, D, A) + d[15] + 0x6ed9eba1), 15);
+
         }
-        for (int i = 0; i < 8; i++) {
-            results[i + 16] = results3[i];
-        }
+
     }
 
-    /** 
-     * Converts a given number to a two byte array in little endian order.
-     * @param num the number to convert.
-     * @return The byte representation of <i>num</i> in little endian order.
-     */
-    private byte[] convertShort(int num) {
-        byte[] val = new byte[2];
-        String hex = Integer.toString(num, 16);
-        while (hex.length() < 4) {
-            hex = "0" + hex;
+    /** Cryptography support - HMACMD5 - algorithmically based on various web resources by Karl Wright */
+    protected static class HMACMD5
+    {
+        protected byte[] ipad;
+        protected byte[] opad;
+        protected MessageDigest md5;
+
+        public HMACMD5(byte[] key)
+            throws AuthenticationException
+        {
+            try
+            {
+                md5 = MessageDigest.getInstance("MD5");
+            }
+            catch (Exception ex)
+            {
+                // Umm, the algorithm doesn't exist - throw an AuthenticationException!
+                throw new AuthenticationException("Error getting md5 message digest implementation: "+ex.getMessage(),ex);
+            }
+
+            // Initialize the pad buffers with the key
+            ipad = new byte[64];
+            opad = new byte[64];
+
+            int keyLength = key.length;
+            if (keyLength > 64)
+            {
+                // Use MD5 of the key instead, as described in RFC 2104
+                md5.update(key);
+                key = md5.digest();
+                keyLength = key.length;
+            }
+            int i = 0;
+            while (i < keyLength)
+            {
+                ipad[i] = (byte) (key[i] ^ (byte)0x36);
+                opad[i] = (byte) (key[i] ^ (byte)0x5c);
+                i++;
+            }
+            while (i < 64)
+            {
+                ipad[i] = (byte)0x36;
+                opad[i] = (byte)0x5c;
+                i++;
+            }
+	    
+            // Very important: update the digest with the ipad buffer
+            md5.reset();
+            md5.update(ipad);
+
         }
-        String low = hex.substring(2, 4);
-        String high = hex.substring(0, 2);
-
-        val[0] = (byte) Integer.parseInt(low, 16);
-        val[1] = (byte) Integer.parseInt(high, 16);
-        return val;
+	
+        /** Grab the current digest.  This is the "answer". */
+        public byte[] getOutput()
+        {
+            byte[] digest = md5.digest();
+            md5.update(opad);
+            return md5.digest(digest);
+        }
+	
+        /** Update by adding a complete array */
+        public void update(byte[] input)
+        {
+            md5.update(input);
+        }
+	
+        /** Update the algorithm */
+        public void update(byte[] input, int offset, int length)
+        {
+            md5.update(input,offset,length);
+        }
+	
     }
     
-    /**
-     * @return Returns the credentialCharset.
-     */
-    public String getCredentialCharset() {
-        return credentialCharset;
+    /* Run test suite */
+    public static void main(String[] args)
+        throws Exception
+    {
+        // MD4 test suite:
+        checkMD4("","31d6cfe0d16ae931b73c59d7e0c089c0");
+        checkMD4("a","bde52cb31de33e46245e05fbdbd6fb24");
+        checkMD4("abc","a448017aaf21d8525fc10ae87aa6729d");
+        checkMD4("message digest","d9130a8164549fe818874806e1c7014b");
+        checkMD4("abcdefghijklmnopqrstuvwxyz","d79e1c308aa5bbcdeea8ed63df412da9");
+        checkMD4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+            "043f8582f241db351ce627e153e7f0e4");
+        checkMD4("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+            "e33b4ddc9c38f2199c3e7b164fcc0536");
+	    
+        System.out.println("Tests pass");
     }
-
-    /**
-     * @param credentialCharset The credentialCharset to set.
-     */
-    public void setCredentialCharset(String credentialCharset) {
-        this.credentialCharset = credentialCharset;
+   
+    /* Test suite helper */
+    protected static byte checkToNibble(char c)
+    {
+        if (c >= 'a' && c <= 'f')
+            return (byte)(c - 'a' + 0x0a);
+        return (byte)(c - '0');
     }
+    
+    /*Test suite helper */
+    protected static byte[] checkToBytes(String hex)
+    {
+        byte[] rval = new byte[hex.length()/2];
+        int i = 0;
+        while (i < rval.length)
+        {
+            rval[i] = (byte)((checkToNibble(hex.charAt(i*2)) << 4) | (checkToNibble(hex.charAt(i*2+1))));
+            i++;
+        }
+        return rval;
+    }
+    
+    /* Test suite MD4 helper */
+    protected static void checkMD4(String input, String hexOutput)
+        throws Exception
+    {
+        MD4 md4;
+        md4 = new MD4 ();
+        md4.update(input.getBytes("ASCII"));
+        byte[] answer = md4.getOutput();
+        byte[] correctAnswer = checkToBytes(hexOutput);
+        if (answer.length != correctAnswer.length)
+            throw new Exception("Answer length disagrees for MD4('"+input+"')");
+        int i = 0;
+        while (i < answer.length)
+        {
+            if (answer[i] != correctAnswer[i])
+                throw new Exception("Answer value for MD4('"+input+"') disagrees at position "+Integer.toString(i));
+            i++;
+        }
+    }
 
 }
Index: src/java/org/apache/commons/httpclient/cookie/CookieSpecMediumSecurity.java
===================================================================
--- src/java/org/apache/commons/httpclient/cookie/CookieSpecMediumSecurity.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 0)
+++ src/java/org/apache/commons/httpclient/cookie/CookieSpecMediumSecurity.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(revision 1308601)
@@ -0,0 +1,153 @@
+/*
+ * $HeadURL: https://svn.apache.org/repos/asf/incubator/lcf/upstream/commons-httpclient-3x/src/java/org/apache/commons/httpclient/cookie/CookieSpecBase.java $
+ * $Revision: 653067 $
+ * $Date: 2008-05-03 08:42:39 -0400 (Sat, 03 May 2008) $
+ *
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (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.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */ 
+
+package org.apache.commons.httpclient.cookie;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HeaderElement;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.util.DateParseException;
+import org.apache.commons.httpclient.util.DateUtil;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 
+ * Cookie management functions shared by all specification.
+ *
+ * @author  B.C. Holmes
+ * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
+ * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
+ * @author Rod Waldhoff
+ * @author dIon Gillard
+ * @author Sean C. Sullivan
+ * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
+ * @author Marc A. Saegesser
+ * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
+ * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
+ * 
+ * @since 2.0 
+ */
+public class CookieSpecMediumSecurity extends CookieSpecBase {
+    
+    /** Log object */
+    protected static final Log LOG = LogFactory.getLog(CookieSpecMediumSecurity.class);
+
+    /** Default constructor */
+    public CookieSpecMediumSecurity() {
+        super();
+    }
+
+	/**
+      * Performs most common {@link Cookie} validation
+      *
+      * @param host the host from which the {@link Cookie} was received
+      * @param port the port from which the {@link Cookie} was received
+      * @param path the path from which the {@link Cookie} was received
+      * @param secure <tt>true</tt> when the {@link Cookie} was received using a
+      * secure connection
+      * @param cookie The cookie to validate.
+      * @throws MalformedCookieException if an exception occurs during
+      * validation
+      */
+    
+    public void validate(String host, int port, String path, 
+        boolean secure, final Cookie cookie) 
+        throws MalformedCookieException {
+            
+        LOG.trace("enter CookieSpecMediumSecurity.validate("
+            + "String, port, path, boolean, Cookie)");
+        if (host == null) {
+            throw new IllegalArgumentException(
+                "Host of origin may not be null");
+        }
+        if (host.trim().equals("")) {
+            throw new IllegalArgumentException(
+                "Host of origin may not be blank");
+        }
+        if (port < 0) {
+            throw new IllegalArgumentException("Invalid port: " + port);
+        }
+        if (path == null) {
+            throw new IllegalArgumentException(
+                "Path of origin may not be null.");
+        }
+        if (path.trim().equals("")) {
+            path = PATH_DELIM;
+        }
+        host = host.toLowerCase(Locale.ENGLISH);
+        // check version
+        if (cookie.getVersion() < 0) {
+            throw new MalformedCookieException ("Illegal version number " 
+                + cookie.getValue());
+        }
+
+        // security check... we musn't allow the server to give us an
+        // invalid domain scope
+
+        // Validate the cookies domain attribute.  NOTE:  Domains without 
+        // any dots are allowed to support hosts on private LANs that don't 
+        // have DNS names.  Since they have no dots, to domain-match the 
+        // request-host and domain must be identical for the cookie to sent 
+        // back to the origin-server.
+        if (host.indexOf(".") >= 0) {
+            // Not required to have at least two dots.  RFC 2965.
+            // A Set-Cookie2 with Domain=ajax.com will be accepted.
+
+            // domain must match host
+            if (!host.endsWith(cookie.getDomain())) {
+                String s = cookie.getDomain();
+                if (s.startsWith(".")) {
+                    s = s.substring(1, s.length());
+                }
+                if (!host.equals(s)) { 
+                    throw new MalformedCookieException(
+                        "Illegal domain attribute \"" + cookie.getDomain() 
+                        + "\". Domain of origin: \"" + host + "\"");
+                }
+            }
+        } else {
+            if (!host.equals(cookie.getDomain())) {
+                throw new MalformedCookieException(
+                    "Illegal domain attribute \"" + cookie.getDomain() 
+                    + "\". Domain of origin: \"" + host + "\"");
+            }
+        }
+
+    }
+
+}

Property changes on: src/java/org/apache/commons/httpclient/cookie/CookieSpecMediumSecurity.java
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
Added: svn:eol-style
## -0,0 +1 ##
+native
Index: src/java/org/apache/commons/httpclient/cookie/CookiePolicy.java
===================================================================
--- src/java/org/apache/commons/httpclient/cookie/CookiePolicy.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 915934)
+++ src/java/org/apache/commons/httpclient/cookie/CookiePolicy.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(working copy)
@@ -69,6 +69,11 @@
      */
     public static final String BROWSER_COMPATIBILITY = "compatibility";
     
+    /**
+     * Medium-security browser compatibility setting.
+     */
+    public static final String BROWSER_COMPATIBILITY_MEDIUM_SECURITY = "compatibilitymediumsecurity";
+    
     /** 
      * The Netscape cookie draft compliant policy. 
      * 
@@ -109,6 +114,7 @@
         CookiePolicy.registerCookieSpec(RFC_2109, RFC2109Spec.class);
         CookiePolicy.registerCookieSpec(RFC_2965, RFC2965Spec.class);
         CookiePolicy.registerCookieSpec(BROWSER_COMPATIBILITY, CookieSpecBase.class);
+        CookiePolicy.registerCookieSpec(BROWSER_COMPATIBILITY_MEDIUM_SECURITY, CookieSpecMediumSecurity.class);
         CookiePolicy.registerCookieSpec(NETSCAPE, NetscapeDraftSpec.class);
         CookiePolicy.registerCookieSpec(IGNORE_COOKIES, IgnoreCookiesSpec.class);
     }
Index: src/java/org/apache/commons/httpclient/params/HttpClientParams.java
===================================================================
--- src/java/org/apache/commons/httpclient/params/HttpClientParams.java	(.../httpcomponents/oac.hc3x/trunk)	(revision 915934)
+++ src/java/org/apache/commons/httpclient/params/HttpClientParams.java	(.../incubator/lcf/upstream/commons-httpclient-3.1-mcf/trunk)	(working copy)
@@ -81,6 +81,14 @@
      */
     public static final String REJECT_RELATIVE_REDIRECT = "http.protocol.reject-relative-redirect"; 
 
+    /**
+     * Supplies a ProtocolFactory object, for custom protocol support even across redirections.
+     * <p>
+     * This parameter expects a value of type {@link ProtocolFactory}.
+     * </p>
+     */
+    public static final String PROTOCOL_FACTORY = "http.protocol.factory"; 
+
     /** 
      * Defines the maximum number of redirects to be followed. 
      * The limit on number of redirects is intended to prevent infinite loops. 
