cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From devd...@apache.org
Subject [12/22] CLOUDSTACK-5344: Update to allow rdp console to access hyper-v vm virtual framebuffer.
Date Mon, 23 Dec 2013 09:13:06 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
new file mode 100755
index 0000000..e93f630
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspChallenge.java
@@ -0,0 +1,293 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import java.util.Arrays;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236642.aspx
+ */
+public class ServerNtlmsspChallenge extends OneTimeSwitch implements NtlmConstants {
+
+    protected NtlmState ntlmState;
+
+    public ServerNtlmsspChallenge(String id, NtlmState state) {
+        super(id);
+        this.ntlmState = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Extract server challenge, extract server flags.
+
+        // Parse TSRequest in BER format
+        TSRequest request = new TSRequest("TSRequest");
+        request.readTag(buf);
+
+        ByteBuffer negoToken = ((NegoItem)request.negoTokens.tags[0]).negoToken.value;
+        ntlmState.challengeMessage = negoToken.toByteArray(); // Store message for MIC calculation in AUTH message
+
+        parseNtlmChallenge(negoToken);
+
+        negoToken.unref();
+        buf.unref();
+        switchOff();
+    }
+
+    public void parseNtlmChallenge(ByteBuffer buf) {
+
+        // Signature: "NTLMSSP\0"
+        String signature = buf.readVariableString(RdpConstants.CHARSET_8);
+        if (!signature.equals(NTLMSSP))
+            throw new RuntimeException("Unexpected NTLM message singature: \"" + signature + "\". Expected signature: \"" + NTLMSSP + "\". Data: " + buf + ".");
+
+        // MessageType (CHALLENGE)
+        int messageType = buf.readSignedIntLE();
+        if (messageType != NtlmConstants.CHALLENGE)
+            throw new RuntimeException("Unexpected NTLM message type: " + messageType + ". Expected type: CHALLENGE (" + NtlmConstants.CHALLENGE + "). Data: " + buf
+                    + ".");
+
+        // TargetName
+        ntlmState.serverTargetName = readStringByDescription(buf);
+
+        // NegotiateFlags
+        ntlmState.negotiatedFlags = new NegoFlags(buf.readSignedIntLE());
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Server negotiate flags: " + ntlmState.negotiatedFlags + ".");
+
+        // ServerChallenge
+        ByteBuffer challenge = buf.readBytes(8);
+        ntlmState.serverChallenge = challenge.toByteArray();
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Server challenge: " + challenge + ".");
+        challenge.unref();
+
+        // Reserved/context
+        buf.skipBytes(8);
+
+        // TargetInfo
+        ByteBuffer targetInfo = readBlockByDescription(buf);
+
+        // Store raw target info block for Type3 message
+        ntlmState.serverTargetInfo = targetInfo.toByteArray();
+
+        // Parse target info block
+        parseTargetInfo(targetInfo);
+        targetInfo.unref();
+
+        // OS Version, NTLM revision, 8 bytes, Optional. Ignore it.
+
+        // Ignore rest of buffer with allocated blocks
+
+        buf.unref();
+    }
+
+    public void parseTargetInfo(ByteBuffer buf) {
+        // Parse attribute list
+
+        while (buf.remainderLength() > 0) {
+            int type = buf.readUnsignedShortLE();
+            int length = buf.readUnsignedShortLE();
+
+            if (type == MSV_AV_EOL)
+                // End of list
+                break;
+
+            ByteBuffer data = buf.readBytes(length);
+            parseAttribute(data, type, length);
+            data.unref();
+        }
+    }
+
+    public void parseAttribute(ByteBuffer buf, int type, int length) {
+        switch (type) {
+        case MSV_AV_NETBIOS_DOMAIN_NAME:
+            ntlmState.serverNetbiosDomainName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_NETBIOS_COMPUTER_NAME:
+            ntlmState.serverNetbiosComputerName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_DOMAIN_NAME:
+            ntlmState.serverDnsDomainName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_COMPUTER_NAME:
+            ntlmState.serverDnsComputerName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+        case MSV_AV_DNS_TREE_NAME:
+            ntlmState.serverDnsTreeName = buf.readString(length, RdpConstants.CHARSET_16);
+            break;
+
+        case MSV_AV_TIMESTAMP:
+            ByteBuffer tmp = buf.readBytes(length);
+            ntlmState.serverTimestamp = tmp.toByteArray();
+            //*DEBUG*/System.out.println("Server timestamp: "+tmp.toPlainHexString());
+            tmp.unref();
+            break;
+
+        default:
+            // Ignore
+            //throw new RuntimeException("[" + this + "] ERROR: Unknown NTLM target info attribute: " + type + ". Data: " + buf + ".");
+
+        }
+
+    }
+
+    /**
+     * Read NTLM wide string, by it description. Buffer offset must point to
+     * beginning of NTLM message signature.
+     * 
+     * @param buf
+     *          buffer with cursor pointing to description
+     * @return
+     */
+    public static String readStringByDescription(ByteBuffer buf) {
+        ByteBuffer block = readBlockByDescription(buf);
+        String value = block.readString(block.length, RdpConstants.CHARSET_16);
+        block.unref();
+
+        return value;
+    }
+
+    public static ByteBuffer readBlockByDescription(ByteBuffer buf) {
+        int blockLength = buf.readUnsignedShortLE(); // In bytes
+        int allocatedSpace = buf.readUnsignedShortLE();
+        int offset = buf.readSignedIntLE();
+
+        if (allocatedSpace < blockLength)
+            blockLength = allocatedSpace;
+
+        if (offset > buf.length || offset < 0 || offset + allocatedSpace > buf.length)
+            throw new RuntimeException("ERROR: NTLM block is too long. Allocated space: " + allocatedSpace + ", block offset: " + offset + ", data: "
+                    + buf + ".");
+
+        // Move cursor to position of allocated block, starting from beginning of
+        // this buffer
+        int storedCursor = buf.cursor;
+        buf.cursor = offset;
+
+        // Read string
+        ByteBuffer value = buf.readBytes(blockLength);
+
+        // Restore cursor
+        buf.cursor = storedCursor;
+
+        return value;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+        (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x03,  // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+        (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+        0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+        0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+        (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+        0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+        0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE) 
+        0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+        0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags
+        0x52, (byte) 0xbe, (byte) 0x83, (byte) 0xd1, (byte) 0xf8, (byte) 0x80, 0x16, 0x6a,  //  ServerChallenge 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  Reserved
+        (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+        0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f,  // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  // Target name value: "WIN-LO419B2LSR0"
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00, //  Item Length: 8 (LE)
+        (byte) 0x99, 0x4f, 0x02, (byte) 0xd8, (byte) 0xf4, (byte) 0xaf, (byte) 0xce, 0x01, // TODO
+
+        // Attribute: End of list
+        0x00, 0x00,
+        0x00, 0x00, 
+    };
+    /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] {1, 2, 3}));
+        NtlmState state = new NtlmState();
+        Element ntlmssp_challenge = new ServerNtlmsspChallenge("ntlmssp_challenge", state);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers());
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_challenge, sink, mainSink);
+        pipeline.link("source", "ntlmssp_challenge", "mainSink");
+        pipeline.link("ntlmssp_challenge >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state challenge
+        byte[] challenge = new byte[] {0x52, (byte)0xbe, (byte)0x83, (byte)0xd1, (byte)0xf8, (byte)0x80, 0x16, 0x6a};
+        if (state.serverChallenge == null)
+            throw new RuntimeException("Challenge was not extracted from server NTLMSSP Challenge packet.");
+        if (!Arrays.equals(challenge, state.serverChallenge))
+            throw new RuntimeException("Challenge was extracted from server NTLMSSP Challenge packet is not equal to expected. Actual value: "
+                    + state.serverChallenge + ", expected value: " + challenge + ".");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
new file mode 100755
index 0000000..bbb75fc
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ServerNtlmsspPubKeyPlus1.java
@@ -0,0 +1,125 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import java.util.Arrays;
+
+import rdpclient.ntlmssp.asn1.TSRequest;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerNtlmsspPubKeyPlus1 extends OneTimeSwitch implements Element {
+
+    protected NtlmState ntlmState;
+
+    public ServerNtlmsspPubKeyPlus1(String id, NtlmState ntlmState) {
+        super(id);
+        this.ntlmState = ntlmState;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.readTag(buf);
+
+        ByteBuffer encryptedPubKey = tsRequest.pubKeyAuth.value;
+        if (encryptedPubKey == null || encryptedPubKey.length == 0)
+            throw new RuntimeException("[" + this
+                    + "] ERROR: Unexpected message from RDP server. Expected encrypted server public key but got nothing instead. Data: " + buf);
+
+        byte[] decryptedPubKey = ntlmState.ntlm_DecryptMessage(encryptedPubKey.toByteArray());
+        //* DEBUG */System.out.println("Decrypted pub key:\n" + new ByteBuffer(decryptedPubKey).dump());
+
+        // Decrease first byte by 1
+        decryptedPubKey[0]--;
+
+        // Compare returned value with expected value
+        if (!Arrays.equals(decryptedPubKey, ntlmState.subjectPublicKey))
+            throw new RuntimeException("[" + this
+                    + "] ERROR: Unexpected message from RDP server. Expected encrypted server public key but an unknown response. Encryted key after decryption: "
+                    + new ByteBuffer(decryptedPubKey).toPlainHexString());
+
+        buf.unref();
+        switchOff(); // Ignore packet
+    }
+}
+
+/* @formatter:off */
+
+// CredSSP header in BER format:
+
+// 0x30, (byte) 0x82, 0x01, 0x2b, // TAG: [UNIVERSAL 16] (constructed)
+// "SEQUENCE" LEN: 299 bytes
+// (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+// 0x02, 0x01, 0x03, // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes,
+// Version: 0x3
+// (byte) 0xa3, (byte) 0x82, 0x01, 0x22, // TAG: [3] (constructed) LEN: 290
+// bytes
+// 0x04, (byte) 0x82, 0x01, 0x1e, // TAG: [UNIVERSAL 4] (primitive)
+// "OCTET STRING" LEN: 286 bytes
+
+// ???
+
+// 0x01, 0x00, 0x00, 0x00, // ???
+// (byte) 0x98, (byte) 0xb0, 0x72, 0x48, 0x42, 0x09, (byte) 0xbd, 0x42, 0x00,
+// 0x00, 0x00, //
+// 0x00, (byte) 0xf6, 0x76, 0x0a, 0x40, (byte) 0xb4, 0x7b, (byte) 0xee, 0x69,
+// (byte) 0xfc, (byte) 0x95, 0x2d, 0x5f, 0x6a, (byte) 0xe8, (byte) 0x87, //
+// 0x4e, (byte) 0xeb, (byte) 0xae, 0x29, (byte) 0xf2, (byte) 0xde, 0x5e, 0x0a,
+// 0x6e, 0x45, (byte) 0xeb, (byte) 0x95, (byte) 0xd9, 0x48, (byte) 0xfc, 0x44,
+// //
+// 0x7a, 0x34, (byte) 0xb4, (byte) 0xc4, (byte) 0xee, (byte) 0x93, (byte) 0xd2,
+// (byte) 0xb4, (byte) 0xe5, (byte) 0xe5, (byte) 0xc1, 0x0f, (byte) 0x9e, 0x3b,
+// (byte) 0xce, (byte) 0xaa, //
+// 0x76, (byte) 0x9e, 0x2b, 0x33, 0x44, 0x76, 0x2f, 0x2f, (byte) 0x83, 0x34,
+// 0x3c, (byte) 0xe9, (byte) 0xc2, (byte) 0xeb, 0x0e, (byte) 0xce, //
+// 0x6c, (byte) 0xcd, 0x1c, (byte) 0xae, 0x74, 0x78, 0x3e, (byte) 0x8c, 0x17,
+// (byte) 0xb4, 0x39, (byte) 0x9a, 0x21, (byte) 0x99, (byte) 0xde, (byte) 0xae,
+// //
+// 0x72, 0x23, (byte) 0x94, (byte) 0xc6, (byte) 0xe9, (byte) 0xcb, 0x48, (byte)
+// 0xb1, 0x54, 0x20, 0x70, 0x70, (byte) 0xc0, 0x77, 0x10, 0x4b, //
+// (byte) 0x8a, (byte) 0xe0, (byte) 0xa0, 0x6c, (byte) 0xb9, 0x65, (byte) 0xfc,
+// 0x67, (byte) 0xe3, 0x3b, (byte) 0xb6, 0x46, 0x5e, (byte) 0xaf, (byte) 0xe7,
+// (byte) 0x92, //
+// 0x6a, (byte) 0xaf, (byte) 0x86, 0x4d, 0x74, 0x33, 0x49, 0x2a, (byte) 0xf0,
+// (byte) 0xdd, 0x66, (byte) 0xce, (byte) 0xec, (byte) 0xcc, 0x6b, 0x62, //
+// 0x4f, 0x35, (byte) 0xb5, 0x0f, (byte) 0x95, (byte) 0xd7, (byte) 0xf7, (byte)
+// 0xf3, 0x4b, 0x59, 0x5f, 0x29, (byte) 0xc9, (byte) 0xc4, (byte) 0xdc, 0x47, //
+// (byte) 0xe9, (byte) 0x8d, 0x47, (byte) 0xd2, 0x1d, 0x35, 0x43, (byte) 0xce,
+// (byte) 0xff, (byte) 0xd7, 0x6b, 0x28, (byte) 0xd8, 0x06, (byte) 0xe8, (byte)
+// 0xba, //
+// (byte) 0xf1, 0x4d, (byte) 0xba, 0x43, (byte) 0x8e, 0x64, (byte) 0xba, (byte)
+// 0xcd, (byte) 0xcb, (byte) 0xaf, 0x1a, 0x61, (byte) 0xd8, 0x11, 0x19, (byte)
+// 0xf7, //
+// (byte) 0xae, (byte) 0xfe, (byte) 0x94, 0x48, (byte) 0x8e, (byte) 0x9f, 0x57,
+// 0x17, (byte) 0xd2, (byte) 0xa3, (byte) 0xfd, 0x79, (byte) 0xb5, (byte) 0xa3,
+// 0x7d, (byte) 0xca, //
+// (byte) 0xff, (byte) 0x94, (byte) 0xb5, (byte) 0xb5, 0x03, (byte) 0xf3, 0x13,
+// 0x6a, 0x74, 0x7a, (byte) 0xae, (byte) 0x9d, (byte) 0xe9, 0x5c, 0x32, 0x42, //
+// 0x37, (byte) 0xa6, (byte) 0xb3, (byte) 0xf5, 0x4b, (byte) 0xaa, 0x22, 0x61,
+// (byte) 0xf5, 0x28, 0x5b, 0x41, 0x26, 0x32, 0x63, 0x5f, //
+// 0x43, (byte) 0xfd, 0x2e, 0x44, 0x7d, (byte) 0xfb, (byte) 0xb6, 0x09, (byte)
+// 0xc5, (byte) 0xc8, 0x33, (byte) 0xbe, (byte) 0x81, 0x08, (byte) 0xd4, 0x5f,
+// //
+// (byte) 0xad, (byte) 0xee, 0x49, 0x25, 0x62, 0x52, (byte) 0x83, (byte) 0xc1,
+// 0x3e, 0x17, 0x5b, (byte) 0xea, 0x4b, (byte) 0x90, 0x62, (byte) 0xf7, //
+// 0x4e, 0x28, (byte) 0xfb, (byte) 0xab, (byte) 0x9a, (byte) 0xbc, 0x5e, (byte)
+// 0xd4, (byte) 0xd5, 0x56, (byte) 0xf4, 0x4a, 0x2a, 0x7e, (byte) 0xd7, //
+
+/* @formatter:on */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
new file mode 100755
index 0000000..283c709
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/AlgorithmIdentifier.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.Any;
+import common.asn1.ObjectID;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * X509 SubjectPublicKeyInfo field ASN.1 description.
+ */
+public class AlgorithmIdentifier extends Sequence {
+    public ObjectID algorithm = new ObjectID("algorithm");
+    public Any parameters = new Any("parameters") {
+        {
+            optional = true;
+        }
+    };
+
+    public AlgorithmIdentifier(String name) {
+        super(name);
+        this.tags = new Tag[] {algorithm, parameters};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
new file mode 100755
index 0000000..1e646b4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoData.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.SequenceOf;
+import common.asn1.Tag;
+
+/**
+ * The NegoData structure contains the SPNEGO messages, as specified in
+ * [MS-SPNG] section 2.
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * If we write NegoItem as
+ * 
+ * <pre>
+ * NegoItem ::= SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * then NegoData can be written as
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF NegoItem
+ * </pre>
+ * 
+ * <ul>
+ * <li>negoToken: One or more SPNEGO tokens, as specified in [MS-SPNG].
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226781.aspx
+ */
+public class NegoData extends SequenceOf {
+
+    public NegoData(String name) {
+        super(name);
+        this.type = new NegoItem("NegoItem");
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new NegoData(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
new file mode 100755
index 0000000..302ef5b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/NegoItem.java
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * The NegoData structure contains the SPNEGO messages, as specified in
+ * [MS-SPNG] section 2.
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * If we write NegoItem as
+ * 
+ * <pre>
+ * NegoItem ::= SEQUENCE {
+ *   negoToken     [0] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * then NegoData can be written as
+ * 
+ * <pre>
+ * NegoData ::= SEQUENCE OF NegoItem
+ * </pre>
+ * 
+ * <ul>
+ * <li>negoToken: One or more SPNEGO tokens, as specified in [MS-SPNG].
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226781.aspx
+ */
+public class NegoItem extends Sequence {
+
+    public OctetString negoToken = new OctetString("negoToken") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+
+    public NegoItem(String name) {
+        super(name);
+        this.tags = new Tag[] {negoToken};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new NegoItem(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
new file mode 100755
index 0000000..f2d6962
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/SubjectPublicKeyInfo.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.BitString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * X509 SubjectPublicKeyInfo field ASN.1 description.
+ */
+public class SubjectPublicKeyInfo extends Sequence {
+    public AlgorithmIdentifier algorithm = new AlgorithmIdentifier("algorithm");
+    public BitString subjectPublicKey = new BitString("subjectPublicKey");
+
+    public SubjectPublicKeyInfo(String name) {
+        super(name);
+        this.tags = new Tag[] {algorithm, subjectPublicKey};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
new file mode 100755
index 0000000..1133c7d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCredentials.java
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSCredentials ::= SEQUENCE {
+ *   credType      [0] INTEGER,
+ *   credentials   [1] OCTET STRING
+ * }
+ * 
+ * credType:
+ *   1 - credentials contains a TSPasswordCreds structure that defines the user's password credentials.
+ *   2 - credentials contains a TSSmartCardCreds structure that defines the user's smart card credentials.
+ * </pre>
+ */
+public class TSCredentials extends Sequence {
+    public Asn1Integer credType = new Asn1Integer("credType") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString credentials = new OctetString("credentials") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+
+    public TSCredentials(String name) {
+        super(name);
+        this.tags = new Tag[] {credType, credentials};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSCredentials(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
new file mode 100755
index 0000000..170fed2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSCspDataDetail.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSCspDataDetail ::= SEQUENCE {
+ *   keySpec       [0] INTEGER,
+ *   cardName      [1] OCTET STRING OPTIONAL,
+ *   readerName    [2] OCTET STRING OPTIONAL,
+ *   containerName [3] OCTET STRING OPTIONAL,
+ *   cspName       [4] OCTET STRING OPTIONAL
+ * }
+ * </pre>
+ * <ul>
+ * <li>keySpec: Defines the specification of the user's smart card.
+ * 
+ * <li>cardName: Specifies the name of the smart card.
+ * 
+ * <li>readerName: Specifies the name of the smart card reader.
+ * 
+ * <li>containerName: Specifies the name of the certificate container.
+ * 
+ * <li>cspName: Specifies the name of the CSP.
+ * </ul>
+ * @see http://msdn.microsoft.com/en-us/library/cc226785.aspx
+ */
+public class TSCspDataDetail extends Sequence {
+    public Asn1Integer keySpec = new Asn1Integer("keySpec") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString cardName = new OctetString("cardName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+            optional = true;
+        }
+    };
+    public OctetString readerName = new OctetString("readerName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString containerName = new OctetString("containerName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+    public OctetString cspName = new OctetString("cspName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 4;
+            optional = true;
+        }
+    };
+
+    public TSCspDataDetail(String name) {
+        super(name);
+        this.tags = new Tag[] {keySpec, cardName, readerName, containerName, cspName};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSCspDataDetail(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
new file mode 100755
index 0000000..83d756d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSPasswordCreds.java
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSPasswordCreds ::= SEQUENCE {
+ *   domainName    [0] OCTET STRING,
+ *   userName      [1] OCTET STRING,
+ *   password      [2] OCTET STRING
+ * }
+ * </pre>
+ * 
+ * <ul>
+ * <li>domainName: Contains the name of the user's account domain, as defined in
+ * [MS-GLOS].
+ * 
+ * <li>userName: Contains the user's account name.
+ * 
+ * <li>Password: Contains the user's account password.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226783.aspx
+ */
+public class TSPasswordCreds extends Sequence {
+    public OctetString domainName = new OctetString("domainName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public OctetString userName = new OctetString("userName") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+    public OctetString password = new OctetString("password") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+        }
+    };
+
+    public TSPasswordCreds(String name) {
+        super(name);
+        this.tags = new Tag[] {domainName, userName, password};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSPasswordCreds(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
new file mode 100755
index 0000000..5599b61
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
@@ -0,0 +1,202 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+import streamer.ByteBuffer;
+
+/**
+ * The TSRequest structure is the top-most structure used by the CredSSP client
+ * and CredSSP server. It contains the SPNEGO messages between the client and
+ * server, and either the public key authentication messages that are used to
+ * bind to the TLS session or the client credentials that are delegated to the
+ * server. The TSRequest message is always sent over the TLS-encrypted channel
+ * between the client and server in a CredSSP Protocol exchange (see step 1 in
+ * section 3.1.5).
+ * 
+ * <pre>
+ * TSRequest ::= SEQUENCE {
+ *   version       [0] INTEGER,
+ *   negoTokens    [1] NegoData OPTIONAL,
+ *   authInfo      [2] OCTET STRING OPTIONAL,
+ *   pubKeyAuth    [3] OCTET STRING OPTIONAL
+ * }
+ * 
+ * </pre>
+ * <ul>
+ * 
+ * <li>version: This field specifies the supported version of the CredSSP
+ * Protocol. This field MUST be 2. If the version is greater than 2, a version 2
+ * client or server treats its peer as one that is compatible with version 2 of
+ * the CredSSP Protocol.
+ * 
+ * <li>negoTokens: A NegoData structure, as defined in section 2.2.1.1, that
+ * contains the SPNEGO messages that are passed between the client and server.
+ * 
+ * <li>authInfo: A TSCredentials structure, as defined in section 2.2.1.2, that
+ * contains the user's credentials that are delegated to the server. The
+ * authinfo field <b>MUST be encrypted</b> under the encryption key that is
+ * negotiated under the SPNEGO package.
+ * 
+ * <li>pubKeyAuth: This field is used to assure that the public key that is used
+ * by the server during the TLS handshake belongs to the target server and not
+ * to a "man in the middle". The client encrypts the public key it received from
+ * the server (contained in the X.509 certificate) in the TLS handshake from
+ * step 1, by using the confidentiality support of SPNEGO. The public key that
+ * is encrypted is the ASN.1-encoded SubjectPublicKey sub-field of
+ * SubjectPublicKeyInfo from the X.509 certificate, as specified in [RFC3280]
+ * section 4.1. The encrypted key is encapsulated in the pubKeyAuth field of the
+ * TSRequest structure and is sent over the TLS channel to the server. After the
+ * client completes the SPNEGO phase of the CredSSP Protocol, it uses
+ * GSS_WrapEx() for the negotiated protocol to encrypt the server's public key.
+ * The pubKeyAuth field carries the message signature and then the encrypted
+ * public key to the server. In response, the server uses the pubKeyAuth field
+ * to transmit to the client a modified version of the public key (as described
+ * in section 3.1.5) that is encrypted under the encryption key that is
+ * negotiated under SPNEGO.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226780.aspx
+ */
+public class TSRequest extends Sequence {
+    public Asn1Integer version = new Asn1Integer("version") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public NegoData negoTokens = new NegoData("negoTokens") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+            optional = true;
+        }
+    };
+    public OctetString authInfo = new OctetString("authInfo") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString pubKeyAuth = new OctetString("pubKeyAuth") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+
+    public TSRequest(String name) {
+        super(name);
+        this.tags = new Tag[] {version, negoTokens, authInfo, pubKeyAuth};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSRequest(name + suffix).copyFrom(this);
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String[] args) {
+
+        /* @formatter:off */
+    byte[] packet = new byte[] {
+        0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+        (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+        0x02, 0x01, 0x03,  // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+        (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+        0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+        0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+        (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+        0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+        0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+        0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE) 
+        0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+        0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags TODO
+        0x52, (byte) 0xbe, (byte) 0x83, (byte) 0xd1, (byte) 0xf8, (byte) 0x80, 0x16, 0x6a,  //  ServerChallenge 
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  Reserved
+        (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+        0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f,  // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00,  // Target name value: "WIN-LO419B2LSR0"
+
+        // Target Info value:
+        
+        // Attribute list
+
+        0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x01, 0x00,  //  Item Type: NetBIOS computer name (0x0001, LE) 
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x04, 0x00,  // Item Type: DNS domain name (0x0004, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x03, 0x00,  // Item Type: DNS computer name (0x0003, LE)
+        0x1e, 0x00, //  Item Length: 30 (LE)
+        0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+        0x07, 0x00,  // Item Type: Timestamp (0x0007, LE)
+        0x08, 0x00, //  Item Length: 8 (LE)
+        (byte) 0x99, 0x4f, 0x02, (byte) 0xd8, (byte) 0xf4, (byte) 0xaf, (byte) 0xce, 0x01, // TODO
+
+        // Attribute: End of list
+        0x00, 0x00,
+        0x00, 0x00, 
+    };
+    /* @formatter:on */
+
+        TSRequest request = new TSRequest("TSRequest");
+
+        // Read request from buffer
+        // System.out.println("Request BER tree before parsing: " + request);
+        ByteBuffer toReadBuf = new ByteBuffer(packet);
+        request.readTag(toReadBuf);
+        // System.out.println("Request BER tree after parsing: " + request);
+
+        // System.out.println("version value: " + request.version.value);
+        // System.out.println("negoToken value: " + ((NegoItem)
+        // request.negoTokens.tags[0]).negoToken.value);
+
+        // Write request to buffer and compare with original
+        ByteBuffer toWriteBuf = new ByteBuffer(packet.length + 100, true);
+        request.writeTag(toWriteBuf);
+        toWriteBuf.trimAtCursor();
+
+        if (!toReadBuf.equals(toWriteBuf))
+            throw new RuntimeException("Data written to buffer is not equal to data read from buffer. \nExpected: " + toReadBuf + "\nActual: " + toWriteBuf + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
new file mode 100755
index 0000000..9889747
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSSmartCardCreds.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp.asn1;
+
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * <pre>
+ * TSSmartCardCreds ::= SEQUENCE {
+ *   pin           [0] OCTET STRING,
+ *   cspData       [1] TSCspDataDetail,
+ *   userHint      [2] OCTET STRING OPTIONAL,
+ *   domainHint    [3] OCTET STRING OPTIONAL
+ * }
+ * </pre>
+ * 
+ * <ul>
+ * <li>pin: Contains the user's smart card PIN.
+ * 
+ * <li>cspData: A TSCspDataDetail structure that contains information about the
+ * cryptographic service provider (CSP).
+ * 
+ * <li>userHint: Contains the user's account hint.
+ * 
+ * <li>domainHint: Contains the user's domain name to which the user's account
+ * belongs. This name could be entered by the user when the user is first
+ * prompted for the PIN.
+ * </ul>
+ * 
+ * @see http://msdn.microsoft.com/en-us/library/cc226784.aspx
+ */
+public class TSSmartCardCreds extends Sequence {
+    public OctetString pin = new OctetString("pin") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 0;
+        }
+    };
+    public TSCspDataDetail cspData = new TSCspDataDetail("cspData") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 1;
+        }
+    };
+    public OctetString userHint = new OctetString("userHint") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 2;
+            optional = true;
+        }
+    };
+    public OctetString domainHint = new OctetString("domainHint") {
+        {
+            explicit = true;
+            tagClass = CONTEXT_CLASS;
+            tagNumber = 3;
+            optional = true;
+        }
+    };
+
+    public TSSmartCardCreds(String name) {
+        super(name);
+        this.tags = new Tag[] {pin, cspData, userHint, domainHint};
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new TSSmartCardCreds(name + suffix).copyFrom(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
new file mode 100755
index 0000000..4708c0f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/package-info.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+/**
+ * 
+ * CredSSP/SPNEGO/NTLMSSP implementation.
+ * 
+ * CredSSP ASN.1 definition:
+ * 
+ <pre>
+CredSSP DEFINITIONS EXPLICIT TAGS ::=
+
+BEGIN
+
+TSPasswordCreds ::= SEQUENCE {
+  domainName    [0] OCTET STRING,
+  userName      [1] OCTET STRING,
+  password      [2] OCTET STRING
+}
+
+TSCspDataDetail ::= SEQUENCE {
+  keySpec       [0] INTEGER,
+  cardName      [1] OCTET STRING OPTIONAL,
+  readerName    [2] OCTET STRING OPTIONAL,
+  containerName [3] OCTET STRING OPTIONAL,
+  cspName       [4] OCTET STRING OPTIONAL
+}
+
+TSSmartCardCreds ::= SEQUENCE {
+  pin           [0] OCTET STRING,
+  cspData       [1] TSCspDataDetail,
+  userHint      [2] OCTET STRING OPTIONAL,
+  domainHint    [3] OCTET STRING OPTIONAL
+}
+
+TSCredentials ::= SEQUENCE {
+  credType      [0] INTEGER,
+  credentials   [1] OCTET STRING
+}
+
+NegoData ::= SEQUENCE OF SEQUENCE {
+  negoToken     [0] OCTET STRING
+}
+
+TSRequest ::= SEQUENCE {
+  version       [0] INTEGER,
+  negoTokens    [1] NegoData OPTIONAL,
+  authInfo      [2] OCTET STRING OPTIONAL,
+  pubKeyAuth    [3] OCTET STRING OPTIONAL
+}
+
+END
+</pre>
+
+For packet flow, @see http://msdn.microsoft.com/en-us/library/cc226794.aspx
+ */
+package rdpclient.ntlmssp;
+


Mime
View raw message