FileDocCategorySizeDatePackage
Type2Message.javaAPI DocJCIFS 1.3.17 API13196Tue Oct 18 15:26:24 BST 2011jcifs.ntlmssp

Type2Message

public class Type2Message extends NtlmMessage
Represents an NTLMSSP Type-2 message.

Fields Summary
private static final int
DEFAULT_FLAGS
private static final String
DEFAULT_DOMAIN
private static final byte[]
DEFAULT_TARGET_INFORMATION
private byte[]
challenge
private String
target
private byte[]
context
private byte[]
targetInformation
Constructors Summary
public Type2Message()
Creates a Type-2 message using default values from the current environment.

        DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM |
                (Config.getBoolean("jcifs.smb.client.useUnicode", true) ?
                        NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM);
        DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", null);
        byte[] domain = new byte[0];
        if (DEFAULT_DOMAIN != null) {
            try {
                domain = DEFAULT_DOMAIN.getBytes(UNI_ENCODING);
            } catch (IOException ex) { }
        }
        int domainLength = domain.length;
        byte[] server = new byte[0];
        try {
            String host = NbtAddress.getLocalHost().getHostName();
            if (host != null) {
                try {
                    server = host.getBytes(UNI_ENCODING);
                } catch (IOException ex) { }
            }
        } catch (UnknownHostException ex) { }
        int serverLength = server.length;
        byte[] targetInfo = new byte[(domainLength > 0 ? domainLength + 4 : 0) +
                (serverLength > 0 ? serverLength + 4 : 0) + 4];
        int offset = 0;
        if (domainLength > 0) {
            writeUShort(targetInfo, offset, 2);
            offset += 2;
            writeUShort(targetInfo, offset, domainLength);
            offset += 2;
            System.arraycopy(domain, 0, targetInfo, offset, domainLength);
            offset += domainLength;
        }
        if (serverLength > 0) {
            writeUShort(targetInfo, offset, 1);
            offset += 2;
            writeUShort(targetInfo, offset, serverLength);
            offset += 2;
            System.arraycopy(server, 0, targetInfo, offset, serverLength);
        }
        DEFAULT_TARGET_INFORMATION = targetInfo;
    
        this(getDefaultFlags(), null, null);
    
public Type2Message(Type1Message type1)
Creates a Type-2 message in response to the given Type-1 message using default values from the current environment.

param
type1 The Type-1 message which this represents a response to.

        this(type1, null, null);
    
public Type2Message(Type1Message type1, byte[] challenge, String target)
Creates a Type-2 message in response to the given Type-1 message.

param
type1 The Type-1 message which this represents a response to.
param
challenge The challenge from the domain controller/server.
param
target The authentication target.

        this(getDefaultFlags(type1), challenge, (type1 != null &&
                target == null && type1.getFlag(NTLMSSP_REQUEST_TARGET)) ?
                        getDefaultDomain() : target);
    
public Type2Message(int flags, byte[] challenge, String target)
Creates a Type-2 message with the specified parameters.

param
flags The flags to apply to this message.
param
challenge The challenge from the domain controller/server.
param
target The authentication target.

        setFlags(flags);
        setChallenge(challenge);
        setTarget(target);
        if (target != null) setTargetInformation(getDefaultTargetInformation());
    
public Type2Message(byte[] material)
Creates a Type-2 message using the given raw Type-2 material.

param
material The raw Type-2 material used to construct this message.
throws
IOException If an error occurs while parsing the material.

        parse(material);
    
Methods Summary
public byte[]getChallenge()
Returns the challenge for this message.

return
A byte[] containing the challenge.

        return challenge;
    
public byte[]getContext()
Returns the local security context.

return
A byte[] containing the local security context. This is used by the client to negotiate local authentication.

        return context;
    
public static java.lang.StringgetDefaultDomain()
Returns the default domain from the current environment.

return
A String containing the domain.

        return DEFAULT_DOMAIN;
    
public static intgetDefaultFlags()
Returns the default flags for a generic Type-2 message in the current environment.

return
An int containing the default flags.

        return DEFAULT_FLAGS;
    
public static intgetDefaultFlags(Type1Message type1)
Returns the default flags for a Type-2 message created in response to the given Type-1 message in the current environment.

