[jboss-cvs] JBossAS SVN: r77129 - in projects/security/security-negotiation/trunk: jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Aug 17 09:45:39 EDT 2008


Author: darran.lofthouse at jboss.com
Date: 2008-08-17 09:45:38 -0400 (Sun, 17 Aug 2008)
New Revision: 77129

Added:
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/SPNEGOMessage.java
Modified:
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOMessageFactory.java
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInit.java
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInitDecoder.java
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTarg.java
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargDecoder.java
   projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargEncoder.java
   projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/BasicNegotiationServlet.java
   projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java
Log:
[SECURITY-270] Further MessageFactory work to improve working with NTLM.

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOMessageFactory.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOMessageFactory.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/SPNEGOMessageFactory.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -19,8 +19,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.log4j.Logger;
+import org.ietf.jgss.GSSException;
 import org.jboss.security.negotiation.MessageFactory;
 import org.jboss.security.negotiation.NegotiationMessage;
+import org.jboss.security.negotiation.spnego.encoding.NegTokenInitDecoder;
+import org.jboss.security.negotiation.spnego.encoding.NegTokenTargDecoder;
 
 /**
  * The message factory for reading SPNEGO messages from InputStreams and
@@ -33,6 +37,8 @@
 public class SPNEGOMessageFactory extends MessageFactory
 {
 
+   private static final Logger log = Logger.getLogger(SPNEGOMessageFactory.class);
+
    @Override
    public boolean accepts(InputStream in) throws IOException
    {
@@ -51,8 +57,33 @@
    @Override
    public NegotiationMessage createMessage(InputStream in) throws IOException
    {
-      // TODO Auto-generated method stub
-      return null;
+      if (accepts(in) == true)
+      {
+         in.mark(1);
+         int dataRead = in.read();
+         in.reset();
+
+         try
+         {
+            if (dataRead == 0x60)
+            {
+               return NegTokenInitDecoder.decode(in);
+            }
+            // The accepts method will have confirmed it is either 0x60 or 0xa1
+            return NegTokenTargDecoder.decode(in);
+         }
+         catch (GSSException e)
+         {
+            IOException ioe = new IOException("Unable to createMessage");
+            ioe.initCause(e);
+
+            throw ioe;
+         }
+      }
+      else
+      {
+         throw new IllegalArgumentException("InputStream does not contain SPNEGO message.");
+      }
    }
 
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInit.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInit.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInit.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -16,17 +16,20 @@
 
 package org.jboss.security.negotiation.spnego.encoding;
 
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.LinkedList;
 import java.util.List;
 
 import org.ietf.jgss.Oid;
+import org.jboss.util.NotImplementedException;
 
 /**
  * Representation of NegTokenInit.
  * 
  * @author <a href="darranlofthouse at hotmail.com">Darran Lofthouse</a>
  */
-public class NegTokenInit
+public class NegTokenInit extends SPNEGOMessage
 {
 
    private Oid messageOid;
@@ -90,4 +93,11 @@
       this.mechListMIC = mechListMIC;
    }
 
+   @Override
+   public void writeTo(OutputStream os) throws IOException
+   {
+     throw new NotImplementedException();      
+   }
+
+   
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInitDecoder.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInitDecoder.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenInitDecoder.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -63,7 +63,7 @@
       int length = NegTokenDecoder.readLength(is);
       // TODO - Verify type.
       byte type = (byte) is.read();
-      
+
       int tokenLength = readLength(is);
 
       byte[] mechToken = new byte[tokenLength];
@@ -115,6 +115,27 @@
 
    }
 
