[jcifs] Fix for JCIFS NTLM HTTP Authentication and W2k3
Ti Lian Hwang
lian_hwang.ti at fairprice.com.sg
Wed Jan 9 09:24:34 GMT 2008
The following is a possible fix to the infamous
NTLM HTTP Authentication against W2k3 problem.
It comes with a penalty of not reusing the NtlmPasswordAuthentication
objects and its transports.
Not exactly sure why it works, but it seems the preauthentication
somehow messes up the NtlmPasswordAuthentication object with
regards to the hash and challenges.
I've stress tested it with 4 simultaneous cmd windows,
running over 80 curl calls each,
and setting jcifs.smb.client.soTimeout to 2000, forcing early expiration,
with no error.
The curl version used is
curl 7.16.1 (i386-pc-win32) libcurl/7.16.1 OpenSSL/0.9.8b zlib/1.2.3
Protocols: tftp ftp telnet dict ldap http file https ftps
Features: Largefile NTLM SSL libz
JCIFS 1.2.17
jcifs.smb.NtlmPasswordAuthentication
------------------------------------
public boolean equals( Object obj ) {
if( obj instanceof NtlmPasswordAuthentication ) {
NtlmPasswordAuthentication ntlm = (NtlmPasswordAuthentication)obj;
if( ntlm.domain.toUpperCase().equals( domain.toUpperCase() ) &&
ntlm.username.toUpperCase().equals( username.toUpperCase() )) {
if( hashesExternal && ntlm.hashesExternal ) {
return Arrays.equals( ansiHash, ntlm.ansiHash ) &&
// tlh - add next 2 lines
Arrays.equals( challenge, ntlm.challenge ) &&
Arrays.equals( clientChallenge, ntlm.clientChallenge ) &&
Arrays.equals( unicodeHash, ntlm.unicodeHash );
/* This still isn't quite right. If one npa object does not have external
* hashes and the other does then they will not be considered equal even
* though they may be.
*/
} else if( !hashesExternal && password.equals( ntlm.password )) {
return true;
}
}
}
return false;
}
jcifs.smb.SmbSession
--------------------
boolean matches( NtlmPasswordAuthentication auth ) {
// tlh - return true only if ==
return this.auth == auth ;
// return this.auth == auth || this.auth.equals( auth );
}
void logoff( boolean inError ) {
synchronized( transport() ) {
if( sessionSetup == false ) {
return;
}
//tlh - remove all elements when tree disconnected
// for( Enumeration e = trees.elements(); e.hasMoreElements(); ) {
// SmbTree t = (SmbTree)e.nextElement();
// t.treeDisconnect( inError );
// }
trees.removeAllElements();
if( !inError && transport.server.security != ServerMessageBlock.SECURITY_SHARE ) {
/*
* Logoff And X Request / Response
*/
SmbComLogoffAndX request = new SmbComLogoffAndX( null );
request.uid = uid;
try {
transport.send( request, null );
} catch( SmbException se ) {
}
}
sessionSetup = false;
}
}
jcifs.smb.SmbTransport
----------------------
synchronized SmbSession getSmbSession( NtlmPasswordAuthentication auth ) {
/////////////////// see section below
if (SO_TIMEOUT > 0 && sessionExpiration < (now = System.currentTimeMillis())) {
sessionExpiration = now + SO_TIMEOUT;
iter = sessions.listIterator();
while( iter.hasNext() ) {
ssn = (SmbSession)iter.next();
if( ssn.expiration < now ) {
ssn.logoff( false );
// tlh - remove auths when done
iter.remove();
}
}
}
More information about the jcifs
mailing list