return
An int containing the default flags.

        if (type1 == null) return DEFAULT_FLAGS;
        int flags = NTLMSSP_NEGOTIATE_NTLM;
        int type1Flags = type1.getFlags();
        flags |= ((type1Flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ?
                NTLMSSP_NEGOTIATE_UNICODE : NTLMSSP_NEGOTIATE_OEM;
        if ((type1Flags & NTLMSSP_REQUEST_TARGET) != 0) {
            String domain = getDefaultDomain();
            if (domain != null) {
                flags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_TARGET_TYPE_DOMAIN;
            }
        }
        return flags;
    
public static byte[]getDefaultTargetInformation()

        return DEFAULT_TARGET_INFORMATION;
    
public java.lang.StringgetTarget()
Returns the authentication target.

return
A String containing the authentication target.

        return target;
    
public byte[]getTargetInformation()
Returns the target information block.

return
A byte[] containing the target information block. The target information block is used by the client to create an NTLMv2 response.

        return targetInformation;
    
private voidparse(byte[] material)

        for (int i = 0; i < 8; i++) {
            if (material[i] != NTLMSSP_SIGNATURE[i]) {
                throw new IOException("Not an NTLMSSP message.");
            }
        }
        if (readULong(material, 8) != 2) {
            throw new IOException("Not a Type 2 message.");
        }
        int flags = readULong(material, 20);
        setFlags(flags);
        String target = null;
        byte[] bytes = readSecurityBuffer(material, 12);
        if (bytes.length != 0) {
            target = new String(bytes,
                    ((flags & NTLMSSP_NEGOTIATE_UNICODE) != 0) ?
                            UNI_ENCODING : getOEMEncoding());
        }
        setTarget(target);
        for (int i = 24; i < 32; i++) {
            if (material[i] != 0) {
                byte[] challenge = new byte[8];
                System.arraycopy(material, 24, challenge, 0, 8);
                setChallenge(challenge);
                break;
            }
        }
        int offset = readULong(material, 16); // offset of targetname start
        if (offset == 32 || material.length == 32) return;
        for (int i = 32; i < 40; i++) {
            if (material[i] != 0) {
                byte[] context = new byte[8];
                System.arraycopy(material, 32, context, 0, 8);
                setContext(context);
                break;
            }
        }
        if (offset == 40 || material.length == 40) return;
        bytes = readSecurityBuffer(material, 40);
        if (bytes.length != 0) setTargetInformation(bytes);
    
public voidsetChallenge(byte[] challenge)
Sets the challenge for this message.

param
challenge The challenge from the domain controller/server.

        this.challenge = challenge;
    
public voidsetContext(byte[] context)
Sets the local security context. This is used by the client to negotiate local authentication.

param
context The local security context.

        this.context = context;
    
public voidsetTarget(java.lang.String target)
Sets the authentication target.

param
target The authentication target.

        this.target = target;
    
public voidsetTargetInformation(byte[] targetInformation)
Sets the target information block. The target information block is used by the client to create an NTLMv2 response.

param
targetInformation The target information block.

        this.targetInformation = targetInformation;
    
public byte[]toByteArray()

        try {
            String targetName = getTarget();
            byte[] challenge = getChallenge();
            byte[] context = getContext();
            byte[] targetInformation = getTargetInformation();
            int flags = getFlags();
            byte[] target = new byte[0];
            if ((flags & NTLMSSP_REQUEST_TARGET) != 0) {
                if (targetName != null && targetName.length() != 0) {
                    target = (flags & NTLMSSP_NEGOTIATE_UNICODE) != 0 ?
                            targetName.getBytes(UNI_ENCODING) :
                            targetName.toUpperCase().getBytes(getOEMEncoding());
                } else {
                    flags &= (0xffffffff ^ NTLMSSP_REQUEST_TARGET);
                }
            }
            if (targetInformation != null) {
                flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
                // empty context is needed for padding when t.i. is supplied.
                if (context == null) context = new byte[8];
            }
            int data = 32;
            if (context != null) data += 8;
            if (targetInformation != null) data += 8;
            byte[] type2 = new byte[data + target.length +
                    (targetInformation != null ? targetInformation.length : 0)];
            System.arraycopy(NTLMSSP_SIGNATURE, 0, type2, 0, 8);
            writeULong(type2, 8, 2);
            writeSecurityBuffer(type2, 12, data, target);
            writeULong(type2, 20, flags);
            System.arraycopy(challenge != null ? challenge : new byte[8], 0,
                    type2, 24, 8);
            if (context != null) System.arraycopy(context, 0, type2, 32, 8);
            if (targetInformation != null) {
                writeSecurityBuffer(type2, 40, data + target.length,
                        targetInformation);
            }
            return type2;
        } catch (IOException ex) {
            throw new IllegalStateException(ex.getMessage());
        }
    
public java.lang.StringtoString()

        String target = getTarget();
        byte[] challenge = getChallenge();
        byte[] context = getContext();
        byte[] targetInformation = getTargetInformation();

        return "Type2Message[target=" + target +
            ",challenge=" + (challenge == null ? "null" : "<" + challenge.length + " bytes>") +
            ",context=" + (context == null ? "null" : "<" + context.length + " bytes>") +
            ",targetInformation=" + (targetInformation == null ? "null" : "<" + targetInformation.length + " bytes>") +
            ",flags=0x" + jcifs.util.Hexdump.toHexString(getFlags(), 8) + "]";