+   public static NegTokenInit decode(final InputStream is) throws IOException, GSSException
+   {
+      NegTokenInit negTokenInit = new NegTokenInit();
+
+      // TODO - Drop or verify.
+      byte firstByte = (byte) is.read();
+      // TODO - Drop or verify.
+      int totalLength = NegTokenDecoder.readLength(is);
+
+      negTokenInit.setMessageOid(new Oid(is));
+
+      // TODO - Verify
+      int tokenType = is.read();
+      // TODO - Drop or verify.
+      int remainingLength = NegTokenDecoder.readLength(is);
+
+      decodeNegTokenInitSequence(is, negTokenInit);
+
+      return negTokenInit;
+   }
+
    /**
     *  Decode the SPNEGO message contained witin the byte[] and return a
     *  NegTokenInit object.
@@ -127,22 +148,8 @@
     */
    public static NegTokenInit decode(final byte[] token) throws IOException, GSSException
    {
-      NegTokenInit negTokenInit = new NegTokenInit();
       ByteArrayInputStream bais = new ByteArrayInputStream(token);
-      // TODO - Drop or verify.
-      byte firstByte = (byte) bais.read();
-      // TODO - Drop or verify.
-      int totalLength = NegTokenDecoder.readLength(bais);
 
-      negTokenInit.setMessageOid(new Oid(bais));
-
-      // TODO - Verify
-      int tokenType = bais.read();
-      // TODO - Drop or verify.
-      int remainingLength = NegTokenDecoder.readLength(bais);
-
-      decodeNegTokenInitSequence(bais, negTokenInit);
-
-      return negTokenInit;
+      return decode(bais);
    }
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTarg.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTarg.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTarg.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -16,6 +16,9 @@
 
 package org.jboss.security.negotiation.spnego.encoding;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 import org.ietf.jgss.Oid;
 
 /**
@@ -23,7 +26,7 @@
  * 
  * @author <a href="darranlofthouse at hotmail.com">Darran Lofthouse</a>
  */
-public class NegTokenTarg
+public class NegTokenTarg extends SPNEGOMessage
 {
    public static final Integer ACCEPT_COMPLETED = new Integer(1);
 
@@ -79,4 +82,12 @@
       this.mechListMIC = mechListMIC;
    }
 
+   @Override
+   public void writeTo(final OutputStream os) throws IOException
+   {
+      // TODO Auto-generated method stub
+      
+   }
+
+   
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargDecoder.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargDecoder.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargDecoder.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -124,18 +124,24 @@
 
    }
 
-   public static NegTokenTarg decode(final byte[] token) throws IOException, GSSException
+   public static NegTokenTarg decode(final InputStream is) throws IOException, GSSException
    {
       NegTokenTarg negTokenTarg = new NegTokenTarg();
-      ByteArrayInputStream bais = new ByteArrayInputStream(token);
 
       // TODO - Drop or verify.
-      byte firstByte = (byte) bais.read();
+      byte firstByte = (byte) is.read();
       // TODO - Drop or verify.
-      int totalLength = readLength(bais);
+      int totalLength = readLength(is);
 
-      decodeNegTokenTargSequence(bais, negTokenTarg);
+      decodeNegTokenTargSequence(is, negTokenTarg);
 
       return negTokenTarg;
    }
+
+   public static NegTokenTarg decode(final byte[] token) throws IOException, GSSException
+   {
+      ByteArrayInputStream bais = new ByteArrayInputStream(token);
+
+      return decode(bais);
+   }
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargEncoder.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargEncoder.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/NegTokenTargEncoder.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -18,6 +18,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -124,19 +125,29 @@
       tokens.add(0, sequenceLength);
    }
 
-   protected static byte[] contructMessage(final List<byte[]> tokens) throws IOException
+   protected static void contructMessage(final List<byte[]> tokens, final OutputStream os) throws IOException
    {
       int length = getTotalLength(tokens);
 
-      ByteArrayOutputStream baous = new ByteArrayOutputStream(length);
-
       Iterator<byte[]> it = tokens.iterator();
       while (it.hasNext())
       {
-         baous.write((byte[]) it.next());
+         os.write((byte[]) it.next());
       }
+   }
 
-      return baous.toByteArray();
+   public void encode(final NegTokenTarg negTokenTarg, final OutputStream os) throws GSSException, IOException
+   {
+      List<byte[]> tokens = new LinkedList<byte[]>();
+
+      encodeMechListMIC(tokens, negTokenTarg.getMechListMIC());
+      encodeResponseToken(tokens, negTokenTarg.getResponseToken());
+      encodeSupportedMech(tokens, negTokenTarg.getSupportedMech());
+      encodeNegResult(tokens, negTokenTarg.getNegResult());
+      encodeConstructedSequence(tokens);
+      encodeNegTokenTarg(tokens);
+
+      contructMessage(tokens, os);
    }
 
    public static byte[] encode(final NegTokenTarg negTokenTarg) throws GSSException, IOException
@@ -150,6 +161,9 @@
       encodeConstructedSequence(tokens);
       encodeNegTokenTarg(tokens);
 
