[jboss-cvs] JBossAS SVN: r76853 - in projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main: webapp and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Aug 9 08:42:35 EDT 2008


Author: darran.lofthouse at jboss.com
Date: 2008-08-09 08:42:34 -0400 (Sat, 09 Aug 2008)
New Revision: 76853

Added:
   projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java
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/webapp/WEB-INF/web.xml
   projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/index.html
Log:
[SECURITY-270] Adding some NTLM support to the toolkit.

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-09 11:48:59 UTC (rev 76852)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/BasicNegotiationServlet.java	2008-08-09 12:42:34 UTC (rev 76853)
@@ -27,6 +27,7 @@
 import java.util.Arrays;
 import java.util.List;
 
+import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -38,6 +39,7 @@
 import org.ietf.jgss.Oid;
 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.spnego.encoding.NegTokenInit;
 import org.jboss.security.negotiation.spnego.encoding.NegTokenInitDecoder;
 
@@ -48,6 +50,8 @@
  * Clients that return an NTLM header do not trust the server sufficiently so the KDC
  * configuration will need to be checked.
  * 
+ * NTLM responses received will be forwarded to the NTLMNegotiationServlet for display.
+ * 
  * @author darran.lofthouse at jboss.com
  * @version $Revision$
  */
@@ -66,7 +70,7 @@
       if (authHeader == null)
       {
          log.info("No Authorization Header, sending 401");
-         resp.setHeader("WWW-Authenticate", "NTLM");
+         resp.setHeader("WWW-Authenticate", "Negotiate");
          resp.sendError(401);
 
          return;
@@ -92,20 +96,57 @@
       writer.println(authHeader);
       writer.println("    </p>");
 
-      try
+      String requestHeader = "";
+      if (authHeader.startsWith("Negotiate "))
       {
-         writeHeaderDetail(authHeader, writer);
+         // Drop the 'Negotiate ' from the header.
+         requestHeader = authHeader.substring(10);
       }
-      catch (Exception e)
+      else if (authHeader.startsWith("NTLM "))
       {
-         if (e instanceof RuntimeException)
+         // Drop the 'NTLM ' from the header.
+         requestHeader = authHeader.substring(5);
+      }
+
+      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);
+
+         byte[] ntlmSignature = Constants.SIGNATURE;
+         if (reqToken.length > 8)
          {
-            throw (RuntimeException) e;
+            byte[] reqHeader = new byte[8];
+            System.arraycopy(reqToken, 0, reqHeader, 0, 8);
+
+            if (Arrays.equals(ntlmSignature, reqHeader))
+            {
+
+               RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/NTLMNegotiation");
+               dispatcher.forward(req, resp);
+
+               return;
+            }
          }
-         else
+
+         try
          {
-            throw new ServletException("Unable to writeHeaderDetail", e);
+            writeHeaderDetail(reqToken, writer);
          }
+         catch (Exception e)
+         {
+            if (e instanceof RuntimeException)
+            {
+               throw (RuntimeException) e;
+            }
+            else
+            {
+               throw new ServletException("Unable to writeHeaderDetail", e);
+            }
+         }
       }
 
       writer.println("  </body>");
@@ -121,27 +162,9 @@
       doGet(req, resp);
    }
 
-   private void writeHeaderDetail(final String authHeader, final PrintWriter writer) throws IOException, GSSException
+   private void writeHeaderDetail(final byte[] reqToken, final PrintWriter writer) throws IOException, GSSException
    {
-      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);
-
       if (reqToken[0] == 0x60)
       {
          NegTokenInit negTokenInit = NegTokenInitDecoder.decode(reqToken);
@@ -194,21 +217,6 @@
          return;
       }
 
-      byte[] ntlmHeader = "NTLMSSP".getBytes();
-      if (reqToken.length > 7)
-      {
-         byte[] reqHeader = new byte[7];
-         System.arraycopy(reqToken, 0, reqHeader, 0, 7);
-
-         if (Arrays.equals(ntlmHeader, reqHeader))
-         {
-            writer.println("<h3>NTLM</h3>");
-
-            return;
-         }
-
-      }
-
       writer.println("<p><b>Unsupported negotiation mechanism</b></p>");
    }
 

