Bug 33157

Summary: basic authentication fails in some cases
Product: Tomcat 5 Reporter: andrew taylor <aktweb>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 5.5.4   
Target Milestone: ---   
Hardware: All   
OS: Windows XP   

Description andrew taylor 2005-01-18 21:29:10 UTC
setup
- java 1.5.0.1
- tomcat 5.5.4
- UserDatabaseRealm

to cause failuer, using wget as my test client
- wget -O o --http-user=user --http-
passwd=pinotnoir "http://localhost:8080/myapp/myjsp.jsp"
- wget -O o --http-user=user --http-
passwd=pinotnoir1 "http://localhost:8080/myapp/myjsp.jsp"
- wget -O o --http-user=user --http-
passwd=pinotnoir "http://localhost:8080/myapp/myjsp.jsp"

by setting a breakpoint in RealmBase.authenticate, the username/credentials 
strings show up as
- user/pinotnoir
- user/pinotnoir1
- user/pinotnoir1  <==== incorrect, should be pinotnoir

The issues seems to be in Base64.decode:

decodedDataCC.allocate(lastData - numberQuadruple, -1);
decodedDataCC.setEnd(lastData - numberQuadruple);
decodedData = decodedDataCC.getBuffer();


decodedDataCC.allocate(lastData - numberQuadruple, -1);
- allocate does not reallocate for the 3 test (pinotnoir) since the buffer was 
already big enough from the previous request (pinotnoir1)
- setEnd sets an end flag
- getBuffer just gets the byte[], which is too big (pinotnoir1)

from there on, things are just messed up.

for a quicky, I have just hacked the CharChunk.allocate to remove the size 
check:

    public void allocate( int initial, int limit  ) {
	isOutput=true;
//	if( buff==null || buff.length < initial ) {
	    buff=new char[initial];
//	}
	this.limit=limit;
	start=0;
	end=0;
	isOutput=true;
	isSet=true;
    }
Comment 1 Remy Maucherat 2005-01-18 23:00:02 UTC
Nice try, but your analysis of the problem is wrong (and the quick fix is very
bad). The issue is in BasicAuthenticator:
                if (colon < 0) {
                    ...
                } else {
                    char[] buf = authorizationCC.getBuffer();
                    username = new String(buf, 0, colon);
                    password = new String(buf, colon + 1, 
                            buf.length - colon - 1);
                }
This need to use authorizationCC.getEnd as the end of the buffer, rather than
its length. I'll test it.
Comment 2 Remy Maucherat 2005-01-18 23:17:15 UTC
I tested my patch, and this fixes the issue. Thanks for finding it.