-      return contructMessage(tokens);
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      contructMessage(tokens, baos);
+
+      return baos.toByteArray();
    }
 }

Added: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/SPNEGOMessage.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/SPNEGOMessage.java	                        (rev 0)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/SPNEGOMessage.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2008  Red Hat Middleware, LLC. or third-party contributors as indicated 
+ * by the @author tags or express copyright attribution statements applied by the 
+ * authors. All third-party contributions are distributed under license by Red Hat 
+ * Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify, copy, 
+ * or redistribute it subject to the terms and conditions of the GNU Lesser General 
+ * Public License, v. 2.1. This program is distributed in the hope that it will be 
+ * useful, but WITHOUT A WARRANTY; without even the implied warranty of MERCHANTABILITY 
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 
+ * more details. You should have received a copy of the GNU Lesser General Public License, 
+ * v.2.1 along with this distribution; if not, write to the Free Software Foundation, Inc., 
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.jboss.security.negotiation.spnego.encoding;
+
+import org.jboss.security.negotiation.NegotiationMessage;
+
+/**
+ * The common base type for all SPNEGO messages.
+ * 
+ * @author darran.lofthouse at jboss.com
+ * @since 17th August 2008
+ * @version $Revision$
+ */
+public abstract class SPNEGOMessage extends NegotiationMessage
+{
+
+}


Property changes on: projects/security/security-negotiation/trunk/jboss-negotiation-spnego/src/main/java/org/jboss/security/negotiation/spnego/encoding/SPNEGOMessage.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/BasicNegotiationServlet.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/BasicNegotiationServlet.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/BasicNegotiationServlet.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -22,9 +22,9 @@
  */
 package org.jboss.security.negotiation.toolkit;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.Arrays;
 import java.util.List;
 
 import javax.servlet.RequestDispatcher;
@@ -33,15 +33,17 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.jboss.util.Base64;
 import org.apache.log4j.Logger;
-import org.ietf.jgss.GSSException;
 import org.ietf.jgss.Oid;
+import org.jboss.security.negotiation.MessageFactory;
+import org.jboss.security.negotiation.NegotiationException;
+import org.jboss.security.negotiation.NegotiationMessage;
 import org.jboss.security.negotiation.OidNameUtil;
 import org.jboss.security.negotiation.common.DebugHelper;
-import org.jboss.security.negotiation.ntlm.Constants;
+import org.jboss.security.negotiation.ntlm.encoding.NegotiateMessage;
 import org.jboss.security.negotiation.spnego.encoding.NegTokenInit;
-import org.jboss.security.negotiation.spnego.encoding.NegTokenInitDecoder;
+import org.jboss.security.negotiation.spnego.encoding.NegTokenTarg;
+import org.jboss.util.Base64;
 
 /**
  * A basic servlet to test that if prompted the client browser will return a SPNEGO
@@ -76,26 +78,10 @@
          return;
       }
 
-      log.info("Authorization header received - formatting web page response.");
+      log.info("Authorization header received - decoding token.");
 
-      /* At this stage no further negotiation will take place so the information */
-      /* can be output in the servlet response.                                  */
+      Object response = null;
 
-      PrintWriter writer = resp.getWriter();
-
-      writer.println("<html>");
-      writer.println("  <head>");
-      writer.println("    <title>Negotiation Toolkit</title>");
-      writer.println("  </head>");
-      writer.println("  <body>");
-      writer.println("    <h1>Negotiation Toolkit</h1>");
-      writer.println("    <h2>Basic Negotiation</h2>");
-
-      // Output the raw header.
-      writer.println("    <p>WWW-Authenticate - ");
-      writer.println(authHeader);
-      writer.println("    </p>");
-
       String requestHeader = "";
       if (authHeader.startsWith("Negotiate "))
       {
@@ -108,47 +94,76 @@
          requestHeader = authHeader.substring(5);
       }
 
