[ 
https://issues.apache.org/jira/browse/DIRKRB-620?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Emmanuel Lecharny resolved DIRKRB-620.
--------------------------------------
       Resolution: Fixed
    Fix Version/s: 2.0.0-RC1

Fixed with http://svn.apache.org/viewvc?rev=1784265&view=rev

> 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
>             Fix For: 2.0.0-RC1
>
>
> 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)

Reply via email to