Signature verification failed, SmbException only on the last packet

View: New views
2 Messages — Rating Filter:   Alert me  

Signature verification failed, SmbException only on the last packet

by Paul Knell :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I am working on a project that uses jcifs to read files from a Windows share
that requires signatures. It works fine when tested on a similar server that
does not require signing. The signature verification works successfully while
the file is being transferred, but it fails on the last (zero-byte) packet.

The exception is:

Caused by: jcifs.smb.SmbException: Signature verification failed.
        at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:517)
        at jcifs.smb.SmbTransport.send(SmbTransport.java:614)
        at jcifs.smb.SmbSession.send(SmbSession.java:239)
        at jcifs.smb.SmbTree.send(SmbTree.java:109)
        at jcifs.smb.SmbFile.send(SmbFile.java:695)
        at jcifs.smb.SmbFileInputStream.readDirect(SmbFileInputStream.java:160)
        at jcifs.smb.SmbFileInputStream.read(SmbFileInputStream.java:121)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:229)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:267)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:324)
        at java.io.FilterInputStream.read(FilterInputStream.java:113)
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)

The work-around I found is to first get the file size, and then only read that
exact number of bytes from the SmbFileInputStream. When doing that, jcifs
doesn't send the last "Read AndX Request" packet, and therefore the problematic
response is not received.

In other words, the problem is seen when using something like this:
byte[] buffer = new byte[100];
int bytesRead;
while ((bytesRead = smbFileInputStream.read(buffer)) != -1) {
 ...do something
}

The problem is NOT seen when using something like this:
long fileSize = smbFile.length();
byte[] buffer = new byte[fileSize];
smbFileInputStream.read(buffer);

It is always the last read() call (the call that returns -1) that results in
"Signature verification failed.".

We are using NTLMv1. This problem happens with both jcifs-1.2.17 and
jcifs-1.3.12 (with lmCompatibility=0,1,or 2 and useExtendedSecurity=false).

Has anyone else has run into this problem? Are there any better solutions other
than the work-around that I have described?

Thanks,
Paul



Re: Signature verification failed, SmbException only on the last packet

by Michael B Allen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 14, 2009 at 10:42 AM, Paul Knell <pknell@...> wrote:

> Hello,
>
> I am working on a project that uses jcifs to read files from a Windows share
> that requires signatures. It works fine when tested on a similar server that
> does not require signing. The signature verification works successfully while
> the file is being transferred, but it fails on the last (zero-byte) packet.
>
> The exception is:
>
> Caused by: jcifs.smb.SmbException: Signature verification failed.
>        at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:517)
>        at jcifs.smb.SmbTransport.send(SmbTransport.java:614)
>        at jcifs.smb.SmbSession.send(SmbSession.java:239)
>        at jcifs.smb.SmbTree.send(SmbTree.java:109)
>        at jcifs.smb.SmbFile.send(SmbFile.java:695)
>        at jcifs.smb.SmbFileInputStream.readDirect(SmbFileInputStream.java:160)
>        at jcifs.smb.SmbFileInputStream.read(SmbFileInputStream.java:121)
>        at java.io.BufferedInputStream.fill(BufferedInputStream.java:229)
>        at java.io.BufferedInputStream.read1(BufferedInputStream.java:267)
>        at java.io.BufferedInputStream.read(BufferedInputStream.java:324)
>        at java.io.FilterInputStream.read(FilterInputStream.java:113)
>        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1025)
>        at org.apache.commons.io.IOUtils.copy(IOUtils.java:999)
>
> The work-around I found is to first get the file size, and then only read that
> exact number of bytes from the SmbFileInputStream. When doing that, jcifs
> doesn't send the last "Read AndX Request" packet, and therefore the problematic
> response is not received.
>
> In other words, the problem is seen when using something like this:
> byte[] buffer = new byte[100];
> int bytesRead;
> while ((bytesRead = smbFileInputStream.read(buffer)) != -1) {
>  ...do something
> }
>
> The problem is NOT seen when using something like this:
> long fileSize = smbFile.length();
> byte[] buffer = new byte[fileSize];
> smbFileInputStream.read(buffer);
>
> It is always the last read() call (the call that returns -1) that results in
> "Signature verification failed.".
>
> We are using NTLMv1. This problem happens with both jcifs-1.2.17 and
> jcifs-1.3.12 (with lmCompatibility=0,1,or 2 and useExtendedSecurity=false).
>
> Has anyone else has run into this problem? Are there any better solutions other
> than the work-around that I have described?

Hi Paul,

Please send me a packet capture?

 http://jcifs.samba.org/capture.html

It's probably some corner case in the code that's wrong. NTLMv1 code
paths aren't exercised much anymore. Or it's some odd server.

Mike

--
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/