1 18 19 package jcifs.smb; 20 21 import jcifs.Config; 22 import java.io.InputStream ; 23 import java.io.PushbackInputStream ; 24 import java.io.IOException ; 25 import java.io.UnsupportedEncodingException ; 26 import java.util.Calendar ; 27 import java.util.Date ; 28 import jcifs.util.Hexdump; 29 import jcifs.util.LogStream; 30 import jcifs.util.transport.*; 31 32 abstract class ServerMessageBlock extends Response implements Request, SmbConstants { 33 34 static LogStream log = LogStream.getInstance(); 35 36 static final byte[] header = { 37 (byte)0xFF, (byte)'S', (byte)'M', (byte)'B', 38 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 39 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 40 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 41 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 42 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 43 }; 44 45 static void writeInt2( long val, byte[] dst, int dstIndex ) { 46 dst[dstIndex] = (byte)(val); 47 dst[++dstIndex] = (byte)(val >> 8); 48 } 49 static void writeInt4( long val, byte[] dst, int dstIndex ) { 50 dst[dstIndex] = (byte)(val); 51 dst[++dstIndex] = (byte)(val >>= 8); 52 dst[++dstIndex] = (byte)(val >>= 8); 53 dst[++dstIndex] = (byte)(val >> 8); 54 } 55 static int readInt2( byte[] src, int srcIndex ) { 56 return ( src[srcIndex] & 0xFF ) + 57 (( src[srcIndex + 1] & 0xFF ) << 8 ); 58 } 59 static int readInt4( byte[] src, int srcIndex ) { 60 return ( src[srcIndex] & 0xFF ) + 61 (( src[srcIndex + 1] & 0xFF ) << 8 ) + 62 (( src[srcIndex + 2] & 0xFF ) << 16 ) + 63 (( src[srcIndex + 3] & 0xFF ) << 24 ); 64 } 65 static long readInt8( byte[] src, int srcIndex ) { 66 return (readInt4( src, srcIndex ) & 0xFFFFFFFFL) + 67 ((long)(readInt4( src, srcIndex + 4 )) << 32); 68 } 69 static void writeInt8( long val, byte[] dst, int dstIndex ) { 70 dst[dstIndex] = (byte)(val); 71 dst[++dstIndex] = (byte)(val >>= 8); 72 dst[++dstIndex] = (byte)(val >>= 8); 73 dst[++dstIndex] = (byte)(val >>= 8); 74 dst[++dstIndex] = (byte)(val >>= 8); 75 dst[++dstIndex] = (byte)(val >>= 8); 76 dst[++dstIndex] = (byte)(val >>= 8); 77 dst[++dstIndex] = (byte)(val >> 8); 78 } 79 static long readTime( byte[] src, int srcIndex ) { 80 int low = readInt4( src, srcIndex ); 81 int hi = readInt4( src, srcIndex + 4 ); 82 long t = ((long)hi << 32L ) | (low & 0xFFFFFFFFL); 83 t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 ); 84 return t; 85 } 86 static void writeTime( long t, byte[] dst, int dstIndex ) { 87 if( t != 0L ) { 88 t = (t + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L; 89 } 90 writeInt8( t, dst, dstIndex ); 91 } 92 static long readUTime( byte[] buffer, int bufferIndex ) { 93 return readInt4( buffer, bufferIndex ) * 1000L; 94 } 95 static void writeUTime( long t, byte[] dst, int dstIndex ) { 96 if( t == 0L || t == 0xFFFFFFFFFFFFFFFFL ) { 97 writeInt4( 0xFFFFFFFF, dst, dstIndex ); 98 return; 99 } 100 synchronized( TZ ) { 101 if( TZ.inDaylightTime( new Date () )) { 102 if( TZ.inDaylightTime( new Date ( t ))) { 104 } else { 106 t -= 3600000; 108 } 109 } else { 110 if( TZ.inDaylightTime( new Date ( t ))) { 112 t += 3600000; 114 } else { 115 } 117 } 118 } 119 writeInt4( (int)(t / 1000L), dst, dstIndex ); 120 } 121 122 131 132 static final byte SMB_COM_CREATE_DIRECTORY = (byte)0x00; 133 static final byte SMB_COM_DELETE_DIRECTORY = (byte)0x01; 134 static final byte SMB_COM_CLOSE = (byte)0x04; 135 static final byte SMB_COM_DELETE = (byte)0x06; 136 static final byte SMB_COM_RENAME = (byte)0x07; 137 static final byte SMB_COM_QUERY_INFORMATION = (byte)0x08; 138 static final byte SMB_COM_WRITE = (byte)0x0B; 139 static final byte SMB_COM_CHECK_DIRECTORY = (byte)0x10; 140 static final byte SMB_COM_TRANSACTION = (byte)0x25; 141 static final byte SMB_COM_TRANSACTION_SECONDARY = (byte)0x26; 142 static final byte SMB_COM_MOVE = (byte)0x2A; 143 static final byte SMB_COM_ECHO = (byte)0x2B; 144 static final byte SMB_COM_OPEN_ANDX = (byte)0x2D; 145 static final byte SMB_COM_READ_ANDX = (byte)0x2E; 146 static final byte SMB_COM_WRITE_ANDX = (byte)0x2F; 147 static final byte SMB_COM_TRANSACTION2 = (byte)0x32; 148 static final byte SMB_COM_FIND_CLOSE2 = (byte)0x34; 149 static final byte SMB_COM_TREE_DISCONNECT = (byte)0x71; 150 static final byte SMB_COM_NEGOTIATE = (byte)0x72; 151 static final byte SMB_COM_SESSION_SETUP_ANDX = (byte)0x73; 152 static final byte SMB_COM_LOGOFF_ANDX = (byte)0x74; 153 static final byte SMB_COM_TREE_CONNECT_ANDX = (byte)0x75; 154 static final byte SMB_COM_NT_TRANSACT = (byte)0xA0; 155 static final byte SMB_COM_NT_TRANSACT_SECONDARY = (byte)0xA1; 156 static final byte SMB_COM_NT_CREATE_ANDX = (byte)0xA2; 157 158 170 171 byte command, flags; 172 int headerStart, 173 length, 174 batchLevel, 175 errorCode, 176 flags2, 177 tid, pid, uid, mid, 178 wordCount, byteCount; 179 boolean useUnicode, received; 180 long responseTimeout = 1; 181 int signSeq; 182 boolean verifyFailed; 183 NtlmPasswordAuthentication auth = null; 184 String path; 185 SigningDigest digest = null; 186 ServerMessageBlock response; 187 188 ServerMessageBlock() { 189 flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED ); 190 pid = PID; 191 batchLevel = 0; 192 } 193 194 void reset() { 195 flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED ); 196 flags2 = 0; 197 errorCode = 0; 198 received = false; 199 digest = null; 200 } 201 int writeString( String str, byte[] dst, int dstIndex ) { 202 return writeString( str, dst, dstIndex, useUnicode ); 203 } 204 int writeString( String str, byte[] dst, int dstIndex, boolean useUnicode ) { 205 int start = dstIndex; 206 207 try { 208 if( useUnicode ) { 209 if((( dstIndex - headerStart ) % 2 ) != 0 ) { 211 dst[dstIndex++] = (byte)'\0'; 212 } 213 System.arraycopy( str.getBytes( "UnicodeLittleUnmarked" ), 0, 214 dst, dstIndex, str.length() * 2 ); 215 dstIndex += str.length() * 2; 216 dst[dstIndex++] = (byte)'\0'; 217 dst[dstIndex++] = (byte)'\0'; 218 } else { 219 byte[] b = str.getBytes( OEM_ENCODING ); 220 System.arraycopy( b, 0, dst, dstIndex, b.length ); 221 dstIndex += b.length; 222 dst[dstIndex++] = (byte)'\0'; 223 } 224 } catch( UnsupportedEncodingException uee ) { 225 if( log.level > 1 ) 226 uee.printStackTrace( log ); 227 } 228 229 return dstIndex - start; 230 } 231 String readString( byte[] src, int srcIndex ) { 232 return readString( src, srcIndex, 256, useUnicode ); 233 } 234 String readString( byte[] src, int srcIndex, int maxLen, boolean useUnicode ) { 235 int len = 0; 236 String str = null; 237 try { 238 if( useUnicode ) { 239 if((( srcIndex - headerStart ) % 2 ) != 0 ) { 241 srcIndex++; 242 } 243 while( src[srcIndex + len] != (byte)0x00 || 244 src[srcIndex + len + 1] != (byte)0x00 ) { 245 len += 2; 246 if( len > maxLen ) { 247 if( log.level > 0 ) 248 Hexdump.hexdump( System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128 ); 249 throw new RuntimeException ( "zero termination not found" ); 250 } 251 } 252 str = new String ( src, srcIndex, len, "UnicodeLittleUnmarked" ); 253 } else { 254 while( src[srcIndex + len] != (byte)0x00 ) { 255 len++; 256 if( len > maxLen ) { 257 if( log.level > 0 ) 258 Hexdump.hexdump( System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128 ); 259 throw new RuntimeException ( "zero termination not found" ); 260 } 261 } 262 str = new String ( src, srcIndex, len, OEM_ENCODING ); 263 } 264 } catch( UnsupportedEncodingException uee ) { 265 if( log.level > 1 ) 266 uee.printStackTrace( log ); 267 } 268 return str; 269 } 270 int stringWireLength( String str, int offset ) { 271 int len = str.length() + 1; 272 if( useUnicode ) { 273 len = str.length() * 2 + 2; 274 len = ( offset % 2 ) != 0 ? len + 1 : len; 275 } 276 return len; 277 } 278 int readStringLength( byte[] src, int srcIndex, int max ) { 279 int len = 0; 280 while( src[srcIndex + len] != (byte)0x00 ) { 281 if( len++ > max ) { 282 throw new RuntimeException ( "zero termination not found: " + this ); 283 } 284 } 285 return len; 286 } 287 int encode( byte[] dst, int dstIndex ) { 288 int start = headerStart = dstIndex; 289 290 dstIndex += writeHeaderWireFormat( dst, dstIndex ); 291 wordCount = writeParameterWordsWireFormat( dst, dstIndex + 1 ); 292 dst[dstIndex++] = (byte)(( wordCount / 2 ) & 0xFF ); 293 dstIndex += wordCount; 294 wordCount /= 2; 295 byteCount = writeBytesWireFormat( dst, dstIndex + 2 ); 296 dst[dstIndex++] = (byte)( byteCount & 0xFF ); 297 dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF ); 298 dstIndex += byteCount; 299 300 length = dstIndex - start; 301 302 if( digest != null ) { 303 digest.sign( dst, headerStart, length, this, response ); 304 } 305 306 return length; 307 } 308 int decode( byte[] buffer, int bufferIndex ) { 309 int start = headerStart = bufferIndex; 310 311 bufferIndex += readHeaderWireFormat( buffer, bufferIndex ); 312 313 wordCount = buffer[bufferIndex++]; 314 if( wordCount != 0 ) { 315 int n; 316 if(( n = readParameterWordsWireFormat( buffer, bufferIndex )) != wordCount * 2 ) { 317 if( log.level >= 5 ) { 318 log.println( "wordCount * 2=" + ( wordCount * 2 ) + 319 " but readParameterWordsWireFormat returned " + n ); 320 } 321 } 322 bufferIndex += wordCount * 2; 323 } 324 325 byteCount = readInt2( buffer, bufferIndex ); 326 bufferIndex += 2; 327 328 if( byteCount != 0 ) { 329 int n; 330 if(( n = readBytesWireFormat( buffer, bufferIndex )) != byteCount ) { 331 if( log.level >= 5 ) { 332 log.println( "byteCount=" + byteCount + 333 " but readBytesWireFormat returned " + n ); 334 } 335 } 336 339 bufferIndex += byteCount; 340 } 341 342 length = bufferIndex - start; 343 return length; 344 } 345 int writeHeaderWireFormat( byte[] dst, int dstIndex ) { 346 System.arraycopy( header, 0, dst, dstIndex, header.length ); 347 dst[dstIndex + CMD_OFFSET] = command; 348 dst[dstIndex + FLAGS_OFFSET] = flags; 349 writeInt2( flags2, dst, dstIndex + FLAGS_OFFSET + 1 ); 350 dstIndex += TID_OFFSET; 351 writeInt2( tid, dst, dstIndex ); 352 writeInt2( pid, dst, dstIndex + 2 ); 353 writeInt2( uid, dst, dstIndex + 4 ); 354 writeInt2( mid, dst, dstIndex + 6 ); 355 return HEADER_LENGTH; 356 } 357 int readHeaderWireFormat( byte[] buffer, int bufferIndex ) { 358 command = buffer[bufferIndex + CMD_OFFSET]; 359 errorCode = readInt4( buffer, bufferIndex + ERROR_CODE_OFFSET ); 360 flags = buffer[bufferIndex + FLAGS_OFFSET]; 361 flags2 = readInt2( buffer, bufferIndex + FLAGS_OFFSET + 1 ); 362 tid = readInt2( buffer, bufferIndex + TID_OFFSET ); 363 pid = readInt2( buffer, bufferIndex + TID_OFFSET + 2 ); 364 uid = readInt2( buffer, bufferIndex + TID_OFFSET + 4 ); 365 mid = readInt2( buffer, bufferIndex + TID_OFFSET + 6 ); 366 return HEADER_LENGTH; 367 } 368 boolean isResponse() { 369 return ( flags & FLAGS_RESPONSE ) == FLAGS_RESPONSE; 370 } 371 372 392 393 abstract int writeParameterWordsWireFormat( byte[] dst, int dstIndex ); 394 abstract int writeBytesWireFormat( byte[] dst, int dstIndex ); 395 abstract int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ); 396 abstract int readBytesWireFormat( byte[] buffer, int bufferIndex ); 397 398 public int hashCode() { 399 return mid; 400 } 401 public boolean equals( Object obj ) { 402 return obj instanceof ServerMessageBlock && ((ServerMessageBlock)obj).mid == mid; 403 } 404 public String toString() { 405 String c; 406 switch( command ) { 407 case SMB_COM_NEGOTIATE: 408 c = "SMB_COM_NEGOTIATE"; 409 break; 410 case SMB_COM_SESSION_SETUP_ANDX: 411 c = "SMB_COM_SESSION_SETUP_ANDX"; 412 break; 413 case SMB_COM_TREE_CONNECT_ANDX: 414 c = "SMB_COM_TREE_CONNECT_ANDX"; 415 break; 416 case SMB_COM_QUERY_INFORMATION: 417 c = "SMB_COM_QUERY_INFORMATION"; 418 break; 419 case SMB_COM_CHECK_DIRECTORY: 420 c = "SMB_COM_CHECK_DIRECTORY"; 421 break; 422 case SMB_COM_TRANSACTION: 423 c = "SMB_COM_TRANSACTION"; 424 break; 425 case SMB_COM_TRANSACTION2: 426 c = "SMB_COM_TRANSACTION2"; 427 break; 428 case SMB_COM_TRANSACTION_SECONDARY: 429 c = "SMB_COM_TRANSACTION_SECONDARY"; 430 break; 431 case SMB_COM_FIND_CLOSE2: 432 c = "SMB_COM_FIND_CLOSE2"; 433 break; 434 case SMB_COM_TREE_DISCONNECT: 435 c = "SMB_COM_TREE_DISCONNECT"; 436 break; 437 case SMB_COM_LOGOFF_ANDX: 438 c = "SMB_COM_LOGOFF_ANDX"; 439 break; 440 case SMB_COM_ECHO: 441 c = "SMB_COM_ECHO"; 442 break; 443 case SMB_COM_MOVE: 444 c = "SMB_COM_MOVE"; 445 break; 446 case SMB_COM_RENAME: 447 c = "SMB_COM_RENAME"; 448 break; 449 case SMB_COM_DELETE: 450 c = "SMB_COM_DELETE"; 451 break; 452 case SMB_COM_DELETE_DIRECTORY: 453 c = "SMB_COM_DELETE_DIRECTORY"; 454 break; 455 case SMB_COM_NT_CREATE_ANDX: 456 c = "SMB_COM_NT_CREATE_ANDX"; 457 break; 458 case SMB_COM_OPEN_ANDX: 459 c = "SMB_COM_OPEN_ANDX"; 460 break; 461 case SMB_COM_READ_ANDX: 462 c = "SMB_COM_READ_ANDX"; 463 break; 464 case SMB_COM_CLOSE: 465 c = "SMB_COM_CLOSE"; 466 break; 467 case SMB_COM_WRITE_ANDX: 468 c = "SMB_COM_WRITE_ANDX"; 469 break; 470 case SMB_COM_CREATE_DIRECTORY: 471 c = "SMB_COM_CREATE_DIRECTORY"; 472 break; 473 case SMB_COM_NT_TRANSACT: 474 c = "SMB_COM_NT_TRANSACT"; 475 break; 476 case SMB_COM_NT_TRANSACT_SECONDARY: 477 c = "SMB_COM_NT_TRANSACT_SECONDARY"; 478 break; 479 default: 480 c = "UNKNOWN"; 481 } 482 String str = errorCode == 0 ? "0" : SmbException.getMessageByCode( errorCode ); 483 return new String ( 484 "command=" + c + 485 ",received=" + received + 486 ",errorCode=" + str + 487 ",flags=0x" + Hexdump.toHexString( flags & 0xFF, 4 ) + 488 ",flags2=0x" + Hexdump.toHexString( flags2, 4 ) + 489 ",signSeq=" + signSeq + 490 ",tid=" + tid + 491 ",pid=" + pid + 492 ",uid=" + uid + 493 ",mid=" + mid + 494 ",wordCount=" + wordCount + 495 ",byteCount=" + byteCount ); 496 } 497 } 498 | Popular Tags |