-      if (requestHeader.length() == 0)
+      if (requestHeader.length() > 0)
       {
-         writer.println("<p><b>Header WWW-Authenticate does not beging with 'Negotiate' or 'NTLM'!</b></p>");
-      }
-      else
-      {
          byte[] reqToken = Base64.decode(requestHeader);
+         ByteArrayInputStream bais = new ByteArrayInputStream(reqToken);
+         MessageFactory mf = null;
 
-         byte[] ntlmSignature = Constants.SIGNATURE;
-         if (reqToken.length > 8)
+         try
          {
-            byte[] reqHeader = new byte[8];
-            System.arraycopy(reqToken, 0, reqHeader, 0, 8);
+            mf = MessageFactory.newInstance();
+         }
+         catch (NegotiationException e)
+         {
+            throw new ServletException("Unable to create MessageFactory", e);
+         }
 
-            if (Arrays.equals(ntlmSignature, reqHeader))
+         if (mf.accepts(bais))
+         {
+            NegotiationMessage message = mf.createMessage(bais);
+
+            if (message instanceof NegotiateMessage)
             {
+               req.setAttribute("message", message);
 
                RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/NTLMNegotiation");
                dispatcher.forward(req, resp);
 
                return;
             }
-         }
 
-         try
-         {
-            writeHeaderDetail(reqToken, writer);
-         }
-         catch (Exception e)
-         {
-            if (e instanceof RuntimeException)
+            if (message instanceof NegTokenInit)
             {
-               throw (RuntimeException) e;
+               response = message;
             }
-            else
+            else if (message instanceof NegTokenTarg)
             {
-               throw new ServletException("Unable to writeHeaderDetail", e);
+               response = "<p><b>Unexpected NegTokenTarg, first token should be NegTokenInit!</b></p>";
             }
+
          }
+         else
+         {
+            response = "<p><b>Unsuported negotiation token.</b></p>";
+         }
+
       }
+      else
+      {
+         response = "<p><b>Header WWW-Authenticate does not beging with 'Negotiate' or 'NTLM'!</b></p>";
+      }
 
+      /* At this stage no further negotiation will take place so the information */
+      /* can be output in the servlet response.                                  */
+
+      PrintWriter writer = resp.getWriter();
+
+      writer.println("<html>");
+      writer.println("  <head>");
+      writer.println("    <title>Negotiation Toolkit</title>");
+      writer.println("  </head>");
+      writer.println("  <body>");
+      writer.println("    <h1>Negotiation Toolkit</h1>");
+      writer.println("    <h2>Basic Negotiation</h2>");
+
+      // Output the raw header.
+      writer.println("    <p>WWW-Authenticate - ");
+      writer.println(authHeader);
+      writer.println("    </p>");
+
+      writeHeaderDetail(response, writer);
+
       writer.println("  </body>");
       writer.println("</html>");
       writer.flush();
@@ -162,12 +177,15 @@
       doGet(req, resp);
    }
 
-   private void writeHeaderDetail(final byte[] reqToken, final PrintWriter writer) throws IOException, GSSException
+   private void writeHeaderDetail(final Object response, final PrintWriter writer) throws IOException
    {
-
-      if (reqToken[0] == 0x60)
+      if (response instanceof String)
       {
-         NegTokenInit negTokenInit = NegTokenInitDecoder.decode(reqToken);
+         writer.println((String) response);
+      }
+      else if (response instanceof NegTokenInit)
+      {
+         NegTokenInit negTokenInit = (NegTokenInit) response;
          writer.println("<h3>NegTokenInit</h3>");
 
          writer.print("<b>Message Oid - </b>");
@@ -207,17 +225,8 @@
             writer.print(new String(Base64.encodeBytes(mechTokenMic)));
          }
          writer.println("<br>");
-
-         return;
       }
 
-      if (reqToken[0] == (byte) 0xa1)
-      {
-         writer.println("<p><b>Unexpected NegTokenTarg, first token should be NegTokenInit!</b></p>");
-         return;
-      }
-
-      writer.println("<p><b>Unsupported negotiation mechanism</b></p>");
    }
 
 }

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java	2008-08-17 03:35:40 UTC (rev 77128)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java	2008-08-17 13:45:38 UTC (rev 77129)
@@ -34,6 +34,7 @@
 import org.apache.log4j.Logger;
 import org.jboss.security.negotiation.MessageFactory;
 import org.jboss.security.negotiation.NegotiationException;
+import org.jboss.security.negotiation.NegotiationMessage;
 import org.jboss.security.negotiation.ntlm.encoding.NTLMField;
 import org.jboss.security.negotiation.ntlm.encoding.NegotiateMessage;
 import org.jboss.util.Base64;
