jcifs.internal.smb2.ServerMessageBlock2Response Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcifs-ng Show documentation
Show all versions of jcifs-ng Show documentation
A pure-java CIFS/SMB client library
/*
* © 2017 AgNO3 Gmbh & Co. KG
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.internal.smb2;
import jcifs.Configuration;
import jcifs.internal.CommonServerMessageBlockRequest;
import jcifs.internal.CommonServerMessageBlockResponse;
import jcifs.internal.SMBProtocolDecodingException;
import jcifs.smb.NtStatus;
/**
* @author mbechler
*
*/
public abstract class ServerMessageBlock2Response extends ServerMessageBlock2 implements CommonServerMessageBlockResponse {
private boolean received;
private boolean error;
private Long expiration;
private boolean verifyFailed;
private Exception exception;
private boolean asyncHandled;
/**
* @param config
* @param command
*/
public ServerMessageBlock2Response ( Configuration config, int command ) {
super(config, command);
}
/**
* @param config
*/
public ServerMessageBlock2Response ( Configuration config ) {
super(config);
}
/**
* {@inheritDoc}
*
* @see jcifs.internal.CommonServerMessageBlockResponse#getNextResponse()
*/
@Override
public CommonServerMessageBlockResponse getNextResponse () {
return (CommonServerMessageBlockResponse) getNext();
}
/**
* {@inheritDoc}
*
* @see jcifs.internal.CommonServerMessageBlockResponse#prepare(jcifs.internal.CommonServerMessageBlockRequest)
*/
@Override
public void prepare ( CommonServerMessageBlockRequest next ) {
CommonServerMessageBlockResponse n = getNextResponse();
if ( n != null ) {
n.prepare(next);
}
}
/**
* {@inheritDoc}
*
* @see jcifs.internal.smb2.ServerMessageBlock2#reset()
*/
@Override
public void reset () {
super.reset();
this.received = false;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#received()
*/
@Override
public final void received () {
if ( isAsync() && getStatus() == NtStatus.NT_STATUS_PENDING ) {
synchronized ( this ) {
notifyAll();
}
return;
}
this.received = true;
synchronized ( this ) {
notifyAll();
}
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#exception(java.lang.Exception)
*/
@Override
public final void exception ( Exception e ) {
this.error = true;
this.exception = e;
this.received = true;
synchronized ( this ) {
notifyAll();
}
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#error()
*/
@Override
public final void error () {
this.error = true;
synchronized ( this ) {
notifyAll();
}
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#clearReceived()
*/
@Override
public final void clearReceived () {
this.received = false;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#isReceived()
*/
@Override
public final boolean isReceived () {
return this.received;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#isError()
*/
@Override
public final boolean isError () {
return this.error;
}
/**
* @return whether the packet has been signed.
*/
public boolean isSigned () {
return ( getFlags() & SMB2_FLAGS_SIGNED ) != 0;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#getExpiration()
*/
@Override
public Long getExpiration () {
return this.expiration;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#setExpiration(java.lang.Long)
*/
@Override
public void setExpiration ( Long exp ) {
this.expiration = exp;
}
/**
* @return whether the interim response has been handled
*/
public boolean isAsyncHandled () {
return this.asyncHandled;
}
/**
* @param asyncHandled
* the asyncHandled to set
*/
public void setAsyncHandled ( boolean asyncHandled ) {
this.asyncHandled = asyncHandled;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#getException()
*/
@Override
public Exception getException () {
return this.exception;
}
/**
*
* @return error status code
*/
@Override
public final int getErrorCode () {
return getStatus();
}
/**
*
* @return whether signature verification failed
*/
@Override
public final boolean isVerifyFailed () {
return this.verifyFailed;
}
/**
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#getGrantedCredits()
*/
@Override
public int getGrantedCredits () {
return getCredit();
}
/**
* {@inheritDoc}
*
* @throws SMBProtocolDecodingException
*
* @see jcifs.internal.smb2.ServerMessageBlock2#haveResponse(byte[], int, int)
*/
@Override
protected void haveResponse ( byte[] buffer, int start, int len ) throws SMBProtocolDecodingException {
if ( isRetainPayload() ) {
byte[] payload = new byte[len];
System.arraycopy(buffer, start, payload, 0, len);
setRawPayload(payload);
}
if ( !verifySignature(buffer, start, len) ) {
throw new SMBProtocolDecodingException("Signature verification failed for " + getClass().getName());
}
setAsyncHandled(false);
received();
}
/**
*
* {@inheritDoc}
*
* @see jcifs.util.transport.Response#verifySignature(byte[], int, int)
*/
@Override
public boolean verifySignature ( byte[] buffer, int i, int size ) {
// observed too that signatures on error responses are sometimes wrong??
// Looks like the failure case also is just reflecting back the signature we sent
// with SMB3's negotiation validation it's no longer possible to ignore this (on the validation response)
// make sure that validation is performed in any case
Smb2SigningDigest dgst = getDigest();
if ( dgst != null && !isAsync() && ( getConfig().isRequireSecureNegotiate() || getErrorCode() == NtStatus.NT_STATUS_OK ) ) {
// TODO: SMB2 - do we need to check the MIDs?
// We only read what we were waiting for, so first guess would be no.
boolean verify = dgst.verify(buffer, i, size, 0, this);
this.verifyFailed = verify;
return !verify;
}
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy