Author: remm
Date: Thu Oct 22 15:11:06 2015
New Revision: 1710030

URL: http://svn.apache.org/viewvc?rev=1710030&view=rev
Log:
Remove some duplicate code (helper classes are public for now), add 
configuration for digest, cleanups.

Modified:
    tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
    
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/BasicAuthModule.java
    
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/DigestAuthModule.java
    
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/FormAuthModule.java
    
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/SpnegoAuthModule.java
    
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/TomcatAuthModule.java

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java 
(original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java 
Thu Oct 22 15:11:06 2015
@@ -402,7 +402,7 @@ public class DigestAuthenticator extends
         };
     }
 
-    private static class DigestInfo {
+    public static class DigestInfo {
 
         private final String opaque;
         private final long nonceValidity;
@@ -608,7 +608,7 @@ public class DigestAuthenticator extends
 
     }
 
-    private static class NonceInfo {
+    public static class NonceInfo {
         private final long timestamp;
         private final boolean seen[];
         private final int offset;

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java 
(original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java 
Thu Oct 22 15:11:06 2015
@@ -307,13 +307,13 @@ public class SpnegoAuthenticator extends
     /**
      * This class gets a gss credential via a privileged action.
      */
-    private static class AcceptAction implements 
PrivilegedExceptionAction<byte[]> {
+    public static class AcceptAction implements 
PrivilegedExceptionAction<byte[]> {
 
         GSSContext gssContext;
 
         byte[] decoded;
 
-        AcceptAction(GSSContext context, byte[] decodedToken) {
+        public AcceptAction(GSSContext context, byte[] decodedToken) {
             this.gssContext = context;
             this.decoded = decodedToken;
         }
@@ -326,7 +326,7 @@ public class SpnegoAuthenticator extends
     }
 
 
-    private static class AuthenticateAction implements 
PrivilegedAction<Principal> {
+    public static class AuthenticateAction implements 
PrivilegedAction<Principal> {
 
         private final Realm realm;
         private final GSSContext gssContext;
@@ -359,7 +359,7 @@ public class SpnegoAuthenticator extends
      * This hack works by re-ordering the list of mechTypes in the NegTokenInit
      * token.
      */
-    private static class SpnegoTokenFixer {
+    public static class SpnegoTokenFixer {
 
         public static void fix(byte[] token) {
             SpnegoTokenFixer fixer = new SpnegoTokenFixer(token);

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/BasicAuthModule.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/BasicAuthModule.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/BasicAuthModule.java
 (original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/BasicAuthModule.java
 Thu Oct 22 15:11:06 2015
@@ -18,7 +18,6 @@ package org.apache.catalina.authenticato
 
 import java.io.IOException;
 import java.text.MessageFormat;
-import java.util.Iterator;
 import java.util.Map;
 
 import javax.security.auth.Subject;
@@ -35,7 +34,6 @@ import javax.servlet.http.HttpServletRes
 import org.apache.catalina.Context;
 import org.apache.catalina.authenticator.BasicAuthenticator.BasicCredentials;
 import org.apache.catalina.connector.Request;
-import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
 
@@ -53,10 +51,9 @@ public class BasicAuthModule extends Tom
     }
 
 
-    @SuppressWarnings("rawtypes")
     @Override
     public void initializeModule(MessagePolicy requestPolicy, MessagePolicy 
responsePolicy,
-            CallbackHandler handler, Map options) throws AuthException {
+            CallbackHandler handler, Map<String, String> options) throws 
AuthException {
     }
 
 
@@ -114,13 +111,6 @@ public class BasicAuthModule extends Tom
     }
 
 
-    private GenericPrincipal getPrincipal(PasswordValidationCallback 
passwordCallback) {
-        Iterator<Object> credentials = 
passwordCallback.getSubject().getPrivateCredentials()
-                .iterator();
-        return (GenericPrincipal) credentials.next();
-    }
-
-
     @Override
     public AuthStatus secureResponse(MessageInfo messageInfo, Subject 
serviceSubject)
             throws AuthException {

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/DigestAuthModule.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/DigestAuthModule.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/DigestAuthModule.java
 (original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/DigestAuthModule.java
 Thu Oct 22 15:11:06 2015
@@ -17,7 +17,6 @@
 package org.apache.catalina.authenticator.jaspic.provider.modules;
 
 import java.io.IOException;
-import java.io.StringReader;
 import java.nio.charset.StandardCharsets;
 import java.security.Principal;
 import java.text.MessageFormat;
@@ -36,10 +35,12 @@ import javax.servlet.http.HttpServletRes
 
 import org.apache.catalina.Context;
 import org.apache.catalina.Realm;
+import org.apache.catalina.authenticator.DigestAuthenticator.DigestInfo;
+import org.apache.catalina.authenticator.DigestAuthenticator.NonceInfo;
+import org.apache.catalina.connector.Request;
 import org.apache.catalina.util.StandardSessionIdGenerator;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.util.http.parser.Authorization;
 import org.apache.tomcat.util.security.ConcurrentMessageDigest;
 import org.apache.tomcat.util.security.MD5Encoder;
 
@@ -179,17 +180,31 @@ public class DigestAuthModule extends To
 
 
     @Override
-    @SuppressWarnings("rawtypes")
-    public void initializeModule(MessagePolicy requestPolicy, MessagePolicy 
responsePolicy,
-            CallbackHandler handler, Map options) throws AuthException {
+    public synchronized void initializeModule(MessagePolicy requestPolicy, 
MessagePolicy responsePolicy,
+            CallbackHandler handler, Map<String, String> options) throws 
AuthException {
         this.handler = handler;
-        startInternal();
-    }
-
-
-    protected synchronized void startInternal() {
         this.sessionIdGenerator = new StandardSessionIdGenerator();
 
+        // Get properties from options
+        this.key = options.get("key");
+        String nonceCacheSizeValue = options.get("nonceCacheSize");
+        if (nonceCacheSizeValue != null) {
+            this.nonceCacheSize = Integer.parseInt(nonceCacheSizeValue);
+        }
+        String nonceCountWindowSizeValue = options.get("nonceCountWindowSize");
+        if (nonceCountWindowSizeValue != null) {
+            this.nonceCountWindowSize = 
Integer.parseInt(nonceCountWindowSizeValue);
+        }
+        String nonceValidityValue = options.get("nonceValidity");
+        if (nonceValidityValue != null) {
+            this.nonceValidity = Long.parseLong(nonceValidityValue);
+        }
+        this.opaque = options.get("opaque");
+        String validateUriValue = options.get("validateUri");
+        if (validateUriValue != null) {
+            this.validateUri = Boolean.parseBoolean(validateUriValue);
+        }
+
         // Generate a random secret key
         if (getKey() == null) {
             setKey(sessionIdGenerator.generateSessionId());
@@ -231,12 +246,12 @@ public class DigestAuthModule extends To
             Subject serviceSubject) throws AuthException {
 
         Principal principal = null;
-        HttpServletRequest request = (HttpServletRequest) 
messageInfo.getRequestMessage();
+        Request request = (Request) messageInfo.getRequestMessage();
         HttpServletResponse response = (HttpServletResponse) 
messageInfo.getResponseMessage();
         String authorization = request.getHeader(AUTHORIZATION_HEADER);
 
         DigestInfo digestInfo = new DigestInfo(getOpaque(), 
getNonceValidity(), getKey(), nonces,
-                isValidateUri(), getRealmName());
+                isValidateUri());
 
         if (authorization == null || !digestInfo.parse(request, 
authorization)) {
             String nonce = generateNonce(request);
@@ -245,6 +260,7 @@ public class DigestAuthModule extends To
         }
 
         if (digestInfo.validate(request)) {
+            // FIXME: maybe use a custom callback handler instead
             principal = digestInfo.authenticate(realm);
         }
 
@@ -391,240 +407,4 @@ public class DigestAuthModule extends To
     }
 
 
-    private static class DigestInfo {
-
-        private final String opaque;
-        private final long nonceValidity;
-        private final String key;
-        private final Map<String, NonceInfo> nonces;
-        private boolean validateUri = true;
-
-        private String userName = null;
-        private String method = null;
-        private String uri = null;
-        private String response = null;
-        private String nonce = null;
-        private String nc = null;
-        private String cnonce = null;
-        private String realmName = null;
-        private String qop = null;
-        private String opaqueReceived = null;
-
-        private boolean nonceStale = false;
-
-        private String contextRealmName;
-
-        public DigestInfo(String opaque, long nonceValidity, String key,
-                Map<String, NonceInfo> nonces, boolean validateUri, String 
contextRealmName) {
-            this.opaque = opaque;
-            this.nonceValidity = nonceValidity;
-            this.key = key;
-            this.nonces = nonces;
-            this.validateUri = validateUri;
-            this.contextRealmName = contextRealmName;
-        }
-
-        public String getUsername() {
-            return userName;
-        }
-
-        public boolean parse(HttpServletRequest request, String authorization) 
{
-            // Validate the authorization credentials format
-            if (authorization == null) {
-                return false;
-            }
-
-            Map<String, String> directives;
-            try {
-                directives = Authorization.parseAuthorizationDigest(
-                        new StringReader(authorization));
-            } catch (IOException e) {
-                return false;
-            }
-
-            if (directives == null) {
-                return false;
-            }
-
-            method = request.getMethod();
-            userName = directives.get("username");
-            realmName = directives.get("realm");
-            nonce = directives.get("nonce");
-            nc = directives.get("nc");
-            cnonce = directives.get("cnonce");
-            qop = directives.get("qop");
-            uri = directives.get("uri");
-            response = directives.get("response");
-            opaqueReceived = directives.get("opaque");
-
-            return true;
-        }
-
-        public boolean validate(HttpServletRequest request) {
-            if ((userName == null) || (realmName == null) || (nonce == null) 
|| (uri == null)
-                    || (response == null)) {
-                return false;
-            }
-
-            // Validate the URI - should match the request line sent by client
-            if (validateUri) {
-                String uriQuery;
-                String query = request.getQueryString();
-                if (query == null) {
-                    uriQuery = request.getRequestURI();
-                } else {
-                    uriQuery = request.getRequestURI() + "?" + query;
-                }
-                if (!uri.equals(uriQuery)) {
-                    // Some clients (older Android) use an absolute URI for
-                    // DIGEST but a relative URI in the request line.
-                    // request. 2.3.5 < fixed Android version <= 4.0.3
-                    String host = request.getHeader("host");
-                    String scheme = request.getScheme();
-                    if (host != null && !uriQuery.startsWith(scheme)) {
-                        StringBuilder absolute = new StringBuilder();
-                        absolute.append(scheme);
-                        absolute.append("://");
-                        absolute.append(host);
-                        absolute.append(uriQuery);
-                        if (!uri.equals(absolute.toString())) {
-                            return false;
-                        }
-                    } else {
-                        return false;
-                    }
-                }
-            }
-
-            // Validate the Realm name
-            if (!contextRealmName.equals(realmName)) {
-                return false;
-            }
-
-            // Validate the opaque string
-            if (!opaque.equals(opaqueReceived)) {
-                return false;
-            }
-
-            // Validate nonce
-            int i = nonce.indexOf(":");
-            if (i < 0 || (i + 1) == nonce.length()) {
-                return false;
-            }
-            long nonceTime;
-            try {
-                nonceTime = Long.parseLong(nonce.substring(0, i));
-            } catch (NumberFormatException nfe) {
-                return false;
-            }
-            String md5clientIpTimeKey = nonce.substring(i + 1);
-            long currentTime = System.currentTimeMillis();
-            if ((currentTime - nonceTime) > nonceValidity) {
-                nonceStale = true;
-                synchronized (nonces) {
-                    nonces.remove(nonce);
-                }
-            }
-            String serverIpTimeKey = request.getRemoteAddr() + ":" + nonceTime 
+ ":" + key;
-            byte[] buffer = ConcurrentMessageDigest.digestMD5(serverIpTimeKey
-                    .getBytes(StandardCharsets.ISO_8859_1));
-            String md5ServerIpTimeKey = MD5Encoder.encode(buffer);
-            if (!md5ServerIpTimeKey.equals(md5clientIpTimeKey)) {
-                return false;
-            }
-
-            // Validate qop
-            if (qop != null && !QOP.equals(qop)) {
-                return false;
-            }
-
-            // Validate cnonce and nc
-            // Check if presence of nc and Cnonce is consistent with presence 
of
-            // qop
-            if (qop == null) {
-                if (cnonce != null || nc != null) {
-                    return false;
-                }
-            } else {
-                if (cnonce == null || nc == null) {
-                    return false;
-                }
-                // RFC 2617 says nc must be 8 digits long. Older Android 
clients
-                // use 6. 2.3.5 < fixed Android version <= 4.0.3
-                if (nc.length() < 6 || nc.length() > 8) {
-                    return false;
-                }
-                long count;
-                try {
-                    count = Long.parseLong(nc, 16);
-                } catch (NumberFormatException nfe) {
-                    return false;
-                }
-                NonceInfo info;
-                synchronized (nonces) {
-                    info = nonces.get(nonce);
-                }
-                if (info == null) {
-                    // Nonce is valid but not in cache. It must have dropped 
out
-                    // of the cache - force a re-authentication
-                    nonceStale = true;
-                } else {
-                    if (!info.nonceCountValid(count)) {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-
-        public boolean isNonceStale() {
-            return nonceStale;
-        }
-
-        public Principal authenticate(Realm realm) {
-            // Second MD5 digest used to calculate the digest :
-            // MD5(Method + ":" + uri)
-            String a2 = method + ":" + uri;
-
-            byte[] buffer = ConcurrentMessageDigest.digestMD5(a2
-                    .getBytes(StandardCharsets.ISO_8859_1));
-            String md5a2 = MD5Encoder.encode(buffer);
-
-            return realm.authenticate(userName, response, nonce, nc, cnonce, 
qop, realmName, md5a2);
-        }
-
-    }
-
-
-    private static class NonceInfo {
-        private final long timestamp;
-        private final boolean seen[];
-        private final int offset;
-        private int count = 0;
-
-        public NonceInfo(long currentTime, int seenWindowSize) {
-            this.timestamp = currentTime;
-            seen = new boolean[seenWindowSize];
-            offset = seenWindowSize / 2;
-        }
-
-        public synchronized boolean nonceCountValid(long nonceCount) {
-            if ((count - offset) >= nonceCount || (nonceCount > count - offset 
+ seen.length)) {
-                return false;
-            }
-            int checkIndex = (int) ((nonceCount + offset) % seen.length);
-            if (seen[checkIndex]) {
-                return false;
-            } else {
-                seen[checkIndex] = true;
-                seen[count % seen.length] = false;
-                count++;
-                return true;
-            }
-        }
-
-        public long getTimestamp() {
-            return timestamp;
-        }
-    }
 }

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/FormAuthModule.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/FormAuthModule.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/FormAuthModule.java
 (original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/FormAuthModule.java
 Thu Oct 22 15:11:06 2015
@@ -25,6 +25,7 @@ import java.util.Locale;
 import java.util.Map;
 
 import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.message.AuthException;
@@ -45,7 +46,6 @@ import org.apache.catalina.authenticator
 import org.apache.catalina.authenticator.SavedRequest;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
-import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.coyote.ActionCode;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -124,7 +124,6 @@ public class FormAuthModule extends Tomc
     }
 
 
- // TODO Extract common patterns in processing cached principal and cached 
credentials
     private AuthStatus handleSavedCredentials(Subject clientSubject, Request 
request,
             HttpServletResponse response) throws IOException, 
UnsupportedCallbackException {
         Session session = request.getSessionInternal(true);
@@ -133,16 +132,20 @@ public class FormAuthModule extends Tomc
         }
 
         String username = (String) 
session.getNote(Constants.SESS_USERNAME_NOTE);
-        String password = (String) 
session.getNote(Constants.SESS_PASSWORD_NOTE);
+        String passwordString = (String) 
session.getNote(Constants.SESS_PASSWORD_NOTE);
+        char[] password = (passwordString != null) ? 
passwordString.toCharArray() : null;
         if (log.isDebugEnabled()) {
             log.debug("Reauthenticating username '" + username + "'");
         }
 
-        Principal principal = realm.authenticate(username, password);
-        if (principal == null) {
+        PasswordValidationCallback passwordCallback = new 
PasswordValidationCallback(
+                clientSubject, username, password);
+        handler.handle(new Callback[] { passwordCallback });
+        if (!passwordCallback.getResult()) {
             forwardToErrorPage(request, response);
             return AuthStatus.FAILURE;
         }
+        Principal principal = getPrincipal(passwordCallback);
 
         session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
         if (isMatchingSavedRequest(request)) {
@@ -342,13 +345,6 @@ public class FormAuthModule extends Tomc
     }
 
 
-    private GenericPrincipal getPrincipal(PasswordValidationCallback 
passwordCallback) {
-        Iterator<Object> credentials = 
passwordCallback.getSubject().getPrivateCredentials()
-                .iterator();
-        return (GenericPrincipal) credentials.next();
-    }
-
-
     /**
      * Called to forward to the login page
      *

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/SpnegoAuthModule.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/SpnegoAuthModule.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/SpnegoAuthModule.java
 (original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/SpnegoAuthModule.java
 Thu Oct 22 15:11:06 2015
@@ -19,10 +19,8 @@ package org.apache.catalina.authenticato
 import java.io.File;
 import java.io.IOException;
 import java.security.Principal;
-import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 
@@ -39,8 +37,10 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.catalina.Context;
-import org.apache.catalina.Realm;
 import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.authenticator.SpnegoAuthenticator.AcceptAction;
+import 
org.apache.catalina.authenticator.SpnegoAuthenticator.AuthenticateAction;
+import org.apache.catalina.authenticator.SpnegoAuthenticator.SpnegoTokenFixer;
 import org.apache.catalina.connector.Request;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -317,193 +317,4 @@ public class SpnegoAuthModule extends To
     }
 
 
-    /**
-     * This class gets a gss credential via a privileged action.
-     */
-    private static class AcceptAction implements 
PrivilegedExceptionAction<byte[]> {
-
-        GSSContext gssContext;
-
-        byte[] decoded;
-
-        AcceptAction(GSSContext context, byte[] decodedToken) {
-            this.gssContext = context;
-            this.decoded = decodedToken;
-        }
-
-        @Override
-        public byte[] run() throws GSSException {
-            return gssContext.acceptSecContext(decoded,
-                    0, decoded.length);
-        }
-    }
-
-    private static class AuthenticateAction implements 
PrivilegedAction<Principal> {
-
-        private final Realm realm;
-        private final GSSContext gssContext;
-        private final boolean storeDelegatedCredential;
-
-        public AuthenticateAction(Realm realm, GSSContext gssContext,
-                boolean storeDelegatedCredential) {
-            this.realm = realm;
-            this.gssContext = gssContext;
-            this.storeDelegatedCredential = storeDelegatedCredential;
-        }
-
-        @Override
-        public Principal run() {
-            return realm.authenticate(gssContext, storeDelegatedCredential);
-        }
-    }
-
-
-    /**
-     * This class implements a hack around an incompatibility between the
-     * SPNEGO implementation in Windows and the SPNEGO implementation in Java 8
-     * update 40 onwards. It was introduced by the change to fix this bug:
-     * https://bugs.openjdk.java.net/browse/JDK-8048194
-     * (note: the change applied is not the one suggested in the bug report)
-     * <p>
-     * It is not clear to me if Windows, Java or Tomcat is at fault here. I
-     * think it is Java but I could be wrong.
-     * <p>
-     * This hack works by re-ordering the list of mechTypes in the NegTokenInit
-     * token.
-     */
-    private static class SpnegoTokenFixer {
-
-        public static void fix(byte[] token) {
-            SpnegoTokenFixer fixer = new SpnegoTokenFixer(token);
-            fixer.fix();
-        }
-
-
-        private final byte[] token;
-        private int pos = 0;
-
-
-        private SpnegoTokenFixer(byte[] token) {
-            this.token = token;
-        }
-
-
-        // Fixes the token in-place
-        private void fix() {
-            /*
-             * Useful references:
-             * http://tools.ietf.org/html/rfc4121#page-5
-             * http://tools.ietf.org/html/rfc2743#page-81
-             * https://msdn.microsoft.com/en-us/library/ms995330.aspx
-             */
-
-            // Scan until we find the mech types list. If we find anything
-            // unexpected, abort the fix process.
-            if (!tag(0x60)) return;
-            if (!length()) return;
-            if (!oid("1.3.6.1.5.5.2")) return;
-            if (!tag(0xa0)) return;
-            if (!length()) return;
-            if (!tag(0x30)) return;
-            if (!length()) return;
-            if (!tag(0xa0)) return;
-            lengthAsInt();
-            if (!tag(0x30)) return;
-            // Now at the start of the mechType list.
-            // Read the mechTypes into an ordered set
-            int mechTypesLen = lengthAsInt();
-            int mechTypesStart = pos;
-            LinkedHashMap<String, int[]> mechTypeEntries = new 
LinkedHashMap<>();
-            while (pos < mechTypesStart + mechTypesLen) {
-                int[] value = new int[2];
-                value[0] = pos;
-                String key = oidAsString();
-                value[1] = pos - value[0];
-                mechTypeEntries.put(key, value);
-            }
-            // Now construct the re-ordered mechType list
-            byte[] replacement = new byte[mechTypesLen];
-            int replacementPos = 0;
-
-            int[] first = mechTypeEntries.remove("1.2.840.113554.1.2.2");
-            if (first != null) {
-                System.arraycopy(token, first[0], replacement, replacementPos, 
first[1]);
-                replacementPos += first[1];
-            }
-            for (int[] markers : mechTypeEntries.values()) {
-                System.arraycopy(token, markers[0], replacement, 
replacementPos, markers[1]);
-                replacementPos += markers[1];
-            }
-
-            // Finally, replace the original mechType list with the re-ordered
-            // one.
-            System.arraycopy(replacement, 0, token, mechTypesStart, 
mechTypesLen);
-        }
-
-
-        private boolean tag(int expected) {
-            return (token[pos++] & 0xFF) == expected;
-        }
-
-
-        private boolean length() {
-            // No need to retain the length - just need to consume it and make
-            // sure it is valid.
-            int len = lengthAsInt();
-            return pos + len == token.length;
-        }
-
-
-        private int lengthAsInt() {
-            int len = token[pos++] & 0xFF;
-            if (len > 127) {
-                int bytes = len - 128;
-                len = 0;
-                for (int i = 0; i < bytes; i++) {
-                    len = len << 8;
-                    len = len + (token[pos++] & 0xff);
-                }
-            }
-            return len;
-        }
-
-
-        private boolean oid(String expected) {
-            return expected.equals(oidAsString());
-        }
-
-
-        private String oidAsString() {
-            if (!tag(0x06)) return null;
-            StringBuilder result = new StringBuilder();
-            int len = lengthAsInt();
-            // First byte is special case
-            int v = token[pos++] & 0xFF;
-            int c2 = v % 40;
-            int c1 = (v - c2) / 40;
-            result.append(c1);
-            result.append('.');
-            result.append(c2);
-            int c = 0;
-            boolean write = false;
-            for (int i = 1; i < len; i++) {
-                int b = token[pos++] & 0xFF;
-                if (b > 127) {
-                    b -= 128;
-                } else {
-                    write = true;
-                }
-                c = c << 7;
-                c += b;
-                if (write) {
-                    result.append('.');
-                    result.append(c);
-                    c = 0;
-                    write = false;
-                }
-            }
-            return result.toString();
-        }
-    }
-
 }

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/TomcatAuthModule.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/TomcatAuthModule.java?rev=1710030&r1=1710029&r2=1710030&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/TomcatAuthModule.java
 (original)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/provider/modules/TomcatAuthModule.java
 Thu Oct 22 15:11:06 2015
@@ -18,6 +18,7 @@ package org.apache.catalina.authenticato
 
 import java.io.IOException;
 import java.security.Principal;
+import java.util.Iterator;
 import java.util.Map;
 
 import javax.security.auth.Subject;
@@ -29,10 +30,12 @@ import javax.security.auth.message.Messa
 import javax.security.auth.message.MessagePolicy;
 import javax.security.auth.message.callback.CallerPrincipalCallback;
 import javax.security.auth.message.callback.GroupPrincipalCallback;
+import javax.security.auth.message.callback.PasswordValidationCallback;
 import javax.security.auth.message.module.ServerAuthModule;
 
 import org.apache.catalina.Context;
 import org.apache.catalina.authenticator.jaspic.MessageInfoImpl;
+import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -123,4 +126,12 @@ public abstract class TomcatAuthModule i
         GroupPrincipalCallback groupCallback = new 
GroupPrincipalCallback(clientSubject, roles);
         handler.handle(new Callback[] { principalCallback, groupCallback });
     }
+
+    protected GenericPrincipal getPrincipal(PasswordValidationCallback 
passwordCallback) {
+        Iterator<Object> credentials = 
passwordCallback.getSubject().getPrivateCredentials()
+                .iterator();
+        return (GenericPrincipal) credentials.next();
+    }
+
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to