@@ -55,7 +56,9 @@
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
       String authHeader = req.getHeader("Authorization");
-      if (authHeader == null)
+      NegotiationMessage message = (NegotiationMessage) req.getAttribute("message");
+
+      if (message == null && authHeader == null)
       {
          log.info("No Authorization Header, sending 401");
          resp.setHeader("WWW-Authenticate", "NTLM");
@@ -64,8 +67,65 @@
          return;
       }
 
-      log.info("Authorization header received - formatting web page response.");
+      log.info("Authorization header received - decoding token.");
 
+      Object response = null;
+      if (message == null)
+      {
+         String requestHeader = "";
+         if (authHeader.startsWith("Negotiate "))
+         {
+            // Drop the 'Negotiate ' from the header.
+            requestHeader = authHeader.substring(10);
+         }
+         else if (authHeader.startsWith("NTLM "))
+         {
+            // Drop the 'NTLM ' from the header.
+            requestHeader = authHeader.substring(5);
+         }
+
+         if (requestHeader.length() > 0)
+         {
+            byte[] reqToken = Base64.decode(requestHeader);
+            ByteArrayInputStream bais = new ByteArrayInputStream(reqToken);
+            MessageFactory mf = null;
+
+            try
+            {
+               mf = MessageFactory.newInstance();
+            }
+            catch (NegotiationException e)
+            {
+               throw new ServletException("Unable to create MessageFactory", e);
+            }
+
+            if (mf.accepts(bais))
+            {
+               message = mf.createMessage(bais);
+               if (message instanceof NegotiateMessage)
+               {
+                  response = message;
+               }
+               else
+               {
+                  response = "<p><b>Unsuported negotiation token.</b></p>";
+               }
+
+            }
+            else
+            {
+               response = "<p><b>Unsuported negotiation token.</b></p>";
+            }
+
+         }
+
+      }
+      else
+      {
+         log.info("Using existing message.");
+         response = message;
+      }
+
       /* At this stage no further negotiation will take place so the information */
       /* can be output in the servlet response.                                  */
 
@@ -86,7 +146,7 @@
 
       try
       {
-         writeHeaderDetail(authHeader, writer);
+         writeHeaderDetail(response, writer);
       }
       catch (Exception e)
       {
@@ -113,42 +173,16 @@
       doGet(req, resp);
    }
 
-   private void writeHeaderDetail(final String authHeader, final PrintWriter writer) throws IOException
+   private void writeHeaderDetail(final Object response, final PrintWriter writer) throws IOException
    {
-      String requestHeader;
-      if (authHeader.startsWith("Negotiate "))
-      {
-         // Drop the 'Negotiate ' from the header.
-         requestHeader = authHeader.substring(10);
-      }
-      else if (authHeader.startsWith("NTLM "))
-      {
-         // Drop the 'NTLM ' from the header.
-         requestHeader = authHeader.substring(5);
-      }
-      else
-      {
-         writer.println("<p><b>Header WWW-Authenticate does not beging with 'Negotiate' or 'NTLM'!</b></p>");
-         return;
-      }
 
-      byte[] reqToken = Base64.decode(requestHeader);
-
-      MessageFactory messageFactory = null;
-
-      try
+      if (response instanceof String)
       {
-         messageFactory = MessageFactory.newInstance();
+         writer.println((String) response);
       }
-      catch (NegotiationException e)
+      else if (response instanceof NegotiateMessage)
       {
-         writer.println("<p><b>Unable to obtain MessageFactory '" + e.getMessage() + "'</b></p>");
-      }
-
-      ByteArrayInputStream bais = new ByteArrayInputStream(reqToken);
-      if (messageFactory != null && messageFactory.accepts(bais))
-      {
-         NegotiateMessage message = (NegotiateMessage) messageFactory.createMessage(bais);
+         NegotiateMessage message = (NegotiateMessage) response;
          writer.println("<h3>NTLM - Negotiate_Message</h3>");
 
          writer.write("<h4><font color='red'>"
@@ -167,12 +201,7 @@
             writer.write(new String(message.getVersion()));
             writer.write("<br>");
          }
-
       }
-      else
-      {
-         writer.println("<p><b>Unsupported negotiation mechanism</b></p>");
-      }
 
    }
 




More information about the jboss-cvs-commits mailing list