Added: 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	                        (rev 0)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/java/org/jboss/security/negotiation/toolkit/NTLMNegotiationServlet.java	2008-08-09 12:42:34 UTC (rev 76853)
@@ -0,0 +1,186 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * 
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.security.negotiation.toolkit;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.jboss.security.negotiation.ntlm.Constants;
+import org.jboss.security.negotiation.ntlm.encoding.NTLMField;
+import org.jboss.security.negotiation.ntlm.encoding.NegotiateMessage;
+import org.jboss.security.negotiation.ntlm.encoding.NegotiateMessageDecoder;
+import org.jboss.util.Base64;
+
+/**
+ * A basic servlet to specifically test the NTLM negotiation.
+ * 
+ * @author darran.lofthouse at jboss.com
+ * @version $Revision$
+ */
+public class NTLMNegotiationServlet extends HttpServlet
+{
+
+   private static final long serialVersionUID = -3291448937864587130L;
+
+   private static final Logger log = Logger.getLogger(NTLMNegotiationServlet.class);
+
+   @Override
+   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+   {
+      String authHeader = req.getHeader("Authorization");
+      if (authHeader == null)
+      {
+         log.info("No Authorization Header, sending 401");
+         resp.setHeader("WWW-Authenticate", "NTLM");
+         resp.sendError(401);
+
+         return;
+      }
+
+      log.info("Authorization header received - formatting web page response.");
+
+      /* 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>NTLM Negotiation</h2>");
+
+      // Output the raw header.
+      writer.println("    <p>WWW-Authenticate - ");
+      writer.println(authHeader);
+      writer.println("    </p>");
+
+      try
+      {
+         writeHeaderDetail(authHeader, writer);
+      }
+      catch (Exception e)
+      {
+         if (e instanceof RuntimeException)
+         {
+            throw (RuntimeException) e;
+         }
+         else
+         {
+            throw new ServletException("Unable to writeHeaderDetail", e);
+         }
+      }
+
+      writer.println("  </body>");
+      writer.println("</html>");
+      writer.flush();
+   }
+
+   @Override
+   protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException,
+         IOException
+   {
+      // Handle POST as GET.
+      doGet(req, resp);
+   }
+
+   private void writeHeaderDetail(final String authHeader, 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);
+
+      byte[] ntlmSignature = Constants.SIGNATURE;
+      if (reqToken.length > 8)
+      {
+         byte[] reqHeader = new byte[8];
+         System.arraycopy(reqToken, 0, reqHeader, 0, 8);
+
+         if (Arrays.equals(ntlmSignature, reqHeader))
+         {
+            NegotiateMessage message = NegotiateMessageDecoder.decode(reqToken);
+            writer.println("<h3>NTLM - Negotiate_Message</h3>");
+
+            writer.write("<h4><font color='red'>"
+                  + "Warning, this is NTLM, please verify that you were not expecting SPNEGO!</font></h4>");
+
+            writer.write("<b>Negotiate Flags</b> - ");
+            writer.write(String.valueOf(message.getNegotiateFlags()));
+            writer.write("<br>");
+
+            writeNTLMField("Domain Name", message.getDomainName(), message.getDomainNameFields(), writer);
+            writeNTLMField("Workstation Name", message.getWorkstationName(), message.getWorkstationFields(), writer);
+
+            if (message.getVersion() != null && message.getVersion().length > 0)
+            {
+               writer.write("<b>Version </b> - ");
+               writer.write(new String(message.getVersion()));
+               writer.write("<br>");
+            }
+
+         }
+         else
+         {
+            writer.println("<p><b>Unsupported negotiation mechanism</b></p>");
+         }
+
+      }
+
+   }
+
+   private void writeNTLMField(final String name, final String value, final NTLMField field, final PrintWriter writer)
+   {
+      writer.write("<b>");
+      writer.write(name);
+      writer.write("</b> = ");
+      writer.write(String.valueOf(value));
+      writer.write(" - <i>");
+      writer.write(String.valueOf(field));
+      writer.write("</i><br>");
+   }
+
+}


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

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/WEB-INF/web.xml
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/WEB-INF/web.xml	2008-08-09 11:48:59 UTC (rev 76852)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/WEB-INF/web.xml	2008-08-09 12:42:34 UTC (rev 76853)
@@ -10,6 +10,13 @@
 		</servlet-class>
 	</servlet>
 
+    <servlet>
+      <servlet-name>NTLMNegotiation</servlet-name>
+      <servlet-class>
+        org.jboss.security.negotiation.toolkit.NTLMNegotiationServlet
+      </servlet-class>
+    </servlet>
+
 	<servlet>
 		<servlet-name>SecurityDomainTest</servlet-name>
 		<servlet-class>
@@ -27,7 +34,11 @@
 	<servlet-mapping>
 		<servlet-name>BasicNegotiation</servlet-name>
 		<url-pattern>/BasicNegotiation</url-pattern>
-	</servlet-mapping>    
+	</servlet-mapping>
+    <servlet-mapping>
+      <servlet-name>NTLMNegotiation</servlet-name>
+      <url-pattern>/NTLMNegotiation</url-pattern>
+    </servlet-mapping>      
 	<servlet-mapping>
 		<servlet-name>SecurityDomainTest</servlet-name>
 		<url-pattern>/SecurityDomainTest</url-pattern>

Modified: projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/index.html
===================================================================
--- projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/index.html	2008-08-09 11:48:59 UTC (rev 76852)
+++ projects/security/security-negotiation/trunk/jboss-negotiation-toolkit/src/main/webapp/index.html	2008-08-09 12:42:34 UTC (rev 76853)
@@ -16,6 +16,20 @@
       respond with a SPNEGO token and displays the contents of the token.<br>
       <a href="BasicNegotiation">Basic Negotiation</a> 
     </p>
+
+    <h3>NTLM Negotiation</h3>
+    <p> 
+      The NTLM Negotiation servlet specifically prompts the browser for 
+      NTLM negotiation.<br>
+      
+      Generally the output of the Basic Negotiation servlet is of more interest
+      as SPNEGO should be the preferred negotiation mechanism, however NTLM may
+      be considered an acceptable fallback.<br>
+      
+      If the Basic Negotiation servlet it will forward the request to this servlet 
+      to display the output.<br>
+      <a href="NTLMNegotiation">NTLM Negotiation</a> 
+    </p>
     
     <h3>Security Domain Test</h3>
     <p> 




More information about the jboss-cvs-commits mailing list