1 19 20 package jcifs.ntlmssp; 21 22 import java.io.IOException ; 23 24 import java.net.UnknownHostException ; 25 26 import jcifs.Config; 27 28 import jcifs.netbios.NbtAddress; 29 30 33 public class Type2Message extends NtlmMessage { 34 35 private static final int DEFAULT_FLAGS; 36 37 private static final String DEFAULT_DOMAIN; 38 39 private static final byte[] DEFAULT_TARGET_INFORMATION; 40 41 private byte[] challenge; 42 43 private String target; 44 45 private byte[] context; 46 47 private byte[] targetInformation; 48 49 static { 50 DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM | 51 (Config.getBoolean("jcifs.smb.client.useUnicode", true) ? 52 NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM); 53 DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", null); 54 byte[] domain = new byte[0]; 55 if (DEFAULT_DOMAIN != null) { 56 try { 57 domain = DEFAULT_DOMAIN.getBytes("UnicodeLittleUnmarked"); 58 } catch (IOException ex) { } 59 } 60 int domainLength = domain.length; 61 byte[] server = new byte[0]; 62 try { 63 String host = NbtAddress.getLocalHost().getHostName(); 64 if (host != null) { 65 try { 66 server = host.getBytes("UnicodeLittleUnmarked"); 67 } catch (IOException ex) { } 68 } 69 } catch (UnknownHostException ex) { } 70 int serverLength = server.length; 71 byte[] targetInfo = new byte[(domainLength > 0 ? domainLength + 4 : 0) + 72 (serverLength > 0 ? serverLength + 4 : 0) + 4]; 73 int offset = 0; 74 if (domainLength > 0) { 75 writeUShort(targetInfo, offset, 2); 76 offset += 2; 77 writeUShort(targetInfo, offset, domainLength); 78 offset += 2; 79 System.arraycopy(domain, 0, targetInfo, offset, domainLength); 80 offset += domainLength; 81 } 82 if (serverLength > 0) { 83 writeUShort(targetInfo, offset, 1); 84 offset += 2; 85 writeUShort(targetInfo, offset, serverLength); 86 offset += 2; 87 System.arraycopy(server, 0, targetInfo, offset, serverLength); 88 } 89 DEFAULT_TARGET_INFORMATION = targetInfo; 90 } 91 92 96 public Type2Message() { 97 this(getDefaultFlags(), null, null); 98 } 99 100 106 public Type2Message(Type1Message type1) { 107 this(type1, null, null); 108 } 109 110 117 public Type2Message(Type1Message type1, byte[] challenge, String target) { 118 this(getDefaultFlags(type1), challenge, (type1 != null && 119 target == null && type1.getFlag(NTLMSSP_REQUEST_TARGET)) ? 120 getDefaultDomain() : target); 121 } 122 123 130 public Type2Message(int flags, byte[] challenge, String target) { 131 setFlags(flags); 132 setChallenge(challenge); 133 setTarget(target); 134 if (target != null) setTargetInformation(getDefaultTargetInformation()); 135 } 136 137 143 public Type2Message(byte[] material) throws IOException { 144 parse(material); 145 } 146 147 152 public byte[] getChallenge() { 153 return challenge; 154 } 155 156 161 public void setChallenge(byte[] challenge) { 162 this.challenge = challenge; 163 } 164 165 170 public String getTarget() { 171 return target; 172 } 173 174 179 public void setTarget(String target) { 180 this.target = target; 181 } 182 183 190 public byte[] getTargetInformation() { 191 return targetInformation; 192 } 193 194 201 public void setTargetInformation(byte[] targetInformation) { 202 this.targetInformation = targetInformation; 203 } 204 205 212 public byte[] getContext() { 213 return context; 214 } 215 216 222 public void setContext(byte[] context) { 223 this.context = context; 224 } 225 226 public byte[] toByteArray() { 227 try { 228 String targetName = getTarget(); 229 byte[] challenge = getChallenge(); 230 byte[] context = getContext(); 231 byte[] targetInformation = getTargetInformation(); 232 int flags = getFlags(); 233 byte[] target = new byte[0]; 234 if ((flags & (NTLMSSP_TARGET_TYPE_DOMAIN | 235 NTLMSSP_TARGET_TYPE_SERVER | 236 NTLMSSP_TARGET_TYPE_SHARE)) != 0) { 237 if (targetName != null && targetName.length() != 0) { 238 target = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0 ? 239 targetName.getBytes("UnicodeLittleUnmarked") : 240 targetName.toUpperCase().getBytes(getOEMEncoding()); 241 } else { 242 flags &= (0xffffffff ^ (NTLMSSP_TARGET_TYPE_DOMAIN | 243 NTLMSSP_TARGET_TYPE_SERVER | 244 NTLMSSP_TARGET_TYPE_SHARE)); 245 } 246 } 247 if (targetInformation != null) { 248 flags ^= NTLMSSP_NEGOTIATE_TARGET_INFO; 249 if (context == null) context = new byte[8]; 251 } 252 int data = 32; 253 if (context != null) data += 8; 254 if (targetInformation != null) data += 8; 255 byte[] type2 = new byte[data + target.length + 256 (targetInformation != null ? targetInformation.length : 0)]; 257 System.arraycopy(NTLMSSP_SIGNATURE, 0, type2, 0, 8); 258 writeULong(type2, 8, 2); 259 writeSecurityBuffer(type2, 12, data, target); 260 writeULong(type2, 20, flags); 261 System.arraycopy(challenge != null ? challenge : new byte[8], 0, 262 type2, 24, 8); 263 if (context != null) System.arraycopy(context, 0, type2, 32, 8); 264 if (targetInformation != null) { 265 writeSecurityBuffer(type2, 40, data + target.length, 266 targetInformation); 267 } 268 return type2; 269 } catch (IOException ex) { 270 throw new IllegalStateException (ex.getMessage()); 271 } 272 } 273 274 public String toString() { 275 String target = getTarget(); 276 byte[] challenge = getChallenge(); 277 byte[] context = getContext(); 278 byte[] targetInformation = getTargetInformation(); 279 int flags = getFlags(); 280 StringBuffer buffer = new StringBuffer (); 281 if (target != null) { 282 buffer.append("target: ").append(target); 283 } 284 if (challenge != null) { 285 if (buffer.length() > 0) buffer.append("; "); 286 buffer.append("challenge: "); 287 buffer.append("0x"); 288 for (int i = 0; i < challenge.length; i++) { 289 buffer.append(Integer.toHexString((challenge[i] >> 4) & 0x0f)); 290 buffer.append(Integer.toHexString(challenge[i] & 0x0f)); 291 } 292 } 293 if (context != null) { 294 if (buffer.length() > 0) buffer.append("; "); 295 buffer.append("context: "); 296 buffer.append("0x"); 297 for (int i = 0; i < context.length; i++) { 298 buffer.append(Integer.toHexString((context[i] >> 4) & 0x0f)); 299 buffer.append(Integer.toHexString(context[i] & 0x0f)); 300 } 301 } 302 if (targetInformation != null) { 303 if (buffer.length() > 0) buffer.append("; "); 304 buffer.append("targetInformation: "); 305 buffer.append("0x"); 306 for (int i = 0; i < targetInformation.length; i++) { 307 buffer.append(Integer.toHexString((targetInformation[i] >> 4) & 308 0x0f)); 309 buffer.append(Integer.toHexString(targetInformation[i] & 0x0f)); 310 } 311 } 312 if (flags != 0) { 313 if (buffer.length() > 0) buffer.append("; "); 314 buffer.append("flags: "); 315 buffer.append("0x"); 316 buffer.append(Integer.toHexString((flags >> 28) & 0x0f)); 317 buffer.append(Integer.toHexString((flags >> 24) & 0x0f)); 318 buffer.append(Integer.toHexString((flags >> 20) & 0x0f)); 319 buffer.append(Integer.toHexString((flags >> 16) & 0x0f)); 320 buffer.append(Integer.toHexString((flags >> 12) & 0x0f)); 321 buffer.append(Integer.toHexString((flags >> 8) & 0x0f)); 322 buffer.append(Integer.toHexString((flags >> 4) & 0x0f)); 323 buffer.append(Integer.toHexString(flags & 0x0f)); 324 } 325 return buffer.toString(); 326 } 327 328 334 public static int getDefaultFlags() { 335 return DEFAULT_FLAGS; 336 } 337 338 344 public static int getDefaultFlags(Type1Message type1) { 345 if (type1 == null) return DEFAULT_FLAGS; 346 int flags = NTLMSSP_NEGOTIATE_NTLM; 347 int type1Flags = type1.getFlags(); 348 flags |= ((type1Flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? 349 NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM; 350 if ((type1Flags & NTLMSSP_REQUEST_TARGET) != 0) { 351 String domain = getDefaultDomain(); 352 if (domain != null) { 353 flags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_TARGET_TYPE_DOMAIN; 354 } 355 } 356 return flags; 357 } 358 359 364 public static String getDefaultDomain() { 365 return DEFAULT_DOMAIN; 366 } 367 368 public static byte[] getDefaultTargetInformation() { 369 return DEFAULT_TARGET_INFORMATION; 370 } 371 372 private void parse(byte[] material) throws IOException { 373 for (int i = 0; i < 8; i++) { 374 if (material[i] != NTLMSSP_SIGNATURE[i]) { 375 throw new IOException ("Not an NTLMSSP message."); 376 } 377 } 378 if (readULong(material, 8) != 2) { 379 throw new IOException ("Not a Type 2 message."); 380 } 381 int flags = readULong(material, 20); 382 setFlags(flags); 383 String target = null; 384 byte[] bytes = readSecurityBuffer(material, 12); 385 if (bytes.length != 0) { 386 target = new String (bytes, 387 ((flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ? 388 "UnicodeLittleUnmarked" : getOEMEncoding()); 389 } 390 setTarget(target); 391 for (int i = 24; i < 32; i++) { 392 if (material[i] != 0) { 393 byte[] challenge = new byte[8]; 394 System.arraycopy(material, 24, challenge, 0, 8); 395 setChallenge(challenge); 396 break; 397 } 398 } 399 int offset = readULong(material, 16); if (offset == 32 || material.length == 32) return; 401 for (int i = 32; i < 40; i++) { 402 if (material[i] != 0) { 403 byte[] context = new byte[8]; 404 System.arraycopy(material, 32, context, 0, 8); 405 setContext(context); 406 break; 407 } 408 } 409 if (offset == 40 || material.length == 40) return; 410 bytes = readSecurityBuffer(material, 40); 411 if (bytes.length != 0) setTargetInformation(bytes); 412 } 413 414 } 415 | Popular Tags |