directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Maciej Miklas (JIRA)" <j...@apache.org>
Subject [jira] [Created] (DIRKRB-620) KerberosChannel does not read whole response
Date Thu, 23 Feb 2017 11:57:44 GMT
Maciej Miklas created DIRKRB-620:
------------------------------------

             Summary: KerberosChannel does not read whole response
                 Key: DIRKRB-620
                 URL: https://issues.apache.org/jira/browse/DIRKRB-620
             Project: Directory Kerberos
          Issue Type: Bug
          Components: changepw
            Reporter: Maciej Miklas


We have in production some customers who cannot change their password. In log we observe following
exception:
{noformat}
20.02.2017 10:59:11,987 DEBUG [http-bio-127.22.1.62-80-exec-383] org.apache.directory.api.asn1.ber.Asn1Decoder
- <<<==========================================
20.02.2017 10:59:11,987 ERROR [http-bio-127.22.1.62-80-exec-383] org.apache.directory.kerberos.client.KdcConnection
- Authentication failed : timeout occured
20.02.2017 10:59:11,987 WARN [http-bio-127.22.1.62-80-exec-383] org.apache.directory.kerberos.client.KdcConnection
- failed to change the password
org.apache.directory.shared.kerberos.exceptions.KerberosException: TimeOut occured
at org.apache.directory.kerberos.client.KdcConnection._getTgt(KdcConnection.java:294)
at org.apache.directory.kerberos.client.KdcConnection.getTgt(KdcConnection.java:181)
at org.apache.directory.kerberos.client.KdcConnection.changePassword(KdcConnection.java:535)
{noformat}

Real reason for this error is incorrect socket implementation:
{code:title=org.apache.directory.kerberos.client.KerberosChannel|borderStyle=solid}
            byte[] tmp = new byte[ 1024 * 8 ];
            while ( in.available() > 0 )
            {
                int read = in.read( tmp );
                repData.put( tmp, 0, read );
            }
{code}

You should not relay on _available()_ - it returns only assumption. In our case for some users
it returns 0 before whole message has been consumed.

In order to fix it, you should first read header of the message in order to figure out its
size. Now use _in.read(...)_ until you consume expected amount of bytes. Eventually you will
run into timeout, which is fine and happens if server does not keep its promise from header
and cuts the message.

I've changed code into this:
{code:title=org.apache.directory.kerberos.client.KerberosChannel|borderStyle=solid}
	    byte[] tmp = new byte[1024 * 8];
	    int read;
	    try {
		while ((read = in.read(tmp)) > 0) {
		    repData.put(tmp, 0, read);
		}
	    }
	    catch (SocketTimeoutException e) {
		// OK
	    }
{code}

and customers now can change their password. Obviously this implementation is *incorrect*,
because it runs into timeout with every call. Bu it proves that using _available()_ does not
work.




--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Mime
View raw message