/* * Copyright (c) 2016 Dell EMC Software * All Rights Reserved */ package com.iwave.ext.windows.winrm.ntlm; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.codec.CharEncoding; /** * A structure representing target information. https://msdn.microsoft.com/en-us/library/cc236646.aspx */ public class TargetInformation { /** * The different byte arrays in the information. */ private Map<Short, byte[]> infos; /** Constant for the MsvAvNbComputerName. */ public static final short MSV_AV_NB_COMPUTER_NAME = 1; /** Constant for the MsvAvNbDomainName. */ public static final short MSV_AV_NB_DOMAIN_NAME = 2; /** Constant for the MsvAvDnsComputerName. */ public static final short MSV_AV_DNS_COMPUTER_NAME = 3; /** Constant for the MsvAvDnsDomainName. */ public static final short MSV_AV_DNS_DOMAIN_NAME = 4; /** Constant for the MsvAvDnsTreeName. */ public static final short MSV_AV_DNS_TREE_NAME = 5; /** Constant for the MsvAvFlags. */ public static final short MSV_AV_FLAGS = 6; /** Constant for the MsvAvTimestamp. */ public static final short MSV_AV_TIMESTAMP = 7; /** Constant for the MsvAvSingleHost. */ public static final short MSV_AV_SINGLE_HOST = 8; /** Constant for the MsvAvTargetName. */ public static final short MSV_AV_TARGET_NAME = 9; /** Constant for the MsvChannelBindings. */ public static final short MSV_CHANNEL_BINDINGS = 10; /** * Constructor for target information. * * @param originalBytes * the bytes of the information */ public TargetInformation(byte[] originalBytes) { infos = new HashMap<Short, byte[]>(); int index = 0; while (index < originalBytes.length) { short type = NTLMUtils.getShort(index, originalBytes); short length = NTLMUtils.getShort(index + 2, originalBytes); index += 4; if (type == 0) { // End of array break; } else { infos.put(type, Arrays.copyOfRange(originalBytes, index, index + length)); } index += length; } } /** * Helper to build the target information byte array. * * @param msg * the byte message that is being built * @param bytes * the bytes to add * @param num * the type of the bytes */ private void put(NTLMByteMessage msg, byte[] bytes, int num) { if (bytes != null) { msg.putHeader(NTLMUtils.convertShort((short) num)); msg.putHeader(NTLMUtils.convertShort((short) bytes.length)); msg.putHeader(bytes); } } /** * Builds the target information byte array. * * @return the target information */ public byte[] build() { NTLMByteMessage msg = new NTLMByteMessage(); for (Entry<Short, byte[]> entry : infos.entrySet()) { put(msg, entry.getValue(), entry.getKey()); } // Cap with 4 0's msg.putHeader(NTLMUtils.convertInt(0)); return msg.getMsg(); } /** * Put a section of the target information into the target information. * * @param num * the type of the section * @param buffer * the data of the section */ public void put(short num, byte[] buffer) { infos.put(num, buffer); } /** * Retrieves a section of the target information. * * @param num * the type of the section to retrieve * @return the section */ public byte[] get(short num) { return infos.get(num); } @Override public String toString() { try { StringBuilder builder = new StringBuilder(); for (Entry<Short, byte[]> entry : infos.entrySet()) { builder.append(entry.getKey()).append(" = "); if (entry.getKey() == MSV_AV_FLAGS) { builder.append(NTLMUtils.getInt(0, infos.get(MSV_AV_FLAGS))); } else if (entry.getKey() == MSV_AV_TIMESTAMP) { builder.append(NTLMUtils.fromMicrosoftTimestamp(infos.get(MSV_AV_TIMESTAMP))); } else { builder.append(new String(entry.getValue(), CharEncoding.UTF_16LE)); } builder.append("\n"); } return builder.toString(); } catch (Exception e) { // Guess we just don't get a to string on this one } return ""; } }