1 18 19 package com.knowgate.jcifs.smb; 20 21 import java.io.InputStream ; 22 import java.io.IOException ; 23 24 import com.knowgate.misc.Gadgets; 25 26 abstract class AndXServerMessageBlock extends ServerMessageBlock { 27 28 private static final int ANDX_COMMAND_OFFSET = 1; 29 private static final int ANDX_RESERVED_OFFSET = 2; 30 private static final int ANDX_OFFSET_OFFSET = 3; 31 32 private byte andxCommand = (byte)0xFF; 33 private int andxOffset = 0; 34 35 ServerMessageBlock andx = null; 36 37 AndXServerMessageBlock() { 38 } 39 AndXServerMessageBlock( ServerMessageBlock andx ) { 40 this.andx = andx; 41 if( andx != null ) { 42 andxCommand = andx.command; 43 } 44 } 45 46 53 54 abstract int readBytesDirectWireFormat( InputStream in, int byteCount, 55 byte[] buffer, int bufferIndex ) throws IOException ; 56 57 int getBatchLimit( byte command ) { 58 61 return 0; 62 } 63 64 72 73 int writeWireFormat( byte[] dst, int dstIndex ) { 74 int start = headerStart = dstIndex; 75 76 dstIndex += writeHeaderWireFormat( dst, dstIndex ); 77 dstIndex += writeAndXWireFormat( dst, dstIndex ); 78 length = dstIndex - start; 79 80 if( digest != null ) { 81 digest.sign( dst, headerStart, length, this, response ); 82 } 83 84 return length; 85 } 86 87 93 94 int readWireFormat( InputStream in, 95 byte[] buffer, 96 int bufferIndex ) 97 throws IOException { 98 int start = bufferIndex; 99 100 if( in.read( buffer, bufferIndex, HEADER_LENGTH ) != HEADER_LENGTH ) { 101 throw new IOException ( "unexpected EOF reading smb header" ); 102 } 103 bufferIndex += readHeaderWireFormat( buffer, bufferIndex ); 104 bufferIndex += readAndXWireFormat( in, buffer, bufferIndex ); 105 106 length = bufferIndex - start; 107 return length; 108 } 109 int writeAndXWireFormat( byte[] dst, int dstIndex ) { 110 int start = dstIndex; 111 112 wordCount = writeParameterWordsWireFormat( dst, 113 start + ANDX_OFFSET_OFFSET + 2 ); 114 wordCount += 4; dstIndex += wordCount + 1; 116 wordCount /= 2; 117 dst[start] = (byte)( wordCount & 0xFF ); 118 119 byteCount = writeBytesWireFormat( dst, dstIndex + 2 ); 120 dst[dstIndex++] = (byte)( byteCount & 0xFF ); 121 dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF ); 122 dstIndex += byteCount; 123 124 133 134 135 if( andx == null || USE_BATCHING == false || 136 batchLevel >= getBatchLimit( andx.command )) { 137 andxCommand = (byte)0xFF; 138 andx = null; 139 140 dst[start + ANDX_COMMAND_OFFSET] = (byte)0xFF; 141 dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00; 142 dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00; 143 dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00; 144 145 return dstIndex - start; 147 } 148 149 155 156 andx.batchLevel = batchLevel + 1; 157 158 159 dst[start + ANDX_COMMAND_OFFSET] = andxCommand; 160 dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00; 161 andxOffset = dstIndex - headerStart; 162 writeInt2( andxOffset, dst, start + ANDX_OFFSET_OFFSET ); 163 164 andx.useUnicode = useUnicode; 165 if( andx instanceof AndXServerMessageBlock ) { 166 167 181 182 andx.uid = uid; 183 dstIndex += ((AndXServerMessageBlock)andx).writeAndXWireFormat( dst, dstIndex ); 184 } else { 185 int andxStart = dstIndex; 188 andx.wordCount = andx.writeParameterWordsWireFormat( dst, dstIndex ); 189 dstIndex += andx.wordCount + 1; 190 andx.wordCount /= 2; 191 dst[andxStart] = (byte)( andx.wordCount & 0xFF ); 192 193 andx.byteCount = andx.writeBytesWireFormat( dst, dstIndex + 2 ); 194 dst[dstIndex++] = (byte)( andx.byteCount & 0xFF ); 195 dst[dstIndex++] = (byte)(( andx.byteCount >> 8 ) & 0xFF ); 196 dstIndex += andx.byteCount; 197 } 198 199 return dstIndex - start; 200 } 201 int readAndXWireFormat( InputStream in, 202 byte[] buffer, 203 int bufferIndex ) 204 throws IOException { 205 int start = bufferIndex; 206 207 210 211 if(( wordCount = in.read() ) == -1 ) { 212 throw new IOException ( "unexpected EOF reading smb wordCount" ); 213 } 214 buffer[bufferIndex++] = (byte)( wordCount & 0xFF ); 215 216 219 220 if( wordCount != 0 ) { 221 if( in.read( buffer, bufferIndex, wordCount * 2 ) != ( wordCount * 2 )) { 222 throw new IOException ( "unexpected EOF reading andx parameter words" ); 223 } 224 225 229 230 andxCommand = buffer[bufferIndex]; 231 bufferIndex += 2; 232 andxOffset = readInt2( buffer, bufferIndex ); 233 bufferIndex += 2; 234 235 if( andxOffset == 0 ) { 236 andxCommand = (byte)0xFF; 237 } 238 239 243 244 if( wordCount > 2 ) { 245 bufferIndex += readParameterWordsWireFormat( buffer, bufferIndex ); 246 } 247 } 248 249 252 253 if( in.read( buffer, bufferIndex, 2 ) != 2 ) { 254 throw new IOException ( "unexpected EOF reading smb byteCount" ); 255 } 256 byteCount = readInt2( buffer, bufferIndex ); 257 bufferIndex += 2; 258 259 262 263 if( byteCount != 0 ) { 264 int n; 265 n = readBytesDirectWireFormat( in, byteCount, buffer, bufferIndex ); 266 if( n == 0 ) { 267 if( in.read( buffer, bufferIndex, byteCount ) != byteCount ) { 268 throw new IOException ( "unexpected EOF reading andx bytes" ); 269 } 270 n = readBytesWireFormat( buffer, bufferIndex ); 271 } 272 bufferIndex += byteCount; 273 } 274 275 281 282 if( errorCode != 0 || andxCommand == (byte)0xFF ) { 283 andxCommand = (byte)0xFF; 284 andx = null; 285 } else if( andx == null ) { 286 andxCommand = (byte)0xFF; 287 throw new IOException ( "no andx command supplied with response" ); 288 } else { 289 290 308 309 bufferIndex += in.read( buffer, bufferIndex, 310 andxOffset - ( bufferIndex - headerStart )); 311 312 andx.headerStart = headerStart; 313 andx.command = andxCommand; 314 andx.errorCode = errorCode; 315 andx.flags = flags; 316 andx.flags2 = flags2; 317 andx.tid = tid; 318 andx.pid = pid; 319 andx.uid = uid; 320 andx.mid = mid; 321 andx.useUnicode = useUnicode; 322 323 if( andx instanceof AndXServerMessageBlock ) { 324 bufferIndex += ((AndXServerMessageBlock)andx).readAndXWireFormat( 325 in, buffer, andxOffset - headerStart ); 326 } else { 327 328 331 332 335 336 if(( andx.wordCount = in.read() ) == -1 ) { 337 throw new IOException ( "unexpected EOF reading smb wordCount" ); 338 } 339 buffer[bufferIndex++] = (byte)( andx.wordCount & 0xFF ); 340 341 344 345 if( andx.wordCount != 0 ) { 346 if( in.read( buffer, bufferIndex, andx.wordCount * 2 ) != 347 ( andx.wordCount * 2 )) { 348 throw new IOException ( "unexpected EOF reading andx parameter words" ); 349 } 350 351 355 356 if( andx.wordCount > 2 ) { 357 bufferIndex += 358 andx.readParameterWordsWireFormat( buffer, bufferIndex ); 359 } 360 } 361 362 365 366 if( in.read( buffer, bufferIndex, 2 ) != 2 ) { 367 throw new IOException ( "unexpected EOF reading smb byteCount" ); 368 } 369 andx.byteCount = readInt2( buffer, bufferIndex ); 370 bufferIndex += 2; 371 372 375 376 if( andx.byteCount != 0 ) { 377 if( in.read( buffer, bufferIndex, andx.byteCount ) != andx.byteCount ) { 378 throw new IOException ( "unexpected EOF reading andx bytes" ); 379 } 380 andx.readBytesWireFormat( buffer, bufferIndex ); 381 bufferIndex += andx.byteCount; 382 } 383 } 384 andx.received = true; 385 } 386 387 return bufferIndex - start; 388 } 389 390 public String toString() { 391 return new String ( super.toString() + 392 ",andxCommand=0x" + Gadgets.toHexString( andxCommand, 2 ) + 393 ",andxOffset=" + andxOffset ); 394 } 395 } 396 | Popular Tags |