You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2014/01/02 08:53:03 UTC

[01/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Updated Branches:
  refs/heads/master 97ede2524 -> 48c47101a


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
new file mode 100755
index 0000000..5914cb3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
@@ -0,0 +1,420 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.BitmapOrder;
+import common.BitmapRectangle;
+import common.CopyRectOrder;
+import common.ScreenDescription;
+import common.adapter.AwtClipboardAdapter;
+
+public class VncMessageHandler extends BaseElement {
+    protected ScreenDescription screen = null;
+
+    // Pad names
+    public static final String SERVER_BELL_ADAPTER_PAD = "bell";
+    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
+    public static final String PIXEL_ADAPTER_PAD = "pixels";
+    public static final String FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD = "fbur";
+
+    // Keys for metadata
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+    public static final String SOURCE_X = "srcX";
+    public static final String SOURCE_Y = "srcY";
+    public static final String PIXEL_FORMAT = "pixel_format";
+
+    private static final String NUM_OF_PROCESSED_RECTANGLES = "rects";
+    private static final String SAVED_CURSOR_POSITION = "cursor";
+
+    // Pixel format: RGB888 LE 32
+    public static final String RGB888LE32 = "RGB888LE32";
+
+    public VncMessageHandler(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+        declarePads();
+    }
+
+    private void declarePads() {
+        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
+        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
+        outputPads.put(SERVER_CLIPBOARD_ADAPTER_PAD, null);
+        outputPads.put(PIXEL_ADAPTER_PAD, null);
+        outputPads.put(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, null);
+
+        inputPads.put("stdin", null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        try {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+            if (!cap(buf, 1, UNLIMITED, link, false))
+                return;
+
+            // Read server message type
+            int messageType = buf.readUnsignedByte();
+
+            // Invoke packet handler by packet type.
+            switch (messageType) {
+
+            case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
+                // Handle frame buffer update
+                if (!handleFBU(buf, link))
+                    return;
+
+                // Frame buffer update is received and fully processed, send request for
+                // another frame buffer update to server.
+                sendFBUR();
+
+                break;
+            }
+
+            case RfbConstants.SERVER_BELL: {
+                if (!handleBell(buf, link))
+                    return;
+                break;
+            }
+
+            case RfbConstants.SERVER_CUT_TEXT: {
+                if (!handleClipboard(buf, link))
+                    return;
+                break;
+            }
+
+            default:
+                // TODO: allow to extend functionality
+                throw new RuntimeException("Unknown server packet type: " + messageType + ".");
+            }
+
+            // Cut tail, if any
+            cap(buf, 0, 0, link, true);
+        } finally {
+
+            // Return processed buffer back to pool
+            buf.unref();
+        }
+    }
+
+    private boolean handleClipboard(ByteBuffer buf, Link link) {
+        if (!cap(buf, 3 + 4, UNLIMITED, link, true))
+            return false;
+
+        // Skip padding
+        buf.skipBytes(3);
+
+        // Read text length
+        int length = buf.readSignedInt();
+
+        // We need full string to parse it
+        if (!cap(buf, length, UNLIMITED, link, true))
+            return false;
+
+        String content = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
+
+        // Send content in metadata
+        ByteBuffer outBuf = new ByteBuffer(0);
+        outBuf.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, content);
+
+        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
+
+        return true;
+    }
+
+    private boolean handleBell(ByteBuffer buf, Link link) {
+        // Send empty packet to bell adapter to produce bell
+        pushDataToPad(SERVER_BELL_ADAPTER_PAD, new ByteBuffer(0));
+
+        return true;
+    }
+
+    // FIXME: this method is too complex
+    private boolean handleFBU(ByteBuffer buf, Link link) {
+
+        // We need at least 3 bytes here, 1 - padding, 2 - number of rectangles
+        if (!cap(buf, 3, UNLIMITED, link, true))
+            return false;
+
+        buf.skipBytes(1);// Skip padding
+
+        // Read number of rectangles
+        int numberOfRectangles = buf.readUnsignedShort();
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Frame buffer update. Number of rectangles: " + numberOfRectangles + ".");
+
+        // Each rectangle must have header at least, header length is 12 bytes.
+        if (!cap(buf, 12 * numberOfRectangles, UNLIMITED, link, true))
+            return false;
+
+        // For all rectangles
+
+        // Restore saved point, to avoid flickering and performance problems when
+        // frame buffer update is split between few incoming packets.
+        int numberOfProcessedRectangles = (buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) != null) ? (Integer)buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) : 0;
+        if (buf.getMetadata(SAVED_CURSOR_POSITION) != null)
+            buf.cursor = (Integer)buf.getMetadata(SAVED_CURSOR_POSITION);
+
+        if (verbose && numberOfProcessedRectangles > 0)
+            System.out.println("[" + this + "] INFO: Restarting from saved point. Number of already processed rectangles: " + numberOfRectangles + ", cursor: "
+                    + buf.cursor + ".");
+
+        // For all new rectangles
+        for (int i = numberOfProcessedRectangles; i < numberOfRectangles; i++) {
+
+            // We need coordinates of rectangle (2x4 bytes) and encoding type (4
+            // bytes)
+            if (!cap(buf, 12, UNLIMITED, link, true))
+                return false;
+
+            // Read coordinates of rectangle
+            int x = buf.readUnsignedShort();
+            int y = buf.readUnsignedShort();
+            int width = buf.readUnsignedShort();
+            int height = buf.readUnsignedShort();
+
+            // Read rectangle encoding
+            int encodingType = buf.readSignedInt();
+
+            // Process rectangle
+            switch (encodingType) {
+
+            case RfbConstants.ENCODING_RAW: {
+                if (!handleRawRectangle(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            case RfbConstants.ENCODING_COPY_RECT: {
+                if (!handleCopyRect(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            case RfbConstants.ENCODING_DESKTOP_SIZE: {
+                if (!handleScreenSizeChangeRect(buf, link, x, y, width, height))
+                    return false;
+                break;
+            }
+
+            default:
+                // TODO: allow to extend functionality
+                throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
+            }
+
+            // Update information about processed rectangles to avoid handling of same
+            // rectangle multiple times.
+            // TODO: push back partial rectangle only instead
+            buf.putMetadata(NUM_OF_PROCESSED_RECTANGLES, ++numberOfProcessedRectangles);
+            buf.putMetadata(SAVED_CURSOR_POSITION, buf.cursor);
+        }
+
+        return true;
+    }
+
+    private boolean handleScreenSizeChangeRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Remote screen size is changed
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Screen size rect. Width: " + width + ", height: " + height + ".");
+
+        screen.setFramebufferSize(width, height);
+
+        return true;
+    }
+
+    private boolean handleCopyRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Copy rectangle from one part of screen to another.
+        // Areas may overlap. Antialiasing may cause visible artifacts.
+
+        // We need 4 bytes with coordinates of source rectangle
+        if (!cap(buf, 4, UNLIMITED, link, true))
+            return false;
+
+        CopyRectOrder order = new CopyRectOrder();
+
+        order.srcX = buf.readUnsignedShort();
+        order.srcY = buf.readUnsignedShort();
+        order.x = x;
+        order.y = y;
+        order.width = width;
+        order.height = height;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Copy rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", srcX: " + order.srcX
+                    + ", srcY: " + order.srcY + ".");
+
+        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
+
+        return true;
+    }
+
+    private boolean handleRawRectangle(ByteBuffer buf, Link link, int x, int y, int width, int height) {
+        // Raw rectangle is just array of pixels to draw on screen.
+        int rectDataLength = width * height * screen.getBytesPerPixel();
+
+        // We need at least rectDataLength bytes. Extra bytes may contain other
+        // rectangles.
+        if (!cap(buf, rectDataLength, UNLIMITED, link, true))
+            return false;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: "
+                    + rectDataLength + ".");
+
+        BitmapRectangle rectangle = new BitmapRectangle();
+        rectangle.x = x;
+        rectangle.y = y;
+        rectangle.width = width;
+        rectangle.height = height;
+        rectangle.bufferWidth = width;
+        rectangle.bufferHeight = height;
+        rectangle.bitmapDataStream = buf.readBytes(rectDataLength);
+        rectangle.colorDepth = screen.getColorDeph();
+
+        BitmapOrder order = new BitmapOrder();
+        order.rectangles = new BitmapRectangle[] {rectangle};
+
+        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
+        return true;
+    }
+
+    @Override
+    public void onStart() {
+        // Send Frame Buffer Update request
+        sendFBUR();
+    }
+
+    private void sendFBUR() {
+        ByteBuffer buf = new ByteBuffer(0);
+        buf.putMetadata("incremental", true);
+        pushDataToPad(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, buf);
+    }
+
+    @Override
+    public String toString() {
+        return "VNCMessageHandler(" + id + ")";
+    }
+
+    /**
+     * 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");
+
+        Element source = new MockSource("source") {
+            {
+                // Split messages at random boundaries to check "pushback" logic
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                        // Message type: server bell
+                        RfbConstants.SERVER_BELL,
+
+                        // Message type: clipboard text
+                        RfbConstants.SERVER_CUT_TEXT,
+                        // Padding
+                        0, 0, 0,
+                        // Length (test)
+                        0, 0, 0, 4,
+
+                }, new byte[] {
+                        // Clipboard text
+                        't', 'e', 's', 't',
+
+                        // Message type: frame buffer update
+                        RfbConstants.SERVER_FRAMEBUFFER_UPDATE,
+                        // Padding
+                        0,
+                        // Number of rectangles
+                        0, 3,},
+
+                        new byte[] {
+
+                        // x, y, width, height: 0x0@4x4
+                        0, 0, 0, 0, 0, 4, 0, 4,
+                        // Encoding: desktop size
+                        (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 24) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 16) & 0xff),
+                        (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 8) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 0) & 0xff),},
+
+                        new byte[] {
+
+                        // x, y, width, height: 0x0@4x4
+                        0, 0, 0, 0, 0, 4, 0, 4,
+                        // Encoding: raw rect
+                        (byte)((RfbConstants.ENCODING_RAW >> 24) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 16) & 0xff),
+                        (byte)((RfbConstants.ENCODING_RAW >> 8) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 0) & 0xff),
+                        // Raw pixel data 4x4x1 bpp
+                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}, new byte[] {11, 12, 13, 14, 15, 16,
+
+                        // x, y, width, height: 0x0@2x2
+                        0, 0, 0, 0, 0, 2, 0, 2,
+                        // Encoding: copy rect
+                        (byte)((RfbConstants.ENCODING_COPY_RECT >> 24) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 16) & 0xff),
+                        (byte)((RfbConstants.ENCODING_COPY_RECT >> 8) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 0) & 0xff),
+                        // srcX, srcY: 2x2
+                        0, 2, 0, 2,});
+            }
+        };
+
+        ScreenDescription screen = new ScreenDescription() {
+            {
+                bytesPerPixel = 1;
+            }
+        };
+
+        final Element handler = new VncMessageHandler("handler", screen);
+
+        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
+        Element fburSink = new MockSink("fbur", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}, new byte[] {}));
+        Element bellSink = new MockSink("bell", emptyBuf);
+        Element clipboardSink = new MockSink("clipboard", emptyBuf);
+        Element desktopSizeChangeSink = new MockSink("desktop_size", emptyBuf);
+        Element pixelsSink = new MockSink("pixels",
+                ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,}));
+        Element copyRectSink = new MockSink("copy_rect", emptyBuf);
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, handler);
+        pipeline.add(fburSink, bellSink, clipboardSink, desktopSizeChangeSink, pixelsSink, copyRectSink);
+
+        pipeline.link("handler >" + FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, "fbur");
+        pipeline.link("handler >" + SERVER_BELL_ADAPTER_PAD, "bell");
+        pipeline.link("handler >" + SERVER_CLIPBOARD_ADAPTER_PAD, "clipboard");
+        pipeline.link("handler >" + PIXEL_ADAPTER_PAD, "pixels");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt b/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
new file mode 100755
index 0000000..4137609
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/resources/jaas_ntlm_config.txt
@@ -0,0 +1,21 @@
+// 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.
+
+MyConfig { com.sun.security.auth.module.Krb5LoginModule required
+  useTicketCache=true
+  doNotPrompt=false;
+};

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt b/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
old mode 100644
new mode 100755
index dd41683..704f5f5
--- a/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/README.txt
@@ -30,3 +30,5 @@ fingerprints.
 
 File rdp-key.pem contains private key in PEM format for use with
 Wireshark.
+
+As alternative, mimikatz can be used to extract RDP private key.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat b/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
old mode 100644
new mode 100755
index 14a7bbd..4e19157
--- a/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/dev-rdp-config.bat
@@ -111,6 +111,19 @@ rem Start TS service
 
 net start Termservice
 
+rem Enable logs
+
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Admin /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Analytic /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Debug /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Admin /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Analytic /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Debug /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-TerminalServices-SessionBroker-Client/Operational /enabled:true /quiet:true
+wevtutil sl Microsoft-Windows-NTLM/Operational /enabled:true /quiet:true
+
+
 
 rem For Network Monitor Decrypt Expert.
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt b/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
new file mode 100755
index 0000000..d3101d6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/test/doc/freerdp-debug-log.txt
@@ -0,0 +1,772 @@
+// 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.
+connected to 192.168.1.3:3389
+NEGOTIATE_MESSAGE (length = 40)
+0000 4e 54 4c 4d 53 53 50 00 01 00 00 00 b7 82 08 e2 NTLMSSP.........
+0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0020 06 01 b1 1d 00 00 00 0f                         ........
+
+VERSION =
+{
+	ProductMajorVersion: 6
+	ProductMinorVersion: 1
+	ProductBuild: 7601
+	Reserved: 0x000000
+	NTLMRevisionCurrent: 0x0F
+ntlm_generate_client_challenge: ClientChallenge (random bytes): 
+0000 01 02 03 04 05 06 07 08                         ........
+
+CHALLENGE_MESSAGE (length = 238)
+0000 4e 54 4c 4d 53 53 50 00 02 00 00 00 1e 00 1e 00 NTLMSSP.........
+0010 38 00 00 00 35 82 8a e2 4a 25 50 a5 11 9b d6 16 8...5...J%P.....
+0020 00 00 00 00 00 00 00 00 98 00 98 00 56 00 00 00 ............V...
+0030 06 03 d7 24 00 00 00 0f 57 00 49 00 4e 00 2d 00 ...$....W.I.N.-.
+0040 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0050 53 00 52 00 30 00 02 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0060 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0070 4c 00 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0080 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0090 32 00 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 2.L.S.R.0.....W.
+00a0 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00b0 42 00 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 B.2.L.S.R.0.....
+00c0 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+00d0 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 9.B.2.L.S.R.0...
+00e0 08 00 a0 e8 85 2c e4 c9 ce 01 00 00 00 00       .....,........
+
+negotiateFlags "0xE28A8235"{
+	NTLMSSP_NEGOTIATE_56 (0),
+	NTLMSSP_NEGOTIATE_KEY_EXCH (1),
+	NTLMSSP_NEGOTIATE_128 (2),
+	NTLMSSP_NEGOTIATE_VERSION (6),
+	NTLMSSP_NEGOTIATE_TARGET_INFO (8),
+	NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY (12),
+	NTLMSSP_TARGET_TYPE_SERVER (14),
+	NTLMSSP_NEGOTIATE_ALWAYS_SIGN (16),
+	NTLMSSP_NEGOTIATE_NTLM (22),
+	NTLMSSP_NEGOTIATE_SEAL (26),
+	NTLMSSP_NEGOTIATE_SIGN (27),
+	NTLMSSP_REQUEST_TARGET (29),
+	NTLMSSP_NEGOTIATE_UNICODE (31),
+}
+VERSION =
+{
+	ProductMajorVersion: 6
+	ProductMinorVersion: 3
+	ProductBuild: 9431
+	Reserved: 0x000000
+	NTLMRevisionCurrent: 0x0F
+TargetName (Len: 30 MaxLen: 30 BufferOffset: 56)
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+
+TargetInfo (Len: 152 MaxLen: 152 BufferOffset: 86)
+0000 02 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0010 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0020 30 00 01 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0030 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+0040 52 00 30 00 04 00 1e 00 57 00 49 00 4e 00 2d 00 R.0.....W.I.N.-.
+0050 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0060 53 00 52 00 30 00 03 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0070 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0080 4c 00 53 00 52 00 30 00 07 00 08 00 a0 e8 85 2c L.S.R.0........,
+0090 e4 c9 ce 01 00 00 00 00                         ........
+
+ChallengeTargetInfo (152):
+AV_PAIRs =
+{
+	MsvAvNbDomainName AvId: 2 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvNbComputerName AvId: 1 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvDnsDomainName AvId: 4 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvDnsComputerName AvId: 3 AvLen: 30
+0000 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0010 39 00 42 00 32 00 4c 00 53 00 52 00 30 00       9.B.2.L.S.R.0.
+	MsvAvTimestamp AvId: 7 AvLen: 8
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+}
+ntlm_generate_timestamp: timestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+ntlm_generate_timestamp: ChallengeTimestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+NTOWFv1W: Password:
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+NTOWFv1W: NtHash (MD4(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: NtHashV1 (NTOWFv1W(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: User:
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+NTOWFv2W: Domain:
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+NTOWFv2W: buffer (User+Domain):
+0000 41 00 44 00 4d 00 49 00 4e 00 49 00 53 00 54 00 A.D.M.I.N.I.S.T.
+0010 52 00 41 00 54 00 4f 00 52 00 77 00 6f 00 72 00 R.A.T.O.R.w.o.r.
+0020 6b 00 67 00 72 00 6f 00 75 00 70 00             k.g.r.o.u.p.
+
+NTOWFv2W: NtHash (HMAC_MD5(NtHashV1, User+Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_hash: hash (NTOWFv2W(Password, User, Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_lm_v2_response: ntlm_v2_hash:
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_lm_v2_response: value (ServerChallenge + ClientChallenge):
+0000 4a 25 50 a5 11 9b d6 16 01 02 03 04 05 06 07 08 J%P.............
+
+ntlm_compute_lm_v2_response: response (HMAC_MD5(ntlm_v2_hash, value) + ClientChallenge):
+0000 7c c0 fd 08 c5 14 05 34 f3 12 9e 3e a3 09 bc c6 |......4...>....
+0010 01 02 03 04 05 06 07 08                         ........
+
+NTOWFv1W: Password:
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+NTOWFv1W: NtHash (MD4(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: NtHashV1 (NTOWFv1W(Password)):
+0000 25 f3 39 c9 86 b5 c2 6f dc ab 91 34 93 a2 18 2a %.9....o...4...*
+
+NTOWFv2W: User:
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+NTOWFv2W: Domain:
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+NTOWFv2W: buffer (User+Domain):
+0000 41 00 44 00 4d 00 49 00 4e 00 49 00 53 00 54 00 A.D.M.I.N.I.S.T.
+0010 52 00 41 00 54 00 4f 00 52 00 77 00 6f 00 72 00 R.A.T.O.R.w.o.r.
+0020 6b 00 67 00 72 00 6f 00 75 00 70 00             k.g.r.o.u.p.
+
+NTOWFv2W: NtHash (HMAC_MD5(NtHashV1, User+Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_hash: hash (NTOWFv2W(Password, User, Domain)):
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_response: Password (length = 20)
+0000 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 R.2.P.r.e.v.i.e.
+0010 77 00 21 00                                     w.!.
+
+ntlm_compute_ntlm_v2_response: Username (length = 26)
+0000 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 A.d.m.i.n.i.s.t.
+0010 72 00 61 00 74 00 6f 00 72 00                   r.a.t.o.r.
+
+ntlm_compute_ntlm_v2_response: Domain (length = 18)
+0000 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 w.o.r.k.g.r.o.u.
+0010 70 00                                           p.
+
+ntlm_compute_ntlm_v2_response: Workstation (length = 12)
+0000 61 00 70 00 6f 00 6c 00 6c 00 6f 00             a.p.o.l.l.o.
+
+ntlm_compute_ntlm_v2_response: TargetInfo (length = 234)
+0000 02 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0010 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0020 30 00 01 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0030 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+0040 52 00 30 00 04 00 1e 00 57 00 49 00 4e 00 2d 00 R.0.....W.I.N.-.
+0050 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0060 53 00 52 00 30 00 03 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0070 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0080 4c 00 53 00 52 00 30 00 07 00 08 00 a0 e8 85 2c L.S.R.0........,
+0090 e4 c9 ce 01 06 00 04 00 02 00 00 00 0a 00 10 00 ................
+00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00b0 09 00 26 00 54 00 45 00 52 00 4d 00 53 00 52 00 ..&.T.E.R.M.S.R.
+00c0 56 00 2f 00 31 00 39 00 32 00 2e 00 31 00 36 00 V./.1.9.2...1.6.
+00d0 38 00 2e 00 31 00 2e 00 33 00 00 00 00 00 00 00 8...1...3.......
+00e0 00 00 00 00 00 00 00 00 00 00                   ..........
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_hash (ntlm_compute_ntlm_v2_hash(context, (char*) ntlm_v2_hash))
+0000 5f cc 4c 48 74 6b 94 ce b7 ae f1 0d c9 11 22 8f _.LHtk........".
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_temp (0x0101 + reserved 6 bytes + Timestamp + ClientChallenge + TargetInfo)
+0000 01 01 00 00 00 00 00 00 a0 e8 85 2c e4 c9 ce 01 ...........,....
+0010 01 02 03 04 05 06 07 08 00 00 00 00 02 00 1e 00 ................
+0020 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0030 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 01 00 9.B.2.L.S.R.0...
+0040 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 ..W.I.N.-.L.O.4.
+0050 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 1.9.B.2.L.S.R.0.
+0060 04 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0070 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0080 30 00 03 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+0090 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+00a0 52 00 30 00 07 00 08 00 a0 e8 85 2c e4 c9 ce 01 R.0........,....
+00b0 06 00 04 00 02 00 00 00 0a 00 10 00 00 00 00 00 ................
+00c0 00 00 00 00 00 00 00 00 00 00 00 00 09 00 26 00 ..............&.
+00d0 54 00 45 00 52 00 4d 00 53 00 52 00 56 00 2f 00 T.E.R.M.S.R.V./.
+00e0 31 00 39 00 32 00 2e 00 31 00 36 00 38 00 2e 00 1.9.2...1.6.8...
+00f0 31 00 2e 00 33 00 00 00 00 00 00 00 00 00 00 00 1...3...........
+0100 00 00 00 00 00 00                               ......
+
+ntlm_compute_ntlm_v2_response: ntlm_v2_chal (ServerChallenge + ntlm_v2_temp)
+0000 4a 25 50 a5 11 9b d6 16 01 01 00 00 00 00 00 00 J%P.............
+0010 a0 e8 85 2c e4 c9 ce 01 01 02 03 04 05 06 07 08 ...,............
+0020 00 00 00 00 02 00 1e 00 57 00 49 00 4e 00 2d 00 ........W.I.N.-.
+0030 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0040 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0050 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0060 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0070 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0080 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 57 00 2.L.S.R.0.....W.
+0090 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00a0 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 08 00 B.2.L.S.R.0.....
+00b0 a0 e8 85 2c e4 c9 ce 01 06 00 04 00 02 00 00 00 ...,............
+00c0 0a 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+00d0 00 00 00 00 09 00 26 00 54 00 45 00 52 00 4d 00 ......&.T.E.R.M.
+00e0 53 00 52 00 56 00 2f 00 31 00 39 00 32 00 2e 00 S.R.V./.1.9.2...
+00f0 31 00 36 00 38 00 2e 00 31 00 2e 00 33 00 00 00 1.6.8...1...3...
+0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00       ..............
+
+ntlm_compute_ntlm_v2_response: nt_proof_str ( HMAC_MD5(ntlm_v2_hash, ntlm_v2_temp_chal))
+0000 19 4b eb ad da 24 d5 96 85 2e 24 94 d6 4a b8 5e .K...$....$..J.^
+
+ntlm_compute_ntlm_v2_response: NtChallengeResponse ( nt_proof_str + ntlm_v2_temp)
+0000 19 4b eb ad da 24 d5 96 85 2e 24 94 d6 4a b8 5e .K...$....$..J.^
+0010 01 01 00 00 00 00 00 00 a0 e8 85 2c e4 c9 ce 01 ...........,....
+0020 01 02 03 04 05 06 07 08 00 00 00 00 02 00 1e 00 ................
+0030 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+0040 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 01 00 9.B.2.L.S.R.0...
+0050 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 ..W.I.N.-.L.O.4.
+0060 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 1.9.B.2.L.S.R.0.
+0070 04 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 4f 00 ....W.I.N.-.L.O.
+0080 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 52 00 4.1.9.B.2.L.S.R.
+0090 30 00 03 00 1e 00 57 00 49 00 4e 00 2d 00 4c 00 0.....W.I.N.-.L.
+00a0 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 53 00 O.4.1.9.B.2.L.S.
+00b0 52 00 30 00 07 00 08 00 a0 e8 85 2c e4 c9 ce 01 R.0........,....
+00c0 06 00 04 00 02 00 00 00 0a 00 10 00 00 00 00 00 ................
+00d0 00 00 00 00 00 00 00 00 00 00 00 00 09 00 26 00 ..............&.
+00e0 54 00 45 00 52 00 4d 00 53 00 52 00 56 00 2f 00 T.E.R.M.S.R.V./.
+00f0 31 00 39 00 32 00 2e 00 31 00 36 00 38 00 2e 00 1.9.2...1.6.8...
+0100 31 00 2e 00 33 00 00 00 00 00 00 00 00 00 00 00 1...3...........
+0110 00 00 00 00 00 00                               ......
+
+ntlm_compute_ntlm_v2_response: SessionBaseKey ( HMAC_MD5(ntlm_v2_hash, nt_proof_str)
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_generate_key_exchange_key: KeyExchangeKey (SessionBaseKey): 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_generate_random_session_key: RandomSessionKey (random bytes): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_exported_session_key: ExportedSessionKey (RandomSessionKey): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_rc4k: key, 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_rc4k: plaintext 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_rc4k: ciphertext (RC4K(key, plaintext)) 
+0000 e4 e9 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f ....A./<.Lr..*|o
+
+ntlm_encrypt_random_session_key: KeyExchangeKey: 
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_encrypt_random_session_key: RandomSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_encrypt_random_session_key: EncryptedRandomSessionKey (RC4K(KeyExchangeKey, RandomSessionKey)): 
+0000 e4 e9 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f ....A./<.Lr..*|o
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0020 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0030 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_generate_client_signing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_client_signing_key: client_sign_magic: ":session key to client-to-server signing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_client_signing_key: ClientSigningKey ( ntlm_generate_signing_key(context->ExportedSessionKey, &sign_magic, context->ClientSigningKey))
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0020 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0030 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_generate_server_signing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_server_signing_key: server_sign_magic: ":session key to server-to-client signing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 69 67 6e 69 6e 67 20 6b 65 79 20 6d 61 67 69 signing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_server_signing_key: ServerSigningKey (ntlm_generate_signing_key(context->ExportedSessionKey, &sign_magic, context->ServerSigningKey))
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0020 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0030 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_generate_client_sealing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_client_sealing_key: client_seal_magic: ":session key to client-to-server sealing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 63 session key to c
+0010 6c 69 65 6e 74 2d 74 6f 2d 73 65 72 76 65 72 20 lient-to-server 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_client_sealing_key: ClientSealingKey (ntlm_generate_signing_key(context->ExportedSessionKey, &seal_magic, context->ClientSealingKey))
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_generate_signing_key: exported_session_key: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_signing_key: sign_magic: 
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: value ( exported_session_key + sign_magic ): 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+0010 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0020 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0030 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0040 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_signing_key: signing_key (MD5(value)): 
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_generate_server_sealing_key: ExportedSessionKey: 
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_generate_server_sealing_key: server_seal_magic: ":session key to server-to-client sealing key magic constant"
+0000 73 65 73 73 69 6f 6e 20 6b 65 79 20 74 6f 20 73 session key to s
+0010 65 72 76 65 72 2d 74 6f 2d 63 6c 69 65 6e 74 20 erver-to-client 
+0020 73 65 61 6c 69 6e 67 20 6b 65 79 20 6d 61 67 69 sealing key magi
+0030 63 20 63 6f 6e 73 74 61 6e 74 00                c constant.
+
+ntlm_generate_server_sealing_key: ServerSealingKey (ntlm_generate_signing_key(context->ExportedSessionKey, &seal_magic, context->ServerSealingKey))
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_init_rc4_seal_states: SendSigningKey (ClientSigningKey)
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_init_rc4_seal_states: RecvSigningKey (ServerSigningKey)
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_init_rc4_seal_states: SendSealingKey (ServerSealingKey)
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_init_rc4_seal_states: RecvSealingKey (ClientSealingKey)
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_init_rc4_seal_states: SendRc4Seal = 0xb6a28da0 (RC4_set_key(&context->SendRc4Seal, 16, context->ClientSealingKey))
+ntlm_init_rc4_seal_states: RecvRc4Seal = 0xb6a291a8 (RC4_set_key(&context->RecvRc4Seal, 16, context->ServerSealingKey))
+ntlm_read_ChallengeMessage: ClientChallenge
+0000 01 02 03 04 05 06 07 08                         ........
+
+ntlm_read_ChallengeMessage: ServerChallenge
+0000 4a 25 50 a5 11 9b d6 16                         J%P.....
+
+ntlm_read_ChallengeMessage: SessionBaseKey
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_read_ChallengeMessage: KeyExchangeKey
+0000 8e 0f dd 12 4c 3b 11 7f 22 b9 4b 59 52 bc a7 18 ....L;..".KYR...
+
+ntlm_read_ChallengeMessage: ExportedSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_read_ChallengeMessage: RandomSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_read_ChallengeMessage: ClientSigningKey
+0000 f6 ae 96 cb 05 e2 ab 54 f6 dd 59 f3 c9 d9 a0 43 .......T..Y....C
+
+ntlm_read_ChallengeMessage: ClientSealingKey
+0000 58 19 44 c2 7a c6 34 45 e4 b8 2b 55 b9 0b 1f b5 X.D.z.4E..+U....
+
+ntlm_read_ChallengeMessage: ServerSigningKey
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_read_ChallengeMessage: ServerSealingKey
+0000 92 3a 73 5c 92 a7 04 34 be 9a a2 9f ed c1 e6 13 .:s\...4........
+
+ntlm_read_ChallengeMessage: Timestamp
+0000 a0 e8 85 2c e4 c9 ce 01                         ...,....
+
+ntlm_compute_message_integrity_check: ExportedSessionKey
+0000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ................
+
+ntlm_compute_message_integrity_check: NegotiateMessage
+0000 4e 54 4c 4d 53 53 50 00 01 00 00 00 b7 82 08 e2 NTLMSSP.........
+0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0020 06 01 b1 1d 00 00 00 0f                         ........
+
+ntlm_compute_message_integrity_check: ChallengeMessage
+0000 4e 54 4c 4d 53 53 50 00 02 00 00 00 1e 00 1e 00 NTLMSSP.........
+0010 38 00 00 00 35 82 8a e2 4a 25 50 a5 11 9b d6 16 8...5...J%P.....
+0020 00 00 00 00 00 00 00 00 98 00 98 00 56 00 00 00 ............V...
+0030 06 03 d7 24 00 00 00 0f 57 00 49 00 4e 00 2d 00 ...$....W.I.N.-.
+0040 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+0050 53 00 52 00 30 00 02 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0060 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0070 4c 00 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0080 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0090 32 00 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 2.L.S.R.0.....W.
+00a0 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+00b0 42 00 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 B.2.L.S.R.0.....
+00c0 57 00 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 W.I.N.-.L.O.4.1.
+00d0 39 00 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 9.B.2.L.S.R.0...
+00e0 08 00 a0 e8 85 2c e4 c9 ce 01 00 00 00 00       .....,........
+
+ntlm_compute_message_integrity_check: AuthenticateMessage
+0000 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 NTLMSSP.........
+0010 90 00 00 00 16 01 16 01 a8 00 00 00 12 00 12 00 ................
+0020 58 00 00 00 1a 00 1a 00 6a 00 00 00 0c 00 0c 00 X.......j.......
+0030 84 00 00 00 10 00 10 00 be 01 00 00 35 b2 88 e2 ............5...
+0040 06 01 b1 1d 00 00 00 0f 00 00 00 00 00 00 00 00 ................
+0050 00 00 00 00 00 00 00 00 77 00 6f 00 72 00 6b 00 ........w.o.r.k.
+0060 67 00 72 00 6f 00 75 00 70 00 41 00 64 00 6d 00 g.r.o.u.p.A.d.m.
+0070 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 i.n.i.s.t.r.a.t.
+0080 6f 00 72 00 61 00 70 00 6f 00 6c 00 6c 00 6f 00 o.r.a.p.o.l.l.o.
+0090 7c c0 fd 08 c5 14 05 34 f3 12 9e 3e a3 09 bc c6 |......4...>....
+00a0 01 02 03 04 05 06 07 08 19 4b eb ad da 24 d5 96 .........K...$..
+00b0 85 2e 24 94 d6 4a b8 5e 01 01 00 00 00 00 00 00 ..$..J.^........
+00c0 a0 e8 85 2c e4 c9 ce 01 01 02 03 04 05 06 07 08 ...,............
+00d0 00 00 00 00 02 00 1e 00 57 00 49 00 4e 00 2d 00 ........W.I.N.-.
+00e0 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 4c 00 L.O.4.1.9.B.2.L.
+00f0 53 00 52 00 30 00 01 00 1e 00 57 00 49 00 4e 00 S.R.0.....W.I.N.
+0100 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 32 00 -.L.O.4.1.9.B.2.
+0110 4c 00 53 00 52 00 30 00 04 00 1e 00 57 00 49 00 L.S.R.0.....W.I.
+0120 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 42 00 N.-.L.O.4.1.9.B.
+0130 32 00 4c 00 53 00 52 00 30 00 03 00 1e 00 57 00 2.L.S.R.0.....W.
+0140 49 00 4e 00 2d 00 4c 00 4f 00 34 00 31 00 39 00 I.N.-.L.O.4.1.9.
+0150 42 00 32 00 4c 00 53 00 52 00 30 00 07 00 08 00 B.2.L.S.R.0.....
+0160 a0 e8 85 2c e4 c9 ce 01 06 00 04 00 02 00 00 00 ...,............
+0170 0a 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+0180 00 00 00 00 09 00 26 00 54 00 45 00 52 00 4d 00 ......&.T.E.R.M.
+0190 53 00 52 00 56 00 2f 00 31 00 39 00 32 00 2e 00 S.R.V./.1.9.2...
+01a0 31 00 36 00 38 00 2e 00 31 00 2e 00 33 00 00 00 1.6.8...1...3...
+01b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e4 e9 ................
+01c0 c2 ad 41 02 2f 3c f9 4c 72 84 c5 2a 7c 6f       ..A./<.Lr..*|o
+
+ntlm_compute_message_integrity_check: MessageIntegrityCheck (HMAC_MD5(ExportedSessionKey + NegotiateMessage + ChallengeMessage + AuthenticateMessage))
+0000 d9 e9 bc 9b 6f a5 f9 c8 70 16 10 20 f8 f1 61 42 ....o...p.. ..aB
+
+credssp_encrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key before encryption:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+credssp_encrypt_public_key_echo: Signature for decryption:
+0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ntlm_EncryptMessage: data:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_EncryptMessage: digest (HMAC_MD5(SendSigningKey, seq_num + data)), seq_num: 0
+0000 bf e8 70 ad ac d8 5b a8 33 1a 74 1f 6c ec c9 b3 ..p...[.3.t.l...
+
+ntlm_EncryptMessage: Data Buffer before encryption (length = 270)
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_EncryptMessage: SendRc4Seal = 0xe
+ntlm_EncryptMessage: Encrypted Data Buffer (RC4(&context->SendRc4Seal, length, data, data_buffer->pvBuffer))
+0000 15 f7 f2 54 da a9 e5 ad 85 04 67 4d 0b cb f9 b1 ...T......gM....
+0010 f8 02 8a 77 c2 63 ab d5 74 23 9f 9d 5d 1f d3 b3 ...w.c..t#..]...
+0020 a0 ac 16 8a 4b 08 f5 47 70 58 10 b4 e7 87 b3 4b ....K..GpX.....K
+0030 c9 a2 d5 d1 ca 0f d4 e3 8d 76 5a 60 28 f8 06 5d .........vZ`(..]
+0040 e4 7e 21 c8 bb ac e5 79 85 30 9b 88 13 2f 8f fc .~!....y.0.../..
+0050 04 52 fe 87 94 cf cb 49 4a da 6f dd ee 57 a5 e4 .R.....IJ.o..W..
+0060 4d 0e 5c 3d 0b 63 1f f6 3d 1b ae 5a f6 42 2a 46 M.\=.c..=..Z.B*F
+0070 fa 42 71 67 46 02 71 ea 51 98 f7 d4 43 bf 8e e8 .BqgF.q.Q...C...
+0080 3c c8 fa 79 9d 8c fc c2 42 c9 bb d0 ab 81 c4 53 <..y....B......S
+0090 fd 41 da ab 0f 25 79 5f bd a3 8c d3 f5 1b ab 20 .A...%y_....... 
+00a0 d1 f4 d8 81 9c 18 4a a4 77 ee e1 51 ee 2a c1 94 ......J.w..Q.*..
+00b0 37 c5 06 7a 3f 0f 25 5b 4e 6a dc 0b 62 6f 12 83 7..z?.%[Nj..bo..
+00c0 03 ae 4e ce 2b 6e d4 d5 23 27 f6 a6 38 67 ec 95 ..N.+n..#'..8g..
+00d0 82 c6 ba d4 f6 e6 22 7d b9 e4 81 97 24 ff 40 b2 ......"}....$.@.
+00e0 42 3c 11 24 d0 3a 96 d9 c1 13 d6 62 45 21 60 5b B<.$.:.....bE!`[
+00f0 7b 2b 62 44 f7 40 93 29 5b 44 b7 da 9c a6 a9 3b {+bD.@.)[D.....;
+0100 e1 3b 9d 31 f2 21 53 0f b3 70 55 84 2c b4       .;.1.!S..pU.,.
+
+ntlm_EncryptMessage: Checksum ( RC4(&context->SendRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 72 76 1e 57 49 b5 0f ad                         rv.WI...
+ntlm_EncryptMessage: signature (version + checksum + seq_num)
+0000 01 00 00 00 72 76 1e 57 49 b5 0f ad 00 00 00 00 ....rv.WI.......
+
+ntlm_EncryptMessage: SendSeqNum (after increase): 1, SeqNo: 0.
+credssp_encrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key after encryption:
+0000 15 f7 f2 54 da a9 e5 ad 85 04 67 4d 0b cb f9 b1 ...T......gM....
+0010 f8 02 8a 77 c2 63 ab d5 74 23 9f 9d 5d 1f d3 b3 ...w.c..t#..]...
+0020 a0 ac 16 8a 4b 08 f5 47 70 58 10 b4 e7 87 b3 4b ....K..GpX.....K
+0030 c9 a2 d5 d1 ca 0f d4 e3 8d 76 5a 60 28 f8 06 5d .........vZ`(..]
+0040 e4 7e 21 c8 bb ac e5 79 85 30 9b 88 13 2f 8f fc .~!....y.0.../..
+0050 04 52 fe 87 94 cf cb 49 4a da 6f dd ee 57 a5 e4 .R.....IJ.o..W..
+0060 4d 0e 5c 3d 0b 63 1f f6 3d 1b ae 5a f6 42 2a 46 M.\=.c..=..Z.B*F
+0070 fa 42 71 67 46 02 71 ea 51 98 f7 d4 43 bf 8e e8 .BqgF.q.Q...C...
+0080 3c c8 fa 79 9d 8c fc c2 42 c9 bb d0 ab 81 c4 53 <..y....B......S
+0090 fd 41 da ab 0f 25 79 5f bd a3 8c d3 f5 1b ab 20 .A...%y_....... 
+00a0 d1 f4 d8 81 9c 18 4a a4 77 ee e1 51 ee 2a c1 94 ......J.w..Q.*..
+00b0 37 c5 06 7a 3f 0f 25 5b 4e 6a dc 0b 62 6f 12 83 7..z?.%[Nj..bo..
+00c0 03 ae 4e ce 2b 6e d4 d5 23 27 f6 a6 38 67 ec 95 ..N.+n..#'..8g..
+00d0 82 c6 ba d4 f6 e6 22 7d b9 e4 81 97 24 ff 40 b2 ......"}....$.@.
+00e0 42 3c 11 24 d0 3a 96 d9 c1 13 d6 62 45 21 60 5b B<.$.:.....bE!`[
+00f0 7b 2b 62 44 f7 40 93 29 5b 44 b7 da 9c a6 a9 3b {+bD.@.)[D.....;
+0100 e1 3b 9d 31 f2 21 53 0f b3 70 55 84 2c b4       .;.1.!S..pU.,.
+credssp_decrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 0
+Public key before decryption:
+0000 03 12 dd ea 47 b3 ff e1 66 08 f6 6b a0 62 42 67 ....G...f..k.bBg
+0010 bf 3d 59 60 ef 52 b0 26 95 ed 84 48 44 bb 8d 65 .=Y`.R.&...HD..e
+0020 cf e4 8e 6f 69 ae ed 44 bb 49 1d 2a 40 29 2b 13 ...oi..D.I.*@)+.
+0030 42 1c eb b1 6c 8a 3b 80 d1 70 fd dd 79 e4 93 0b B...l.;..p..y...
+0040 47 bd 3a 7e 31 66 4b 65 8d 5c 2a cd c2 09 7a 3b G.:~1fKe.\*...z;
+0050 b2 fd 09 52 09 47 05 a4 6f 32 d1 76 b2 d4 59 e0 ...R.G..o2.v..Y.
+0060 85 f1 36 7d 76 50 21 0e 20 22 83 1a 08 c0 85 5d ..6}vP!. ".....]
+0070 4f 5c 77 68 32 95 a9 a2 59 69 ea 19 34 08 ed 76 O\wh2...Yi..4..v
+0080 a3 58 37 f2 0a 0c ba 4d bb 6f 82 94 d3 87 de c9 .X7....M.o......
+0090 8f ef 34 2d 8f d0 0c 91 59 fd ea 6b cb bd a2 20 ..4-....Y..k... 
+00a0 ed b9 76 d3 64 1b b3 3b f5 9b 61 d7 ab 26 9b 0d ..v.d..;..a..&..
+00b0 a0 ea bf ad 2c ad 63 65 c6 70 c4 e5 8d 40 aa 08 ....,.ce.p...@..
+00c0 45 66 e2 4d c9 46 00 33 43 e0 ba d6 80 29 21 5e Ef.M.F.3C....)!^
+00d0 d1 9a bc 44 fa 4d 46 f9 25 80 40 b5 27 dd c5 02 ...D.MF.%.@.'...
+00e0 f8 a4 9a cb cf 3f ef c7 cd 71 45 a5 35 b1 21 14 .....?...qE.5.!.
+00f0 39 57 f8 0a 24 98 ea 15 e1 e3 cb 9d f2 4e ef 89 9W..$........N..
+0100 97 c0 b2 96 9a 1e ad d0 9a 99 62 9f 13 2e       ..........b...
+credssp_decrypt_public_key_echo: Signature for decryption:
+0000 01 00 00 00 25 f8 2d 1e 4e 6a ec 4f 00 00 00 00 ....%.-.Nj.O....
+ntlm_DecryptMessage: Data Buffer before decryption (length = 270)
+0000 03 12 dd ea 47 b3 ff e1 66 08 f6 6b a0 62 42 67 ....G...f..k.bBg
+0010 bf 3d 59 60 ef 52 b0 26 95 ed 84 48 44 bb 8d 65 .=Y`.R.&...HD..e
+0020 cf e4 8e 6f 69 ae ed 44 bb 49 1d 2a 40 29 2b 13 ...oi..D.I.*@)+.
+0030 42 1c eb b1 6c 8a 3b 80 d1 70 fd dd 79 e4 93 0b B...l.;..p..y...
+0040 47 bd 3a 7e 31 66 4b 65 8d 5c 2a cd c2 09 7a 3b G.:~1fKe.\*...z;
+0050 b2 fd 09 52 09 47 05 a4 6f 32 d1 76 b2 d4 59 e0 ...R.G..o2.v..Y.
+0060 85 f1 36 7d 76 50 21 0e 20 22 83 1a 08 c0 85 5d ..6}vP!. ".....]
+0070 4f 5c 77 68 32 95 a9 a2 59 69 ea 19 34 08 ed 76 O\wh2...Yi..4..v
+0080 a3 58 37 f2 0a 0c ba 4d bb 6f 82 94 d3 87 de c9 .X7....M.o......
+0090 8f ef 34 2d 8f d0 0c 91 59 fd ea 6b cb bd a2 20 ..4-....Y..k... 
+00a0 ed b9 76 d3 64 1b b3 3b f5 9b 61 d7 ab 26 9b 0d ..v.d..;..a..&..
+00b0 a0 ea bf ad 2c ad 63 65 c6 70 c4 e5 8d 40 aa 08 ....,.ce.p...@..
+00c0 45 66 e2 4d c9 46 00 33 43 e0 ba d6 80 29 21 5e Ef.M.F.3C....)!^
+00d0 d1 9a bc 44 fa 4d 46 f9 25 80 40 b5 27 dd c5 02 ...D.MF.%.@.'...
+00e0 f8 a4 9a cb cf 3f ef c7 cd 71 45 a5 35 b1 21 14 .....?...qE.5.!.
+00f0 39 57 f8 0a 24 98 ea 15 e1 e3 cb 9d f2 4e ef 89 9W..$........N..
+0100 97 c0 b2 96 9a 1e ad d0 9a 99 62 9f 13 2e       ..........b...
+
+ntlm_DecryptMessage: RecvRc4Seal = 0xe
+ntlm_DecryptMessage: Data Buffer after decryption (RC4(&context->RecvRc4Seal, length, data, data_buffer->pvBuffer))
+0000 31 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 1.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+
+ntlm_DecryptMessage: RecvSigningKey:
+0000 b6 58 c5 98 7a 25 f8 6e d8 e5 6c e9 3e 3c c0 88 .X..z%.n..l.><..
+
+ntlm_DecryptMessage: digest (HMAC_MD5(RecvSigningKey, seq_num + data)), seq_num: 0
+0000 33 77 62 77 99 a9 14 40 1d 76 17 98 21 65 36 05 3wbw...@.v..!e6.
+
+ntlm_DecryptMessage: Checksum (RC4(&context->RecvRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 25 f8 2d 1e 4e 6a ec 4f                         %.-.Nj.O
+ntlm_DecryptMessage: Expected Signature (version + checksum + seq_num):
+0000 01 00 00 00 25 f8 2d 1e 4e 6a ec 4f 00 00 00 00 ....%.-.Nj.O....
+ntlm_DecryptMessage: RecvSeqNum (after increase): 1, SeqNo: 0.
+credssp_decrypt_public_key_echo: Server public key (length = 270):
+recv_seq_num: 1
+Public key after decryption:
+0000 30 82 01 0a 02 82 01 01 00 a8 56 65 d3 ce 8a 54 0.........Ve...T
+0010 4d 9d b0 84 31 19 71 7f dd 42 fb 2a 7a 72 13 a1 M...1.q..B.*zr..
+0020 b9 72 bb d3 08 ad 7d 6c 15 65 03 d1 c4 54 c5 33 .r....}l.e...T.3
+0030 6b 7d 69 89 5e fe e0 01 c0 7e 9b cb 5d 65 36 cd k}i.^....~..]e6.
+0040 77 5d f3 7a 5b 29 44 72 d5 38 e2 cf b1 c7 78 9b w].z[)Dr.8....x.
+0050 58 b9 17 7c b7 d6 c7 c7 bf 90 4e 7c 39 93 cb 2e X..|......N|9...
+0060 e0 c2 33 2d a5 7e e0 7b b6 f9 91 32 b7 d4 85 b7 ..3-.~.{...2....
+0070 35 2d 2b 00 6d f8 ea 8c 97 5f 51 1d 68 04 3c 79 5-+.m...._Q.h.<y
+0080 14 71 a7 c7 d7 70 7a e0 ba 12 69 c8 d3 d9 4e ab .q...pz...i...N.
+0090 51 47 a3 ec 99 d4 88 ca da c2 7f 79 4b 66 ed 87 QG.........yKf..
+00a0 be c2 5f ea cf e1 b5 f0 3d 9b f2 19 c3 e0 e1 7a .._.....=......z
+00b0 45 71 12 3d 72 1d 6f 2b 1c 46 68 c0 8f 4f ce 3a Eq.=r.o+.Fh..O.:
+00c0 c5 cd 22 65 2d 43 b0 5c dd 89 ae be 70 59 5e 0c .."e-C.\....pY^.
+00d0 bd f5 46 82 1e e4 86 95 7b 60 ae 45 50 c2 54 08 ..F.....{`.EP.T.
+00e0 49 9a 9e fb b2 b6 78 e5 2f 9c 5a d0 8a 03 77 68 I.....x./.Z...wh
+00f0 30 93 78 6d 90 6d 50 fa a7 65 fe 59 33 27 4e 4b 0.xm.mP..e.Y3'NK
+0100 f8 38 44 3a 12 f4 07 a0 8d 02 03 01 00 01       .8D:..........
+ntlm_EncryptMessage: data:
+0000 30 57 a0 03 02 01 01 a1 50 04 4e 30 4c a0 14 04 0W......P.N0L...
+0010 12 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 .w.o.r.k.g.r.o.u
+0020 00 70 00 a1 1c 04 1a 41 00 64 00 6d 00 69 00 6e .p.....A.d.m.i.n
+0030 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 .i.s.t.r.a.t.o.r
+0040 00 a2 16 04 14 52 00 32 00 50 00 72 00 65 00 76 .....R.2.P.r.e.v
+0050 00 69 00 65 00 77 00 21 00                      .i.e.w.!.
+
+ntlm_EncryptMessage: digest (HMAC_MD5(SendSigningKey, seq_num + data)), seq_num: 1
+0000 40 75 a0 e9 45 65 d1 78 54 1c 7e 27 08 4c 6f bd @u..Ee.xT.~'.Lo.
+
+ntlm_EncryptMessage: Data Buffer before encryption (length = 89)
+0000 30 57 a0 03 02 01 01 a1 50 04 4e 30 4c a0 14 04 0W......P.N0L...
+0010 12 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 .w.o.r.k.g.r.o.u
+0020 00 70 00 a1 1c 04 1a 41 00 64 00 6d 00 69 00 6e .p.....A.d.m.i.n
+0030 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 .i.s.t.r.a.t.o.r
+0040 00 a2 16 04 14 52 00 32 00 50 00 72 00 65 00 76 .....R.2.P.r.e.v
+0050 00 69 00 65 00 77 00 21 00                      .i.e.w.!.
+
+ntlm_EncryptMessage: SendRc4Seal = 0x6f
+ntlm_EncryptMessage: Encrypted Data Buffer (RC4(&context->SendRc4Seal, length, data, data_buffer->pvBuffer))
+0000 5a 26 69 b7 70 4b 41 55 82 43 a2 3a 72 6a e0 69 Z&i.pKAU.C.:rj.i
+0010 9b 53 66 b6 70 75 c4 80 4f 61 e6 85 20 7e 3a 1b .Sf.pu..Oa.. ~:.
+0020 a9 6a da 69 0b a5 4e 16 d9 da 71 5e ce e4 60 89 .j.i..N...q^..`.
+0030 98 e6 30 59 d0 43 38 55 4a 97 e4 20 83 cd db 6b ..0Y.C8UJ.. ...k
+0040 2b ca ac 9d 99 e6 2b ea 47 5f c1 4c 54 67 d1 75 +.....+.G_.LTg.u
+0050 2c f7 d6 d6 04 8b 28 99 e9                      ,.....(..
+
+ntlm_EncryptMessage: Checksum ( RC4(&context->SendRc4Seal, 8, digest, checksum), first 8 bytes of digest only!):
+0000 7a 7e b7 6c 49 3e 6b 7a                         z~.lI>kz
+ntlm_EncryptMessage: signature (version + checksum + seq_num)
+0000 01 00 00 00 7a 7e b7 6c 49 3e 6b 7a 01 00 00 00 ....z~.lI>kz....
+
+ntlm_EncryptMessage: SendSeqNum (after increase): 2, SeqNo: 1.
+Unable to detect time zone
+Closed from X11

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx b/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx
new file mode 100755
index 0000000..311ca43
Binary files /dev/null and b/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx differ

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
old mode 100644
new mode 100755
index 283beac..a40cdb8
--- a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
+++ b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
@@ -16,9 +16,9 @@
 // under the License.
 package rdpclient;
 
-import static rdpclient.MockServer.Packet.PacketType.CLIENT;
-import static rdpclient.MockServer.Packet.PacketType.SERVER;
-import static rdpclient.MockServer.Packet.PacketType.UPGRADE_TO_SSL;
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+import static streamer.debug.MockServer.Packet.PacketType.UPGRADE_TO_SSL;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -30,7 +30,8 @@ import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
 import junit.framework.TestCase;
-import rdpclient.MockServer.Packet;
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
 
 public class MockServerTest extends TestCase {
 


[14/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
deleted file mode 100644
index 7dd70eb..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224ConnectionConfirmPDU.java
+++ /dev/null
@@ -1,237 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * Once the External Security Protocol handshake has run to completion, the
- * client MUST continue with the connection sequence by sending the MCS Connect
- * Initial PDU to the server over the newly established secure channel.
- *
- *
- * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
- */
-public class ServerX224ConnectionConfirmPDU extends OneTimeSwitch {
-
-    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
-    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
-    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
-    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
-    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
-    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
-    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
-    public static final int X224_TPDU_REJECT = 0x51;
-    public static final int X224_TPDU_ERROR = 0x70;
-    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
-
-    /**
-     * The server requires that the client support Enhanced RDP Security with
-     * either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then
-     * the server only supports TLS.
-     */
-    public static final int SSL_REQUIRED_BY_SERVER = 0x00000001;
-
-    /**
-     * The server is configured to only use Standard RDP Security mechanisms and
-     * does not support any External Security Protocols.
-     */
-    public static final int SSL_NOT_ALLOWED_BY_SERVER = 0x00000002;
-
-    /**
-     * The server does not possess a valid authentication certificate and cannot
-     * initialize the External Security Protocol Provider.
-     */
-    public static final int SSL_CERT_NOT_ON_SERVER = 0x00000003;
-
-    /**
-     * The list of requested security protocols is not consistent with the current
-     * security protocol in effect. This error is only possible when the Direct
-     * Approach is used and an External Security Protocolis already being used.
-     */
-    public static final int INCONSISTENT_FLAGS = 0x00000004;
-
-    /**
-     * The server requires that the client support Enhanced RDP Security with
-     * CredSSP.
-     */
-    public static final int HYBRID_REQUIRED_BY_SERVER = 0x00000005;
-
-    /**
-     * The server requires that the client support Enhanced RDP Security with TLS
-     * 1.0, 1.1 or 1.2 and certificate-based client authentication.
-     */
-    public static final int SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 0x00000006;
-
-    public ServerX224ConnectionConfirmPDU(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        int x224Length = buf.readVariableSignedIntLE();
-
-        int x224Type = buf.readUnsignedByte();
-        if (x224Type != X224_TPDU_CONNECTION_CONFIRM)
-            throw new RuntimeException("Unexpected type of packet. Expected type: " + X224_TPDU_CONNECTION_CONFIRM + " (CONNECTION CONFIRM), actual type: " + x224Type +
-                ", length: " + x224Length + ", buf: " + buf + ".");
-
-        // Ignore destination reference, because client side has only one node
-        buf.skipBytes(2);
-
-        // Source reference
-        // int srcRef = buf.readUnsignedShort();
-        buf.skipBytes(2);
-
-        // Ignore class and options
-        buf.skipBytes(1);
-
-        // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
-        int negType = buf.readUnsignedByte();
-
-        // RDP_NEG_RSP::flags (0)
-        buf.skipBytes(1); // Ignore: always 0
-
-        // RDP_NEG_RSP::length (always 8 bytes)
-        int length = buf.readUnsignedShortLE();
-
-        if (length != 8)
-            throw new RuntimeException("Unexpected length of buffer. Expected value: 8, actual value: " + length + ", RDP NEG buf: " + buf + ".");
-
-        // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
-        int protocol = buf.readSignedIntLE();
-
-        if (negType != RdpConstants.RDP_NEG_REQ_TYPE_NEG_RSP) {
-            // Parse error code, see
-            // http://msdn.microsoft.com/en-us/library/cc240507.aspx
-            int errorCode = protocol;
-            String message = "Unknown error.";
-            switch (errorCode) {
-                case SSL_REQUIRED_BY_SERVER:
-                    message =
-                        "The server requires that the client support Enhanced RDP Security with either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then the server only supports TLS.";
-                    break;
-
-                case SSL_NOT_ALLOWED_BY_SERVER:
-                    message = "The server is configured to only use Standard RDP Security mechanisms and does not support any External Security Protocols.";
-                    break;
-
-                case SSL_CERT_NOT_ON_SERVER:
-                    message = "The server does not possess a valid authentication certificate and cannot initialize the External Security Protocol Provider.";
-                    break;
-
-                case INCONSISTENT_FLAGS:
-                    message =
-                        "The list of requested security protocols is not consistent with the current security protocol in effect. This error is only possible when the Direct Approach is used and an External Security Protocolis already being used.";
-                    break;
-
-                case HYBRID_REQUIRED_BY_SERVER:
-                    message = "The server requires that the client support Enhanced RDP Security with CredSSP.";
-                    break;
-
-                case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
-                    message = "The server requires that the client support Enhanced RDP Security  with TLS 1.0, 1.1 or 1.2 and certificate-based client authentication.";
-                    break;
-
-            }
-            throw new RuntimeException("Connection failure: " + message);
-        }
-
-        if (protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL)
-            throw new RuntimeException("Unexpected protocol type. Expected protocol type: " + RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL + " (SSL), actual response type: " +
-                protocol + ", RDP NEG buf: " + buf + ".");
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: RDP Negotiation response. Type: " + negType + ", protocol: " + protocol + ".");
-
-        // Next: upgrade socket to SSL, send ConnectInitial packet
-        switchOff();
-    }
-
-    /**
-     * 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");
-
-//    byte[] packet = new byte[] {
-//
-//        0x03, // -> TPKT Header: TPKT version = 3
-//        0x00, // TPKT Header: Reserved = 0
-//        0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
-//        0x0e, // X.224: Length indicator (14 bytes)
-//        (byte) 0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
-//                     // (low nibble) = 0
-//        0x00, 0x00, // X.224: Destination reference = 0
-//        0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
-//        0x00, // X.224: Class and options = 0
-//
-//        0x02, // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
-//        0x00, // RDP_NEG_RSP::flags (0)
-//        0x08, 0x00, // RDP_NEG_RSP::length (8 bytes)
-//        0x01, 0x00, 0x00, 0x00 // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
-//    };
-
-        // Connection failure
-        // 03 00 00 13 0e d0 00 00 12 34 00 03 00 08 00 05 00 00 00
-        byte[] packet = new byte[] {
-
-            0x03, // -> TPKT Header: TPKT version = 3
-            0x00, // TPKT Header: Reserved = 0
-            0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
-            0x0e, // X.224: Length indicator (14 bytes)
-            (byte)0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
-                        // (low nibble) = 0
-            0x00, 0x00, // X.224: Destination reference = 0
-            0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
-            0x00, // X.224: Class and options = 0
-            (byte)0x03, // Failure
-            (byte)0x00, // RDP_NEG_RSP::flags (0)
-            (byte)0x08, (byte)0x00, // RDP_NEG_RSP::length (8 bytes)
-            (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, // Code:  HYBRID_REQUIRED_BY_SERVER
-
-        };
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element cc = new ServerX224ConnectionConfirmPDU("cc");
-        Element tpkt = new ServerTpkt("tpkt");
-        Element sink = new MockSink("sink", new ByteBuffer[] {});
-        Element mainSink = new MockSink("mainSink", new ByteBuffer[] {});
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, tpkt, cc, sink, mainSink);
-        pipeline.link("source", "tpkt", "cc", "mainSink");
-        pipeline.link("cc >" + OTOUT, "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
deleted file mode 100644
index 62b0f55..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerX224DataPdu.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ServerX224DataPdu extends BaseElement {
-
-    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
-    public static final int X224_TPDU_DATA = 0xF0;
-
-    public ServerX224DataPdu(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        int headerLength = buf.readVariableSignedIntLE();
-
-        if (headerLength != 2)
-            throw new RuntimeException("Unexpected X224 Data PDU header length. Expected header length: 2 , actual header length: " + headerLength + ".");
-
-        // Read X224 type and options
-        int type = buf.readUnsignedByte(); // High nibble: type, low nibble:
-
-        if ((type & 0xf0) != X224_TPDU_DATA)
-            throw new RuntimeException("[" + this + "] ERROR: Unexepcted X224 packet type. Expected packet type: " + X224_TPDU_DATA +
-                " (X224_TPDU_DATA), actual packet type: " + type + ", buf: " + buf + ".");
-
-        int options = buf.readUnsignedByte();
-
-        if ((options & X224_TPDU_LAST_DATA_UNIT) != X224_TPDU_LAST_DATA_UNIT)
-            throw new RuntimeException("Unexepcted X224 packet options. Expected options: " + X224_TPDU_LAST_DATA_UNIT +
-                " (X224_TPDU_LAST_DATA_UNIT), actual packet options: " + options + ", buf: " + buf + ".");
-
-        ByteBuffer payload = buf.readBytes(buf.length - buf.cursor);
-
-        buf.unref();
-
-        pushDataToAllOuts(payload);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
deleted file mode 100644
index 088094a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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;
-
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.X509TrustManager;
-
-public class TrustAllX509TrustManager implements X509TrustManager {
-    @Override
-    public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
-        // TODO: ask user to confirm self-signed certificates
-    }
-
-    @Override
-    public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
-        // TODO: ask user to confirm self-signed certificates
-    }
-
-    @Override
-    public X509Certificate[] getAcceptedIssuers() {
-        // TODO: use system CA certificates here
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
deleted file mode 100644
index 7267708..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Direction;
-import streamer.Event;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class UpgradeSocketToSSL extends OneTimeSwitch {
-
-    public UpgradeSocketToSSL(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void onStart() {
-
-        sendEventToAllPads(Event.SOCKET_UPGRADE_TO_SSL, Direction.IN);
-        switchOff();
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        throw new RuntimeException("Unexpected data: " + buf + ".");
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
new file mode 100755
index 0000000..f2b19e1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java
@@ -0,0 +1,350 @@
+// 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.adapter;
+
+import java.awt.event.KeyEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import common.KeyOrder;
+
+public class AwtRdpKeyboardAdapter extends BaseElement {
+
+    /**
+     * Absence of this flag indicates a key-down event, while its presence
+     * indicates a key-release event.
+     */
+    public static final int FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01;
+
+    /**
+     * Keystroke message contains an extended scancode. For enhanced 101-key and
+     * 102-key keyboards, extended keys include the right ALT and right CTRL keys
+     * on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE
+     * DOWN and ARROW keys in the clusters to the left of the numeric keypad; and
+     * the Divide ("/") and ENTER keys in the numeric keypad.
+     */
+    public static final int FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02;
+
+    public static final int FASTPATH_INPUT_EVENT_SCANCODE = 0;
+
+    public AwtRdpKeyboardAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        KeyOrder order = (KeyOrder)buf.getOrder();
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(2, true);
+
+        int scanCode = map_en_us(order.event);
+
+        // eventHeader (1 byte): An 8-bit, unsigned integer. The format of this
+        // field is the same as the eventHeader byte field described in section
+        // 2.2.8.1.2.2. The eventCode bitfield (3 bits in size) MUST be set to
+        // FASTPATH_INPUT_EVENT_SCANCODE (0). The eventFlags bitfield (5 bits in
+        // size) contains flags describing the keyboard event.
+        outBuf.writeByte((scanCode >> 8) | (FASTPATH_INPUT_EVENT_SCANCODE << 5) | ((order.pressed) ? 0 : FASTPATH_INPUT_KBDFLAGS_RELEASE));
+
+        // keyCode (1 byte): An 8-bit, unsigned integer. The scancode of the key
+        // which triggered the event.
+        outBuf.writeByte(scanCode);
+
+        // Push buffer to one pad only, so it can be modified without copying of
+        // data
+        pushDataToPad(STDOUT, outBuf);
+    }
+
+    /**
+     * Return key scan code (in lower byte) and extended flags (in second byte).
+     */
+    private int map_en_us(KeyEvent event) {
+        // Also set extended key flag when necessary.
+        // For enhanced 101-key and 102-key keyboards, extended keys include the
+        // right ALT and right CTRL keys on the main section of the keyboard; the
+        // INS, DEL, HOME, END, PAGE UP, PAGE DOWN and ARROW keys in the clusters to
+        // the left of the numeric keypad; and the Divide ("/") and ENTER keys in
+        // the numeric keypad.
+
+        switch (event.getKeyCode()) {
+        // Functional keys
+        case KeyEvent.VK_ESCAPE:
+            return 1;
+        case KeyEvent.VK_F1:
+            return 59;
+        case KeyEvent.VK_F2:
+            return 60;
+        case KeyEvent.VK_F3:
+            return 61;
+        case KeyEvent.VK_F4:
+            return 62;
+        case KeyEvent.VK_F5:
+            return 63;
+        case KeyEvent.VK_F6:
+            return 64;
+        case KeyEvent.VK_F7:
+            return 65;
+        case KeyEvent.VK_F8:
+            return 66;
+        case KeyEvent.VK_F9:
+            return 67;
+        case KeyEvent.VK_F10:
+            return 68;
+        case KeyEvent.VK_F11:
+            return 87;
+        case KeyEvent.VK_F12:
+            return 88;
+
+            // Row #1
+        case KeyEvent.VK_BACK_QUOTE:
+            return 41;
+        case KeyEvent.VK_1:
+            return 2;
+        case KeyEvent.VK_2:
+            return 3;
+        case KeyEvent.VK_3:
+            return 4;
+        case KeyEvent.VK_4:
+            return 5;
+        case KeyEvent.VK_5:
+            return 6;
+        case KeyEvent.VK_6:
+            return 7;
+        case KeyEvent.VK_7:
+            return 8;
+        case KeyEvent.VK_8:
+            return 9;
+        case KeyEvent.VK_9:
+            return 10;
+        case KeyEvent.VK_0:
+            return 11;
+        case KeyEvent.VK_MINUS:
+            return 12;
+        case KeyEvent.VK_EQUALS:
+            return 13;
+        case KeyEvent.VK_BACK_SPACE:
+            return 14;
+
+            // Row #2
+        case KeyEvent.VK_TAB:
+            return 15;
+        case KeyEvent.VK_Q:
+            return 16;
+        case KeyEvent.VK_W:
+            return 17;
+        case KeyEvent.VK_E:
+            return 18;
+        case KeyEvent.VK_R:
+            return 19;
+        case KeyEvent.VK_T:
+            return 20;
+        case KeyEvent.VK_Y:
+            return 21;
+        case KeyEvent.VK_U:
+            return 22;
+        case KeyEvent.VK_I:
+            return 23;
+        case KeyEvent.VK_O:
+            return 24;
+        case KeyEvent.VK_P:
+            return 25;
+        case KeyEvent.VK_OPEN_BRACKET:
+            return 26;
+        case KeyEvent.VK_CLOSE_BRACKET:
+            return 27;
+        case KeyEvent.VK_ENTER:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_STANDARD:
+                return 28;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 28;
+            }
+
+            // Row #3
+        case KeyEvent.VK_CAPS_LOCK:
+            return 58;
+        case KeyEvent.VK_A:
+            return 30;
+        case KeyEvent.VK_S:
+            return 31;
+        case KeyEvent.VK_D:
+            return 32;
+        case KeyEvent.VK_F:
+            return 33;
+        case KeyEvent.VK_G:
+            return 34;
+        case KeyEvent.VK_H:
+            return 35;
+        case KeyEvent.VK_J:
+            return 36;
+        case KeyEvent.VK_K:
+            return 37;
+        case KeyEvent.VK_L:
+            return 38;
+        case KeyEvent.VK_SEMICOLON:
+            return 39;
+        case KeyEvent.VK_QUOTE:
+            return 40;
+
+            // Row #4
+        case KeyEvent.VK_SHIFT:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 42;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 54;
+            }
+        case KeyEvent.VK_BACK_SLASH:
+            return 43;
+        case KeyEvent.VK_Z:
+            return 44;
+        case KeyEvent.VK_X:
+            return 45;
+        case KeyEvent.VK_C:
+            return 46;
+        case KeyEvent.VK_V:
+            return 47;
+        case KeyEvent.VK_B:
+            return 48;
+        case KeyEvent.VK_N:
+            return 49;
+        case KeyEvent.VK_M:
+            return 50;
+        case KeyEvent.VK_COMMA:
+            return 51;
+        case KeyEvent.VK_PERIOD:
+            return 52;
+        case KeyEvent.VK_SLASH:
+            return 53;
+
+            //
+            // Bottom row
+        case KeyEvent.VK_CONTROL:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 29;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 29;
+            }
+        case KeyEvent.VK_WINDOWS:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 91;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 92;
+            }
+        case KeyEvent.VK_ALT:
+            switch (event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 56;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
+            }
+        case KeyEvent.VK_ALT_GRAPH:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
+
+        case KeyEvent.VK_SPACE:
+            return 57;
+
+        case KeyEvent.VK_CONTEXT_MENU:
+            return 93;
+
+            //
+            // Special keys
+        case KeyEvent.VK_PRINTSCREEN:
+            return 55;
+        case KeyEvent.VK_SCROLL_LOCK:
+            return 70;
+        case KeyEvent.VK_PAUSE:
+            return 29;
+
+            // Text navigation keys
+        case KeyEvent.VK_INSERT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 82;
+        case KeyEvent.VK_HOME:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 71;
+        case KeyEvent.VK_PAGE_UP:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 73;
+        case KeyEvent.VK_DELETE:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 83;
+        case KeyEvent.VK_END:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 79;
+        case KeyEvent.VK_PAGE_DOWN:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 81;
+
+            // Cursor keys
+        case KeyEvent.VK_UP:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 72;
+        case KeyEvent.VK_LEFT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 75;
+        case KeyEvent.VK_DOWN:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 80;
+        case KeyEvent.VK_RIGHT:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 77;
+
+            // Keypad
+        case KeyEvent.VK_NUM_LOCK:
+            return 69;
+        case KeyEvent.VK_DIVIDE:
+            return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 53;
+        case KeyEvent.VK_MULTIPLY:
+            return 55;
+        case KeyEvent.VK_SUBTRACT:
+            return 74;
+        case KeyEvent.VK_ADD:
+            return 78;
+
+        case KeyEvent.VK_NUMPAD7:
+            return 71;
+        case KeyEvent.VK_NUMPAD8:
+            return 72;
+        case KeyEvent.VK_NUMPAD9:
+            return 73;
+        case KeyEvent.VK_NUMPAD4:
+            return 75;
+        case KeyEvent.VK_NUMPAD5:
+            return 76;
+        case KeyEvent.VK_NUMPAD6:
+            return 77;
+        case KeyEvent.VK_NUMPAD1:
+            return 79;
+        case KeyEvent.VK_NUMPAD2:
+            return 80;
+        case KeyEvent.VK_NUMPAD3:
+            return 81;
+        case KeyEvent.VK_NUMPAD0:
+            return 82;
+        case KeyEvent.VK_DECIMAL:
+            return 83;
+
+        default:
+            System.err.println("Key is not mapped: " + event + ".");
+            return 57; // Space
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
new file mode 100755
index 0000000..6b347aa
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpMouseAdapter.java
@@ -0,0 +1,179 @@
+// 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.adapter;
+
+import java.awt.event.InputEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import common.MouseOrder;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240594.aspx
+ */
+public class AwtRdpMouseAdapter extends BaseElement {
+    public final static int FASTPATH_INPUT_EVENT_MOUSE = 0x01;
+
+    /**
+     * Event is a mouse wheel rotation. The only valid flags in a wheel rotation
+     * event are PTRFLAGS_WHEEL_NEGATIVE and the WheelRotationMask; all other
+     * pointer flags are ignored.
+     */
+    public final static int PTRFLAGS_WHEEL = 0x0200;
+
+    /**
+     * Wheel rotation value (contained in the WheelRotationMask bit field) is
+     * negative and MUST be sign-extended before injection at the server.
+     */
+    public final static int PTRFLAGS_WHEEL_NEGATIVE = 0x0100;
+
+    /**
+     * Bit field describing the number of rotation units the mouse wheel was
+     * rotated. The value is negative if the PTRFLAGS_WHEEL_NEGATIVE flag is set.
+     */
+    public final static int WHEEL_ROTATION_MASK = 0x01FF;
+
+    /**
+     * Indicates that the mouse position MUST be updated to the location specified
+     * by the xPos and yPos fields.
+     */
+    public final static int PTRFLAGS_MOVE = 0x0800;
+
+    /**
+     * Indicates that a click event has occurred at the position specified by the
+     * xPos and yPos fields. The button flags indicate which button has been
+     * clicked and at least one of these flags MUST be set.
+     */
+    public final static int PTRFLAGS_DOWN = 0x8000;
+
+    /**
+     * Mouse button 1 (left button) was clicked or released. If the PTRFLAGS_DOWN
+     * flag is set, then the button was clicked, otherwise it was released.
+     */
+    public final static int PTRFLAGS_BUTTON1 = 0x1000;
+
+    /**
+     * Mouse button 2 (right button) was clicked or released. If the PTRFLAGS_DOWN
+     * flag is set, then the button was clicked, otherwise it was released.
+     */
+    public final static int PTRFLAGS_BUTTON2 = 0x2000;
+
+    /**
+     * Mouse button 3 (middle button or wheel) was clicked or released. If the
+     * PTRFLAGS_DOWN flag is set, then the button was clicked, otherwise it was
+     * released.
+     */
+    public final static int PTRFLAGS_BUTTON3 = 0x4000;
+
+    public AwtRdpMouseAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Get mouse event
+        MouseOrder order = (MouseOrder)buf.getOrder();
+
+        ByteBuffer outBuf = new ByteBuffer(7, true);
+
+        // eventHeader (1 byte): An 8-bit, unsigned integer. EventCode bitfield (top
+        // 3 bits) MUST be set to FASTPATH_INPUT_EVENT_MOUSE (1). The
+        // eventFlags bitfield (low 5 bits) MUST be zeroed out.
+        outBuf.writeByte(FASTPATH_INPUT_EVENT_MOUSE << 5);
+
+        // pointerFlags (2 bytes): A 16-bit, unsigned integer.
+        outBuf.writeShortLE(getPointerFlags(order));
+
+        // xPos (2 bytes): A 16-bit, unsigned integer. The x-coordinate of the
+        // pointer.
+        outBuf.writeShortLE(order.event.getX());
+
+        // yPos (2 bytes): A 16-bit, unsigned integer. The y-coordinate of the
+        // pointer.
+        outBuf.writeShortLE(order.event.getY());
+
+        // Push buffer to one pad only, so it can be modified without copying of
+        // data
+        pushDataToPad(STDOUT, outBuf);
+    }
+
+    // Remember mouse buttons
+    protected boolean button1, button2, button3;
+
+    protected int getPointerFlags(MouseOrder order) {
+        int flags = 0;
+
+        int modifiers = order.event.getModifiersEx();
+
+        if (order.pressed) {
+            // Mouse pressed
+            flags |= PTRFLAGS_DOWN;
+
+            // Check, which one of buttons is released
+            boolean b1 = ((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && !button1;
+            boolean b2 = ((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && !button2;
+            boolean b3 = ((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && !button3;
+
+            if (b1) {
+                flags |= PTRFLAGS_BUTTON1;
+                button1 = true;
+            }
+
+            if (b2) {
+                flags |= PTRFLAGS_BUTTON3;
+                button2 = true;
+            }
+
+            if (b3) {
+                flags |= PTRFLAGS_BUTTON2;
+                button3 = true;
+            }
+        } else if (order.released) {
+            // Mouse released
+
+            // Check, which one of buttons is released
+            boolean b1 = !((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && button1;
+            boolean b2 = !((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && button2;
+            boolean b3 = !((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && button3;
+
+            if (b1) {
+                flags |= PTRFLAGS_BUTTON1;
+                button1 = false;
+            }
+
+            if (b2) {
+                flags |= PTRFLAGS_BUTTON3;
+                button2 = false;
+            }
+
+            if (b3) {
+                flags |= PTRFLAGS_BUTTON2;
+                button3 = false;
+            }
+        } else {
+            // Mouse moved
+            flags |= PTRFLAGS_MOVE;
+        }
+
+        return flags;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
new file mode 100755
index 0000000..3a16536
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardDataFormat.java
@@ -0,0 +1,143 @@
+// 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.clip;
+
+import java.util.Map;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+
+public class ClipboardDataFormat {
+
+    public static final String HTML_FORMAT = "HTML Format";
+    public static final String RTF_AS_TEXT = "RTF As Text";
+    public static final String RICH_TEXT_FORMAT_WITHOUT_OBJECTS = "Rich Text Format Without Objects";
+    public static final String RICH_TEXT_FORMAT = "Rich Text Format";
+
+    public static final int CB_FORMAT_TEXT = 0x0001;
+    public static final int CB_FORMAT_UNICODETEXT = 0x000D;
+
+    /**
+     * Supported clipboard data formats in order of preference.
+     */
+    public static final Object[] supportedTextBasedFormats = new Object[] {
+        // ID's
+        CB_FORMAT_UNICODETEXT, CB_FORMAT_TEXT,
+
+        // Names
+        HTML_FORMAT,
+
+        // RTF_AS_TEXT,
+        // RICH_TEXT_FORMAT_WITHOUT_OBJECTS,
+        // RICH_TEXT_FORMAT,
+
+    };
+
+    public final int id;
+    public final String name;
+
+    public ClipboardDataFormat(int id, String name) {
+        super();
+        this.id = id;
+        this.name = name;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + id;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ClipboardDataFormat other = (ClipboardDataFormat)obj;
+        if (id != other.id)
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "ClipboardDataFormat [id=" + id + ", name=\"" + name + "\"" + ((id == CB_FORMAT_UNICODETEXT) ? " (Unicode text)" : "")
+                + ((id == CB_FORMAT_TEXT) ? " (text)" : "") + "]";
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Parse response of supported format and return it as string.
+     */
+    public String parseServerResponseAsString(ByteBuffer buf) {
+        switch (id) {
+        case CB_FORMAT_UNICODETEXT:
+            return buf.readVariableWideString(RdpConstants.CHARSET_16);
+        case CB_FORMAT_TEXT:
+            return buf.readVariableString(RdpConstants.CHARSET_8);
+        }
+
+        if (name == null || name.length() == 0)
+            return null;
+
+        if (HTML_FORMAT.equals(name))
+            return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+
+        // if (RTF_AS_TEXT.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+        //
+        // if (RICH_TEXT_FORMAT_WITHOUT_OBJECTS.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+        //
+        // if (RICH_TEXT_FORMAT.equals(name))
+        // return buf.readVariableString(RdpConstants.CHARSET_8); // TODO: verify
+
+        return null;
+    }
+
+    /**
+     * Find first (richest) text-based data format.
+     *
+     * @return text-based data format or null, when not found
+     */
+    public static ClipboardDataFormat findBestTextFormat(Map<Object, ClipboardDataFormat> serverClipboardDataFormats) {
+        for (Object formatKey : ClipboardDataFormat.supportedTextBasedFormats)
+            if (serverClipboardDataFormats.containsKey(formatKey))
+                return serverClipboardDataFormats.get(formatKey);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
new file mode 100755
index 0000000..9c465b5
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ClipboardState.java
@@ -0,0 +1,70 @@
+// 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.clip;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClipboardState {
+
+    /**
+     * The Long Format Name variant of the Format List PDU is supported for
+     * exchanging updated format names. If this flag is not set, the Short Format
+     * Name variant MUST be used. If this flag is set by both protocol endpoints,
+     * then the Long Format Name variant MUST be used.
+     */
+    public boolean serverUseLongFormatNames = false;
+    public final boolean clientUseLongFormatNames = false;
+
+    /**
+     * File copy and paste using stream-based operations are supported using the
+     * File Contents Request PDU and File Contents Response PDU.
+     */
+    public boolean serverStreamFileClipEnabled = false;
+    public final boolean clientStreamFileClipEnabled = false;
+
+    /**
+     * Indicates that any description of files to copy and paste MUST NOT include
+     * the source path of the files.
+     */
+    public boolean serverFileClipNoFilePaths = false;
+    public final boolean clientFileClipNoFilePaths = false;
+
+    /**
+     * Locking and unlocking of File Stream data on the clipboard is supported
+     * using the Lock Clipboard Data PDU and Unlock Clipboard Data PDU.
+     */
+    public boolean serverCanLockClipdata = false;
+    public final boolean clientCanLockClipdata = false;
+
+    /**
+     * The Monitor Ready PDU is sent from the server to the client to indicate
+     * that the server is initialized and ready.
+     */
+    public boolean serverReady = false;
+
+    /**
+     * Set of data formats, which are supported by server for paste operation.
+     */
+    public Map<Object, ClipboardDataFormat> serverClipboardDataFormats = new HashMap<Object, ClipboardDataFormat>(0);
+
+    /**
+     * Server sends clipboard data in requested format.
+     */
+    public ClipboardDataFormat serverRequestedFormat;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
new file mode 100755
index 0000000..3238124
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipRdrChannelRouter.java
@@ -0,0 +1,193 @@
+// 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.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerClipRdrChannelRouter extends BaseElement {
+
+    /**
+     * Key for ASCII names message flag in payload metadata.  Value is Boolean.
+     */
+    public static final String ASCII_NAMES = "ascii_names";
+
+    /**
+     * Key for success/fail message flag in payload metadata. Value is Boolean.
+     */
+    public static final String SUCCESS = "success";
+
+    /**
+     * Monitor Ready PDU
+     */
+    public static final int CB_MONITOR_READY = 0x0001;
+
+    /**
+     * Format List PDU
+     */
+    public static final int CB_FORMAT_LIST = 0x0002;
+
+    /**
+     * Format List Response PDU
+     */
+    public static final int CB_FORMAT_LIST_RESPONSE = 0x0003;
+
+    /**
+     * Format Data Request PDU
+     */
+    public static final int CB_FORMAT_DATA_REQUEST = 0x0004;
+
+    /**
+     * Format Data Response PDU
+     */
+    public static final int CB_FORMAT_DATA_RESPONSE = 0x0005;
+
+    /**
+     * Temporary Directory PDU
+     */
+    public static final int CB_TEMP_DIRECTORY = 0x0006;
+
+    /**
+     * Clipboard Capabilities PDU
+     */
+    public static final int CB_CLIP_CAPS = 0x0007;
+
+    /**
+     * File Contents Request PDU
+     */
+    public static final int CB_FILECONTENTS_REQUEST = 0x0008;
+
+    /**
+     * File Contents Response PDU
+     */
+    public static final int CB_FILECONTENTS_RESPONSE = 0x0009;
+
+    /**
+     * Lock Clipboard Data PDU
+     */
+    public static final int CB_LOCK_CLIPDATA = 0x000A;
+
+    /**
+     * Unlock Clipboard Data PDU
+     */
+    public static final int CB_UNLOCK_CLIPDATA = 0x000B;
+
+    /**
+     * Used by the Format List Response PDU, Format Data Response PDU, and File
+     * Contents Response PDU to indicate that the associated request Format List
+     * PDU, Format Data Request PDU, and File Contents Request PDU were processed
+     * successfully.
+     */
+    public static final int CB_RESPONSE_OK = 0x0001;
+
+    /**
+     * Used by the Format List Response PDU, Format Data Response PDU, and File
+     * Contents Response PDU to indicate that the associated Format List PDU,
+     * Format Data Request PDU, and File Contents Request PDU were not processed
+     * successfully.
+     */
+    public static final int CB_RESPONSE_FAIL = 0x0002;
+
+    /**
+     * Used by the Short Format Name variant of the Format List Response PDU to
+     * indicate the format names are in ASCII 8.
+     */
+    public static final int CB_ASCII_NAMES = 0x0004;
+
+    public ServerClipRdrChannelRouter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Parse PDU header
+        // Example: 07 00 -> CLIPRDR_HEADER::msgType = CB_CLIP_CAPS (7)
+        int msgType = buf.readUnsignedShortLE();
+
+        // Example: 00 00 -> CLIPRDR_HEADER::msgFlags = 0
+        int msgFlags = buf.readUnsignedShortLE();
+
+        // Example: 10 00 00 00 -> CLIPRDR_HEADER::dataLen = 0x10 = 16 bytes
+        long dataLenLong = buf.readSignedIntLE();
+        if (dataLenLong > 4 * 1024 * 1024)
+            throw new RuntimeException("Clipboard packet is too long. Expected length: less than 4MiB. Actual length: " + dataLenLong + ".");
+        int dataLen = (int)dataLenLong;
+
+        ByteBuffer payload = buf.readBytes(dataLen);
+
+        // Parse message flags and store them in the payload metadata
+        if ((msgFlags & CB_RESPONSE_OK) == CB_RESPONSE_OK)
+            payload.putMetadata("success", true);
+        if ((msgFlags & CB_RESPONSE_FAIL) == CB_RESPONSE_FAIL)
+            payload.putMetadata(SUCCESS, false);
+        if ((msgFlags & CB_ASCII_NAMES) == CB_ASCII_NAMES)
+            payload.putMetadata(ASCII_NAMES, true);
+
+        // Push PDU to appropriate handler
+        switch (msgType) {
+        case CB_MONITOR_READY:
+            pushDataToPad("monitor_ready", payload);
+            break;
+        case CB_FORMAT_LIST:
+            pushDataToPad("format_list", payload);
+            break;
+        case CB_FORMAT_LIST_RESPONSE:
+            pushDataToPad("format_list_response", payload);
+            break;
+        case CB_FORMAT_DATA_REQUEST:
+            pushDataToPad("format_data_request", payload);
+            break;
+        case CB_FORMAT_DATA_RESPONSE:
+            pushDataToPad("format_data_response", payload);
+            break;
+        case CB_TEMP_DIRECTORY:
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected clipboard temporary directory PDU received from server. Data: " + buf + ".");
+        case CB_CLIP_CAPS:
+            pushDataToPad("clipboard_capabilities", payload);
+            break;
+        case CB_FILECONTENTS_REQUEST:
+            pushDataToPad("filecontent_request", payload);
+            break;
+        case CB_FILECONTENTS_RESPONSE:
+            pushDataToPad("filecontent_response", payload);
+            break;
+        case CB_LOCK_CLIPDATA:
+            pushDataToPad("lock_clipdata", payload);
+            break;
+        case CB_UNLOCK_CLIPDATA:
+            pushDataToPad("unlock_clipdata", payload);
+            break;
+        default:
+            throw new RuntimeException("[" + this + "] ERROR: Unknown clipboard PDU message type: " + msgType + ".");
+        }
+
+        buf.unref();
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        // TODO
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
new file mode 100755
index 0000000..68278e8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerClipboardCapabilitiesPDU.java
@@ -0,0 +1,180 @@
+// 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.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerClipboardCapabilitiesPDU extends BaseElement {
+
+    /**
+     * General capability set.
+     */
+    public static final int CB_CAPSTYPE_GENERAL = 0x1;
+
+    /**
+     * The Long Format Name variant of the Format List PDU is supported for
+     * exchanging updated format names. If this flag is not set, the Short Format
+     * Name variant MUST be used. If this flag is set by both protocol endpoints,
+     * then the Long Format Name variant MUST be used.
+     */
+    public static final int CB_USE_LONG_FORMAT_NAMES = 0x00000002;
+
+    /**
+     * File copy and paste using stream-based operations are supported using the
+     * File Contents Request PDU and File Contents Response PDU.
+     */
+    public static final int CB_STREAM_FILECLIP_ENABLED = 0x00000004;
+
+    /**
+     * Indicates that any description of files to copy and paste MUST NOT include
+     * the source path of the files.
+     */
+    public static final int CB_FILECLIP_NO_FILE_PATHS = 0x00000008;
+
+    /**
+     * Locking and unlocking of File Stream data on the clipboard is supported
+     * using the Lock Clipboard Data PDU and Unlock Clipboard Data PDU.
+     */
+    public static final int CB_CAN_LOCK_CLIPDATA = 0x00000010;
+
+    protected ClipboardState state;
+
+    public ServerClipboardCapabilitiesPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // 0x01, 0x00, // CLIPRDR_CAPS::cCapabilitiesSets = 1
+        int cCapabilitiesSets = buf.readUnsignedShortLE();
+
+        // 0x00, 0x00, // CLIPRDR_CAPS::pad1
+        buf.skipBytes(2);
+
+        // Parse all capability sets
+        for (int capabilitySet = 0; capabilitySet < cCapabilitiesSets; capabilitySet++) {
+            // 0x01, 0x00, // CLIPRDR_CAPS_SET::capabilitySetType =
+            // CB_CAPSTYPE_GENERAL (1)
+            int capabilitySetType = buf.readUnsignedShortLE();
+
+            // 0x0c, 0x00, // CLIPRDR_CAPS_SET::lengthCapability = 0x0c = 12 bytes
+            int lengthCapability = buf.readUnsignedShortLE();
+
+            // parse capability set
+            switch (capabilitySetType) {
+            case CB_CAPSTYPE_GENERAL:
+                parseGeneralCapabilitySet(buf.readBytes(lengthCapability - 4));
+                break;
+            default:
+                // Ignore
+                // throw new RuntimeException("Unknown capability set type: " +
+                // capabilitySetType + ". Expected value: CB_CAPSTYPE_GENERAL (1).");
+            }
+        }
+
+        buf.unref();
+    }
+
+    protected void parseGeneralCapabilitySet(ByteBuffer buf) {
+        // 0x02, 0x00, 0x00, 0x00, // CLIPRDR_GENERAL_CAPABILITY::version =
+        // CB_CAPS_VERSION_2 (2)
+        // long version = buf.readUnsignedIntLE();
+        buf.skipBytes(4);
+
+        // 0x0e, 0x00, 0x00, 0x00, // CLIPRDR_GENERAL_CAPABILITY::capabilityFlags
+        // = 0x0000000e = 0x02 |0x04 |0x08 = CB_USE_LONG_FORMAT_NAMES |
+        // CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS
+        int flags = buf.readSignedIntLE();
+
+        if ((flags & CB_USE_LONG_FORMAT_NAMES) == CB_USE_LONG_FORMAT_NAMES) {
+            state.serverUseLongFormatNames = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server can use long format names for clipboard data.");
+        }
+
+        if ((flags & CB_STREAM_FILECLIP_ENABLED) == CB_STREAM_FILECLIP_ENABLED) {
+            state.serverStreamFileClipEnabled = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server supports stream based file clipboard operations.");
+        }
+
+        if ((flags & CB_FILECLIP_NO_FILE_PATHS) == CB_FILECLIP_NO_FILE_PATHS) {
+            state.serverFileClipNoFilePaths = true;
+            if (verbose)
+                System.out.println("[" + this
+                        + "] INFO: Server Indicates that any description of files to copy and paste MUST NOT include the source path of the files.");
+        }
+
+        if ((flags & CB_CAN_LOCK_CLIPDATA) == CB_CAN_LOCK_CLIPDATA) {
+            state.serverCanLockClipdata = true;
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Server can lock and unlock file streams on the clipboard.");
+        }
+
+    }
+
+    /**
+     * 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[] {
+                0x07, 0x00,  //  CLIPRDR_HEADER::msgType = CB_CLIP_CAPS (7)
+                0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+                0x10, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0x10 = 16 bytes
+                0x01, 0x00,  //  CLIPRDR_CAPS::cCapabilitiesSets = 1
+                0x00, 0x00,  //  CLIPRDR_CAPS::pad1
+                0x01, 0x00,  //  CLIPRDR_CAPS_SET::capabilitySetType = CB_CAPSTYPE_GENERAL (1)
+                0x0c, 0x00,  //  CLIPRDR_CAPS_SET::lengthCapability = 0x0c = 12 bytes
+                0x02, 0x00, 0x00, 0x00,  //  CLIPRDR_GENERAL_CAPABILITY::version = CB_CAPS_VERSION_2 (2)
+                0x0e, 0x00, 0x00, 0x00,  //  CLIPRDR_GENERAL_CAPABILITY::capabilityFlags = 0x0000000e = 0x02 |0x04 |0x08 = CB_USE_LONG_FORMAT_NAMES | CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        Element clip_cap = new ServerClipboardCapabilitiesPDU("clip_cap", state);
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, clip_cap, sink);
+        pipeline.link("source", "router >clipboard_capabilities", "clip_cap", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!state.serverUseLongFormatNames || !state.serverStreamFileClipEnabled || !state.serverFileClipNoFilePaths || state.serverCanLockClipdata)
+            throw new RuntimeException("Server clipboard capabilities packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
new file mode 100755
index 0000000..99f9eda
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatDataResponsePDU.java
@@ -0,0 +1,97 @@
+// 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.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.adapter.AwtClipboardAdapter;
+
+public class ServerFormatDataResponsePDU extends BaseElement {
+
+    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
+
+    protected ClipboardState state;
+
+    public ServerFormatDataResponsePDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        parseData(buf);
+
+        buf.unref();
+    }
+
+    protected void parseData(ByteBuffer buf) {
+
+        String content = state.serverRequestedFormat.parseServerResponseAsString(buf);
+
+        // Send response to clipboard adapter
+        ByteBuffer outBuf = new ByteBuffer(0);
+        outBuf.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, content);
+
+        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
+    }
+
+    /**
+     * 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[] {
+                0x05, 0x00,  //  CLIPRDR_HEADER::msgType = CB_FORMAT_DATA_RESPONSE (5)
+                0x01, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0x0001 = CB_RESPONSE_OK
+                0x18, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0x18 = 24 bytes
+
+                0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x77, 0x00, 0x6f, 0x00,
+                0x72, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x00, 0x00,  //  CLIPRDR_FORMAT_DATA_RESPONSE::requestedFormatData: "hello world"
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        state.serverRequestedFormat = new ClipboardDataFormat(ClipboardDataFormat.CB_FORMAT_UNICODETEXT, "");
+        Element format_data_response = new ServerFormatDataResponsePDU("format_data_response", state);
+
+        ByteBuffer clipboardAdapterPacket = new ByteBuffer(0);
+        clipboardAdapterPacket.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, "hello world");
+        Element sink = new MockSink("sink", new ByteBuffer[] {clipboardAdapterPacket});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, format_data_response, sink);
+        pipeline.link("source", "router >format_data_response", "format_data_response >clipboard", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
new file mode 100755
index 0000000..776f451
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerFormatListPDU.java
@@ -0,0 +1,237 @@
+// 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.clip;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerFormatListPDU extends BaseElement {
+
+    protected ClipboardState state;
+
+    public ServerFormatListPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        parseFormatNames(buf);
+        buf.unref();
+
+        // Automatically send request for text-based data to insert it into local
+        // clipboard
+        ClipboardDataFormat textFormat = ClipboardDataFormat.findBestTextFormat(state.serverClipboardDataFormats);
+        if (textFormat != null) {
+            // Send response: OK
+            sendFormatListParseResponse(true);
+            // Request data
+            sendFormatDataRequest(textFormat);
+        } else {
+            // Send response: FAIL, we are not interested in this data
+            sendFormatListParseResponse(false);
+        }
+    }
+
+    /**
+     * The Format Data Request PDU is sent by the recipient of the Format List
+     * PDU. It is used to request the data for one of the formats that was listed
+     * in the Format List PDU.
+     */
+    protected void sendFormatDataRequest(ClipboardDataFormat textFormat) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Sending request for data in following format: " + textFormat + ".");
+
+        // Store data format to parse server response later
+        state.serverRequestedFormat = textFormat;
+
+        ByteBuffer buf = new ByteBuffer(12, true);
+
+        // Type
+        buf.writeShortLE(ServerClipRdrChannelRouter.CB_FORMAT_DATA_REQUEST);
+        // Message flags
+        buf.writeShortLE(0);
+        // Length
+        buf.writeIntLE(4);
+
+        // ID of chosen format
+        buf.writeIntLE(textFormat.id);
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    /**
+     * The Format List Response PDU is sent as a reply to the Format List PDU. It
+     * is used to indicate whether processing of the Format List PDU was
+     * successful.
+     *
+     * @param b
+     */
+    protected void sendFormatListParseResponse(boolean ok) {
+        ByteBuffer buf = new ByteBuffer(8, true);
+
+        // Type
+        buf.writeShortLE(ServerClipRdrChannelRouter.CB_FORMAT_LIST_RESPONSE);
+        // Message flags
+        buf.writeShortLE((ok) ? ServerClipRdrChannelRouter.CB_RESPONSE_OK : ServerClipRdrChannelRouter.CB_RESPONSE_FAIL);
+        // Length
+        buf.writeIntLE(0);
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    protected void parseFormatNames(ByteBuffer buf) {
+
+        // Set will not be modified after creation, so there is no need to make it
+        // synchronous.
+        Map<Object, ClipboardDataFormat> formats = new HashMap<Object, ClipboardDataFormat>();
+
+        while (buf.cursor < buf.length) {
+            int id = buf.readSignedIntLE();
+
+            String name;
+            if (state.serverUseLongFormatNames) {
+                // Long format names in Unicode
+                name = buf.readVariableWideString(RdpConstants.CHARSET_16);
+            } else {
+                Boolean asciiNames = (Boolean)buf.getMetadata(ServerClipRdrChannelRouter.ASCII_NAMES);
+
+                if (asciiNames != null && asciiNames) {
+                    // Short format names in ASCII
+                    name = buf.readString(32, RdpConstants.CHARSET_8);
+                } else {
+                    // Short format names in Unicode
+                    name = buf.readString(32, RdpConstants.CHARSET_16);
+                }
+
+            }
+
+            // Store format in map by both ID and name (if name is not empty)
+            formats.put(id, new ClipboardDataFormat(id, name));
+            if (name.length() > 0)
+                formats.put(name, new ClipboardDataFormat(id, name));
+        }
+
+        if (verbose)
+            System.out.println("Server supports following formats for clipboard data: " + formats.values().toString() + ".");
+
+        state.serverClipboardDataFormats = formats;
+    }
+
+    /**
+     * 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[] {
+                0x02, 0x00,  //  CLIPRDR_HEADER::msgType = CB_FORMAT_LIST (2)
+                0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+                (byte) 0xe0, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0xe0 = 224 bytes
+
+                (byte) 0x8a, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc08a = 49290
+                0x52, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Rich Text Format"
+
+                0x45, (byte) 0xc1, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc145 = 49477
+                0x52, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x78, 0x00,
+                0x74, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00,
+                0x20, 0x00, 0x57, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00,
+                0x20, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x73, 0x00,
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Rich Text Format Without Objects"
+
+                0x43, (byte) 0xc1, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc143 = 49475
+                0x52, 0x00, 0x54, 0x00, 0x46, 0x00, 0x20, 0x00, 0x41, 0x00, 0x73, 0x00, 0x20, 0x00, 0x54, 0x00,
+                0x65, 0x00, 0x78, 0x00, 0x74, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "RTF As Text"
+
+                0x01, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 1
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+                0x0d, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0x0d = 13
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+                0x04, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc004 = 49156
+                0x4e, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x00, 0x00,  //  "Native"
+
+                0x0e, (byte) 0xc0, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 0xc00e = 49166
+                0x4f, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00,
+                0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00,
+                0x72, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = "Object Descriptor"
+
+                0x03, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 3
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+                0x10, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 16
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+
+                0x07, 0x00, 0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatId = 7
+                0x00, 0x00,  //  CLIPRDR_LONG_FORMAT_NAME::formatName = ""
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        state.serverUseLongFormatNames = true;
+        Element format_list = new ServerFormatListPDU("format_list", state);
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Format List Response PDU
+                0x03, 0x00, // CLIPRDR_HEADER::msgType = CB_FORMAT_LIST_RESPONSE (3)
+                0x01, 0x00, // CLIPRDR_HEADER::msgFlags = 0x0001 = CB_RESPONSE_OK
+                0x00, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 0 bytes
+        }, new byte[] {
+                // Format Data Request PDU
+                0x04, 0x00, // CLIPRDR_HEADER::msgType = CB_FORMAT_DATA_REQUEST (4)
+                0x00, 0x00, // CLIPRDR_HEADER::msgFlags = 0
+                0x04, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 4 bytes
+                0x0d, 0x00, 0x00, 0x00, // CLIPRDR_FORMAT_DATA_REQUEST::requestedFormatId
+                // = 0x0d
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, format_list, sink);
+        pipeline.link("source", "router >format_list", "format_list", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!(state.serverClipboardDataFormats.containsKey(49475) && state.serverClipboardDataFormats.containsKey("Rich Text Format")))
+            throw new RuntimeException("Server format list packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
new file mode 100755
index 0000000..bbc356e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/clip/ServerMonitorReadyPDU.java
@@ -0,0 +1,85 @@
+// 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.clip;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerMonitorReadyPDU extends BaseElement {
+
+    protected ClipboardState state;
+
+    public ServerMonitorReadyPDU(String id, ClipboardState state) {
+        super(id);
+        this.state = state;
+    }
+
+    // 0x01, 0x00, // CLIPRDR_HEADER::msgType = CB_MONITOR_READY (1)
+    // 0x00, 0x00, // CLIPRDR_HEADER::msgFlags = 0
+    // 0x00, 0x00, 0x00, 0x00, // CLIPRDR_HEADER::dataLen = 0 bytes
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        state.serverReady = true;
+
+        buf.unref();
+
+    }
+
+    /**
+     * 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[] {
+                0x01, 0x00,  //  CLIPRDR_HEADER::msgType = CB_MONITOR_READY (1)
+                0x00, 0x00,  //  CLIPRDR_HEADER::msgFlags = 0
+                0x00, 0x00, 0x00, 0x00,  //  CLIPRDR_HEADER::dataLen = 0 bytes
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element router = new ServerClipRdrChannelRouter("router");
+        ClipboardState state = new ClipboardState();
+        Element monitor_ready = new ServerMonitorReadyPDU("monitor_ready", state);
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, router, monitor_ready, sink);
+        pipeline.link("source", "router >monitor_ready", "monitor_ready", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        // Check state
+        if (!state.serverReady)
+            throw new RuntimeException("Server monitor ready packet parsed incorrectly.");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
new file mode 100755
index 0000000..203fde4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ClientPacketSniffer.java
@@ -0,0 +1,51 @@
+// 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.debug;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class ClientPacketSniffer extends PacketSniffer {
+
+    private static final Pair[] clientRegexps = new Pair[] {
+// @formatter:off
+        new Pair("Client FastPath input",           "04"),
+        new Pair("Client X224ConnectionRequest",    "03 00 XX XX 27 E0"),
+        new Pair("Client ConnectionRequest",        "03 00 XX XX XX E0"),
+        new Pair("Client MCConnectInitial",         "03 00 XX XX 02 F0 80 7F 65"),
+        new Pair("Client ErectDomainRequest",       "03 00 XX XX 02 F0 80 04"),
+        new Pair("Client AttachUserRequest",        "03 00 XX XX 02 F0 80 28"),
+        new Pair("Client ChannelJoinRequest",       "03 00 XX XX 02 F0 80 38"),
+        new Pair("Client Info",                     "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 00 00"),
+        new Pair("Client ConfirmActivePDU",         "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 13 00"),
+        new Pair("Client SynchronizePDU",           "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 1F"),
+        new Pair("Client ControlPDU",               "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 14"),
+        new Pair("Client FontListPDU",              "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 27"),
+        new Pair("Client BitmapCachePersistentList","03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX XX XX XX XX XX 2b"),
+        new Pair("Client CredSSP",                  "30"),
+        new Pair("Client HyperV PreConnection Blob","5E"),
+        new Pair("Client a TPKT packet",            "03"),
+        new Pair("Client a Fast Path packet",       "00"),
+        // @formatter:on
+
+    };
+
+    public ClientPacketSniffer(String id) {
+        super(id, clientRegexps);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
new file mode 100755
index 0000000..efbe689
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/PacketSniffer.java
@@ -0,0 +1,75 @@
+// 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.debug;
+
+import java.util.regex.Pattern;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class PacketSniffer extends BaseElement {
+
+    protected Pair regexps[] = null;
+
+    public PacketSniffer(String id, Pair[] regexps) {
+        super(id);
+        this.regexps = regexps;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        matchPacket(buf);
+
+        super.handleData(buf, link);
+    }
+
+    private void matchPacket(ByteBuffer buf) {
+        String header = buf.toPlainHexString(100);
+        for (Pair pair : regexps) {
+            if (pair.regexp.matcher(header).find()) {
+                System.out.println("[" + this + "] INFO: Packet: " + pair.name + ".");
+                return;
+            }
+        }
+
+        System.out.println("[" + this + "] INFO: Unknown packet: " + header + ".");
+    }
+
+    protected static class Pair {
+        String name;
+        Pattern regexp;
+
+        protected Pair(String name, String regexp) {
+            this.name = name;
+            this.regexp = Pattern.compile("^" + replaceShortcuts(regexp), Pattern.CASE_INSENSITIVE);
+        }
+
+        private static String replaceShortcuts(String regexp) {
+            String result = regexp;
+            result = result.replaceAll("XX\\*", "([0-9a-fA-F]{2} )*?");
+            result = result.replaceAll("XX\\?", "([0-9a-fA-F]{2} )?");
+            result = result.replaceAll("XX", "[0-9a-fA-F]{2}");
+            return result;
+        }
+    }
+
+}


[17/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
deleted file mode 100644
index cd3a5ed..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RLEBitmapDecompression.java
+++ /dev/null
@@ -1,985 +0,0 @@
-// 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;
-
-import streamer.AssertingByteBuffer;
-import streamer.ByteBuffer;
-
-/**
- * Based on code example from MSDN, @see
- * http://msdn.microsoft.com/en-us/library/dd240593.aspx .
- */
-public class RLEBitmapDecompression {
-
-    public static final int g_MaskRegularRunLength = 0x1F;
-    public static final int g_MaskLiteRunLength = 0x0F;
-
-    public static final int g_MaskSpecialFgBg1 = 0x03;
-    public static final int g_MaskSpecialFgBg2 = 0x05;
-
-    public static final int REGULAR_BG_RUN = 0x00;
-    public static final int REGULAR_FG_RUN = 0x01;
-    public static final int REGULAR_FGBG_IMAGE = 0x02;
-    public static final int REGULAR_COLOR_RUN = 0x03;
-    public static final int REGULAR_COLOR_IMAGE = 0x04;
-
-    public static final int LITE_SET_FG_FG_RUN = 0x0C;
-    public static final int LITE_SET_FG_FGBG_IMAGE = 0x0D;
-    public static final int LITE_DITHERED_RUN = 0x0E;
-
-    public static final int MEGA_MEGA_BG_RUN = 0xF0;
-    public static final int MEGA_MEGA_FG_RUN = 0xF1;
-    public static final int MEGA_MEGA_FGBG_IMAGE = 0xF2;
-    public static final int MEGA_MEGA_COLOR_RUN = 0xF3;
-    public static final int MEGA_MEGA_COLOR_IMAGE = 0xF4;
-    public static final int MEGA_MEGA_SET_FG_RUN = 0xF6;
-    public static final int MEGA_MEGA_SET_FGBG_IMAGE = 0xF7;
-    public static final int MEGA_MEGA_DITHERED_RUN = 0xF8;
-
-    public static final int SPECIAL_FGBG_1 = 0xF9;
-    public static final int SPECIAL_FGBG_2 = 0xFA;
-
-    public static final int SPECIAL_WHITE = 0xFD;
-    public static final int SPECIAL_BLACK = 0xFE;
-
-    /**
-     * Writes a pixel to the specified buffer and advance cursor by bpp.
-     *
-     * @param bpp
-     *          bytes per pixel
-     */
-    private static void writePixel(int bpp, ByteBuffer destBuf, int pixel) {
-        switch (bpp) {
-            case 1:
-                destBuf.writeByte(pixel);
-                break;
-            case 2:
-                destBuf.writeShortLE(pixel);
-                break;
-            case 3:
-                destBuf.writeByte(pixel);
-                destBuf.writeShortLE(pixel >> 8);
-                break;
-            case 4:
-                destBuf.writeIntLE(pixel);
-                break;
-            default:
-                throw new RuntimeException("Unsupported color depth.");
-        }
-    }
-
-    /**
-     * Reads a pixel from the specified buffer at given offset without changing of
-     * cursor.
-     *
-     * @param bpp
-     *          bytes per pixel
-     * @param offset
-     *          -rowDelta (i.e. (-width*bpp))
-     */
-    private static int peekPixel(int bpp, ByteBuffer destBuf, int offset) {
-        if (offset >= 0 || (-offset) > destBuf.cursor)
-            throw new RuntimeException("Incorrect value for offset: offset in destination buffer must point to pixel in previous row.");
-
-        // Adjust cursor to point to pixel in previous row
-        int oldCursor = destBuf.cursor;
-        destBuf.cursor += offset;
-
-        int pixel;
-        switch (bpp) {
-            case 1:
-                pixel = destBuf.readUnsignedByte();
-                break;
-            case 2:
-                pixel = destBuf.readUnsignedShortLE();
-                break;
-            case 3:
-                pixel = destBuf.readUnsignedByte() | (destBuf.readUnsignedShortLE() >> 8);
-                break;
-            case 4:
-                pixel = destBuf.readSignedIntLE();
-                break;
-            default:
-                throw new RuntimeException("Unsupported color depth.");
-        }
-        destBuf.cursor = oldCursor;
-
-        return pixel;
-    }
-
-    /**
-     * Reads a pixel from the specified buffer and advance cursor by bpp value.
-     *
-     * @param bpp
-     *          bytes per pixel
-     */
-    private static int readPixel(int bpp, ByteBuffer srcBuf) {
-        int pixel;
-        switch (bpp) {
-            case 1:
-                pixel = srcBuf.readUnsignedByte();
-                break;
-            case 2:
-                pixel = srcBuf.readUnsignedShortLE();
-                break;
-            case 3:
-                pixel = srcBuf.readUnsignedByte() | (srcBuf.readUnsignedShortLE() >> 8);
-                break;
-            case 4:
-                pixel = srcBuf.readSignedIntLE();
-                break;
-            default:
-                throw new RuntimeException("Unsupported color depth.");
-        }
-
-        return pixel;
-    }
-
-    /**
-     * Returns the size of a pixel in bytes.
-     */
-    private static int getPixelSize(int colorDepth) {
-        switch (colorDepth) {
-            case 8:
-                return 1;
-            case 15:
-            case 16:
-                return 2;
-            case 24:
-                return 3;
-            default:
-                throw new RuntimeException("Unsupported pixel color depth: " + colorDepth + " bpp.");
-        }
-    }
-
-    /**
-     * Reads the supplied order header & extracts the compression order code ID.
-     */
-    private static int extractCodeId(int orderHeader) {
-        // Taken from FreeRDP code, bitmap.c
-        switch (orderHeader) {
-            case MEGA_MEGA_BG_RUN:
-            case MEGA_MEGA_FG_RUN:
-            case MEGA_MEGA_SET_FG_RUN:
-            case MEGA_MEGA_DITHERED_RUN:
-            case MEGA_MEGA_COLOR_RUN:
-            case MEGA_MEGA_FGBG_IMAGE:
-            case MEGA_MEGA_SET_FGBG_IMAGE:
-            case MEGA_MEGA_COLOR_IMAGE:
-            case SPECIAL_FGBG_1:
-            case SPECIAL_FGBG_2:
-            case SPECIAL_WHITE:
-            case SPECIAL_BLACK:
-                return orderHeader;
-        }
-
-        int code = orderHeader >> 5;
-        switch (code) {
-            case REGULAR_BG_RUN:
-            case REGULAR_FG_RUN:
-            case REGULAR_COLOR_RUN:
-            case REGULAR_FGBG_IMAGE:
-            case REGULAR_COLOR_IMAGE:
-                return code;
-        }
-
-        return orderHeader >> 4;
-    }
-
-    /**
-     * Returns a black pixel.
-     */
-    private static int getColorBlack() {
-        return 0x000000;
-    }
-
-    /**
-     * Returns a white pixel.
-     */
-    private static int getColorWhite(int colorDepth) {
-        if (colorDepth == 8) {
-            //
-            // Palette entry #255 holds white.
-            //
-            return 0xFF;
-        } else if (colorDepth == 15) {
-            //
-            // 5 bits per RGB component:
-            // 0111 1111 1111 1111 (binary)
-            //
-            return 0x7FFF;
-        } else if (colorDepth == 16) {
-            //
-            // 5 bits for red, 6 bits for green, 5 bits for green:
-            // 1111 1111 1111 1111 (binary)
-            //
-            return 0xFFFF;
-        } else if (colorDepth == 24) {
-            //
-            // 8 bits per RGB component:
-            // 1111 1111 1111 1111 1111 1111 (binary)
-            //
-            return 0xFFFFFF;
-        } else
-            throw new RuntimeException("Unsupported color depth.");
-    }
-
-    /**
-     * Extract the run length of a compression order.
-     */
-    private static int extractRunLength(int code, int orderHeader, ByteBuffer srcBuf) {
-        switch (code) {
-            case REGULAR_FGBG_IMAGE: {
-                int runLength = orderHeader & g_MaskRegularRunLength;
-                if (runLength == 0)
-                    runLength = srcBuf.readUnsignedByte() + 1;
-                else
-                    runLength = runLength * 8;
-                return runLength;
-            }
-            case LITE_SET_FG_FGBG_IMAGE: {
-                int runLength = orderHeader & g_MaskLiteRunLength;
-                if (runLength == 0)
-                    runLength = srcBuf.readUnsignedByte() + 1;
-                else
-                    runLength = runLength * 8;
-                return runLength;
-            }
-            case REGULAR_BG_RUN:
-            case REGULAR_COLOR_IMAGE:
-            case REGULAR_COLOR_RUN:
-            case REGULAR_FG_RUN: {
-                int runLength = orderHeader & g_MaskRegularRunLength;
-                if (runLength == 0)
-                    // An extended (MEGA) run.
-                    runLength = srcBuf.readUnsignedByte() + 32;
-                return runLength;
-            }
-            case LITE_DITHERED_RUN:
-            case LITE_SET_FG_FG_RUN: {
-                int runLength = orderHeader & g_MaskLiteRunLength;
-                if (runLength == 0)
-                    // An extended (MEGA) run.
-                    runLength = srcBuf.readUnsignedByte() + 16;
-                return runLength;
-            }
-            case MEGA_MEGA_BG_RUN:
-            case MEGA_MEGA_COLOR_IMAGE:
-            case MEGA_MEGA_COLOR_RUN:
-            case MEGA_MEGA_DITHERED_RUN:
-            case MEGA_MEGA_FG_RUN:
-            case MEGA_MEGA_FGBG_IMAGE:
-            case MEGA_MEGA_SET_FG_RUN:
-            case MEGA_MEGA_SET_FGBG_IMAGE: {
-                return srcBuf.readUnsignedShortLE();
-            }
-            default:
-                return 0;
-        }
-
-    }
-
-    /**
-     * Write a foreground/background image to a destination buffer.
-     */
-    private static void writeFgBgImage(int bpp, ByteBuffer destBuf, int rowDelta, int bitmask, int fgPel, int cBits) {
-        for (; cBits > 0; cBits--, bitmask >>= 1) {
-            int xorPixel = peekPixel(bpp, destBuf, -rowDelta);
-            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? xorPixel ^ fgPel : xorPixel);
-        }
-    }
-
-    /**
-     * Write a foreground/background image to a destination buffer for the first
-     * line of compressed data.
-     */
-    private static void writeFirstLineFgBgImage(int bpp, ByteBuffer destBuf, int bitmask, int fgPel, int cBits) {
-        for (; cBits > 0; cBits--, bitmask >>= 1) {
-            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? fgPel : getColorBlack());
-        }
-    }
-
-    /**
-     * Decompress a RLE compressed bitmap and flip decompressed image.
-     *
-     * @param srcBuf
-     *          source buffer containing compressed bitmap
-     * @param imageWidth
-     *          width of destination image in pixels
-     * @param imageHeight
-     *          height of destination image in pixels
-     * @param colorDepth
-     *          bits per pixel
-     * @return destination image buffer
-     */
-    public static ByteBuffer rleDecompress(ByteBuffer srcBuf, int imageWidth, int imageHeight, int colorDepth) {
-        int bpp = getPixelSize(colorDepth);
-
-        // Decompress image
-        ByteBuffer destBuf = new ByteBuffer(new byte[imageWidth * imageHeight * bpp]);
-        rleDecompress(srcBuf, destBuf, imageWidth, imageHeight, colorDepth);
-
-        // Flip image
-        return flipRawImage(destBuf, imageWidth, imageHeight, bpp);
-    }
-
-    /**
-     * Decompress a RLE compressed bitmap.
-     *
-     * @param srcBuf
-     *          source buffer containing compressed bitmap
-     * @param destBuf
-     *          destination buffer
-     * @param imageWidth
-     *          width of destination image in pixels
-     * @param imageHeight
-     *          height of destination image in pixels
-     * @param colorDepth
-     *          bits per pixel
-     */
-    protected static void rleDecompress(final ByteBuffer srcBuf, final ByteBuffer destBuf, final int imageWidth, final int imageHeight, final int colorDepth) {
-        final int bpp = getPixelSize(colorDepth);
-        final int rowDelta = imageWidth * bpp;
-        final int whitePixel = getColorWhite(colorDepth);
-        final int blackPixel = getColorBlack();
-
-        int fgPel = whitePixel;
-        boolean insertFgPel = false;
-        boolean firstLine = true;
-
-        if (destBuf.length != imageWidth * imageHeight * bpp)
-            throw new RuntimeException("Incorrect size of destination buffer. Expected size (imageWidth*imageHeight*bpp): " + (imageWidth * imageHeight * bpp) +
-                ", actual size: " + destBuf.length + ".");
-
-        while (srcBuf.cursor < srcBuf.length) {
-            // Watch out for the end of the first scanline in destination buffer.
-            if (firstLine) {
-                if (destBuf.cursor >= rowDelta) {
-                    firstLine = false;
-                    insertFgPel = false;
-                }
-            }
-
-            // Extract the compression order code ID from the compression
-            // order header.
-            int orderHeader = srcBuf.readUnsignedByte();
-            int code = extractCodeId(orderHeader);
-
-            // Handle Background Run Orders.
-            if (code == REGULAR_BG_RUN | code == MEGA_MEGA_BG_RUN) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                if (firstLine) {
-                    if (insertFgPel) {
-                        writePixel(bpp, destBuf, fgPel);
-                        runLength--;
-                    }
-
-                    for (; runLength > 0; runLength--)
-                        writePixel(bpp, destBuf, blackPixel);
-
-                } else {
-                    if (insertFgPel) {
-                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
-                        runLength--;
-                    }
-
-                    // Copy pixels from previous row of destination image
-                    for (; runLength > 0; runLength--)
-                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta));
-                }
-
-                //
-                // A follow-on background run order will need a
-                // foreground pel inserted.
-                //
-                insertFgPel = true;
-                continue;
-            }
-
-            //
-            // For any of the other run-types a follow-on background run
-            // order does not need a foreground pel inserted.
-            //
-            insertFgPel = false;
-
-            //
-            // Handle Foreground Run Orders.
-            //
-            if (code == REGULAR_FG_RUN | code == MEGA_MEGA_FG_RUN | code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                if (code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN)
-                    fgPel = readPixel(bpp, srcBuf);
-
-                if (firstLine) {
-                    for (; runLength > 0; runLength--) {
-                        writePixel(bpp, destBuf, fgPel);
-                    }
-                } else {
-                    for (; runLength > 0; runLength--) {
-                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
-                    }
-                }
-
-                continue;
-            }
-
-            //
-            // Handle Dithered Run Orders.
-            //
-            if (code == LITE_DITHERED_RUN | code == MEGA_MEGA_DITHERED_RUN) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                int pixelA = readPixel(bpp, srcBuf);
-                int pixelB = readPixel(bpp, srcBuf);
-
-                for (; runLength > 0; runLength--) {
-                    writePixel(bpp, destBuf, pixelA);
-                    writePixel(bpp, destBuf, pixelB);
-                }
-
-                continue;
-            }
-
-            //
-            // Handle Color Run Orders.
-            //
-            if (code == REGULAR_COLOR_RUN | code == MEGA_MEGA_COLOR_RUN) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                int pixelA = readPixel(bpp, srcBuf);
-
-                for (; runLength > 0; runLength--)
-                    writePixel(bpp, destBuf, pixelA);
-
-                continue;
-            }
-
-            //
-            // Handle Foreground/Background Image Orders.
-            //
-            if (code == REGULAR_FGBG_IMAGE | code == MEGA_MEGA_FGBG_IMAGE | code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                if (code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
-                    fgPel = readPixel(bpp, srcBuf);
-                }
-
-                for (; runLength > 8; runLength -= 8) {
-                    int bitmask = srcBuf.readUnsignedByte();
-
-                    if (firstLine)
-                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, 8);
-                    else
-                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, 8);
-                }
-
-                if (runLength > 0) {
-                    int bitmask = srcBuf.readUnsignedByte();
-
-                    if (firstLine)
-                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, runLength);
-                    else
-                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, runLength);
-                }
-
-                continue;
-            }
-
-            //
-            // Handle Color Image Orders.
-            //
-            if (code == REGULAR_COLOR_IMAGE | code == MEGA_MEGA_COLOR_IMAGE) {
-                int runLength = extractRunLength(code, orderHeader, srcBuf);
-
-                /* DEBUG */
-                // Copy bytes from source to destination using writeByte(readByte())
-                // for (int byteCount = runLength * bpp; byteCount > 0; byteCount--) {
-                // destBuf.writeByte(srcBuf.readUnsignedByte());
-                // }
-                /* DEBUG */
-
-                // Copy bytes from source to destination directly using arraycopy()
-                int lengthInBytes = runLength * bpp;
-                System.arraycopy(srcBuf.data, srcBuf.offset + srcBuf.cursor, destBuf.data, destBuf.offset + destBuf.cursor, lengthInBytes);
-                srcBuf.cursor += lengthInBytes;
-                destBuf.cursor += lengthInBytes;
-
-                continue;
-            }
-
-            //
-            // Handle Special Order 1.
-            //
-            if (code == SPECIAL_FGBG_1) {
-                if (firstLine)
-                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg1, fgPel, 8);
-                else
-                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
-
-                continue;
-            }
-
-            //
-            // Handle Special Order 2.
-            //
-            if (code == SPECIAL_FGBG_2) {
-                if (firstLine)
-                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg2, fgPel, 8);
-                else
-                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
-
-                continue;
-            }
-
-            //
-            // Handle White Order.
-            //
-            if (code == SPECIAL_WHITE) {
-                writePixel(bpp, destBuf, whitePixel);
-
-                continue;
-            }
-
-            //
-            // Handle Black Order.
-            //
-            if (code == SPECIAL_BLACK) {
-                writePixel(bpp, destBuf, blackPixel);
-
-                continue;
-            }
-
-            throw new RuntimeException("Unknown code: " + code + ".");
-        }
-    }
-
-    /**
-     * Flip image in vertical direction.
-     */
-    public static ByteBuffer flipRawImage(ByteBuffer src, int width, int height, int bpp) {
-        if (width * height * bpp != src.length)
-            throw new RuntimeException("Incorrect size of buffer. Expected size (imageWidth*imageHeight*bpp): " + (width * height * bpp) + ", actual size: " +
-                src.length + ".");
-        ByteBuffer dest = new ByteBuffer(new byte[src.length]);
-
-        int scanLine = width * bpp;
-
-        for (int i = 0; i < height; i++) {
-            // Copy one row
-            System.arraycopy(src.data, (height - i - 1) * scanLine, dest.data, i * scanLine, scanLine);
-        }
-
-        return dest;
-
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-
-        if (true) {
-            // 16x1@8bpp, all black
-            int width = 16, height = 1, depth = 8, bpp = depth / 8;
-            ByteBuffer src = new ByteBuffer(new byte[] {0x10});
-            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
-            rleDecompress(src, dest, width, height, depth);
-        }
-
-        if (true) {
-            // 16x1@16bpp, all black
-            int width = 16, height = 1, depth = 16, bpp = depth / 8;
-            ByteBuffer src = new ByteBuffer(new byte[] {0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
-            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
-            rleDecompress(src, dest, width, height, depth);
-        }
-
-        if (true) {
-            // 32x32@8
-            int width = 32, height = 32, depth = 8, bpp = depth / 8;
-
-            ByteBuffer src =
-                new ByteBuffer(new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
-                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e, (byte)0x0e, (byte)0x44, (byte)0x0e,
-                    (byte)0x0e, (byte)0x0e, (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
-                    (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe4, (byte)0x04, (byte)0x06, (byte)0x8e, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c,
-                    (byte)0xb4, (byte)0xb5, (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4, (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0xe4, (byte)0x04,
-                    (byte)0x06, (byte)0x02, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66,
-                    (byte)0xb4, (byte)0xdc, (byte)0x68, (byte)0xe2, (byte)0x97, (byte)0xdd, (byte)0xb4, (byte)0xa7, (byte)0x16, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x0b, (byte)0xae, (byte)0xdc, (byte)0xe9, (byte)0x6a, (byte)0xdc, (byte)0x96, (byte)0xe9, (byte)0xe9, (byte)0xb4, (byte)0x0e, (byte)0x00,
-                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06,
-                    (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xd0, (byte)0x09, (byte)0x07, (byte)0xcf, (byte)0x03, (byte)0x95, (byte)0xdb,
-                    (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04,
-                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5, (byte)0x6c, (byte)0xdb, (byte)0x80, (byte)0xaf,
-                    (byte)0xd5, (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed,
-                    (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5, (byte)0xad, (byte)0xd4, (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb,
-                    (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5,
-                    (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x60, (byte)0xa7, (byte)0xb4,
-                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3, (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c, (byte)0xb6, (byte)0x07, (byte)0xb6,
-                    (byte)0x8c, (byte)0xb3, (byte)0xd4, (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4, (byte)0xad, (byte)0x66, (byte)0x00,
-                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad,
-                    (byte)0xad, (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07, (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad,
-                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7, (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04,
-                    (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
-                    (byte)0xb5, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x8b, (byte)0xa7,
-                    (byte)0xa7, (byte)0xc8, (byte)0xc8, (byte)0x60, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x66, (byte)0xc8, (byte)0xa7, (byte)0x66,
-                    (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x92, (byte)0xf1, (byte)0xf1, (byte)0xf1,
-                    (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0xc8, (byte)0x66,
-                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7,
-                    (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07,
-                    (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x6c,
-                    (byte)0x04, (byte)0xa7, (byte)0x60, (byte)0x6b, (byte)0x66, (byte)0x99, (byte)0xb6, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5,
-                    (byte)0xef, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60,
-                    (byte)0xa7, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0x6e, (byte)0xff, (byte)0x85, (byte)0xbd, (byte)0x66,
-                    (byte)0x66, (byte)0x66, (byte)0x60, (byte)0x05, (byte)0x87, (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xf4,
-                    (byte)0x70, (byte)0xff, (byte)0x84, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x05, (byte)0x85, (byte)0x0b, (byte)0xa7, (byte)0xb5,
-                    (byte)0xae, (byte)0x8c, (byte)0xd0, (byte)0x13, (byte)0xc1, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x8e, (byte)0x8c, (byte)0xae, (byte)0xb5,
-                    (byte)0xae, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xd0,
-                    (byte)0x0e, (byte)0x0c, (byte)0x01, (byte)0x00, (byte)0x90, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5,
-                    (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x68, (byte)0xae, (byte)0x82,
-                    (byte)0x8c, (byte)0x0a, (byte)0x05, (byte)0x8c, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5,
-                    (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x05, (byte)0x81, (byte)0xd0, (byte)0x06, (byte)0x9a, (byte)0x8c, (byte)0x0a, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a,
-                    (byte)0xb5, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b, (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x06,
-                    (byte)0x9b, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a, (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c, (byte)0xb5, (byte)0x0a,
-                    (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x05, (byte)0x80, (byte)0x7d, (byte)0xbc, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a, (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0,
-                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x1a, (byte)0xb5, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06,
-                    (byte)0x6e, (byte)0xb5, (byte)0x0a, (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5,
-                    (byte)0xf4, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x0a,
-                    (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a,
-                    (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc, (byte)0xf2, (byte)0x0a, (byte)0xb6, (byte)0xb6,
-                    (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6,
-                    (byte)0x0a, (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0x0a, (byte)0x6a, (byte)0xb6, (byte)0x96, (byte)0x0a,
-                    (byte)0x0a, (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
-                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2, (byte)0xd0, (byte)0x09, (byte)0xbc,
-                    (byte)0x87, (byte)0x03, (byte)0x80, (byte)0x2c, (byte)0xde, (byte)0xf4, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x6c,
-                    (byte)0x87, (byte)0x0a, (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2, (byte)0xf4, (byte)0xf4,
-                    (byte)0x0a, (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00,
-                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x6c, (byte)0x8c, (byte)0xb5,
-                    (byte)0xbc, (byte)0x0a, (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5, (byte)0x8c, (byte)0x6c, (byte)0x06, (byte)0xed, (byte)0x06,
-                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe6, (byte)0x04, (byte)0x06, (byte)0x86,
-                    (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c, (byte)0xe6, (byte)0x04, (byte)0x06, (byte)0x82, (byte)0x00, (byte)0x00
-
-                });
-
-            ByteBuffer flippedImage =
-                new ByteBuffer(new byte[] {(byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x6c, (byte)0x8c, (byte)0xb5, (byte)0xbc, (byte)0x0a,
-                    (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5, (byte)0x8c, (byte)0x6c, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x04, (byte)0x6c, (byte)0x87, (byte)0x0a, (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2,
-                    (byte)0xf4, (byte)0xf4, (byte)0x0a, (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2,
-                    (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xde, (byte)0xf4,
-                    (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6,
-                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc,
-                    (byte)0xf2, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5,
-                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb5,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6,
-                    (byte)0xb6, (byte)0x0a, (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06,
-                    (byte)0x6e, (byte)0xb5, (byte)0x0a, (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5,
-                    (byte)0xf4, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x0a,
-                    (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a, (byte)0xbc, (byte)0xb6,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2,
-                    (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x1a, (byte)0xb5, (byte)0x04, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c, (byte)0xb5, (byte)0x0a, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae,
-                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xbc, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae,
-                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b,
-                    (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5,
-                    (byte)0xb6, (byte)0x0a, (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5,
-                    (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a, (byte)0xb5, (byte)0x6c,
-                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae,
-                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2,
-                    (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae,
-                    (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xf3, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5,
-                    (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x0b, (byte)0xa7, (byte)0xb5, (byte)0xae, (byte)0x8c, (byte)0xa7,
-                    (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xbd, (byte)0xa7, (byte)0x8c, (byte)0xae, (byte)0xb5, (byte)0xae, (byte)0x66,
-                    (byte)0x00, (byte)0x00, (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60, (byte)0xa7,
-                    (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66,
-                    (byte)0x60, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0x04, (byte)0xa7, (byte)0x60, (byte)0x66, (byte)0x66,
-                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xb6, (byte)0xf5, (byte)0xf5,
-                    (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xef, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0xa7,
-                    (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07, (byte)0x66,
-                    (byte)0xa7, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x66,
-                    (byte)0xc8, (byte)0xa7, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x92,
-                    (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0x66,
-                    (byte)0x66, (byte)0xc8, (byte)0x66, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7, (byte)0xa7,
-                    (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb5, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xbd,
-                    (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0xc8, (byte)0xc8, (byte)0x60, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
-                    (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07, (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad,
-                    (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7, (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06,
-                    (byte)0x60, (byte)0xa7, (byte)0xb4, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3, (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c,
-                    (byte)0xb6, (byte)0x07, (byte)0xb6, (byte)0x8c, (byte)0xb3, (byte)0xd4, (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4,
-                    (byte)0xad, (byte)0x66, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5,
-                    (byte)0xad, (byte)0xd4, (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4,
-                    (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5, (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5, (byte)0xdb,
-                    (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xd5,
-                    (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb,
-                    (byte)0xdc, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c,
-                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x0b, (byte)0xae, (byte)0xdc, (byte)0xe9, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc,
-                    (byte)0xdc, (byte)0xdc, (byte)0xe9, (byte)0xe9, (byte)0xb4, (byte)0x0e, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66, (byte)0xb4,
-                    (byte)0xdc, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xdd, (byte)0xb4, (byte)0xa7,
-                    (byte)0x16, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c, (byte)0xb4, (byte)0xb5,
-                    (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4, (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06,
-                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e, (byte)0x0e, (byte)0x44, (byte)0x0e, (byte)0x0e, (byte)0x0e,
-                    (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00});
-            ByteBuffer dest = new AssertingByteBuffer(flipRawImage(flippedImage, width, height, bpp).data);
-
-            rleDecompress(src, dest, width, height, depth);
-
-        }
-
-        if (true) {
-            // 32x32@16
-            int width = 32, height = 32, depth = 16;
-
-            ByteBuffer src =
-                new ByteBuffer(new byte[] {(byte)0x85, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x06, (byte)0x8b, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x06, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0x16,
-                    (byte)0x69, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x69, (byte)0x99, (byte)0xd6, (byte)0x04, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03,
-                    (byte)0x6e, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x6e, (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71,
-                    (byte)0xff, (byte)0xff, (byte)0xce, (byte)0x18, (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66, (byte)0x29,
-                    (byte)0x02, (byte)0xcd, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x88, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
-                    (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xd8, (byte)0x99,
-                    (byte)0xd6, (byte)0x03, (byte)0xf8, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x66, (byte)0x99, (byte)0xd6,
-                    (byte)0x05, (byte)0x6a, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0xc4, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff,
-                    (byte)0xff, (byte)0x02, (byte)0x6e, (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71, (byte)0xff, (byte)0xff,
-                    (byte)0xce, (byte)0x18, (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66, (byte)0x29, (byte)0x02, (byte)0xcd,
-                    (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x00, (byte)0x04, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xc3, (byte)0x80, (byte)0x61, (byte)0x00,
-                    (byte)0xa5, (byte)0x80, (byte)0x40, (byte)0xec, (byte)0x52, (byte)0x00, (byte)0x5a, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x24, (byte)0x00,
-                    (byte)0x12, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x5a, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0xa5, (byte)0x80,
-                    (byte)0x52, (byte)0x00, (byte)0xc3, (byte)0x80, (byte)0x61, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcc, (byte)0x89,
-                    (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0xcb, (byte)0x18, (byte)0xc6, (byte)0x84, (byte)0x08, (byte)0x42,
-                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff,});
-
-            ByteBuffer dest =
-                new AssertingByteBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00,
-                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
-                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
-                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
-                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
-                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
-                    (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
-                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff,});
-
-            rleDecompress(src, dest, width, height, depth);
-
-        }
-    }
-}


[10/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/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/48c47101/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..94f8385
--- /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);
+        tags = new Tag[] {algorithm, parameters};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/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..ef0afc7
--- /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);
+        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/48c47101/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..2b8a26b
--- /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);
+        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/48c47101/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..c3e9137
--- /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);
+        tags = new Tag[] {algorithm, subjectPublicKey};
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/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..8142b04
--- /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);
+        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/48c47101/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..86257c7
--- /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);
+        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/48c47101/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..4922c07
--- /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);
+        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/48c47101/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..c5ba5d6
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/asn1/TSRequest.java
@@ -0,0 +1,201 @@
+// 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 streamer.ByteBuffer;
+import common.asn1.Asn1Integer;
+import common.asn1.OctetString;
+import common.asn1.Sequence;
+import common.asn1.Tag;
+
+/**
+ * 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);
+        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/48c47101/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..4e8fb36
--- /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);
+        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/48c47101/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..42e7c41
--- /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;
+


[19/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
deleted file mode 100644
index d757e8e..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientConfirmActivePDU.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.ScreenDescription;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240488.aspx
- */
-public class ClientConfirmActivePDU extends BaseElement {
-
-    public static final String SOURCE_DESC = "MSTSC";
-
-    public static final int CAPSTYPE_BITMAP = 0x2;
-
-    protected int numberCapabilities;
-
-    protected RdpState state;
-    protected ScreenDescription screen;
-
-    protected boolean desktopResize = false;
-    protected int prefferedBitsPerPixel = 16;
-
-    public ClientConfirmActivePDU(String id, ScreenDescription screen, RdpState state) {
-        super(id);
-        this.state = state;
-        this.screen = screen;
-    }
-
-    @Override
-    public void handleData(ByteBuffer aBuf, Link link) {
-
-        // Body
-        ByteBuffer buf = new ByteBuffer(1024, true);
-        numberCapabilities = 0;
-        writeCapabilities(buf);
-        buf.trimAtCursor();
-
-        // Header
-        ByteBuffer header = createMCSHeader(buf);
-
-        // Length of source descriptor, including NULL character (LE)
-        header.writeShortLE(SOURCE_DESC.length() + 1);
-
-        // Length of combined capabilities + 4 bytes (number of capabilities and
-        // padding) (LE)
-        header.writeShortLE(buf.length + 4);
-
-        header.writeString(SOURCE_DESC, RdpConstants.CHARSET_8);
-        header.writeByte(0);
-
-        // Number of capabilities
-        header.writeShortLE(numberCapabilities);
-
-        // Padding 2 bytes
-        header.writeShortLE(0);
-
-        header.trimAtCursor();
-
-        // Prepend header to capabilities
-        buf.prepend(header);
-
-        // Trim buffer to actual length of data written
-        buf.length = buf.cursor;
-
-        pushDataToPad(STDOUT, buf);
-
-        sendOtherRequredPackets();
-
-    }
-
-    private ByteBuffer createMCSHeader(ByteBuffer buf) {
-        ByteBuffer header = new ByteBuffer(100);
-        // MCS Send Data Request
-        header.writeByte(0x64);
-
-        // Initiator: 1004 (1001+3)
-        header.writeShort(3);
-
-        // Channel ID: 1003 (I/O channel)
-        header.writeShort(1003);
-
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        header.writeByte(0x70);
-
-        int length = buf.length + 26;
-
-        // User data length: (variable length field, LE)
-        header.writeVariableShort(length);
-
-        // Total length: (LE)
-        header.writeShortLE(length);
-
-        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
-        header.writeShortLE(0x13);
-
-        // PDU source: 1004 (LE)
-        header.writeShortLE(1004);
-
-        // Share ID, e.g. 0x000103ea (LE)
-        header.writeIntLE((int)state.serverShareId);
-
-        // Originator ID: 1002 (LE)
-        header.writeShortLE(1002);
-        return header;
-    }
-
-    private void sendOtherRequredPackets() {
-        // Send sequence in bulk
-
-        sendSynchronizePDU();
-        sendControlPDUActionCooperate();
-        sendControlPDUActionRequestControl();
-        // sendBitmapCachePersistentListPDU();
-        sendFontListPDU();
-    }
-
-    private void sendFontListPDU() {
-        {
-            int length = 1024; // Large enough
-            ByteBuffer buf = new ByteBuffer(length, true);
-
-            /* @formatter:off */
-      buf.writeBytes(new byte[] {
-          // MCS Send Data Request
-          (byte)0x64,
-          // Initiator: 1004 (1001+3)
-          (byte)0x00, (byte)0x03,
-          // Channel ID: 1003 (I/O channel)
-          (byte)0x03, (byte)0xeb,
-          // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-          (byte)0x70,
-          // User data length: 26 bytes (0x1a, variable length field)
-          (byte)0x80, (byte)0x1a,
-
-          // Total length: 26 bytes (0x1a, LE)
-          (byte)0x1a, (byte)0x00,
-          // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-          (byte)0x17, (byte)0x00,
-          // PDU source: 1004 (LE)
-          (byte)0xec, (byte)0x03,
-      });
-      // Share ID, 4 bytes  (LE)
-      buf.writeIntLE((int)state.serverShareId);
-
-      buf.writeBytes(new byte[] {
-          // Padding 1 byte
-          (byte)0x00,
-          // Stream ID: STREAM_LOW (1)
-          (byte)0x01,
-          // uncompressedLength : 12 bytes (LE)
-          (byte)0x0c, (byte)0x00,
-
-          // pduType2: PDUTYPE2_FONTLIST (39)
-          (byte)0x27,
-          // generalCompressedType: 0
-          (byte)0x00,
-          // generalCompressedLength: 0 (LE)
-          (byte)0x00, (byte)0x00,
-
-          // numberEntries (should be set to zero): 0 (LE)
-          (byte)0x00, (byte)0x00,
-          // totalNumEntries (should be set to zero): 0 (LE)
-          (byte)0x00, (byte)0x00,
-          // listFlags  (should be set to 0x3): 0x0003 (LE), FONTLIST_LAST(0x2) | FONTLIST_FIRST(0x1)
-          (byte)0x03, (byte)0x00,
-          // entrySize: 50 bytes (0x0032, LE)
-          (byte)0x32, (byte)0x00,
-      });
-      /* @formatter:on */
-
-            // Trim buffer to actual length of data written
-            buf.trimAtCursor();
-
-            pushDataToPad(STDOUT, buf);
-        }
-    }
-
-    private void sendControlPDUActionRequestControl() {
-        int length = 1024; // Large enough
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS Send Data Request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        // User data length: 26 bytes (0x1a, variable length field)
-        (byte)0x80, (byte)0x1a,
-
-        // Total length: 26 bytes (0x1a, LE)
-        (byte)0x1a, (byte)0x00,
-        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-        (byte)0x17, (byte)0x00,
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03,
-    });
-        // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-
-    buf.writeBytes(new byte[] {
-        // Padding 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01,
-        // uncompressedLength : 12 bytes (LE)
-        (byte)0x0c, (byte)0x00,
-        // pduType2: PDUTYPE2_CONTROL (20)
-        (byte)0x14,
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE)
-        (byte)0x00, (byte)0x00,
-
-        // action: CTRLACTION_REQUEST_CONTROL (1) (LE)
-        (byte)0x01, (byte)0x00,
-        // grantId: 0 (LE)
-        (byte)0x00, (byte)0x00,
-        // controlId: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    });
-    /* @formatter:on */
-
-        // Trim buffer to actual length of data written
-        buf.trimAtCursor();
-
-        pushDataToPad(STDOUT, buf);
-    }
-
-    private void sendControlPDUActionCooperate() {
-        int length = 1024; // Large enough
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS Send Data Request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        // User data length: 26 bytes (0x1a, variable length field)
-        (byte)0x80, (byte)0x1a,
-
-        // Total length: 26 bytes (0x1a, LE)
-        (byte)0x1a,(byte)0x00,
-        // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
-        (byte)0x17, (byte)0x00,
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03,
-    });
-    // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-
-    buf.writeBytes(new byte[] {
-        // Padding 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01,
-        // uncompressedLength : 12 bytes (LE)
-        (byte)0x0c, (byte)0x00,
-        // pduType2: PDUTYPE2_CONTROL (20)
-        (byte)0x14,
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        // action: CTRLACTION_COOPERATE (4) (LE)
-        (byte)0x04, (byte)0x00,
-        // grantId: 0 (LE)
-        (byte)0x00, (byte)0x00,
-        // controlId: 0
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    });
-    /* @formatter:on */
-
-        buf.trimAtCursor();
-
-        pushDataToPad(STDOUT, buf);
-    }
-
-    private void sendSynchronizePDU() {
-
-        ByteBuffer buf = new ByteBuffer(1024, true);
-        /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16,
-
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00,
-
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-    });
-    // Share ID, 4 bytes  (LE)
-    buf.writeIntLE((int)state.serverShareId);
-
-    buf.writeBytes(new byte[] {
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01,
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f,
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00,
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-    });
-    /* @formatter:on */
-        buf.trimAtCursor();
-        pushDataToPad(STDOUT, buf);
-    }
-
-    private void writeCapabilities(ByteBuffer buf) {
-        writeGeneralCS(buf);
-
-        writeBitmapCS(buf);
-
-        writeOrderCS(buf);
-
-        writeBitmapCache2CS(buf);
-
-        writeColorTableCacheCS(buf);
-
-        writeWindowActivationCS(buf);
-
-        writeControlCS(buf);
-
-        writePointerCS(buf);
-
-        writeShareCS(buf);
-
-        writeInputCS(buf);
-
-        writeBrushCS(buf);
-
-        writeSoundCS(buf);
-
-        writeFontCS(buf);
-
-        writeOffscreenBitmapCS(buf);
-
-        writeGlyphCacheCS(buf);
-    }
-
-    private void writeBrushCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Brush Capability Set (8 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240564.aspx
-            (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15,
-                                    // LE)
-            (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel:
-                                                            // BRUSH_DEFAULT
-                                                            // (0x0, LE)
-
-        });
-    }
-
-    private void writeInputCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Input Capability Set (88 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240563.aspx
-            (byte)0x0d,
-            (byte)0x00, // capability set type: CAPSTYPE_INPUT (13, LE)
-            (byte)0x58,
-            (byte)0x00, // length of capability set: 88 bytes (LE)
-            (byte)0x35,
-            (byte)0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2
-                        // (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX
-                        // (0x4), INPUT_FLAG_SCANCODES (0x1)
-            (byte)0x00,
-            (byte)0x00, // Padding 2 bytes
-            (byte)0x09,
-            (byte)0x04,
-            (byte)0x00,
-            (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00, // keyboardType: unknown (LE)
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00, // keyboardSubType: unknown (LE)
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00,
-            (byte)0x00, // keyboardFunctionKey: unknown (LE)
-            // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-
-        });
-    }
-
-    private void writeShareCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Share Capability Set (8 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240570.aspx
-            (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
-            (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-            (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
-
-        });
-    }
-
-    private void writePointerCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Pointer Capability Set (10 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240562.aspx
-            (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8,
-                                    // LE)
-            (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
-            (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
-            (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
-            (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
-
-        });
-    }
-
-    private void writeControlCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Control Capability Set (12 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240568.aspx
-            (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
-                                    // (7)
-            (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-            (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
-            (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0
-                                    // (LE)
-            (byte)0x02, (byte)0x00, // controlInterest (should be set to
-                                    // CONTROLPRIORITY_NEVER):
-                                    // CONTROLPRIORITY_NEVER (2) (LE)
-            (byte)0x02, (byte)0x00, // detachInterest (should be set to
-                                    // CONTROLPRIORITY_NEVER):
-                                    // CONTROLPRIORITY_NEVER (2) (LE)
-
-        });
-    }
-
-    private void writeWindowActivationCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Window Activation Capability Set (12 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240569.aspx
-            (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
-                                    // (7) (LE)
-            (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-            (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)):
-                                    // FALSE (0, LE)
-            (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE
-                                    // (0)): FALSE (0, LE)
-            (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE
-                                    // (0)): FALSE (0, LE)
-            (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to
-                                    // FALSE (0)): FALSE (0, LE)
-
-        });
-    }
-
-    private void writeColorTableCacheCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-
-            //
-            // Color Table Cache Capability Set (8 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc241564.aspx
-            (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE
-                                    // (10) (LE)
-            (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-            (byte)0x06, (byte)0x00, // Color table cache size (must be ignored
-                                    // during capability exchange and is assumed
-                                    // to be 0x0006): 6 (LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        });
-    }
-
-    private void writeBitmapCache2CS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Bitmap Cache Rev. 2 Capability Set (40 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240560.aspx
-            (byte)0x13, (byte)0x00, // capability set type:
-                                    // CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
-            (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
-            (byte)0x00, (byte)0x00, // Cache flags: 0 (LE)
-            (byte)0x00, // Padding 1 byte
-            (byte)0x00, // Number of cell caches: 0
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0
-                                                            // cell info: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1
-                                                            // cell info: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2
-                                                            // cell info: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3
-                                                            // cell info: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4
-                                                            // cell info: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-        });
-    }
-
-    private void writeGeneralCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            // Capabilities, see
-            // http://msdn.microsoft.com/en-us/library/cc240486.aspx
-
-            //
-            // General capability set (24 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240549.aspx
-            (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1)
-                                    // (LE)
-            (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
-            (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
-            (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
-            (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-            (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
-
-            // Extra flags: 0x040d (LE)
-            // FastPathOutput: (...............1) Advertiser supports fast-path
-            // output
-            // ShadowCompression: (..............0.) Advertiser NOT supports shadow
-            // compression
-            // LongLengthCredentials: (.............1..) Advertiser supports
-            // long-length credentials for the user name, password, or domain name
-            // SessionAutoreconnection: (............1...) Advertiser supports
-            // session auto-reconnection
-            // ImprovedEncryptionChecksum: (...........0....) Client and server NOT
-            // support improved encryption checksum
-            // Reserved1: (......00000.....)
-            // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is
-            // present for compressed bitmap data
-            // Reserved2: (00000...........)
-            (byte)0x0d, (byte)0x04,
-
-            (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
-            (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
-            (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
-            (byte)0x00, // refreshRectSupport: FALSE (0)
-            (byte)0x00, // suppressOutputSupport: FALSE (0)
-
-        });
-    }
-
-    private void writeBitmapCS(ByteBuffer buf) {
-        // Bitmap capability set (28 bytes), see
-        // http://msdn.microsoft.com/en-us/library/cc240554.aspx
-
-        numberCapabilities++;
-
-        // Capability set type: CAPSTYPE_BITMAP (2) (LE)
-        buf.writeShortLE(CAPSTYPE_BITMAP);
-
-        // Length of capability set: 28 bytes (LE)
-        buf.writeShortLE(28);
-
-        // preferredBitsPerPixel: 16 bpp (LE)
-        buf.writeShortLE(prefferedBitsPerPixel);
-
-        // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        buf.writeShortLE(1);
-
-        // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        buf.writeShortLE(1);
-
-        // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        buf.writeShortLE(1);
-
-        // Desktop width and height (LE)
-        buf.writeShortLE(screen.getFramebufferWidth());
-        buf.writeShortLE(screen.getFramebufferHeight());
-
-        // Padding 2 bytes
-        buf.writeShortLE(0);
-
-        // desktopResizeFlag (LE)
-        buf.writeShortLE((desktopResize) ? 1 : 0);
-
-        buf.writeBytes(new byte[] {(byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE
-                                                           // (0x1)): TRUE (0x1) (LE)
-            (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to
-                        // zero): 0
-            (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
-            (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        });
-    }
-
-    private void writeOrderCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Order Capability Set (88 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240556.aspx
-            (byte)0x03,
-            (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
-            (byte)0x58,
-            (byte)0x00, // length of capability set: 88 bytes (LE)
-            // terminalDescriptor = "" (16 bytes, UCS2)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA
-            (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
-            (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
-            (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
-            (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
-            (byte)0x00, (byte)0x00, // number of fonts (ignored): 0
-            (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE),
-                                    // SOLIDPATTERNBRUSHONLY (0x40),
-                                    // ZEROBOUNDSDELTASSUPPORT (0x8, MUST),
-                                    // NEGOTIATEORDERSUPPORT (0x2, MUST)
-            // Order support: 32 bytes (no primary drawing orders are supported, so
-            // this array MUST be initialized to all zeros, use 0x01 for TRUE).
-            (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
-            (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
-            (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
-            (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
-            (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
-            (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
-            (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE
-            (byte)0x00, // Unused: 0
-            (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
-            (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
-            (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
-            (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE
-            (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
-            (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
-            (byte)0x00, // Unused: 0
-            (byte)0x00, (byte)0x00, // Text flags (ignored): 0 (LE)
-            (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size
-                                                            // (ignored): 0
-                                                            // (assumed to be
-                                                            // 230400 bytes
-                                                            // (480*480,
-                                                            // 0x38400, LE))
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-            (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252, ANSI - Latin I
-                                    // (0x04e4, LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        });
-    }
-
-    private void writeSoundCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Sound Capability Set (8 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240552.aspx
-            (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12,
-                                    // LE)
-            (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags:
-                                                            // 0x0000 (LE) //
-                                                            // SOUND_FLAG_BEEPS
-                                                            // (0x1)
-
-        });
-    }
-
-    private void writeFontCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Font Capability Set (8 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240571.aspx
-            (byte)0x0e, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
-
-        });
-    }
-
-    private void writeOffscreenBitmapCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Offscreen Bitmap Cache Capability Set (12 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240550.aspx
-            (byte)0x11, (byte)0x00, // capability set type:
-                                    // CAPSTYPE_OFFSCREENCACHE (17, LE)
-            (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel:
-                                                            // FALSE (LE)
-            (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
-            (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
-
-        });
-    }
-
-    private void writeGlyphCacheCS(ByteBuffer buf) {
-        numberCapabilities++;
-        buf.writeBytes(new byte[] {
-            //
-            // Glyph Cache Capability Set (52 bytes), see
-            // http://msdn.microsoft.com/en-us/library/cc240565.aspx
-            (byte)0x10, (byte)0x00, // capability set type:
-                                    // CAPSTYPE_OFFSCREENCACHE (16, LE)
-            (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
-            // Glyph Cache (40 bytes)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-            (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-            (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
-            (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
-            (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
-            // FragCache
-            (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
-            (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
-            //
-            (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0,
-                                    // LE)
-            (byte)0x00, (byte)0x00, // Padding 2 bytes
-        });
-    }
-
-    /**
-     * 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[] {
-        // MCS Send Data Request
-        (byte)0x64,
-
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-
-        // Channel ID: 1003 (I/O channel)
-        (byte)0x03, (byte)0xeb,
-
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-
-        // User data length: 432 bytes (0x1b0, variable length field)
-        (byte)0x81, (byte)0xb0,
-
-        // Total length: 432 bytes (0x1b0, LE)
-        (byte)0xb0, (byte)0x01,
-
-        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x13, (byte)0x00,
-
-        // PDU source: 1004 (LE)
-        (byte)0xec, (byte)0x03,
-
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01, (byte)0x00,
-
-        // Originator ID: 1002 (LE)
-        (byte)0xea, (byte)0x03,
-
-        // Length of source descriptor: 6 bytes (including NULL character) (LE)
-        (byte)0x06, (byte)0x00,
-
-        // Length of combined capabilities: 410 bytes (LE)
-        (byte)0x9a, (byte)0x01,
-
-        // Source descriptor: "MSTSC" ???
-        (byte)0x4d, (byte)0x53, (byte)0x54, (byte)0x53, (byte)0x43, (byte)0x00,
-
-        // Number of capabilities: 15 (LE)
-        (byte)0x0f, (byte)0x00,
-
-        // Padding 2 bytes
-        (byte)0x00, (byte)0x00,
-
-        // Capabilities, see http://msdn.microsoft.com/en-us/library/cc240486.aspx
-
-        //
-        // General capability set (24 bytes), see http://msdn.microsoft.com/en-us/library/cc240549.aspx
-        (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) (LE)
-        (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
-        (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
-        (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
-        (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
-
-        // Extra flags: 0x040d (LE)
-//        FastPathOutput:             (...............1) Advertiser supports fast-path output
-//        ShadowCompression:          (..............0.) Advertiser NOT supports shadow compression
-//        LongLengthCredentials:      (.............1..) Advertiser supports long-length credentials for the user name, password, or domain name
-//        SessionAutoreconnection:    (............1...) Advertiser supports session auto-reconnection
-//        ImprovedEncryptionChecksum: (...........0....) Client and server NOT support improved encryption checksum
-//        Reserved1:                  (......00000.....)
-//        CompressedBitMapDataFlag:   (.....1..........) No 8-UINT8 header is present for compressed bitmap data
-//        Reserved2:                  (00000...........)
-        (byte)0x0d, (byte)0x04,
-
-        (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
-        (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
-        (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
-        (byte)0x00, // refreshRectSupport: FALSE (0)
-        (byte)0x00, // suppressOutputSupport: FALSE (0)
-
-        //
-        // Bitmap capability set (28 bytes), see http://msdn.microsoft.com/en-us/library/cc240554.aspx
-        (byte)0x02, (byte)0x00, // capability set type: CAPSTYPE_BITMAP (2) (LE)
-        (byte)0x1c, (byte)0x00, // length of capability set: 28 bytes (LE)
-        (byte)0x10, (byte)0x00, // preferredBitsPerPixel: 16 bpp (LE)
-        (byte)0x01, (byte)0x00, // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x01, (byte)0x00, // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x01, (byte)0x00, // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x00, (byte)0x04, // desktopWidth = 1024 pixels (LE)
-        (byte)0x00, (byte)0x03, // desktopHeight = 768 pixels (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x00, (byte)0x00, // desktopResizeFlag: FALSE (0x0) (LE)
-        (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE (0x1)): TRUE (0x1) (LE)
-        (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to zero): 0
-        (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
-        (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        //
-        // Order Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240556.aspx
-        (byte)0x03, (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
-        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
-        // terminalDescriptor = "" (16 bytes, UCS2)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA
-        (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
-        (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
-        (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
-        (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
-        (byte)0x00, (byte)0x00, // number of fonts (ignored): 0
-        (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), SOLIDPATTERNBRUSHONLY (0x40), ZEROBOUNDSDELTASSUPPORT (0x8, MUST), NEGOTIATEORDERSUPPORT (0x2, MUST)
-        // Order support: 32 bytes (no primary drawing orders are supported, so this array MUST be initialized to all zeros, use 0x01 for TRUE).
-        (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
-        (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
-        (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
-        (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
-        (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
-        (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
-        (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE
-        (byte)0x00, // Unused: 0
-        (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
-        (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
-        (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
-        (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE
-        (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
-        (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
-        (byte)0x00, // Unused: 0
-        (byte)0x00, (byte)0x00, // Text flags (ignored): 0  (LE)
-        (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size (ignored): 0 (assumed to be 230400 bytes (480*480, 0x38400, LE))
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252,  ANSI - Latin I (0x04e4, LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        //
-        // Bitmap Cache Rev. 2 Capability Set (40 bytes), see http://msdn.microsoft.com/en-us/library/cc240560.aspx
-        (byte)0x13, (byte)0x00, // capability set type: CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
-        (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
-        (byte)0x00, (byte)0x00, // Cache flags: 0 (LE)
-        (byte)0x00, // Padding 1 byte
-        (byte)0x00, // Number of cell caches: 0
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 cell info: 0 (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
-
-        //
-        // Color Table Cache Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc241564.aspx
-        (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE (10) (LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x06, (byte)0x00, // Color table cache size (must be ignored during capability exchange and is assumed to be 0x0006): 6 (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-
-        //
-        // Window Activation Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240569.aspx
-        (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) (LE)
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-        (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
-
-        //
-        // Control Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240568.aspx
-        (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7)
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
-        (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 (LE)
-        (byte)0x02, (byte)0x00, // controlInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
-        (byte)0x02, (byte)0x00, // detachInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
-
-        //
-        // Pointer Capability Set (10 bytes), see http://msdn.microsoft.com/en-us/library/cc240562.aspx
-        (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, LE)
-        (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
-        (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
-        (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
-        (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
-
-        //
-        // Share Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240570.aspx
-        (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
-
-        //
-        // Input Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240563.aspx
-        (byte)0x0d, (byte)0x00, // capability set type:  CAPSTYPE_INPUT (13, LE)
-        (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
-        (byte)0x35, (byte)0x00, // inputFlags: 0x0035  (LE),  INPUT_FLAG_FASTPATH_INPUT2 (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX (0x4), INPUT_FLAG_SCANCODES (0x1)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-        (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardType: unknown (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardSubType: unknown (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardFunctionKey: unknown (LE)
-        // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-
-        //
-        // Brush Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240564.aspx
-        (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: BRUSH_DEFAULT (0x0, LE)
-
-        //
-        // Sound Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240552.aspx
-        (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, LE)
-        (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: 0x0000 (LE) // SOUND_FLAG_BEEPS (0x1)
-
-        //
-        // Font Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240571.aspx
-        (byte)0x0e, (byte)0x00,
-        (byte)0x08, (byte)0x00,
-        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
-
-        //
-        // Offscreen Bitmap Cache Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240550.aspx
-        (byte)0x11, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (17, LE)
-        (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: FALSE (LE)
-        (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
-        (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
-
-        //
-        // Glyph Cache Capability Set (52 bytes), see http://msdn.microsoft.com/en-us/library/cc240565.aspx
-        (byte)0x10, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (16, LE)
-        (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
-        // Glyph Cache (40 bytes)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
-        (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
-        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
-        (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
-        (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
-        // FragCache
-        (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
-        (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
-        //
-        (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, LE)
-        (byte)0x00, (byte)0x00, // Padding 2 bytes
-    };
-    /* @formatter:on */
-
-        RdpState rdpState = new RdpState();
-        ScreenDescription screenDescription = new ScreenDescription();
-        screenDescription.setFramebufferSize(1024, 768);
-
-        rdpState.serverShareId = 0x000103ea;
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}));
-        Element confirm_active = new ClientConfirmActivePDU("confirm_active", screenDescription, rdpState);
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, confirm_active, sink);
-        pipeline.link("source", "confirm_active", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
deleted file mode 100644
index 39dc81a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientFastPathPDU.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240589.aspx
- */
-public class ClientFastPathPDU extends BaseElement {
-
-    public ClientFastPathPDU(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        if (buf.length > 32767 - 3)
-            throw new RuntimeException("Packet is too long: " + buf + ".");
-
-        ByteBuffer data = new ByteBuffer(6);
-
-        // FastPath, 1 event, no checksum, not encrypted
-        data.writeByte(0x4);
-
-        // Length of full packet, including length field, in network order.
-        // Topmost bit of first byte indicates that field has 2 bytes
-        data.writeShort((1 + 2 + buf.length) | 0x8000);
-        data.trimAtCursor();
-
-        buf.prepend(data);
-
-        pushDataToAllOuts(buf);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
deleted file mode 100644
index 1269284..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientInfoPDU.java
+++ /dev/null
@@ -1,455 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240475.aspx
- */
-public class ClientInfoPDU extends OneTimeSwitch {
-
-    public static final int INFO_MOUSE = 0x1;
-    public static final int INFO_DISABLECTRLALTDEL = 0x2;
-    public static final int INFO_UNICODE = 0x10;
-
-    public static final int INFO_MAXIMIZESHELL = 0x20;
-    public static final int INFO_LOGONNOTIFY = 0x40;
-    public static final int INFO_ENABLEWINDOWSKEY = 0x100;
-    public static final int INFO_MOUSE_HAS_WHEEL = 0x00020000;
-    public static final int INFO_NOAUDIOPLAYBACK = 0x00080000;
-
-    public static final int PERF_DISABLE_WALLPAPER = 0x1;
-    public static final int PERF_DISABLE_FULLWINDOWDRAG = 0x2;
-    public static final int PERF_DISABLE_MENUANIMATIONS = 0x4;
-
-    protected byte[] userName = "".getBytes(RdpConstants.CHARSET_16);
-    protected byte[] password = "".getBytes(RdpConstants.CHARSET_16); // No effect
-    protected byte[] alternateShell = "".getBytes(RdpConstants.CHARSET_16);
-    protected byte[] domain = "".getBytes(RdpConstants.CHARSET_16);
-    protected byte[] workingDir = "".getBytes(RdpConstants.CHARSET_16);
-    protected byte[] clientAddress = "192.168.0.100".getBytes(RdpConstants.CHARSET_16);
-    protected byte[] clientDir = "C:\\Windows\\System32\\mstscax.dll".getBytes(RdpConstants.CHARSET_16);
-
-    protected String standardTimeZoneName = "EET, Standard Time";
-    protected String daylightTimeZoneName = "EET, Summer Time";
-    protected int standardTimeZoneBias = 0; /* in minutes */
-    protected int daylightTimeZoneBias = 60; /* in minutes */
-
-    public ClientInfoPDU(String id, String userName) {
-        super(id);
-        this.userName = userName.getBytes(RdpConstants.CHARSET_16);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        // Length of packet
-        ByteBuffer buf = new ByteBuffer(1024, true);
-
-        // MCS Send Data Request PDU
-        buf.writeByte(0x64);
-
-        // Initiator: 0x03 + 1001 = 1004
-        buf.writeShort(3);
-
-        // Channel ID: 1003
-        buf.writeShort(1003);
-
-        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
-        buf.writeByte(0x70);
-
-        // User data length: (variable length field)
-        int length = 224 + userName.length + password.length + alternateShell.length + domain.length + workingDir.length + clientAddress.length + clientDir.length;
-        buf.writeShort(length | 0x8000);
-
-        // Flags: SEC_INFO_PKT (0x4000)
-        buf.writeShort(0x4000);
-
-        // TS_SECURITY_HEADER::flagsHi - ignored
-        buf.writeShort(0x0000);
-
-        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)
-        buf.writeIntLE(0x0000);
-
-        // Flags
-        buf.writeIntLE(INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE | INFO_MAXIMIZESHELL | INFO_LOGONNOTIFY | INFO_ENABLEWINDOWSKEY | INFO_MOUSE_HAS_WHEEL |
-            INFO_NOAUDIOPLAYBACK);
-
-        //
-        // Lengths
-        //
-
-        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        buf.writeShortLE(domain.length);
-
-        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
-        buf.writeShortLE(userName.length);
-
-        // cbPassword length: (LE) (NOT including size of mandatory NULL terminator)
-        buf.writeShortLE(password.length);
-
-        // cbAlternateShell:  (LE) (NOT including size of mandatory NULL terminator)
-        buf.writeShortLE(alternateShell.length);
-
-        // cbWorkingDir: (LE) (NOT including size of mandatory NULL terminator)
-        buf.writeShortLE(workingDir.length);
-
-        //
-        // Values
-        //
-
-        // Domain: (UCS2), see cbDomain
-        buf.writeBytes(domain);
-        buf.writeShort(0);
-
-        // User name: (UCS2), see cbUserName
-        buf.writeBytes(userName);
-        buf.writeShort(0);
-
-        // Password: (UCS2), see cbPassword
-        buf.writeBytes(password);
-        buf.writeShort(0);
-
-        // Alternate shell: (UCS2), see cbAlternateShell
-        buf.writeBytes(alternateShell);
-        buf.writeShort(0);
-
-        // Working directory: (UCS2), see cbWorkingDir
-        buf.writeBytes(workingDir);
-        buf.writeShort(0);
-
-        // Client address family: 2 (AF_INET, LE)
-        buf.writeShortLE(2);
-
-        // cbClientAddress: ( LE) (including the size of the mandatory NULL terminator)
-        buf.writeShortLE(clientAddress.length + 2);
-
-        // Client address: (UCS2)
-        buf.writeBytes(clientAddress);
-        buf.writeShort(0);
-
-        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
-        buf.writeShortLE(clientDir.length + 2);
-
-        // Client directory: (UCS2)
-        buf.writeBytes(clientDir);
-        buf.writeShort(0);
-
-        //
-        // Client time zone:
-        //
-
-        // Bias: 0 minutes (LE)
-        buf.writeIntLE(0);
-
-        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
-        buf.writeFixedString(62, standardTimeZoneName, RdpConstants.CHARSET_16);
-        buf.writeShort(0);
-
-        // Standard date
-        buf.writeBytes(new byte[] {
-            // wYear: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMonth: unknown (LE)
-            (byte)0x00, (byte)0x00,
-            // wDayOfWeek: Sunday (LE)
-            (byte)0x00, (byte)0x00,
-            // wDay: unknown (LE)
-            (byte)0x00, (byte)0x00,
-            // wHour: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMinute: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wSecond: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMilliseconds: 0
-            (byte)0x00, (byte)0x00,
-
-        });
-
-        // StandardBias: 0 minutes (LE)
-        buf.writeIntLE(standardTimeZoneBias);
-
-        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
-        buf.writeFixedString(62, daylightTimeZoneName, RdpConstants.CHARSET_16);
-        buf.writeShort(0);
-
-        // Daylight date
-        buf.writeBytes(new byte[] {
-            // wYear: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMonth: unknown (LE)
-            (byte)0x00, (byte)0x00,
-            // wDayOfWeek: Sunday (LE)
-            (byte)0x00, (byte)0x00,
-            // wDay: unknown (LE)
-            (byte)0x00, (byte)0x00,
-            // wHour: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMinute: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wSecond: 0 (LE)
-            (byte)0x00, (byte)0x00,
-            // wMilliseconds: 0
-            (byte)0x00, (byte)0x00,
-
-        });
-
-        // Daylight bias: 60 minutes (LE)
-        buf.writeIntLE(daylightTimeZoneBias);
-
-        // Client session ID: 0x00000000 (LE)
-        buf.writeIntLE(0);
-
-        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
-        buf.writeIntLE(PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS);
-
-        // cbAutoReconnectCookie: 0 bytes (LE)
-        buf.writeShortLE(0);
-
-        // Trim buffer to actual length of data written
-        buf.length = buf.cursor;
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * 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[] {
-
-        // TPKT
-        (byte) 0x03, (byte) 0x00,
-
-        // TPKT length: 343 bytes
-        (byte) 0x01, (byte) 0x57,
-
-        // X224 Data PDU
-        (byte) 0x02, (byte) 0xf0, (byte) 0x80,
-
-
-        // MCS Send Data Request PDU
-        (byte) 0x64,
-
-        // Initiator: 0x03 + 1001 = 1004
-        (byte) 0x00, (byte) 0x03,
-
-        // Channel ID: 1003 (IO Channel)
-        (byte) 0x03, (byte) 0xeb,
-
-        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
-        (byte) 0x70,
-
-        // User data length: 328  (0x148) bytes, variable length field
-        (byte) 0x81, (byte) 0x48,
-
-        // Flags: SEC_INFO_PKT (0x4000)
-        (byte) 0x40, (byte) 0x00,
-
-        // TS_SECURITY_HEADER::flagsHi - ignored
-        (byte) 0x00, (byte) 0x00,
-
-        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // Flags: 0xa0173 (LE), INFO_MOUSE (0x1), INFO_DISABLECTRLALTDEL (0x2), INFO_UNICODE (0x10),
-        // INFO_MAXIMIZESHELL (0x20), INFO_LOGONNOTIFY (0x40), INFO_ENABLEWINDOWSKEY (0x100),
-        // INFO_MOUSE_HAS_WHEEL (0x00020000), INFO_NOAUDIOPLAYBACK (0x00080000),
-        (byte) 0x73, (byte) 0x01, (byte) 0x0a, (byte) 0x00,
-
-        // Lengths
-
-        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-
-        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x10, (byte) 0x00,
-
-        // cbPassword length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-
-        // cbAlternateShell:  0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-
-        // cbWorkingDir: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
-        (byte) 0x00, (byte) 0x00,
-
-        // Values
-
-        // Domain: "" (UCS2), see cbDomain
-        (byte) 0x00, (byte) 0x00,
-
-        // User name: "vlisivka" (UCS2), see cbUserName
-        (byte) 0x76, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x73, (byte) 0x00,
-        (byte) 0x69, (byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x6b, (byte) 0x00, (byte) 0x61, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00,
-
-        // Password: "" (UCS2), see cbPassword
-        (byte) 0x00, (byte) 0x00,
-
-        // Alternate shell: "" (UCS2), see cbAlternateShell
-        (byte) 0x00, (byte) 0x00,
-
-        // Working directory: "" (UCS2), see cbWorkingDir
-        (byte) 0x00, (byte) 0x00,
-
-        // Client address family: 2 (AF_INET, LE)
-        (byte) 0x02, (byte) 0x00,
-
-        // cbClientAddress = 28 bytes (0x1c, LE) (including the size of the mandatory NULL terminator)
-        (byte) 0x1c, (byte) 0x00,
-
-        // Client address: "192.168.0.100" (UCS2)
-        (byte) 0x31, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
-        (byte) 0x31, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
-        (byte) 0x30, (byte) 0x00, (byte) 0x2e, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x30, (byte) 0x00,
-        (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
-        (byte) 0x40, (byte) 0x00,
-
-        // Client directory: "C:\Windows\System32\mstscax.dll" (UCS2)
-        (byte) 0x43, (byte) 0x00, (byte) 0x3a, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x57, (byte) 0x00,
-        (byte) 0x69, (byte) 0x00, (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x6f, (byte) 0x00,
-        (byte) 0x77, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x53, (byte) 0x00,
-        (byte) 0x79, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x65, (byte) 0x00,
-        (byte) 0x6d, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x5c, (byte) 0x00,
-        (byte) 0x6d, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x73, (byte) 0x00,
-        (byte) 0x63, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x78, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
-        (byte) 0x64, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        //
-        // Client time zone:
-
-        // Bias: 0 minutes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
-        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00,
-        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x61, (byte) 0x00,
-        (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x72, (byte) 0x00,
-        (byte) 0x64, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00,
-        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        //
-        // Standard date
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-
-        // StandardBias: 0 minutes (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
-        (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00,
-        (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x75, (byte) 0x00, (byte) 0x6d, (byte) 0x00,
-        (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x72, (byte) 0x00, (byte) 0x20, (byte) 0x00,
-        (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // Daylight date
-        // wYear: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMonth: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDayOfWeek: Sunday (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wDay: unknown (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wHour: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMinute: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wSecond: 0 (LE)
-        (byte) 0x00, (byte) 0x00,
-        // wMilliseconds: 0
-        (byte) 0x00, (byte) 0x00,
-
-        // Daylight bias: 60 minutes (LE)
-        (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-
-        // Client session ID: 0x00000000 (LE)
-        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
-        (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-
-        // cbAutoReconnectCookie: 0 bytes (LE)
-        (byte) 0x00, (byte) 0x00,
-    };
-    /* @formatter:on */
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element todo = new ClientInfoPDU("client_info", "vlisivka");
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "client_info", "mainSink");
-        pipeline.link("client_info >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
deleted file mode 100644
index 55ca08a..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSAttachUserRequest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240684.aspx
- */
-public class ClientMCSAttachUserRequest extends OneTimeSwitch {
-
-    public ClientMCSAttachUserRequest(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        int length = 1;
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        buf.writeByte(0x28); // AttachUserRequest
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * 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[] {
-
-        0x03, 0x00, 0x00, 0x08,  //  TPKT Header (length = 8 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x28,
-
-        // 0x28:
-        // 0 - --\
-        // 0 -   |
-        // 1 -   | CHOICE: From DomainMCSPDU select attachUserRequest (10)
-        // 0 -   | of type AttachUserRequest
-        // 1 -   |
-        // 0 - --/
-        // 0 - padding
-        // 0 - padding
-
-    };
-    /* @formatter:on */
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element todo = new ClientMCSAttachUserRequest("TODO");
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "TODO", "mainSink");
-        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
deleted file mode 100644
index 6e06af4..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
+++ /dev/null
@@ -1,222 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * The MCS Channel Join Request PDUs are sent sequentially. The first PDU is
- * sent after receiving the MCS Attach User Confirm PDU and subsequent PDUs are
- * sent after receiving the MCS Channel Join Confirm PDU for the previous
- * request. Sending of the MCS Channel Join Request PDUs MUST continue until all
- * channels have been successfully joined.
- *
- * @see http://msdn.microsoft.com/en-us/library/cc240686.aspx
- */
-public class ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs extends OneTimeSwitch {
-
-    private static final int MCS_CHANNEL_CONFIRM_PDU = 15;
-
-    protected int[] channels;
-    protected int channelRequestsSent = 0;
-
-    protected RdpState state;
-
-    public ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs(String id, int[] channels, RdpState state) {
-        super(id);
-        this.channels = channels;
-        this.state = state;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        // Parse channel confirm response
-        int typeAndFlags = buf.readUnsignedByte();
-        int type = typeAndFlags >> 2;
-        // int flags = typeAndFlags & 0x3;
-
-        if (type != MCS_CHANNEL_CONFIRM_PDU)
-            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 15, actual value: " + type + ", data: " + buf +
-                ".");
-
-        int rtSuccess = buf.readUnsignedByte() >> 4;
-        if (rtSuccess != 0)
-            throw new RuntimeException("[" + this + "] ERROR: Cannot connect to channel: request failed. Error code: " + rtSuccess + ", channel ID: " +
-                channels[channelRequestsSent - 1] + ", data: " + buf + ".");
-
-        // Initiator and requested fields MAY be ignored, however, the channelId
-        // field MUST be examined. If the value of the channelId field does not
-        // correspond with the value of the channelId field sent in the previous MCS
-        // Channel Join Request PDU the connection SHOULD be dropped.
-
-        // Initiator: 1007 (6+1001)
-        // int initator=buf.readUnsignedShort();
-        buf.skipBytes(2);
-
-        // Requested channel
-        // int requestedChannel=buf.readUnsignedShort();
-        buf.skipBytes(2);
-
-        // Actual channel
-        int actualChannel = buf.readUnsignedShort();
-        if (actualChannel != channels[channelRequestsSent - 1])
-            throw new RuntimeException("Unexpeceted channeld ID returned. Expected channeld ID: " + channels[channelRequestsSent - 1] + ", actual channel ID: " +
-                actualChannel + ", data: " + buf + ".");
-
-        state.channelJoined(actualChannel);
-
-        buf.unref();
-
-        if (channelRequestsSent < channels.length)
-            sendChannelRequest(channels[channelRequestsSent++]);
-        else
-            switchOff();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        sendChannelRequest(channels[channelRequestsSent++]);
-
-        // Switch off after receiving response(s)
-    }
-
-    private void sendChannelRequest(int channel) {
-        ByteBuffer buf = new ByteBuffer(5, true);
-
-        buf.writeByte(0x38); // Channel Join request
-
-        buf.writeShort(0x03); // ChannelJoinRequest::initiator: 1004
-        buf.writeShort(channel);
-
-        pushDataToOTOut(buf);
-    }
-
-    /**
-     * Example.
-     *
-     * @see http://msdn.microsoft.com/en-us/library/cc240834.aspx
-     */
-    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[] clientRequestPacket = new byte[] {
-        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x38, 0x00, 0x03, 0x03, (byte) 0xef,
-
-         // 0x38:
-         // 0 - --\
-         // 0 -   |
-         // 1 -   | CHOICE: From DomainMCSPDU select channelJoinRequest (14)
-         // 1 -   | of type ChannelJoinRequest
-         // 1 -   |
-         // 0 - --/
-         // 0 - padding
-         // 0 - padding
-
-         // 0x00:
-         // 0 - --\
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         //       | ChannelJoinRequest::initiator = 0x03 + 1001 = 1004
-         // 0x03: |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 1 -   |
-         // 1 -   |
-         // 0 - --/
-
-         // 0x03:
-         // 0 - --\
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 0 -   |
-         // 1 -   |
-         // 1 -   |
-         //       | ChannelJoinRequest::channelId = 0x03ef = 1007
-         // 0xef: |
-         // 1 -   |
-         // 1 -   |
-         // 1 -   |
-         // 0 -   |
-         // 1 -   |
-         // 1 -   |
-         // 1 -   |
-         // 1 - --/
-    };
-
-    byte[] serverResponsePacket = new byte[] {
-        // MCS Channel Confirm
-    (byte)0x3e,
-
-    // result: rt-successful (0)
-    (byte)0x00,
-
-    // Initiator: 1007 (6+1001)
-    (byte)0x00, (byte)0x06,
-
-    // Requested channel
-    (byte)0x03, (byte)0xef,
-
-    // Actual channel
-    (byte)0x03, (byte)0xef,
-    };
-    /* @formatter:on */
-
-        RdpState rdpState = new RdpState();
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverResponsePacket, new byte[] {1, 2, 3}));
-        Element todo = new ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs("channels", new int[] {1007}, rdpState);
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientRequestPacket));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "channels", "mainSink");
-        pipeline.link("channels >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}


[06/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
new file mode 100755
index 0000000..6accc16
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerBitmapUpdate.java
@@ -0,0 +1,199 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import common.BitmapOrder;
+import common.BitmapRectangle;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240624.aspx
+ */
+public class ServerBitmapUpdate extends BaseElement {
+    public static final int UPDATETYPE_BITMAP = 0x0001;
+
+    /**
+     * Indicates that the bitmap data is compressed. The bitmapComprHdr field MUST
+     * be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not set.
+     */
+    public static final int BITMAP_COMPRESSION = 0x0001;
+
+    /**
+     * Indicates that the bitmapComprHdr field is not present (removed for
+     * bandwidth efficiency to save 8 bytes).
+     */
+    private static final int NO_BITMAP_COMPRESSION_HDR = 0x0400;
+
+    public ServerBitmapUpdate(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // * DEBUG */System.out.println(buf.toHexString(buf.length));
+
+        BitmapOrder order = new BitmapOrder();
+
+        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
+        // be set to UPDATETYPE_BITMAP (0x0001).
+        int updateType = buf.readSignedShortLE();
+        if (updateType != UPDATETYPE_BITMAP)
+            throw new RuntimeException("Unknown update type. Expected update type: UPDATETYPE_BITMAP (0x1). Actual update type: " + updateType + ", buf: " + buf
+                    + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The number of screen rectangles
+        // present in the rectangles field.
+        int numberRectangles = buf.readSignedShortLE();
+
+        // (variable): Variable-length array of TS_BITMAP_DATA structures, each of
+        // which contains a rectangular clipping taken from the server-side screen
+        // frame buffer. The number of screen clippings in the array is specified by
+        // the numberRectangles field.
+        BitmapRectangle[] rectangles = new BitmapRectangle[numberRectangles];
+        for (int i = 0; i < numberRectangles; i++) {
+            rectangles[i] = readRectangle(buf);
+        }
+        order.rectangles = rectangles;
+
+        buf.assertThatBufferIsFullyRead();
+
+        ByteBuffer data = new ByteBuffer(order);
+        pushDataToAllOuts(data);
+
+        buf.unref();
+    }
+
+    public BitmapRectangle readRectangle(ByteBuffer buf) {
+
+        BitmapRectangle rectangle = new BitmapRectangle();
+
+        // (2 bytes): A 16-bit, unsigned integer. Left bound of the rectangle.
+        rectangle.x = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. Top bound of the rectangle.
+        rectangle.y = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. Inclusive right bound of the
+        // rectangle.
+        int destRight = buf.readSignedShortLE();
+        rectangle.width = destRight - rectangle.x + 1;
+
+        // (2 bytes): A 16-bit, unsigned integer. Inclusive bottom bound of the
+        // rectangle.
+        int destBottom = buf.readSignedShortLE();
+        rectangle.height = destBottom - rectangle.y + 1;
+
+        // (2 bytes): A 16-bit, unsigned integer. The width of the rectangle.
+        rectangle.bufferWidth = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The height of the rectangle.
+        rectangle.bufferHeight = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The color depth of the rectangle
+        // data in bits-per-pixel.
+        rectangle.colorDepth = buf.readSignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The flags describing the format of
+        // the bitmap data in the bitmapDataStream field.
+        int flags = buf.readSignedShortLE();
+
+        // BITMAP_COMPRESSION 0x0001
+        // Indicates that the bitmap data is compressed. The bitmapComprHdr field
+        // MUST be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not
+        // set.
+        boolean compressed = ((flags & BITMAP_COMPRESSION) > 0);
+
+        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the data in
+        // the bitmapComprHdr and bitmapDataStream fields.
+        int bitmapLength = buf.readSignedShortLE();
+
+        // NO_BITMAP_COMPRESSION_HDR 0x0400
+        // Indicates that the bitmapComprHdr field is not present (removed for
+        // bandwidth efficiency to save 8 bytes).
+        if (compressed && (flags & NO_BITMAP_COMPRESSION_HDR) == 0) {
+            // (8 bytes): Optional Compressed Data Header structure specifying the
+            // bitmap data in the bitmapDataStream.
+            // This field MUST be present if the BITMAP_COMPRESSION (0x0001) flag is
+            // present in the Flags field, but the NO_BITMAP_COMPRESSION_HDR (0x0400)
+            // flag is not.
+
+            // Note: Even when compression header is enabled, server sends nothing.
+            // rectangle.compressedBitmapHeader = buf.readBytes(8);
+        }
+
+        // (variable): A variable-length array of bytes describing a bitmap image.
+        // Bitmap data is either compressed or uncompressed, depending on whether
+        // the BITMAP_COMPRESSION flag is present in the Flags field. Uncompressed
+        // bitmap data is formatted as a bottom-up, left-to-right series of pixels.
+        // Each pixel is a whole number of bytes. Each row contains a multiple of
+        // four bytes (including up to three bytes of padding, as necessary).
+        // Compressed bitmaps not in 32 bpp format are compressed using Interleaved
+        // RLE and encapsulated in an RLE Compressed Bitmap Stream structure,
+        // while compressed bitmaps at a color depth of 32 bpp are compressed
+        // using RDP 6.0 Bitmap Compression and stored inside
+        // an RDP 6.0 Bitmap Compressed Stream structure.
+        if (!compressed) {
+            rectangle.bitmapDataStream = buf.readBytes(bitmapLength);
+        } else {
+            ByteBuffer compressedImage = buf.readBytes(bitmapLength);
+            //* DEBUG */System.out.println("Compressed image: " + compressedImage + ", depth: " + rectangle.bitsPerPixel + ".");
+            rectangle.bitmapDataStream = RLEBitmapDecompression.rleDecompress(compressedImage, rectangle.bufferWidth, rectangle.bufferHeight, rectangle.colorDepth);
+            compressedImage.unref();
+        }
+
+        return rectangle;
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        ByteBuffer packet = new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
+                0x01, 0x04, 0x0a, 0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+        Element bitmap = new ServerBitmapUpdate("bitmap") {
+            {
+                verbose = true;
+            }
+        };
+        FakeSink fakeSink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+        Pipeline pipeline = new PipelineImpl("test");
+
+        // BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
+        // Element adapter = new AwtRdpAdapter("test",canvas );
+        // pipeline.addAndLink(bitmap, adapter);
+        pipeline.addAndLink(bitmap, fakeSink);
+
+        bitmap.handleData(packet, null);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
new file mode 100755
index 0000000..2a9d49d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUCooperate.java
@@ -0,0 +1,117 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerControlPDUCooperate extends OneTimeSwitch {
+
+    public ServerControlPDUCooperate(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/* @formatter:off */
+/*
+03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 9A 02 1A 00 14 00 00 00 04 00 00 00 00 00 00 00
+
+
+  Frame: Number = 38, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 40
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 40 (0x28)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 26
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 26
+    RDP: RDPBCGR
+- RDPBCGR: TsControlPDU
+  - SlowPathPacket: TsControlPDU
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 26 (0x1A)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_CONTROL
+        ShareID: 66538 (0x103EA)
+        Pad1: 154 (0x9A)
+        StreamID: TS_STREAM_MED
+        UncompressedLength: 26 (0x1A)
+        PDUType2: TS_PDUTYPE2_CONTROL
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsControlPDU: Action = Cooperate
+        Action: Cooperate
+        GrantID: 0 (0x0)
+        ControlID: 0 (0x0)
+
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
new file mode 100755
index 0000000..974d622
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerControlPDUGrantedControl.java
@@ -0,0 +1,114 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerControlPDUGrantedControl extends OneTimeSwitch {
+
+    public ServerControlPDUGrantedControl(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+/* @formatter:off */
+/*
+03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 50 02 1A 00 14 00 00 00 02 00 EC 03 EA 03 00 00
+
+  Frame: Number = 45, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 40
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 40 (0x28)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 26
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 26
+    RDP: RDPBCGR
+- RDPBCGR: TsControlPDU
+  - SlowPathPacket: TsControlPDU
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 26 (0x1A)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_CONTROL
+        ShareID: 66538 (0x103EA)
+        Pad1: 80 (0x50)
+        StreamID: TS_STREAM_MED
+        UncompressedLength: 26 (0x1A)
+        PDUType2: TS_PDUTYPE2_CONTROL
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsControlPDU: Action = Granted Control
+        Action: Granted Control
+        GrantID: 1004 (0x3EC)
+        ControlID: 1002 (0x3EA)
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
new file mode 100755
index 0000000..88ede17a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerDemandActivePDU.java
@@ -0,0 +1,660 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Order;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSource;
+import common.ScreenDescription;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240669.aspx
+ * @see http://msdn.microsoft.com/en-us/library/cc240484.aspx
+ */
+public class ServerDemandActivePDU extends BaseElement {
+
+    /**
+     * Demand Active PDU.
+     */
+    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
+
+    protected RdpState state;
+    protected ScreenDescription screen;
+
+    public ServerDemandActivePDU(String id, ScreenDescription screen, RdpState state) {
+        super(id);
+        this.state = state;
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Total length of packet
+        int length = buf.readSignedShortLE(); // Ignore
+        if (buf.length != length)
+            throw new RuntimeException("Incorrect length of packet. Length: " + length + ", data: " + buf + ".");
+
+        int type = buf.readSignedShortLE() & 0xf;
+        if (type != PDUTYPE_DEMANDACTIVEPDU)
+            throw new RuntimeException("Unknown PDU type. Expected type: Demand Active PDU (0x1), actual tyoe: " + type + ", data: " + buf + ".");
+
+        // TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
+        int pduSource = buf.readSignedShortLE();
+        if (pduSource != 1002)
+            throw new RuntimeException("Unexepcted source of demand active PDU. Expected source: 1002, actual source: " + pduSource + ".");
+
+        // (4 bytes): A 32-bit, unsigned integer. The share identifier for the
+        // packet (see [T128] section 8.4.2 for more information regarding share
+        // IDs).
+        long shareId = buf.readUnsignedIntLE();
+        state.serverShareId = shareId;
+
+        // Ignore rest of server data because it is not used by this client.
+        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the
+        // sourceDescriptor field.
+        int lengthSourceDescriptor = buf.readUnsignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The combined size in bytes of the
+        // numberCapabilities, pad2Octets, and capabilitySets fields.
+        int lengthCombinedCapabilities = buf.readUnsignedShortLE();
+
+        // (variable): A variable-length array of bytes containing a source
+        // descriptor,
+        // ByteBuffer sourceDescriptor = buf.readBytes(lengthSourceDescriptor);
+        buf.skipBytes(lengthSourceDescriptor);
+
+        // (variable): An array of Capability Set (section 2.2.1.13.1.1.1)
+        // structures. The number of capability sets is specified by the
+        // numberCapabilities field.
+        handleCapabiltySets(buf.readBytes(lengthCombinedCapabilities));
+
+        // (4 bytes): A 32-bit, unsigned integer. The session identifier. This field
+        // is ignored by the client.
+        buf.skipBytes(4);
+
+        /* DEBUG */buf.assertThatBufferIsFullyRead();
+
+        buf.unref();
+
+        sendHandshakePackets();
+    }
+
+    /**
+     * General Capability Set
+     */
+    public static final int CAPSTYPE_GENERAL = 0x0001;
+    /**
+     * Bitmap Capability Set
+     */
+    public static final int CAPSTYPE_BITMAP = 0x0002;
+    /**
+     * Order Capability Set
+     */
+    public static final int CAPSTYPE_ORDER = 0x0003;
+    /**
+     * Revision 1 Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE = 0x0004;
+    /**
+     * Control Capability Set
+     */
+    public static final int CAPSTYPE_CONTROL = 0x0005;
+    /**
+     * Window Activation Capability Set
+     */
+    public static final int CAPSTYPE_ACTIVATION = 0x0007;
+    /**
+     * Pointer Capability Set
+     */
+    public static final int CAPSTYPE_POINTER = 0x0008;
+    /**
+     * Share Capability Set
+     */
+    public static final int CAPSTYPE_SHARE = 0x0009;
+    /**
+     * Color Table Cache Capability Set
+     */
+    public static final int CAPSTYPE_COLORCACHE = 0x000A;
+    /**
+     * Sound Capability Set
+     */
+    public static final int CAPSTYPE_SOUND = 0x000C;
+    /**
+     * Input Capability Set
+     */
+    public static final int CAPSTYPE_INPUT = 0x000D;
+    /**
+     * Font Capability Set
+     */
+    public static final int CAPSTYPE_FONT = 0x000E;
+    /**
+     * Brush Capability Set
+     */
+    public static final int CAPSTYPE_BRUSH = 0x000F;
+    /**
+     * Glyph Cache Capability Set
+     */
+    public static final int CAPSTYPE_GLYPHCACHE = 0x0010;
+    /**
+     * Offscreen Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_OFFSCREENCACHE = 0x0011;
+    /**
+     * Bitmap Cache Host Support Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE_HOSTSUPPORT = 0x0012;
+    /**
+     * Revision 2 Bitmap Cache Capability Set
+     */
+    public static final int CAPSTYPE_BITMAPCACHE_REV2 = 0x0013;
+    /**
+     * Virtual Channel Capability Set
+     */
+    public static final int CAPSTYPE_VIRTUALCHANNEL = 0x0014;
+    /**
+     * DrawNineGrid Cache Capability Set
+     */
+    public static final int CAPSTYPE_DRAWNINEGRIDCACHE = 0x0015;
+    /**
+     * Draw GDI+ Cache Capability Set
+     */
+    public static final int CAPSTYPE_DRAWGDIPLUS = 0x0016;
+    /**
+     * Remote Programs Capability Set
+     */
+    public static final int CAPSTYPE_RAIL = 0x0017;
+    /**
+     * Window List Capability Set
+     */
+    public static final int CAPSTYPE_WINDOW = 0x0018;
+    /**
+     * Desktop Composition Extension Capability Set
+     */
+    public static final int CAPSETTYPE_COMPDESK = 0x0019;
+    /**
+     * Multifragment Update Capability Set
+     */
+    public static final int CAPSETTYPE_MULTIFRAGMENTUPDATE = 0x001A;
+    /**
+     * Large Pointer Capability Set
+     */
+    public static final int CAPSETTYPE_LARGE_POINTER = 0x001B;
+    /**
+     * Surface Commands Capability Set
+     */
+    public static final int CAPSETTYPE_SURFACE_COMMANDS = 0x001C;
+    /**
+     * Bitmap Codecs Capability Set
+     */
+    public static final int CAPSETTYPE_BITMAP_CODECS = 0x001D;
+    /**
+     * Frame Acknowledge Capability Set
+     */
+    public static final int CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E;
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240486.aspx
+     */
+    protected void handleCapabiltySets(ByteBuffer buf) {
+        // (2 bytes): A 16-bit, unsigned integer. The number of capability sets
+        // included in the Demand Active PDU.
+        int numberCapabilities = buf.readSignedShortLE();
+
+        // (2 bytes): Padding.
+        buf.skipBytes(2);
+
+        for (int i = 0; i < numberCapabilities; i++) {
+            // (2 bytes): A 16-bit, unsigned integer. The type identifier of the
+            // capability set.
+            int capabilitySetType = buf.readUnsignedShortLE();
+
+            // (2 bytes): A 16-bit, unsigned integer. The length in bytes of the
+            // capability data, including the size of the capabilitySetType and
+            // lengthCapability fields.
+            int lengthCapability = buf.readUnsignedShortLE();
+
+            // (variable): Capability set data which conforms to the structure of the
+            // type given by the capabilitySetType field.
+            ByteBuffer capabilityData = buf.readBytes(lengthCapability - 4);
+
+            switch (capabilitySetType) {
+            case CAPSTYPE_GENERAL:
+                break;
+            case CAPSTYPE_BITMAP:
+                handleBitmapCapabilities(capabilityData);
+                break;
+            case CAPSTYPE_ORDER:
+                break;
+            case CAPSTYPE_BITMAPCACHE:
+                break;
+            case CAPSTYPE_CONTROL:
+                break;
+            case CAPSTYPE_ACTIVATION:
+                break;
+            case CAPSTYPE_POINTER:
+                break;
+            case CAPSTYPE_SHARE:
+                break;
+            case CAPSTYPE_COLORCACHE:
+                break;
+            case CAPSTYPE_SOUND:
+                break;
+            case CAPSTYPE_INPUT:
+                break;
+            case CAPSTYPE_FONT:
+                break;
+            case CAPSTYPE_BRUSH:
+                break;
+            case CAPSTYPE_GLYPHCACHE:
+                break;
+            case CAPSTYPE_OFFSCREENCACHE:
+                break;
+            case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
+                break;
+            case CAPSTYPE_BITMAPCACHE_REV2:
+                break;
+            case CAPSTYPE_VIRTUALCHANNEL:
+                break;
+            case CAPSTYPE_DRAWNINEGRIDCACHE:
+                break;
+            case CAPSTYPE_DRAWGDIPLUS:
+                break;
+            case CAPSTYPE_RAIL:
+                break;
+            case CAPSTYPE_WINDOW:
+                break;
+            case CAPSETTYPE_COMPDESK:
+                break;
+            case CAPSETTYPE_MULTIFRAGMENTUPDATE:
+                break;
+            case CAPSETTYPE_LARGE_POINTER:
+                break;
+            case CAPSETTYPE_SURFACE_COMMANDS:
+                break;
+            case CAPSETTYPE_BITMAP_CODECS:
+                break;
+            case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
+                break;
+            default:
+                // Ignore
+                break;
+            }
+
+            capabilityData.unref();
+        }
+
+        // TODO
+
+        buf.unref();
+    }
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240554.aspx
+     */
+    protected void handleBitmapCapabilities(ByteBuffer buf) {
+
+        // (2 bytes): A 16-bit, unsigned integer. The server MUST set this field to
+        // the color depth of the session, while the client SHOULD set this field to
+        // the color depth requested in the Client Core Data (section 2.2.1.3.2).
+        int preferredBitsPerPixel = buf.readUnsignedShortLE();
+        screen.setPixelFormatRGBTrueColor(preferredBitsPerPixel);
+
+        // receive1BitPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 1 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // receive4BitsPerPixel(2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 4 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // receive8BitsPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the client can receive 8 bpp. This field is ignored and SHOULD be
+        // set to TRUE (0x0001).
+        buf.skipBytes(2);
+
+        // (2 bytes): A 16-bit, unsigned integer. The width of the desktop in the
+        // session.
+        int desktopWidth = buf.readUnsignedShortLE();
+
+        // (2 bytes): A 16-bit, unsigned integer. The height of the desktop in the
+        // session.
+        int desktopHeight = buf.readUnsignedShortLE();
+
+        screen.setFramebufferSize(desktopWidth, desktopHeight);
+
+        // pad2octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
+        // field MUST be ignored.
+
+        // desktopResizeFlag (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether resizing the desktop by using a Deactivation-Reactivation
+        // Sequence is supported.
+
+        // bitmapCompressionFlag (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether bitmap compression is supported. This field MUST be set to TRUE
+        // (0x0001) because support for compressed bitmaps is required for a
+        // connection to proceed.
+
+        // highColorFlags (1 byte): An 8-bit, unsigned integer. Client support for
+        // 16 bpp color modes. This field is ignored and SHOULD be set to zero.
+
+        // drawingFlags (1 byte): An 8-bit, unsigned integer. Flags describing
+        // support for 32 bpp bitmaps.
+
+        // multipleRectangleSupport (2 bytes): A 16-bit, unsigned integer. Indicates
+        // whether the use of multiple bitmap rectangles is supported in the Bitmap
+        // Update (section 2.2.9.1.1.3.1.2). This field MUST be set to TRUE (0x0001)
+        // because multiple rectangle support is required for a connection to
+        // proceed.
+
+        // pad2octetsB (2 bytes): A 16-bit, unsigned integer. Padding. Values in
+        // this field MUST be ignored.
+    }
+
+    /**
+     * Send all client requests in one hop, to simplify logic.
+     */
+    protected void sendHandshakePackets() {
+        // Send reactivation sequence in bulk
+        pushDataToPad("confirm_active", new ByteBuffer((Order)null));
+    }
+
+    /**
+     * 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[] {
+                0x67, 0x01,  //  TS_SHARECONTROLHEADER::totalLength = 0x0167 = 359 bytes
+                0x11, 0x00,  //  TS_SHARECONTROLHEADER::pduType = 0x0011 0x0011 = 0x0010 | 0x0001  = TS_PROTOCOL_VERSION | PDUTYPE_DEMANDACTIVEPDU
+
+                (byte) 0xea, 0x03,  //  TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
+
+                (byte) 0xea, 0x03, 0x01, 0x00,  //  TS_DEMAND_ACTIVE_PDU::shareId
+                0x04, 0x00,  //  TS_DEMAND_ACTIVE_PDU::lengthSourceDescriptor = 4 bytes
+                0x51, 0x01,  //  TS_DEMAND_ACTIVE_PDU::lengthCombinedCapabilities = 0x151 = 337 bytes
+
+                0x52, 0x44, 0x50, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sourceDescriptor = "RDP"
+
+                0x0d, 0x00,  //  TS_DEMAND_ACTIVE_PDU::numberCapabilities = 13
+                0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::pad2octets
+
+                //  Share Capability Set (8 bytes)
+                // 0x09, 0x00, 0x08, 0x00, (byte) 0xea, 0x03, (byte) 0xdc, (byte) 0xe2,
+                //
+                0x09, 0x00,  //  TS_SHARE_CAPABILITYSET::capabilitySetType = CAPSTYPE_SHARE (9)
+                0x08, 0x00,  //  TS_SHARE_CAPABILITYSET::lengthCapability = 8 bytes
+                (byte) 0xea, 0x03,  //  TS_SHARE_CAPABILITYSET::nodeID = 0x03ea (1002)
+                (byte) 0xdc, (byte) 0xe2,  //  TS_SHARE_CAPABILITYSET::pad2octets
+
+                //  General Capability Set (24 bytes)
+                // 0x01, 0x00, 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x04,
+                // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+                //
+                0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::capabilitySetType = CAPSTYPE_GENERAL (1)
+                0x18, 0x00,  //  TS_GENERAL_CAPABILITYSET::lengthCapability = 24 bytes
+
+                0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMajorType = TS_OSMAJORTYPE_WINDOWS (1)
+                0x03, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMinorType = TS_OSMINORTYPE_WINDOWS_NT (3)
+                0x00, 0x02,  //  TS_GENERAL_CAPABILITYSET::protocolVersion = TS_CAPS_PROTOCOLVERSION (0x0200)
+                0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::pad2octetsA
+                0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionTypes = 0
+                0x1d, 0x04,  //  TS_GENERAL_CAPABILITYSET::extraFlags = 0x041d = 0x0400 | 0x0010 | 0x0008 | 0x0004 | 0x0001 = NO_BITMAP_COMPRESSION_HDR | ENC_SALTED_CHECKSUM | AUTORECONNECT_SUPPORTED | LONG_CREDENTIALS_SUPPORTED | FASTPATH_OUTPUT_SUPPORTED
+
+                0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::updateCapabilityFlag = 0
+                0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::remoteUnshareFlag = 0
+                0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionLevel = 0
+                0x01,  //  TS_GENERAL_CAPABILITYSET::refreshRectSupport = TRUE
+                0x01,  //  TS_GENERAL_CAPABILITYSET::suppressOutputSupport = TRUE
+
+                // Virtual Channel Capability Set (8 bytes)
+                // 0x14, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00,
+                //
+                0x14, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::capabilitySetType = CAPSTYPE_VIRTUALCHANNEL (20)
+                0x08, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::lengthCapability = 8 bytes
+
+                0x02, 0x00, 0x00, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::vccaps1 = 0x00000002 = VCCAPS_COMPR_CS_8K
+
+                //  DrawGdiPlus Capability Set (40 bytes)
+                // 0x16, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, (byte) 0xf6, 0x13, (byte) 0xf3, 0x01, 0x00, 0x00, 0x00,
+                // 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, (byte) 0x9c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x61, (byte) 0xa6, (byte) 0x82, (byte) 0x80,
+                // 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, (byte) 0x91, (byte) 0xbf,
+                //
+                0x16, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::capabilitySetType = CAPSTYPE_DRAWGDIPLUS (22)
+                0x28, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::lengthCapability = 40 bytes
+
+                0x00, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusSupportLevel = TS_DRAW_GDIPLUS_DEFAULT (0)
+                0x70, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::GdipVersion (not initialized by server)
+                0x01, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusCacheLevel  = TS_DRAW_GDIPLUS_CACHE_LEVEL_ONE (1)
+
+                0x01, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipGraphicsCacheEntries  (not initialized by server)
+                0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectBrushCacheEntries (not initialized by server)
+                0x18, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectPenCacheEntries (not initialized by server)
+                0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageCacheEntries (not initialized by server)
+                (byte) 0x9c, (byte) 0xf6,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageAttributesCacheEntries (not initialized by server)
+
+                0x13, (byte) 0xf3,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipGraphicsCacheChunkSize  (not initialized by server)
+                0x61, (byte) 0xa6,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectBrushCacheChunkSize (not initialized by server)
+                (byte) 0x82, (byte) 0x80,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectPenCacheChunkSize (not initialized by server)
+                0x00, 0x00,  //   TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectImageAttributesCacheChunkSize (not initialized by server)
+
+                0x00, 0x00,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheChunkSize  (not initialized by server)
+                0x00, 0x50,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheTotalSize  (not initialized by server)
+                (byte) 0x91, (byte) 0xbf,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheMaxSize (not initialized by server)
+
+                //  Font Capability Set (4 bytes)
+                // 0x0e, 0x00, 0x04, 0x00,
+                //
+                // Due to a bug, the TS_FONT_CAPABILITYSET capability set size is incorrectly set to 4 bytes (it must be 8 bytes). As a result of this bug, the fontSupportFlags and pad2octets fields are missing.
+                0x0e, 0x00,  //  TS_FONT_CAPABILITYSET::capabilitySetType = CAPSTYPE_FONT (14)
+                0x04, 0x00,  //  TS_FONT_CAPABILITYSET::lengthCapability = 4 bytes
+
+
+                //  Bitmap Capability Set (28 bytes)
+                // 0x02, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04,
+                // 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+                //
+                0x02, 0x00,  //  TS_BITMAP_CAPABILITYSET::capabilitySetType = CAPSTYPE_BITMAP (2)
+                0x1c, 0x00,  //  TS_BITMAP_CAPABILITYSET::lengthCapability = 28 bytes
+
+                0x18, 0x00,  //  TS_BITMAP_CAPABILITYSET::preferredBitsPerPixel = 24 bpp
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive1BitPerPixel = TRUE
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive4BitsPerPixel = TRUE
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive8BitsPerPixel = TRUE
+                0x00, 0x05,  //  TS_BITMAP_CAPABILITYSET::desktopWidth = 1280 pixels
+                0x00, 0x04,  //  TS_BITMAP_CAPABILITYSET::desktopHeight = 1024 pixels
+                0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octets
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::desktopResizeFlag = TRUE
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::bitmapCompressionFlag = TRUE
+                0x00,  //  TS_BITMAP_CAPABILITYSET::highColorFlags = 0
+                0x00,  //  TS_BITMAP_CAPABILITYSET::pad1octet
+                0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::multipleRectangleSupport = TRUE
+                0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octetsB
+
+                //  Order Capability Set (88 bytes)
+                // 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                // 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00,
+                // 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+                // 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+                // 0x00, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00,
+                // 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                //
+                0x03, 0x00,  //  TS_ORDER_CAPABILITYSET::capabilitySetType = CAPSTYPE_ORDER (3)
+                0x58, 0x00,  //  TS_ORDER_CAPABILITYSET::lengthCapability = 88 bytes
+
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // TS_ORDER_CAPABILITYSET::terminalDescriptor = ""
+                0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsA
+
+                0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveXGranularity = 1
+                0x14, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveYGranularity = 20
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsA
+                0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::maximumOrderLevel = ORD_LEVEL_1_ORDERS (1)
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::numberFonts = 0
+
+                0x22, 0x00,  //  TS_ORDER_CAPABILITYSET::orderFlags = 0x0022 = 0x0020 | 0x0002 = COLORINDEXSUPPORT | NEGOTIATEORDERSUPPORT
+
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DSTBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_PATBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SCRBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_INDEX] = TRUE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ATEXTOUT_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_AEXTTEXTOUT_INDEX] = FALSE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DRAWNINEGRID_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_LINETO_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_OPAQUERECT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SAVEBITMAP_INDEX] = TRUE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WTEXTOUT_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_R2_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_R2_INDEX] = FALSE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIDSTBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIPATBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTISCRBLT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIOPAQUERECT_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_INDEX_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_SC_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_CB_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYLINE_INDEX] = TRUE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[23] = 0
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_GLYPH_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_SC_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_CB_INDEX] = TRUE
+                0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_INDEX_INDEX] = TRUE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WEXTTEXTOUT_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGTEXTOUT_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGEXTTEXTOUT_INDEX] = FALSE
+                0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[24] = 0
+
+                (byte) 0xa1, 0x06,  //  TS_ORDER_CAPABILITYSET::textFlags = 0x06a1
+
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsB
+                0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsB
+
+                0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveSize = 0xf4240 = 1000000
+                0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsC
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsD
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::textANSICodePage
+                0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsE
+
+                // Color Table Cache Capability Set (8 bytes)
+                // 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00,
+                //
+                0x0a, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::capabilitySetType = CAPSTYPE_COLORCACHE (10)
+                0x08, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::lengthCapability = 8 bytes
+
+                0x06, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::colorTableCacheSize = 6
+                0x00, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::pad2octets
+
+                // Bitmap Cache Host Support Capability Set (8 bytes)
+                // 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
+                //
+                0x12, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::capabilitySetType  = CAPSTYPE_BITMAPCACHE_HOSTSUPPORT (18)
+                0x08, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::lengthCapability  = 8 bytes
+
+                0x01,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::CacheVersion = 1  (corresponds to rev. 2 capabilities)
+                0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad1
+                0x00, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad2
+
+                // Pointer Capability Set (10 bytes)
+                // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00,
+                //
+                0x08, 0x00,  //  TS_POINTER_CAPABILITYSET::capabilitySetType = CAPSTYPE_POINTER (8)
+                0x0a, 0x00,  //  TS_POINTER_CAPABILITYSET::lengthCapability = 10 bytes
+
+                0x01, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerFlag = TRUE
+                0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerCacheSize = 25
+                0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::pointerCacheSize = 25
+
+                //  Input Capability Set (88 bytes)
+                // 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00,
+                // 0x0c, (byte) 0xf6, 0x13, (byte) 0xf3, (byte) 0x93, 0x5a, 0x37, (byte) 0xf3, 0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3,
+                // 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
+                // 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3,
+                // 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00,
+                // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
+                //
+                0x0d, 0x00,  //  TS_INPUT_CAPABILITYSET::capabilitySetType = CAPSTYPE_INPUT (13)
+                0x58, 0x00,  //  TS_INPUT_CAPABILITYSET::lengthCapability = 88 bytes
+
+                0x35, 0x00,  //  TS_INPUT_CAPABILITYSET::inputFlags = 0x0035 = 0x0020 | 0x0010 | 0x0004 | 0x0001 = INPUT_FLAG_FASTPATH_INPUT2 | INPUT_FLAG_VKPACKET | INPUT_FLAG_MOUSEX | INPUT_FLAG_SCANCODES
+
+                0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::pad2octetsA
+                (byte) 0xa1, 0x06, 0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardLayout (not initialized by server)
+                0x40, 0x42, 0x0f, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardType (not initialized by server)
+                0x0c, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardSubType  (not initialized by server)
+                (byte) 0x93, 0x5a, 0x37, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardFunctionKey (not initialized by server)
+
+                // TS_INPUT_CAPABILITYSET::imeFileName (not initialized by server)
+                0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00,
+                0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
+                0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
+                0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
+
+                //  RAIL Capability Set (8 bytes)
+                // 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+                //
+                0x17, 0x00,  //  TS_RAIL_CAPABILITYSET::capabilitySetType = CAPSTYPE_RAIL (23)
+                0x08, 0x00,  //  TS_RAIL_CAPABILITYSET::lengthCapability = 8 bytes
+
+                0x00, 0x00, 0x00, 0x00,  //  TS_RAIL_CAPABILITYSET::railSupportLevel = TS_RAIL_LEVEL_DEFAULT (0)
+
+                //  Windowing Capability Set (11 bytes)
+                // 0x18, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                //
+                0x18, 0x00,  //  TS_WINDOW_CAPABILITYSET::capabilitySetType =  CAPSTYPE_WINDOW (24)
+                0x0b, 0x00,  //  TS_WINDOW_CAPABILITYSET::lengthCapability = 11 bytes
+
+                0x00, 0x00, 0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::wndSupportLevel = TS_WINDOW_LEVEL_DEFAULT (0)
+                0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCaches = 0
+                0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCacheEntries = 0
+
+                // Remainder of Demand Active PDU:
+
+                0x00, 0x00, 0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sessionId = 0
+        };
+        /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        ScreenDescription screenDescription = new ScreenDescription();
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element demandActive = new ServerDemandActivePDU("demand_active", screenDescription, rdpState);
+        Element sink = new FakeSink("sink");
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, demandActive, sink);
+        pipeline.link("source", "demand_active", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
new file mode 100755
index 0000000..f88f492
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerFastPath.java
@@ -0,0 +1,315 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240621.aspx
+ */
+public class ServerFastPath extends BaseElement {
+
+    /**
+     * TPKT protocol version (first byte).
+     */
+    public static final int PROTOCOL_TPKT = 0x03;
+
+    /**
+     * Fast path protocol version (first two bits of first byte).
+     */
+    public static final int PROTOCOL_FASTPATH = 0x00;
+
+    /**
+     * CredSSP packets.
+     */
+    public static final int PROTOCOL_CREDSSP = 0x30;
+
+    /**
+     * TPKT packets will be pushed to that pad.
+     */
+    public static final String TPKT_PAD = "tpkt";
+
+    /**
+     * CredSSP packets will be pushed to same pad as TPKT, because they are part
+     * of slow-path initialization sequence.
+     */
+    public static final String CREDSSP_PAD = "tpkt";
+
+    private static final String ORDERS_PAD = "orders";
+    private static final String BITMAP_PAD = "bitmap";
+    private static final String PALETTE_PAD = "palette";
+
+    /**
+     * Indicates that packet contains 8 byte secure checksum at top of packet. Top
+     * two bits of first byte.
+     */
+    public static final int FASTPATH_OUTPUT_SECURE_CHECKSUM = 1;
+
+    /**
+     * Indicates that packet contains 8 byte secure checksum at top of packet and
+     * packet content is encrypted. Top two bits of first byte.
+     */
+    public static final int FASTPATH_OUTPUT_ENCRYPTED = 2;
+
+    public static final int FASTPATH_UPDATETYPE_ORDERS = 0;
+    public static final int FASTPATH_UPDATETYPE_BITMAP = 1;
+    public static final int FASTPATH_UPDATETYPE_PALETTE = 2;
+    public static final int FASTPATH_UPDATETYPE_SYNCHRONIZE = 3;
+    public static final int FASTPATH_UPDATETYPE_SURFCMDS = 4;
+    public static final int FASTPATH_UPDATETYPE_PTR_NULL = 5;
+    public static final int FASTPATH_UPDATETYPE_PTR_DEFAULT = 6;
+    public static final int FASTPATH_UPDATETYPE_PTR_POSITION = 8;
+    public static final int FASTPATH_UPDATETYPE_COLOR = 9;
+    public static final int FASTPATH_UPDATETYPE_CACHED = 0xa;
+    public static final int FASTPATH_UPDATETYPE_POINTER = 0xb;
+
+    public static final int FASTPATH_FRAGMENT_SINGLE = 0;
+    public static final int FASTPATH_FRAGMENT_LAST = 1;
+    public static final int FASTPATH_FRAGMENT_FIRST = 2;
+    public static final int FASTPATH_FRAGMENT_NEXT = 3;
+
+    public static final int FASTPATH_OUTPUT_COMPRESSION_USED = 2;
+
+    public ServerFastPath(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // * DEBUG */System.out.println(buf.toHexString(buf.length));
+
+        // We need at 4 bytes to read packet type (TPKT or FastPath) and packet
+        // length
+        if (!cap(buf, 4, UNLIMITED, link, false))
+            return;
+
+        int typeAndFlags = buf.readUnsignedByte();
+
+        switch (typeAndFlags) {
+        case PROTOCOL_TPKT: // 0x03
+            handleTpkt(buf, link);
+            break;
+
+        case PROTOCOL_CREDSSP: // 0x30, potential clash with FastPath
+            handleCredSSP(buf, link);
+            break;
+
+        default: // (value & 0x03) == 0x00
+        case PROTOCOL_FASTPATH:
+            handleFastPath(buf, link, typeAndFlags);
+            break;
+        }
+
+    }
+
+    private void handleTpkt(ByteBuffer buf, Link link) {
+        // Reserved
+        buf.skipBytes(1);
+
+        // Read TPKT length
+        int length = buf.readUnsignedShort();
+
+        if (!cap(buf, length, length, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        int payloadLength = length - buf.cursor;
+
+        // Extract payload
+        ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToPad(TPKT_PAD, outBuf);
+    }
+
+    private void handleCredSSP(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: CredSSP data received: " + buf + ".");
+
+        // Store header position: will parse whole header later in BER format parser
+        int headerPosition = buf.cursor - 1;
+
+        long payloadLength = buf.readBerLength();
+        if (payloadLength > 10 * 1024)
+            throw new RuntimeException("[" + this + "] ERROR: CredSSP packets seems to be too long: " + payloadLength + "bytes. Data: " + buf + ".");
+
+        // Length is the size of payload, so we need to append size of header
+        int headerLength = buf.cursor - headerPosition;
+        int packetLength = (int)payloadLength + headerLength;
+        if (!cap(buf, packetLength, packetLength, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        // Extract payload (with header)
+        ByteBuffer outBuf = buf.slice(headerPosition, packetLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToPad(CREDSSP_PAD, outBuf);
+    }
+
+    private void handleFastPath(ByteBuffer buf, Link link, int typeAndFlags) {
+        // Number of bytes in updateData field (including header (1+1 or 2
+        // bytes))
+        int length = buf.readVariableUnsignedShort();
+
+        if (!cap(buf, length, length, link, false))
+            // Wait for full packet to arrive
+            return;
+
+        int type = typeAndFlags & 0x3;
+        int securityFlags = (typeAndFlags >> 6) & 0x3;
+
+        // Assertions
+        {
+            if (type != PROTOCOL_FASTPATH)
+                throw new RuntimeException("Unknown protocol. Expected protocol: 0 (FastPath). Actual protocol: " + type + ", data: " + buf + ".");
+
+            switch (securityFlags) {
+            case FASTPATH_OUTPUT_SECURE_CHECKSUM:
+                // TODO
+                throw new RuntimeException("Secure checksum is not supported in FastPath packets.");
+            case FASTPATH_OUTPUT_ENCRYPTED:
+                // TODO
+                throw new RuntimeException("Encryption is not supported in FastPath packets.");
+            }
+        }
+
+        // TODO: optional FIPS information, when FIPS is selected
+        // TODO: optional data signature (checksum), when checksum or FIPS is
+        // selected
+
+        // Array of FastPath update fields
+        while (buf.cursor < buf.length) {
+
+            int updateHeader = buf.readUnsignedByte();
+
+            int size = buf.readUnsignedShortLE();
+
+            int updateCode = updateHeader & 0xf;
+            int fragmentation = (updateHeader >> 4) & 0x3;
+            int compression = (updateHeader >> 6) & 0x3;
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: FastPath update received. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: "
+                        + compression + ", size: " + size + ".");
+
+            ByteBuffer data = buf.readBytes(size);
+            buf.putMetadata("fragmentation", fragmentation);
+            buf.putMetadata("compression", compression);
+
+            switch (updateCode) {
+
+            case FASTPATH_UPDATETYPE_ORDERS:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_ORDERS.");
+                pushDataToPad(ORDERS_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_BITMAP:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_BITMAP.");
+                pushDataToPad(BITMAP_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_PALETTE:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PALETTE.");
+                pushDataToPad(PALETTE_PAD, data);
+                break;
+
+            case FASTPATH_UPDATETYPE_SYNCHRONIZE:
+                // @see http://msdn.microsoft.com/en-us/library/cc240625.aspx
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SYNCHRONIZE.");
+
+                data.unref();
+
+                if (size != 0)
+                    throw new RuntimeException("Size of FastPath synchronize packet must be 0. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation
+                            + ", compression: " + compression + ", size: " + size + ", data: " + data + ".");
+                break;
+
+            case FASTPATH_UPDATETYPE_SURFCMDS:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SURFCMDS.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_NULL:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_NULL.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_DEFAULT:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_DEFAULT.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_PTR_POSITION:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_POSITION.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_COLOR:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_COLOR.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_CACHED:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_CACHED.");
+
+                break;
+
+            case FASTPATH_UPDATETYPE_POINTER:
+                if (verbose)
+                    System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_POINTER.");
+
+                break;
+
+            default:
+                throw new RuntimeException("Unknown FastPath update. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: " + compression
+                        + ", size: " + size + ", data: " + data + ".");
+
+            }
+            buf.unref();
+
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
new file mode 100755
index 0000000..dad3548
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerIOChannelRouter.java
@@ -0,0 +1,534 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerIOChannelRouter extends BaseElement {
+
+    /**
+     * Demand Active PDU.
+     */
+    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
+
+    /**
+     * Confirm Active PDU.
+     */
+    public static final int PDUTYPE_CONFIRMACTIVEPDU = 0x3;
+
+    /**
+     * Deactivate All PDU.
+     */
+    public static final int PDUTYPE_DEACTIVATEALLPDU = 0x6;
+
+    /**
+     * Data PDU (actual type is revealed by the pduType2 field in the Share Data
+     * Header).
+     */
+    public static final int PDUTYPE_DATAPDU = 0x7;
+
+    /**
+     * Enhanced Security Server Redirection PDU.
+     */
+    public static final int PDUTYPE_SERVER_REDIR_PKT = 0xA;
+
+    protected RdpState state;
+
+    public ServerIOChannelRouter(String id, RdpState state) {
+        super(id);
+        this.state = state;
+    }
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240576.aspx
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int length = buf.readUnsignedShortLE();
+        if (buf.length != length)
+        {
+            // It is ServerErrorAlert-ValidClient
+            // Ignore it
+            //throw new RuntimeException("[" + this + "] ERROR: Incorrect PDU length: " + length + ", data: " + buf + ".");
+        }
+
+        int type = buf.readUnsignedShortLE() & 0xf;
+
+        // int sourceId = buf.readUnsignedShortLE();
+        buf.skipBytes(2);
+
+        switch (type) {
+        case PDUTYPE_DEMANDACTIVEPDU:
+            pushDataToPad("demand_active", buf);
+            break;
+        case PDUTYPE_CONFIRMACTIVEPDU:
+            throw new RuntimeException("Unexpected client CONFIRM ACTIVE PDU. Data: " + buf + ".");
+        case PDUTYPE_DEACTIVATEALLPDU:
+            // pushDataToPad("deactivate_all", buf);
+            /* ignore */buf.unref();
+            break;
+        case PDUTYPE_DATAPDU:
+            handleDataPdu(buf);
+            break;
+        case PDUTYPE_SERVER_REDIR_PKT:
+            // pushDataToPad("server_redir", buf);
+            /* ignore */buf.unref();
+            break;
+        default:
+            throw new RuntimeException("[" + this + "] ERROR: Unknown PDU type: " + type + ", data: " + buf + ".");
+        }
+
+    }
+
+    /**
+     * Graphics Update PDU.
+     */
+    public static final int PDUTYPE2_UPDATE = 0x02;
+
+    /**
+     * Control PDU.
+     */
+    public static final int PDUTYPE2_CONTROL = 0x14;
+
+    /**
+     * Pointer Update PDU.
+     */
+    public static final int PDUTYPE2_POINTER = 0x1B;
+
+    /**
+     * Input Event PDU.
+     */
+    public static final int PDUTYPE2_INPUT = 0x1C;
+
+    /**
+     * Synchronize PDU.
+     */
+    public static final int PDUTYPE2_SYNCHRONIZE = 0x1F;
+
+    /**
+     * Refresh Rect PDU.
+     */
+    public static final int PDUTYPE2_REFRESH_RECT = 0x21;
+
+    /**
+     * Play Sound PDU.
+     */
+    public static final int PDUTYPE2_PLAY_SOUND = 0x22;
+
+    /**
+     * Suppress Output PDU.
+     */
+    public static final int PDUTYPE2_SUPPRESS_OUTPUT = 0x23;
+
+    /**
+     * Shutdown Request PDU.
+     */
+    public static final int PDUTYPE2_SHUTDOWN_REQUEST = 0x24;
+
+    /**
+     * Shutdown Request Denied PDU.
+     */
+    public static final int PDUTYPE2_SHUTDOWN_DENIED = 0x25;
+
+    /**
+     * Save Session Info PDU.
+     */
+    public static final int PDUTYPE2_SAVE_SESSION_INFO = 0x26;
+
+    /**
+     * Font List PDU.
+     */
+    public static final int PDUTYPE2_FONTLIST = 0x27;
+
+    /**
+     * Font Map PDU.
+     */
+    public static final int PDUTYPE2_FONTMAP = 0x28;
+
+    /**
+     * Set Keyboard Indicators PDU.
+     */
+    public static final int PDUTYPE2_SET_KEYBOARD_INDICATORS = 0x29;
+
+    /**
+     * Persistent Key List PDU.
+     */
+    public static final int PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST = 0x2B;
+
+    /**
+     * Bitmap Cache Error PDU.
+     */
+    public static final int PDUTYPE2_BITMAPCACHE_ERROR_PDU = 0x2C;
+
+    /**
+     * Set Keyboard IME Status PDU.
+     */
+    public static final int PDUTYPE2_SET_KEYBOARD_IME_STATUS = 0x2D;
+
+    /**
+     * Offscreen Bitmap Cache Error PDU.
+     */
+    public static final int PDUTYPE2_OFFSCRCACHE_ERROR_PDU = 0x2E;
+
+    /**
+     * Set Error Info PDU.
+     */
+    public static final int PDUTYPE2_SET_ERROR_INFO_PDU = 0x2F;
+
+    /**
+     * DrawNineGrid Cache Error PDU.
+     */
+    public static final int PDUTYPE2_DRAWNINEGRID_ERROR_PDU = 0x30;
+
+    /**
+     * GDI+ Error PDU.
+     */
+    public static final int PDUTYPE2_DRAWGDIPLUS_ERROR_PDU = 0x31;
+
+    /**
+     * Auto-Reconnect Status PDU.
+     */
+    public static final int PDUTYPE2_ARC_STATUS_PDU = 0x32;
+
+    /**
+     * Status Info PDU.
+     */
+    public static final int PDUTYPE2_STATUS_INFO_PDU = 0x36;
+
+    /**
+     * Monitor Layout PDU.
+     */
+    public static final int PDUTYPE2_MONITOR_LAYOUT_PDU = 0x37;
+
+    /**
+     * Indicates an Orders Update.
+     */
+    public static final int UPDATETYPE_ORDERS = 0x0000;
+
+    /**
+     * Indicates a Bitmap Graphics Update.
+     */
+    public static final int UPDATETYPE_BITMAP = 0x0001;
+
+    /**
+     * Indicates a Palette Update.
+     */
+    public static final int UPDATETYPE_PALETTE = 0x0002;
+
+    /**
+     * Indicates a Synchronize Update.
+     */
+    public static final int UPDATETYPE_SYNCHRONIZE = 0x0003;
+
+    /**
+     * @see http://msdn.microsoft.com/en-us/library/cc240577.aspx
+     */
+    protected void handleDataPdu(ByteBuffer buf) {
+
+        // (4 bytes): A 32-bit, unsigned integer. Share identifier for the packet.
+        long shareId = buf.readUnsignedIntLE();
+        if (shareId != state.serverShareId)
+            throw new RuntimeException("Unexpected share ID: " + shareId + ".");
+//    buf.skipBytes(4);
+
+        // Padding.
+        buf.skipBytes(1);
+
+        // (1 byte): An 8-bit, unsigned integer. The stream identifier for the
+        // packet.
+        // int streamId = buf.readUnsignedByte();
+        buf.skipBytes(1);
+
+        // (2 bytes): A 16-bit, unsigned integer. The uncompressed length of the
+        // packet in bytes.
+        int uncompressedLength = buf.readUnsignedShortLE();
+
+        // (1 byte): An 8-bit, unsigned integer. The type of Data PDU.
+        int type2 = buf.readUnsignedByte();
+
+        // (1 byte): An 8-bit, unsigned integer. The compression type and flags
+        // specifying the data following the Share Data Header
+        int compressedType = buf.readUnsignedByte();
+        if (compressedType != 0)
+            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The compressed length of the
+        // packet in bytes.
+        int compressedLength = buf.readUnsignedShortLE();
+        if (compressedLength != 0)
+            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
+
+        ByteBuffer data = buf.readBytes(uncompressedLength - 18);
+        buf.unref();
+
+        switch (type2) {
+
+        case PDUTYPE2_UPDATE: {
+
+            // (2 bytes): A 16-bit, unsigned integer. Type of the graphics update.
+            int updateType = data.readUnsignedShortLE();
+            ByteBuffer payload = data.readBytes(data.length - data.cursor);
+            data.unref();
+
+            switch (updateType) {
+            case UPDATETYPE_ORDERS:
+                pushDataToPad("orders", payload);
+                break;
+            case UPDATETYPE_BITMAP:
+                pushDataToPad("bitmap", payload);
+                break;
+            case UPDATETYPE_PALETTE:
+                pushDataToPad("palette", payload);
+                break;
+            case UPDATETYPE_SYNCHRONIZE:
+                // Ignore
+                payload.unref();
+                break;
+            }
+
+            break;
+        }
+        case PDUTYPE2_CONTROL:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_CONTROL ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_POINTER:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_POINTER ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_INPUT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_INPUT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SYNCHRONIZE:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SYNCHRONIZE ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_REFRESH_RECT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_REFRESH_RECT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_PLAY_SOUND:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_PLAY_SOUND ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SUPPRESS_OUTPUT:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SUPPRESS_OUTPUT ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SHUTDOWN_REQUEST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_REQUEST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SHUTDOWN_DENIED:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_DENIED ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SAVE_SESSION_INFO:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SAVE_SESSION_INFO ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_FONTLIST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTLIST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_FONTMAP:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTMAP ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_KEYBOARD_INDICATORS:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_INDICATORS ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_IME_STATUS ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_OFFSCRCACHE_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_SET_ERROR_INFO_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_ERROR_INFO_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWNINEGRID_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWGDIPLUS_ERROR_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_ARC_STATUS_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_ARC_STATUS_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_STATUS_INFO_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_STATUS_INFO_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+        case PDUTYPE2_MONITOR_LAYOUT_PDU:
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Packet PDUTYPE2_MONITOR_LAYOUT_PDU ignored.");
+            // Ignore
+            data.unref();
+            break;
+
+        default:
+            throw new RuntimeException("Unknow data PDU type: " + type2 + ", data: " + buf + ".");
+        }
+    }
+
+    /**
+     * 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");
+
+        byte[] packet = new byte[] {
+                // TPKT
+                (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
+                (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
+
+                // X224
+                (byte)0x02, // X224 Length: 2 bytes
+                (byte)0xF0, // X224 Type: Data
+                (byte)0x80, // X224 EOT
+
+                // MCS
+                // Type: send data indication: 26 (0x1a, top 6 bits)
+                (byte)0x68, // ??
+
+                (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
+                (byte)0x03, (byte)0xEB, // Channel ID: 1003
+                (byte)0x70, // Data priority: high, segmentation: begin|end
+                (byte)0x0D, // Payload length: 13 bytes
+
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        RdpState rdpState = new RdpState() {
+            {
+                serverShareId = 66538;
+            }
+        };
+        Element channel1003 = new ServerIOChannelRouter("channel_1003", rdpState);
+        Element mcs = new ServerMCSPDU("mcs");
+        Element tpkt = new ServerTpkt("tpkt");
+        Element x224 = new ServerX224DataPdu("x224");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, x224, mcs, channel1003, sink);
+        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "channel_1003 >deactivate_all", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
new file mode 100755
index 0000000..22e8094
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerLicenseErrorPDUValidClient.java
@@ -0,0 +1,121 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerLicenseErrorPDUValidClient extends OneTimeSwitch {
+
+    public ServerLicenseErrorPDUValidClient(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+    /* @formatter:off */
+//   * Server Error alert
+//
+//03 00 00 22 02 F0 80 68 00 01 03 EB 70 14 80 00 F1 BC FF 03 10 00 07 00 00 00 02 00 00 00 04 00 00 00
+//
+//
+// Frame: Number = 30, Captured Frame Length = 91, MediaType = DecryptedPayloadHeader
+//+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+// TLSSSLData: Transport Layer Security (TLS) Payload Data
+//+ TLS: TLS Rec Layer-1 SSL Application Data
+// ISOTS: TPKTCount = 1
+//- TPKT: version: 3, Length: 34
+//    version: 3 (0x3)
+//    Reserved: 0 (0x0)
+//    PacketLength: 34 (0x22)
+//- X224: Data
+//    Length: 2 (0x2)
+//    Type: Data
+//    EOT: 128 (0x80)
+//- T125: Data Packet
+// - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+//  - Type: Send Data Indication
+//    - RootIndex: 26
+//      Value: (011010..) 0x1a
+//  - UserID: 0x3ea
+//    - UserID: 0x3ea
+//    - ChannelId: 1002
+//     - Align: No Padding
+//        Padding2: (00......) 0x0
+//       Value: 1 (0x1)
+//  - Channel: 0x3eb
+//    - ChannelId: 1003
+//      Align: No Padding
+//      Value: 1003 (0x3EB)
+//  - DataPriority: high
+//    - DataPriority: high
+//    - RootIndex: 1
+//       Value: (01......) 0x1
+//  - Segmentation: Begin End
+//     Begin: (1.......) Begin
+//     End:   (.1......) End
+//  - Length: 20
+//    - Align: No Padding
+//      Padding4: (0000....) 0x0
+//     Length: 20
+//    RDP: RDPBCGR
+//- RDPBCGR: RDPELE
+// - SecurityHeader: License Packet
+//  - Flags: 128 (0x80)
+//     SecurityExchange:        (...............0) Not Security Exchange PDU
+//     Reserved1:               (.............00.) Reserved
+//     Encrypted:               (............0...) Not Encrypted packet
+//     ResetSeqNumber:          (...........0....) MUST be ignored.
+//     IgnoreSeqNumber:         (..........0.....) MUST be ignored.
+//     InfoPacket:              (.........0......) Not Client Info PDU
+//     LicensePacket:           (........1.......) License Packet
+//     Reserved2:               (.......0........) Reserved
+//     LicensePacketEncryption: (......0.........) Not License Packet Encryption
+//     ServerRedirectionPacket: (.....0..........) Not Standard Security Server Redirection PDU
+//     ImprovedChecksumForMACG: (....0...........) Not Improved Checksum for MAC Generation
+//     Reserved3:               (.000............) Reserved
+//     FlagsHiValid:            (0...............) FlagsHi should be ignored
+//    FlagsHi: Should be ignored
+//- RDPELE: GM_ERROR_ALERT
+// - TsPreambleHeader: Type = GM_ERROR_ALERT
+//    MsgType: GM_ERROR_ALERT
+//  - Flags: 3 (0x3)
+//     LicenseProtocolVersionMask: (....0011) RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
+//     Unused:                     (.000....)
+//     ExtendedErrorMSGsupported:  (0.......) that extended error information using the License Error Message is NOT supported.
+//    MsgSize: 16 (0x10)
+// - TsLicenseErrorMessage: ErrorCode = STATUS_VALID_CLIENT
+//    ErrorCode: STATUS_VALID_CLIENT
+//    StateTransition: ST_NO_TRANSITION
+//  - LiceseBinaryBlob: Type = Not Available
+//     RandomData: This value should be ignored
+//     BlobLen: 0 (0x0)
+//
+
+}


[13/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
new file mode 100755
index 0000000..a4ead0c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/debug/ServerPacketSniffer.java
@@ -0,0 +1,49 @@
+// 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.debug;
+
+/**
+ * Try to determine packet content by it header fingerprint.
+ */
+public class ServerPacketSniffer extends PacketSniffer {
+
+    private static final Pair[] serverRegexps = new Pair[] {
+// @formatter:off
+        new Pair("Server FastPath update",             "04"),
+        new Pair("Server X224ConnectionRequest",       "03 00 XX XX 0E D0"),
+        new Pair("Server MCSConnectResponse",          "03 00 XX XX 02 F0 80 7F 66 5A"),
+        new Pair("Server AttachUserConfirm",           "03 00 XX XX 02 F0 80 2E"),
+        new Pair("Server ChannelJoinConfirm",          "03 00 XX XX 02 F0 80 3E"),
+        new Pair("Server ErrorAlert",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 14 80 00"),
+        new Pair("Server DemandActivePDU",             "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX XX 11"),
+        new Pair("Server ControlPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 14"),
+        new Pair("Server SynchronizePDU",              "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 1F"),
+        new Pair("Server FontMapPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 28"),
+        new Pair("Server SET_ERROR_INFO_PDU",          "03 00 XX XX 02 F0 80 68 00 01 03 EB 30 XX XX XX 17 00 00 00 EA 03 XX 00 XX XX XX XX 2F"),
+        new Pair("Server DeactivateAllPDU",            "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 16 00"),
+        new Pair("Server CloseConnection",             "03 00 00 09 02 F0 80 21 80"),
+        new Pair("Server CredSSP",                     "30"),
+
+        new Pair("Server a TPKT packet",               "03"),
+        new Pair("Server a FastPath packet",           "00"),
+        // @formatter:on
+    };
+
+    public ServerPacketSniffer(String id) {
+        super(id, serverRegexps);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
new file mode 100755
index 0000000..05af4c0
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
@@ -0,0 +1,121 @@
+// 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.hyperv;
+
+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;
+
+/**
+ * For HyperV server, client must send VM ID before any other packet.
+ */
+public class ClientPreConnectionBlob extends OneTimeSwitch {
+
+    protected String data;
+
+    public ClientPreConnectionBlob(String id, String data) {
+        super(id);
+        this.data = data;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("This element only sends data. This method must not be called. Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        sendPreConnectionBlobData(data);
+    }
+
+    protected void sendPreConnectionBlobData(String data) {
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        // Header
+        buf.writeBytes(new byte[] {(byte)0x5e, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,});
+
+        // Length of string in wide characters + two wide \0 (LE)
+        buf.writeShortLE(data.length() + 2);
+
+        // Wide string + two wide '\0' characters
+        buf.writeString(data + "\0\0", RdpConstants.CHARSET_16);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * 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[] {
+                // Header
+                (byte) 0x5e, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Length of string in wide characters + two wide \0 (LE)
+                (byte) 0x26, (byte) 0x00,
+
+                // Wide string
+                (byte) 0x33, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x46,
+                (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+                (byte) 0x30, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38,
+                (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x42, (byte) 0x00, (byte) 0x37, (byte) 0x00, (byte) 0x39, (byte) 0x00,
+                (byte) 0x36, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x43, (byte) 0x00, (byte) 0x36,
+                (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x36, (byte) 0x00,
+                (byte) 0x35, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x41, (byte) 0x00,
+
+                // Two wide \0
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element pcb = new ClientPreConnectionBlob("pcb", "39418F90-6D03-468E-B796-91C60DD6653A");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, pcb, sink, mainSink);
+        pipeline.link("source", "pcb", "mainSink");
+        pipeline.link("pcb >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
new file mode 100755
index 0000000..8bac4ab
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
@@ -0,0 +1,177 @@
+// 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 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;
+import common.asn1.Tag;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236641.aspx
+ */
+public class ClientNtlmsspNegotiate extends OneTimeSwitch {
+
+    /**
+     * The set of client configuration flags (section 2.2.2.5) that specify the
+     * full set of capabilities of the client.
+     */
+    public NegoFlags clientConfigFlags = new NegoFlags().set_NEGOTIATE_56().set_NEGOTIATE_KEY_EXCH().set_NEGOTIATE_128().set_NEGOTIATE_VERSION()
+            .set_NEGOTIATE_EXTENDED_SESSION_SECURITY().set_NEGOTIATE_ALWAYS_SIGN().set_NEGOTIATE_NTLM().set_NEGOTIATE_LM_KEY().set_NEGOTIATE_SEAL()
+            .set_NEGOTIATE_SIGN().set_REQUEST_TARGET().set_NEGOTIATE_OEM().set_NEGOTIATE_UNICODE();
+
+    protected NtlmState ntlmState;
+
+    public ClientNtlmsspNegotiate(String id, NtlmState state) {
+        super(id);
+        ntlmState = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        ByteBuffer negoToken = generateNegotiateMessage();
+        ntlmState.negotiateMessage = negoToken.toByteArray(); // Store message for MIC calculation in AUTH message
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+        NegoItem negoItem = new NegoItem("NegoItem");
+        negoItem.negoToken.value = negoToken;
+        tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private ByteBuffer generateNegotiateMessage() {
+        ByteBuffer buf = new ByteBuffer(1024);
+
+        // Signature
+        buf.writeString("NTLMSSP", RdpConstants.CHARSET_8);
+        buf.writeByte(0);
+
+        // Message type
+        buf.writeIntLE(NtlmConstants.NEGOTIATE);
+
+        buf.writeIntLE(clientConfigFlags.value); // Flags
+
+        // If the NTLMSSP_NEGOTIATE_VERSION flag is set by the client application,
+        // the Version field MUST be set to the current version (section 2.2.2.10),
+        // the DomainName field MUST be set to a zero-length string, and the
+        // Workstation field MUST be set to a zero-length string.
+
+        // Domain: ""
+        buf.writeShortLE(0); // Length
+        buf.writeShortLE(0); // Allocated space
+        buf.writeIntLE(0); // Offset
+
+        // Workstation: ""
+        buf.writeShortLE(0); // Length
+        buf.writeShortLE(0); // Allocated space
+        buf.writeIntLE(0); // Offset
+
+        // OS Version: 6.1 (Build 7601); NTLM Current Revision 15
+        buf.writeBytes(new byte[] {(byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f});
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        return buf;
+    }
+
+    /**
+     * 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[] {
+                // CredSSP BER header:
+
+                (byte)0x30, // Sequence
+                (byte)0x37, // Length, 55 bytes
+
+                (byte)0xa0, (byte)0x03, // TAG: [0] (constructed) LEN: 3 byte
+                (byte)0x02, (byte)0x01, (byte)0x02, // Version: (int, 1 byte, 0x02)
+
+                // Sequence of sequence
+                (byte)0xa1, (byte)0x30, // TAG: [1] (constructed) LEN: 48 bytes
+                (byte)0x30, (byte)0x2e, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 46 bytes
+                (byte)0x30, (byte)0x2c, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 44 bytes
+                (byte)0xa0, (byte)0x2a, // TAG: [0] (constructed) LEN: 42 bytes
+
+
+                (byte)0x04, (byte)0x28, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 40 bytes
+
+                // NTLM negotiate request
+
+                (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, // "NTLMSSP\0"
+
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, // Message type: NEGOTIATE (0x1, LE)
+
+                (byte)0xb7, (byte)0x82, (byte)0x08, (byte)0xe2, // Flags: 0xe20882b7 (LE)
+
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Domain (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Workstation  (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+                (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f, // OS Version: 6.1 (Build 7601); NTLM Current Revision 15, 8 bytes
+
+        };
+        /* @formatter:on */
+
+        NtlmState state = new NtlmState();
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", state);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_negotiate, sink, mainSink);
+        pipeline.link("source", "ntlmssp_negotiate", "mainSink");
+        pipeline.link("ntlmssp_negotiate >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
new file mode 100755
index 0000000..ffd1630
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
@@ -0,0 +1,680 @@
+// 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.nio.charset.Charset;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.SubjectPublicKeyInfo;
+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.Dumper;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import streamer.ssl.SSLState;
+import common.asn1.Tag;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236643.aspx
+ */
+public class ClientNtlmsspPubKeyAuth extends OneTimeSwitch implements NtlmConstants, Dumper {
+
+    /**
+     * Offset of first byte of allocated block after NTLMSSP header and block
+     * descriptors.
+     */
+    private static final int BLOCKS_OFFSET = 88;
+
+    protected NtlmState ntlmState;
+    protected SSLState sslState;
+
+    protected String targetDomain;
+    protected String user;
+    protected String password;
+    protected String workstation;
+    protected String serverHostName;
+
+    public ClientNtlmsspPubKeyAuth(String id, NtlmState ntlmState, SSLState sslState, String serverHostName, String targetDomain, String workstation,
+            String user, String password) {
+        super(id);
+        this.ntlmState = ntlmState;
+        this.sslState = sslState;
+        this.serverHostName = serverHostName;
+        this.targetDomain = targetDomain;
+        this.workstation = workstation;
+        this.user = user;
+        this.password = password;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        /*
+         * @see
+         * http://blogs.msdn.com/b/openspecification/archive/2010/04/20/ntlm-keys
+         * -and-sundry-stuff.aspx
+         */
+        ntlmState.domain = targetDomain;
+        ntlmState.user = user;
+        ntlmState.password = password;
+        ntlmState.workstation = workstation;
+        ntlmState.generateServicePrincipalName(serverHostName);
+        ntlmState.ntlm_construct_authenticate_target_info();
+        ntlmState.ntlm_generate_timestamp();
+        ntlmState.ntlm_generate_client_challenge();
+        ntlmState.ntlm_compute_lm_v2_response();
+        ntlmState.ntlm_compute_ntlm_v2_response();
+        ntlmState.ntlm_generate_key_exchange_key();
+        ntlmState.ntlm_generate_random_session_key();
+        ntlmState.ntlm_generate_exported_session_key();
+        ntlmState.ntlm_encrypt_random_session_key();
+        ntlmState.ntlm_init_rc4_seal_states();
+
+        ByteBuffer authenticateMessage = generateAuthenticateMessage(ntlmState);
+        ByteBuffer messageSignatureAndEncryptedServerPublicKey = generateMessageSignatureAndEncryptedServerPublicKey(ntlmState);
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(4096, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+        NegoItem negoItem = new NegoItem("NegoItem");
+        negoItem.negoToken.value = authenticateMessage;
+
+        tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+        tsRequest.pubKeyAuth.value = messageSignatureAndEncryptedServerPublicKey;
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private byte[] getServerPublicKey() {
+        // SSL certificate public key with algorithm
+        ByteBuffer subjectPublicKeyInfo = new ByteBuffer(sslState.serverCertificateSubjectPublicKeyInfo);
+
+        // Parse subjectPublicKeyInfo
+        SubjectPublicKeyInfo parser = new SubjectPublicKeyInfo("SubjectPublicKeyInfo");
+        parser.readTag(subjectPublicKeyInfo);
+
+        // Copy subjectPublicKey subfield to separate byte buffer
+        ByteBuffer subjectPublicKey = new ByteBuffer(subjectPublicKeyInfo.length);
+        parser.subjectPublicKey.writeTag(subjectPublicKey);
+
+        subjectPublicKeyInfo.unref();
+        subjectPublicKey.trimAtCursor();
+
+        // Skip tag:
+        // 03 82 01 0f (tag) 00 (padding byte)
+        subjectPublicKey.trimHeader(5);// FIXME: parse it properly
+        // * DEBUG */System.out.println("DEBUG: subjectPublicKey:\n" +
+        // subjectPublicKey.dump());
+
+        ntlmState.subjectPublicKey = subjectPublicKey.toByteArray();
+
+        return ntlmState.subjectPublicKey;
+    }
+
+    /**
+     * 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.
+     */
+    private ByteBuffer generateMessageSignatureAndEncryptedServerPublicKey(NtlmState ntlmState) {
+        return new ByteBuffer(ntlmState.ntlm_EncryptMessage(getServerPublicKey()));
+    }
+
+    public static ByteBuffer generateAuthenticateMessage(NtlmState ntlmState) {
+
+        // Allocate memory for blocks from given fixed offset
+        int blocksCursor = BLOCKS_OFFSET;
+
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        // Signature: "NTLMSSP\0"
+        buf.writeString(NTLMSSP, RdpConstants.CHARSET_8);
+        buf.writeByte(0);
+
+        // NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+        buf.writeIntLE(NtlmConstants.NTLMSSP_AUTH);
+
+        // Although the protocol allows authentication to succeed if the client
+        // provides either LmChallengeResponse or NtChallengeResponse, Windows
+        // implementations provide both.
+
+        // LM V2 response
+        blocksCursor = writeBlock(buf, ntlmState.lmChallengeResponse, blocksCursor);
+
+        // NT v2 response
+        blocksCursor = writeBlock(buf, ntlmState.ntChallengeResponse, blocksCursor);
+
+        // DomainName
+        blocksCursor = writeStringBlock(buf, ntlmState.domain, blocksCursor, RdpConstants.CHARSET_16);
+
+        // UserName
+        blocksCursor = writeStringBlock(buf, ntlmState.user, blocksCursor, RdpConstants.CHARSET_16);
+
+        // Workstation
+        blocksCursor = writeStringBlock(buf, ntlmState.workstation, blocksCursor, RdpConstants.CHARSET_16);
+
+        // EncryptedRandomSessionKey, 16 bytes
+        blocksCursor = writeBlock(buf, ntlmState.encryptedRandomSessionKey, blocksCursor);
+
+        // NegotiateFlags (4 bytes): In connection-oriented mode, a NEGOTIATE
+        // structure that contains the set of bit flags (section 2.2.2.5) negotiated
+        // in the previous messages.
+        buf.writeIntLE(/*ntlmState.negotiatedFlags.value*/0xe288b235); // FIXME: remove hardcoded value
+
+        buf.writeBytes(generateVersion());
+
+        // If the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an
+        // MsvAvTimestamp present, the client SHOULD provide a MIC(Message Integrity
+        // Check)
+
+        int savedCursorForMIC = buf.cursor; // Save cursor position to write MIC
+        // later
+        buf.writeBytes(new byte[16]); // Write 16 zeroes
+
+        if (BLOCKS_OFFSET != buf.cursor)
+            throw new RuntimeException("BUG: Actual offset of first byte of allocated blocks is not equal hardcoded offset. Hardcoded offset: " + BLOCKS_OFFSET
+                    + ", actual offset: " + buf.cursor + ". Update hardcoded offset to match actual offset.");
+
+        buf.cursor = blocksCursor;
+        buf.trimAtCursor();
+
+        ntlmState.authenticateMessage = buf.toByteArray();
+
+        // Calculate and write MIC to reserved position
+        ntlmState.ntlm_compute_message_integrity_check();
+        buf.cursor = savedCursorForMIC;
+        buf.writeBytes(ntlmState.messageIntegrityCheck);
+        buf.rewindCursor();
+
+        return buf;
+    }
+
+    /**
+     * Write string as security buffer, using given charset, without trailing '\0'
+     * character.
+     */
+    private static int writeStringBlock(ByteBuffer buf, String string, int blocksCursor, Charset charset) {
+        return writeBlock(buf, string.getBytes(charset), blocksCursor);
+    }
+
+    /**
+     * Write block to blocks buffer and block descriptor to main buffer.
+     */
+    private static int writeBlock(ByteBuffer buf, byte[] block, int blocksCursor) {
+
+        // Write block descriptor
+
+        // Length
+        buf.writeShortLE(block.length);
+        // Allocated
+        buf.writeShortLE(block.length);
+        // Offset
+        buf.writeIntLE(blocksCursor);
+
+        // Write block to position pointed by blocksCursor instead of buf.cursor
+        int savedCursor = buf.cursor;
+        buf.cursor = blocksCursor;
+        buf.writeBytes(block);
+        blocksCursor = buf.cursor;
+        buf.cursor = savedCursor;
+
+        return blocksCursor;
+    }
+
+    /**
+     * Version (8 bytes): A VERSION structure (section 2.2.2.10) that is present
+     * only when the NTLMSSP_NEGOTIATE_VERSION flag is set in the NegotiateFlags
+     * field. This structure is used for debugging purposes only. In normal
+     * protocol messages, it is ignored and does not affect the NTLM message
+     * processing.
+     */
+    private static byte[] generateVersion() {
+        // Version (6.1, Build 7601), NTLM current revision: 15
+        return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        /* @formatter:off */
+        //
+        // Client NEGOTIATE
+        //
+        byte[] clientNegotiatePacket = new byte[] {
+                (byte)0x30, (byte)0x37, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x30, (byte)0x30, (byte)0x2e, (byte)0x30, (byte)0x2c, (byte)0xa0, (byte)0x2a, (byte)0x04,
+                (byte)0x28, (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xb7, (byte)0x82, (byte)0x08,
+                (byte)0xe2, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f,
+        };
+
+//
+// Server CHALLENGE
+//
+        byte[] serverChallengePacket = 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: NEGOTIATE_56 NEGOTIATE_KEY_EXCH NEGOTIATE_128 NEGOTIATE_VERSION NEGOTIATE_TARGET_INFO NEGOTIATE_EXTENDED_SESSION_SECURITY TARGET_TYPE_SERVER NEGOTIATE_ALWAYS_SIGN NEGOTIATE_NTLM NEGOTIATE_SEAL NEGOTIATE_SIGN REQUEST_TARGET NEGOTIATE_UNICODE
+
+                (byte)0xc1, (byte)0x4a, (byte)0xc8, (byte)0x98, (byte)0x2f, (byte)0xd1, (byte)0x93, (byte)0xd4, //  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)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+
+                // Attribute: End of list
+                0x00, 0x00,
+                0x00, 0x00,
+
+        };
+
+//
+// Client NTLMSSP_AUTH
+//
+        byte[] clientAuthPacket = new byte[] {
+                0x30, (byte) 0x82, 0x03, 0x13, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 787 bytes
+
+                //
+                // TSRequest.version
+                //
+                (byte) 0xa0, 0x03, //  TAG: [0] (constructed) LEN: 3 bytes
+                0x02, 0x01, 0x02, //  TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes
+
+                //
+                // TSRequest.negoData
+                //
+                (byte) 0xa1, (byte) 0x82, 0x01, (byte) 0xe4, //  TAG: [1] (constructed) LEN: 484 bytes
+                0x30, (byte) 0x82, 0x01, (byte) 0xe0, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 480 bytes
+                0x30, (byte) 0x82, 0x01, (byte) 0xdc, //  TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 476 bytes
+
+                //
+                // NegoItem.negoToken
+                //
+                (byte) 0xa0, (byte) 0x82, 0x01, (byte) 0xd8, //  TAG: [0] (constructed) LEN: 472 bytes
+                0x04, (byte) 0x82, 0x01, (byte) 0xd4,  // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 468 bytes
+
+                // NTLMSSP
+
+                0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, //  "NTLMSSP\0"
+
+                0x03, 0x00, 0x00, 0x00, //  NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+                0x18, 0x00, 0x18, 0x00, (byte) 0x92, 0x00, 0x00, 0x00, //  LmChallengeResponse (length 24, allocated: 24, offset 146)
+                0x1a, 0x01, 0x1a, 0x01, (byte) 0xaa, 0x00, 0x00, 0x00, //  NtChallengeResponse (length 282, allocated: 282, offset 170)
+                0x12, 0x00, 0x12, 0x00, 0x58, 0x00, 0x00, 0x00,  // DomainName (length 18, allocated: 88, offset 88)
+                0x1a, 0x00, 0x1a, 0x00, 0x6a, 0x00, 0x00, 0x00,  // UserName (length 26, allocated:26, offset 106)
+                0x0e, 0x00, 0x0e, 0x00, (byte) 0x84, 0x00, 0x00, 0x00,  // Workstation (length 14, offset 132)
+                0x10, 0x00, 0x10, 0x00, (byte) 0xc4, 0x01, 0x00, 0x00,  // EncryptedRandomSessionKey (length 16, offset 452)
+                0x35, (byte) 0xb2, (byte) 0x88, (byte) 0xe2,   // NegotiateFlags
+                0x06, 0x01, (byte) 0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f, //  Version (6.1, Build 7601), NTLM current revision: 15
+
+                (byte)0x8c, (byte)0x69, (byte)0x53, (byte)0x1c, (byte)0xbb, (byte)0x6f, (byte)0xfb, (byte)0x9a, (byte)0x5d, (byte)0x2c, (byte)0x63, (byte)0xf2, (byte)0xc9, (byte)0x51, (byte)0xc5, (byte)0x11, // Message integrity check
+
+                0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x67, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x70, 0x00, // Domain name value: "Workgroup"
+
+                0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00,  // User name value: "Administrator"
+
+                0x61, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x33, 0x00, //  Workstation host name value: "apollo3"
+
+                // Lan manager challenge response value
+                // Response: HMAC_MD(ResponseKeyLM, concatenate(ServerChallenge, ClientChallenge), where ResponseKeyLM=ntlmv2Hash(target, user, password)
+                (byte)0x17, (byte)0x9b, (byte)0x7d, (byte)0x7b, (byte)0x2f, (byte)0x79, (byte)0x9f, (byte)0x19, (byte)0xa0, (byte)0x4b, (byte)0x00, (byte)0xed, (byte)0x2b, (byte)0x39, (byte)0xbb, (byte)0x23,
+                // Client challenge (fixed for debugging)
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+
+                //
+                // NTLM challenge response value:
+                //
+
+                (byte)0x49, (byte)0xea, (byte)0x27, (byte)0x4f, (byte)0xcc, (byte)0x05, (byte)0x8b, (byte)0x79, (byte)0x20, (byte)0x0b, (byte)0x08, (byte)0x42, (byte)0xa9, (byte)0xc8, (byte)0x0e, (byte)0xc7, //  HMAC
+
+                0x01, 0x01, 0x00, 0x00, // Header: 0x00000101 (LE)
+                0x00, 0x00, 0x00, 0x00, // Reserved: 0x00000000
+                (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, // Client challenge (fixed)
+                0x00, 0x00, 0x00, 0x00, //  Reserved
+
+                // 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)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Timestamp: Oct 10, 2013 23:36:20.056937300 EEST
+
+                0x06, 0x00,  // Item Type: Flags (0x0006, LE)
+                0x04, 0x00, // Item Length: 4 (LE)
+                0x02, 0x00, 0x00, 0x00, // Flags: 0x00000002
+
+                0x0a, 0x00, // Item Type: Channel Bindings (0x000a, LE)
+                0x10, 0x00, // Item Length: 16 (LE)
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Channel Bindings: 00000000000000000000000000000000
+
+                0x09, 0x00, // Item Type: Target Name (0x0009, LE)
+                0x2a, 0x00, // Item Length: 42 (LE)
+                0x54, 0x00, 0x45, 0x00, 0x52, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x52, 0x00, 0x56, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, // Target Name: "TERMSRV/192.168.0.101" (UTF-16)
+
+                // Attribute: End of list
+                0x00, 0x00,  //
+                0x00, 0x00,  //
+                // Attribute: End of list
+                0x00, 0x00,  //
+                0x00, 0x00,  //
+                // Attribute: End of list
+                0x00, 0x00,  //
+                0x00, 0x00,  //
+                // Attribute: End of list
+                0x00, 0x00,  //
+                0x00, 0x00,  //
+
+                // Session Key
+                // RC4 key (Server KeyExchangeKey or SessionBaseKey):
+                // 6e bd e3 da 83 c2 fd f1 38 a2 78 be 8c e6 75 d6
+                //
+                // RC4 data (Client nonce):
+                // 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
+                //
+                // RC4 encrypted:
+                // 2c 24 da 10 17 cf 40 69 35 49 6f 58 e1 29 9e 79
+                (byte)0x2c, (byte)0x24, (byte)0xda, (byte)0x10, (byte)0x17, (byte)0xcf, (byte)0x40, (byte)0x69, (byte)0x35, (byte)0x49, (byte)0x6f, (byte)0x58, (byte)0xe1, (byte)0x29, (byte)0x9e, (byte)0x79,
+
+                //
+                // TSRequest.publicKey
+                //
+                (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
+
+                // NTLMSSP_MESSAGE_SIGNATURE, @see http://msdn.microsoft.com/en-us/library/cc422952.aspx
+
+                // Version: 0x00000001
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+
+                // Checksum (8 bytes): An 8-byte array that contains the checksum for the message.
+                (byte)0x72, (byte)0x76, (byte)0x1e, (byte)0x57, (byte)0x49, (byte)0xb5, (byte)0x0f, (byte)0xad,
+
+                // seqNum of the message: 0
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+                // Encrypted public key
+                (byte)0x15, (byte)0xf7, (byte)0xf2, (byte)0x54, (byte)0xda, (byte)0xa9, (byte)0xe5, (byte)0xad, (byte)0x85, (byte)0x04, (byte)0x67, (byte)0x4d, (byte)0x0b, (byte)0xcb, (byte)0xf9, (byte)0xb1,
+                (byte)0xf8, (byte)0x02, (byte)0x8a, (byte)0x77, (byte)0xc2, (byte)0x63, (byte)0xab, (byte)0xd5, (byte)0x74, (byte)0x23, (byte)0x9f, (byte)0x9d, (byte)0x5d, (byte)0x1f, (byte)0xd3, (byte)0xb3,
+                (byte)0xa0, (byte)0xac, (byte)0x16, (byte)0x8a, (byte)0x4b, (byte)0x08, (byte)0xf5, (byte)0x47, (byte)0x70, (byte)0x58, (byte)0x10, (byte)0xb4, (byte)0xe7, (byte)0x87, (byte)0xb3, (byte)0x4b,
+                (byte)0xc9, (byte)0xa2, (byte)0xd5, (byte)0xd1, (byte)0xca, (byte)0x0f, (byte)0xd4, (byte)0xe3, (byte)0x8d, (byte)0x76, (byte)0x5a, (byte)0x60, (byte)0x28, (byte)0xf8, (byte)0x06, (byte)0x5d,
+                (byte)0xe4, (byte)0x7e, (byte)0x21, (byte)0xc8, (byte)0xbb, (byte)0xac, (byte)0xe5, (byte)0x79, (byte)0x85, (byte)0x30, (byte)0x9b, (byte)0x88, (byte)0x13, (byte)0x2f, (byte)0x8f, (byte)0xfc,
+                (byte)0x04, (byte)0x52, (byte)0xfe, (byte)0x87, (byte)0x94, (byte)0xcf, (byte)0xcb, (byte)0x49, (byte)0x4a, (byte)0xda, (byte)0x6f, (byte)0xdd, (byte)0xee, (byte)0x57, (byte)0xa5, (byte)0xe4,
+                (byte)0x4d, (byte)0x0e, (byte)0x5c, (byte)0x3d, (byte)0x0b, (byte)0x63, (byte)0x1f, (byte)0xf6, (byte)0x3d, (byte)0x1b, (byte)0xae, (byte)0x5a, (byte)0xf6, (byte)0x42, (byte)0x2a, (byte)0x46,
+                (byte)0xfa, (byte)0x42, (byte)0x71, (byte)0x67, (byte)0x46, (byte)0x02, (byte)0x71, (byte)0xea, (byte)0x51, (byte)0x98, (byte)0xf7, (byte)0xd4, (byte)0x43, (byte)0xbf, (byte)0x8e, (byte)0xe8,
+                (byte)0x3c, (byte)0xc8, (byte)0xfa, (byte)0x79, (byte)0x9d, (byte)0x8c, (byte)0xfc, (byte)0xc2, (byte)0x42, (byte)0xc9, (byte)0xbb, (byte)0xd0, (byte)0xab, (byte)0x81, (byte)0xc4, (byte)0x53,
+                (byte)0xfd, (byte)0x41, (byte)0xda, (byte)0xab, (byte)0x0f, (byte)0x25, (byte)0x79, (byte)0x5f, (byte)0xbd, (byte)0xa3, (byte)0x8c, (byte)0xd3, (byte)0xf5, (byte)0x1b, (byte)0xab, (byte)0x20,
+                (byte)0xd1, (byte)0xf4, (byte)0xd8, (byte)0x81, (byte)0x9c, (byte)0x18, (byte)0x4a, (byte)0xa4, (byte)0x77, (byte)0xee, (byte)0xe1, (byte)0x51, (byte)0xee, (byte)0x2a, (byte)0xc1, (byte)0x94,
+                (byte)0x37, (byte)0xc5, (byte)0x06, (byte)0x7a, (byte)0x3f, (byte)0x0f, (byte)0x25, (byte)0x5b, (byte)0x4e, (byte)0x6a, (byte)0xdc, (byte)0x0b, (byte)0x62, (byte)0x6f, (byte)0x12, (byte)0x83,
+                (byte)0x03, (byte)0xae, (byte)0x4e, (byte)0xce, (byte)0x2b, (byte)0x6e, (byte)0xd4, (byte)0xd5, (byte)0x23, (byte)0x27, (byte)0xf6, (byte)0xa6, (byte)0x38, (byte)0x67, (byte)0xec, (byte)0x95,
+                (byte)0x82, (byte)0xc6, (byte)0xba, (byte)0xd4, (byte)0xf6, (byte)0xe6, (byte)0x22, (byte)0x7d, (byte)0xb9, (byte)0xe4, (byte)0x81, (byte)0x97, (byte)0x24, (byte)0xff, (byte)0x40, (byte)0xb2,
+                (byte)0x42, (byte)0x3c, (byte)0x11, (byte)0x24, (byte)0xd0, (byte)0x3a, (byte)0x96, (byte)0xd9, (byte)0xc1, (byte)0x13, (byte)0xd6, (byte)0x62, (byte)0x45, (byte)0x21, (byte)0x60, (byte)0x5b,
+                (byte)0x7b, (byte)0x2b, (byte)0x62, (byte)0x44, (byte)0xf7, (byte)0x40, (byte)0x93, (byte)0x29, (byte)0x5b, (byte)0x44, (byte)0xb7, (byte)0xda, (byte)0x9c, (byte)0xa6, (byte)0xa9, (byte)0x3b,
+                (byte)0xe1, (byte)0x3b, (byte)0x9d, (byte)0x31, (byte)0xf2, (byte)0x21, (byte)0x53, (byte)0x0f, (byte)0xb3, (byte)0x70, (byte)0x55, (byte)0x84, (byte)0x2c, (byte)0xb4,
+        };
+
+        SSLState sslState = new SSLState();
+
+        sslState.serverCertificateSubjectPublicKeyInfo = new byte[] {
+                0x30, (byte) 0x82, 0x01, 0x22, // Sequence, length: 290 bytes
+                0x30, 0x0d, // Sequence, length: 13 bytes {
+                0x06, 0x09, // Object ID, length: 9 bytes
+                0x2a, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xf7, 0x0d, 0x01, 0x01, 0x01,
+                0x05, 0x00, // NULL, length: 0 bytes
+
+                (byte)0x03, (byte)0x82, (byte)0x01, (byte)0x0f, // Bit string, length: 271 bytes
+
+                (byte)0x00, // Pading
+                (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a, // Sequence
+                (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, // Integer, length: 257 bytes
+
+                (byte)0x00, (byte)0xa8, (byte)0x56,
+                (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0,
+                (byte)0x84, (byte)0x31, (byte)0x19, (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb,
+                (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13, (byte)0xa1, (byte)0xb9, (byte)0x72, (byte)0xbb,
+                (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65, (byte)0x03,
+                (byte)0xd1, (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69,
+                (byte)0x89, (byte)0x5e, (byte)0xfe, (byte)0xe0, (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b,
+                (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd, (byte)0x77, (byte)0x5d, (byte)0xf3,
+                (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2,
+                (byte)0xcf, (byte)0xb1, (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17,
+                (byte)0x7c, (byte)0xb7, (byte)0xd6, (byte)0xc7, (byte)0xc7, (byte)0xbf, (byte)0x90, (byte)0x4e,
+                (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0, (byte)0xc2, (byte)0x33,
+                (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91,
+                (byte)0x32, (byte)0xb7, (byte)0xd4, (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b,
+                (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea, (byte)0x8c, (byte)0x97, (byte)0x5f, (byte)0x51,
+                (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71, (byte)0xa7,
+                (byte)0xc7, (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69,
+                (byte)0xc8, (byte)0xd3, (byte)0xd9, (byte)0x4e, (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3,
+                (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca, (byte)0xda, (byte)0xc2, (byte)0x7f,
+                (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f,
+                (byte)0xea, (byte)0xcf, (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2,
+                (byte)0x19, (byte)0xc3, (byte)0xe0, (byte)0xe1, (byte)0x7a, (byte)0x45, (byte)0x71, (byte)0x12,
+                (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c, (byte)0x46, (byte)0x68,
+                (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22,
+                (byte)0x65, (byte)0x2d, (byte)0x43, (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae,
+                (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e, (byte)0x0c, (byte)0xbd, (byte)0xf5, (byte)0x46,
+                (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60, (byte)0xae,
+                (byte)0x45, (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e,
+                (byte)0xfb, (byte)0xb2, (byte)0xb6, (byte)0x78, (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a,
+                (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68, (byte)0x30, (byte)0x93, (byte)0x78,
+                (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe,
+                (byte)0x59, (byte)0x33, (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44,
+                (byte)0x3a, (byte)0x12, (byte)0xf4, (byte)0x07, (byte)0xa0, (byte)0x8d, (byte)0x02, (byte)0x03,
+                (byte)0x01, (byte)0x00, (byte)0x01,
+        };
+        /* @formatter:on */
+
+        NtlmState ntlmState = new NtlmState();
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverChallengePacket, new byte[] {1, 2, 3}));
+        Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", ntlmState);
+        Element ntlmssp_challenge = new ServerNtlmsspChallenge("ntlmssp_challenge", ntlmState);
+        Element ntlmssp_auth = new ClientNtlmsspPubKeyAuth("ntlmssp_auth", ntlmState, sslState, "192.168.0.101", "workgroup", "apollo3", "Administrator",
+                "R2Preview!");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientNegotiatePacket, clientAuthPacket), (Dumper)ntlmssp_auth);
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, ntlmssp_negotiate, ntlmssp_challenge, ntlmssp_auth, sink, mainSink);
+        pipeline.link("source", "ntlmssp_negotiate", "ntlmssp_challenge", "ntlmssp_auth", "mainSink");
+        pipeline.link("ntlmssp_negotiate >" + OTOUT, "ntlmssp_negotiate< sink");
+        pipeline.link("ntlmssp_challenge >" + OTOUT, "ntlmssp_challenge< sink");
+        pipeline.link("ntlmssp_auth >" + OTOUT, "ntlmssp_auth< sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+    @Override
+    public void dump(ByteBuffer buf) {
+        buf.rewindCursor();
+        TSRequest request = new TSRequest("TSRequest");
+        request.readTag(buf);
+        System.out.println("TSRequest version: " + request.version.value);
+        System.out.println("TSRequest pubKey: " + request.pubKeyAuth.value.toPlainHexString());
+
+        ByteBuffer negoToken = ((NegoItem)request.negoTokens.tags[0]).negoToken.value;
+        System.out.println("TSRequest negotoken: " + negoToken.toPlainHexString());
+        dumpNegoToken(negoToken);
+
+        negoToken.unref();
+    }
+
+    private void dumpNegoToken(ByteBuffer buf) {
+        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.NTLMSSP_AUTH)
+            throw new RuntimeException("Unexpected NTLM message type: " + messageType + ". Expected type: CHALLENGE (" + NtlmConstants.CHALLENGE + "). Data: " + buf
+                    + ".");
+
+        System.out.println("lmChallengeResponseFields: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+        ByteBuffer ntChallengeResponseBuf = ServerNtlmsspChallenge.readBlockByDescription(buf);
+        System.out.println("NtChallengeResponse: " + ntChallengeResponseBuf.toPlainHexString());
+        System.out.println("DomainName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("UserName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("Workstation: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+        System.out.println("EncryptedRandomSessionKey: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+        System.out.println("NegotiateFlags: " + new NegoFlags(buf.readSignedIntLE()));
+        System.out.println("Version: " + buf.readBytes(8).toPlainHexString());
+
+        dumpNtChallengeResponse(ntChallengeResponseBuf);
+    }
+
+    private void dumpNtChallengeResponse(ByteBuffer buf) {
+        System.out.println("HMAC: " + buf.readBytes(16).toPlainHexString());
+        System.out.format("Header: 0x%08x\n", buf.readUnsignedIntLE());
+        System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+        System.out.println("Time: " + buf.readBytes(8).toPlainHexString());
+        System.out.println("Client challenge: " + buf.readBytes(8).toPlainHexString());
+        System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+
+        // 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);
+            switch (type) {
+            case MSV_AV_NETBIOS_DOMAIN_NAME:
+                System.out.println("AV Netbios Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_NETBIOS_COMPUTER_NAME:
+                System.out.println("AV Netbios Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_DNS_DOMAIN_NAME:
+                System.out.println("AV DNS Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_DNS_COMPUTER_NAME:
+                System.out.println("AV DNS Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            case MSV_AV_CHANNEL_BINDINGS:
+                System.out.println("AV Channel Bindings: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_TIMESTAMP:
+                System.out.println("AV Timestamp: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_FLAGS:
+                System.out.println("AV Flags: " + data.readBytes(length).toPlainHexString());
+                break;
+            case MSV_AV_TARGET_NAME:
+                System.out.println("AV Target Name: " + data.readString(length, RdpConstants.CHARSET_16));
+                break;
+            default:
+                System.out.println("Unknown NTLM target info attribute: " + type + ". Data: " + data + ".");
+            }
+            data.unref();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
new file mode 100755
index 0000000..480f448
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
@@ -0,0 +1,128 @@
+// 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 rdpclient.ntlmssp.asn1.TSCredentials;
+import rdpclient.ntlmssp.asn1.TSPasswordCreds;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ClientNtlmsspUserCredentials extends OneTimeSwitch implements Element {
+
+    protected NtlmState ntlmState;
+
+    public ClientNtlmsspUserCredentials(String id, NtlmState ntlmState) {
+        super(id);
+        this.ntlmState = ntlmState;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        ByteBuffer buf = new ByteBuffer(4096, true);
+
+        TSRequest tsRequest = new TSRequest("TSRequest");
+        tsRequest.version.value = 2L;
+
+        ByteBuffer tsCredentialsBuf = generateTSCredentials();
+        tsRequest.authInfo.value = encryptTSCredentials(tsCredentialsBuf);
+        tsCredentialsBuf.unref();
+
+        tsRequest.writeTag(buf);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    private ByteBuffer encryptTSCredentials(ByteBuffer buf2) {
+        return new ByteBuffer(ntlmState.ntlm_EncryptMessage(buf2.toByteArray()));
+    }
+
+    private ByteBuffer generateTSCredentials() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        TSCredentials tsCredentials = new TSCredentials("authInfo");
+        // 1 means that credentials field contains a TSPasswordCreds structure
+        tsCredentials.credType.value = 1L;
+
+        ByteBuffer tsPasswordCredsBuf = new ByteBuffer(4096, true);
+        TSPasswordCreds tsPasswordCreds = new TSPasswordCreds("credentials");
+        tsPasswordCreds.domainName.value = new ByteBuffer(ntlmState.domain.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.userName.value = new ByteBuffer(ntlmState.user.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.password.value = new ByteBuffer(ntlmState.password.getBytes(RdpConstants.CHARSET_16));
+        tsPasswordCreds.writeTag(tsPasswordCredsBuf);
+        tsPasswordCredsBuf.trimAtCursor();
+        //* DEBUG */System.out.println("TSPasswordCreds:\n" + tsPasswordCredsBuf.dump());
+
+        tsCredentials.credentials.value = tsPasswordCredsBuf;
+
+        tsCredentials.writeTag(buf);
+        tsPasswordCredsBuf.unref();
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+        //* DEBUG */System.out.println("TSCredentials:\n" + buf.dump());
+
+        return buf;
+    }
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        // TODO Auto-generated method stub
+
+        /* @formatter:off */
+        // TSCredentials
+//  30 57 // Sequence
+//  a0 03 // TAG 0
+//  02 01 01 // Integer: 1 : credentials contains a TSPasswordCreds structure
+//  a1 50 // TAG 1
+//  04 4e // OCTETSTRING
+        // TSPasswordCreds
+//  30 4c // SEQUENCE
+//  a0 14 // TAG 0
+//  04 12 // OCTETSTRING
+//  77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 70 00 // "workgroup"
+//  a1 1c // TAG 1
+//  04 1a // OCTETSTRING
+//  41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 00 // "Administrator"
+//  a2 16 // TAG 2
+//  04 14 //
+//  52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 77 00 21 00 // "R2Preview!"
+        /* @formatter:on */
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
new file mode 100755
index 0000000..d0e72e9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
@@ -0,0 +1,361 @@
+// 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.lang.reflect.Method;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import rdpclient.rdp.RdpConstants;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236717.aspx
+ */
+public class CryptoAlgos implements NtlmConstants {
+
+    /**
+     * Indicates the left-to-right concatenation of the string parameters, from
+     * the first string to the Nnth. Any numbers are converted to strings and all
+     * numeric conversions to strings retain all digits, even nonsignificant ones.
+     * The result is a string. For example, ConcatenationOf(0x00122, "XYZ",
+     * "Client") results in the string "00122XYZClient."
+     */
+    public static String concatenationOf(String... args) {
+        StringBuffer sb = new StringBuffer();
+        for (String arg : args) {
+            sb.append(arg);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Concatenate byte arrays.
+     */
+    public static byte[] concatenationOf(byte[]... arrays) {
+        int length = 0;
+        for (byte[] array : arrays) {
+            length += array.length;
+        }
+
+        byte[] result = new byte[length];
+        int destPos = 0;
+        for (byte[] array : arrays) {
+            System.arraycopy(array, 0, result, destPos, array.length);
+            destPos += array.length;
+        }
+
+        return result;
+    }
+
+    /** Indicates a 32-bit CRC calculated over m. */
+    public static byte[] CRC32(byte[] m) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of an 8-byte data item d with the 7-byte key k
+     * using the Data Encryption Standard (DES) algorithm in Electronic Codebook
+     * (ECB) mode. The result is 8 bytes in length ([FIPS46-2]).
+     */
+    public static byte[] DES(byte[] k, byte[] d) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of an 8-byte data item D with the 16-byte key K
+     * using the Data Encryption Standard Long (DESL) algorithm. The result is 24
+     * bytes in length. DESL(K, D) is computed as follows.
+     *
+     * <pre>
+     *   ConcatenationOf( DES(K[0..6], D),
+     *     DES(K[7..13], D), DES(
+     *       ConcatenationOf(K[14..15], Z(5)), D));
+     * </pre>
+     *
+     * Note K[] implies a key represented as a character array.
+     */
+    public static byte[] DESL(byte[] k, byte[] d) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * An auxiliary function that returns an operating system version-specific
+     * value (section 2.2.2.8).
+     */
+    public static byte[] getVersion() {
+        // Version (6.1, Build 7601), NTLM current revision: 15
+        return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+    }
+
+    /**
+     * Retrieve the user's LM response key from the server database (directory or
+     * local database).
+     */
+    public static byte[] LMGETKEY(byte[] u, byte[] d) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /** Retrieve the user's NT response key from the server database. */
+    public static byte[] NTGETKEY(byte[] u, byte[] d) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the encryption of data item m with the key k using the HMAC
+     * algorithm ([RFC2104]).
+     */
+    public static byte[] HMAC(byte[] k, byte[] m) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the computation of a 16-byte HMAC-keyed MD5 message digest of the
+     * byte string m using the key k.
+     */
+    public static byte[] HMAC_MD5(byte[] k, byte[] m) {
+        try {
+            String algorithm = "HMacMD5";
+            Mac hashMac = Mac.getInstance(algorithm);
+
+            Key secretKey = new SecretKeySpec(k, 0, k.length, algorithm);
+            hashMac.init(secretKey);
+            return hashMac.doFinal(m);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate HMAC-MD5.", e);
+        }
+    }
+
+    /**
+     * Produces a key exchange key from the session base key K, LM response and
+     * server challenge SC as defined in the sections KXKEY, SIGNKEY, and SEALKEY.
+     */
+    public static byte[] KXKEY(byte[] sessionBaseKey/*K, byte[] LM, byte[] SC*/) {
+        // Key eXchange Key is server challenge
+        /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */
+        return Arrays.copyOf(sessionBaseKey, sessionBaseKey.length);
+    }
+
+    /**
+     * Computes a one-way function of the user's password to use as the response
+     * key. NTLM v1 and NTLM v2 define separate LMOWF() functions in the NTLM v1
+     * authentication and NTLM v2 authentication sections, respectively.
+     */
+    public static byte[] LMOWF() {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the computation of an MD4 message digest of the null-terminated
+     * byte string m ([RFC1320]).
+     */
+    public static byte[] MD4(byte[] m) {
+        try {
+            return sun.security.provider.MD4.getInstance().digest(m);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /**
+     * Indicates the computation of an MD5 message digest of the null-terminated
+     * byte string m ([RFC1321]).
+     */
+    public static byte[] MD5(byte[] m) {
+        try {
+            return MessageDigest.getInstance("MD5").digest(m);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /**
+     * Indicates the computation of an MD5 message digest of a binary blob
+     * ([RFC4121] section 4.1.1.2).
+     */
+    public static byte[] MD5_HASH(byte[] m) {
+        try {
+            return MessageDigest.getInstance("MD5").digest(m);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot calculate MD5.", e);
+        }
+    }
+
+    /** A zero-length string. */
+    public static final String NIL = "";
+
+    /**
+     * Indicates the computation of an n-byte cryptographic-strength random
+     * number.
+     *
+     * Note The NTLM Authentication Protocol does not define the statistical
+     * properties of the random number generator. It is left to the discretion of
+     * the implementation to define the strength requirements of the NONCE(n)
+     * operation.
+     */
+    public static byte[] NONCE(int n) {
+        // Generate random nonce for LMv2 and NTv2 responses
+        byte[] nonce = new byte[n];
+        SecureRandom random = new SecureRandom();
+        random.nextBytes(nonce);
+
+        // Fixed nonce for debugging purposes
+        //* DEBUG */for (int i = 0; i < N; i++) nonce[i] = (byte) (i + 1);
+
+        return nonce;
+    }
+
+    /**
+     * Computes a one-way function of the user's password to use as the response
+     * key. NTLM v1 and NTLM v2 define separate NTOWF() functions in the NTLM v1
+     * authentication and NTLM v2 authentication sections, respectively.
+     */
+    public static byte[] NTOWF() {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * The RC4 Encryption Algorithm. To obtain this stream cipher that is licensed
+     * by RSA Data Security, Inc., contact this company.
+     *
+     * Indicates the encryption of data item d with the current session or message
+     * key state, using the RC4 algorithm. h is the handle to a key state
+     * structure initialized by RC4INIT.
+     */
+    public static byte[] RC4(Cipher h, byte[] d) {
+        return h.update(d);
+    }
+
+    /**
+     * Indicates the encryption of data item d with the key k using the RC4
+     * algorithm.
+     *
+     * Note The key sizes for RC4 encryption in NTLM are defined in sections
+     * KXKEY, SIGNKEY, and SEALKEY, where they are created.
+     */
+    public static byte[] RC4K(byte[] k, byte[] d) {
+        try {
+            Cipher cipher = Cipher.getInstance("RC4");
+            Key key = new SecretKeySpec(k, "RC4");
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            return cipher.doFinal(d);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Initialization of the RC4 key and handle to a key state structure for the
+     * session.
+     */
+    public static Cipher RC4Init(byte[] k) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Produces an encryption key from the session key as defined in sections
+     * KXKEY, SIGNKEY, and SEALKEY.
+     */
+    public static byte[] SEALKEY(byte[] f, byte[] k, byte[] string1) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Produces a signing key from the session key as defined in sections KXKEY,
+     * SIGNKEY, and SEALKEY.
+     */
+    public static byte[] SIGNKEY(int flag, byte[] k, byte[] string1) {
+        throw new RuntimeException("FATAL: Not implemented.");
+    }
+
+    /**
+     * Indicates the retrieval of the current time as a 64-bit value, represented
+     * as the number of 100-nanosecond ticks elapsed since midnight of January
+     * 1st, 1601 (UTC).
+     */
+    public static byte[] Currenttime() {
+        // (current time + milliseconds from 1.01.1601 to 1.01.1970) *
+        // 100-nanosecond ticks
+        long time = (System.currentTimeMillis() + 11644473600000L) * 10000;
+
+        // Convert 64bit value to byte array.
+        byte[] result = new byte[8];
+        for (int i = 0; i < 8; i++, time >>>= 8) {
+            result[i] = (byte)time;
+        }
+
+        return result;
+    }
+
+    /**
+     * Indicates the 2-byte little-endian byte order encoding of the Unicode
+     * UTF-16 representation of string. The Byte Order Mark (BOM) is not sent over
+     * the wire.
+     */
+    public static byte[] UNICODE(String string) {
+        return string.getBytes(RdpConstants.CHARSET_16);
+    }
+
+    /** Indicates the uppercase representation of string. */
+    public static String UpperCase(String string) {
+        return string.toUpperCase();
+    }
+
+    /**
+     * Indicates the creation of a byte array of length N. Each byte in the array
+     * is initialized to the value zero.
+     */
+    public static byte[] Z(int n) {
+        return new byte[n];
+    }
+
+    public static Cipher initRC4(byte[] key) {
+        try {
+            Cipher cipher = Cipher.getInstance("RC4");
+            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "RC4"));
+            return cipher;
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot initialize RC4 sealing handle with client sealing key.", e);
+        }
+    }
+
+    /**
+     * Helper method for embedded test cases.
+     */
+    public static void callAll(Object obj) {
+        Method[] methods = obj.getClass().getDeclaredMethods();
+        for (Method m : methods) {
+            if (m.getName().startsWith("test")) {
+                try {
+                    m.invoke(obj, (Object[])null);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        callAll(new CryptoAlgos());
+    }
+
+}


[07/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
new file mode 100755
index 0000000..5590911
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RLEBitmapDecompression.java
@@ -0,0 +1,1014 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.debug.AssertingByteBuffer;
+
+/**
+ * Based on code example from MSDN, @see
+ * http://msdn.microsoft.com/en-us/library/dd240593.aspx .
+ */
+public class RLEBitmapDecompression {
+
+    public static final int g_MaskRegularRunLength = 0x1F;
+    public static final int g_MaskLiteRunLength = 0x0F;
+
+    public static final int g_MaskSpecialFgBg1 = 0x03;
+    public static final int g_MaskSpecialFgBg2 = 0x05;
+
+    public static final int REGULAR_BG_RUN = 0x00;
+    public static final int REGULAR_FG_RUN = 0x01;
+    public static final int REGULAR_FGBG_IMAGE = 0x02;
+    public static final int REGULAR_COLOR_RUN = 0x03;
+    public static final int REGULAR_COLOR_IMAGE = 0x04;
+
+    public static final int LITE_SET_FG_FG_RUN = 0x0C;
+    public static final int LITE_SET_FG_FGBG_IMAGE = 0x0D;
+    public static final int LITE_DITHERED_RUN = 0x0E;
+
+    public static final int MEGA_MEGA_BG_RUN = 0xF0;
+    public static final int MEGA_MEGA_FG_RUN = 0xF1;
+    public static final int MEGA_MEGA_FGBG_IMAGE = 0xF2;
+    public static final int MEGA_MEGA_COLOR_RUN = 0xF3;
+    public static final int MEGA_MEGA_COLOR_IMAGE = 0xF4;
+    public static final int MEGA_MEGA_SET_FG_RUN = 0xF6;
+    public static final int MEGA_MEGA_SET_FGBG_IMAGE = 0xF7;
+    public static final int MEGA_MEGA_DITHERED_RUN = 0xF8;
+
+    public static final int SPECIAL_FGBG_1 = 0xF9;
+    public static final int SPECIAL_FGBG_2 = 0xFA;
+
+    public static final int SPECIAL_WHITE = 0xFD;
+    public static final int SPECIAL_BLACK = 0xFE;
+
+    /**
+     * Writes a pixel to the specified buffer and advance cursor by bpp.
+     *
+     * @param bpp
+     *          bytes per pixel
+     */
+    private static void writePixel(int bpp, ByteBuffer destBuf, int pixel) {
+        switch (bpp) {
+        case 1:
+            destBuf.writeByte(pixel);
+            break;
+        case 2:
+            destBuf.writeShortLE(pixel);
+            break;
+        case 3:
+            destBuf.writeByte(pixel);
+            destBuf.writeShortLE(pixel >> 8);
+            break;
+        case 4:
+            destBuf.writeIntLE(pixel);
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+    }
+
+    /**
+     * Reads a pixel from the specified buffer at given offset without changing of
+     * cursor.
+     *
+     * @param bpp
+     *          bytes per pixel
+     * @param offset
+     *          -rowDelta (i.e. (-width*bpp))
+     */
+    private static int peekPixel(int bpp, ByteBuffer destBuf, int offset) {
+        if (offset >= 0 || (-offset) > destBuf.cursor)
+            throw new RuntimeException("Incorrect value for offset: offset in destination buffer must point to pixel in previous row.");
+
+        // Adjust cursor to point to pixel in previous row
+        int oldCursor = destBuf.cursor;
+        destBuf.cursor += offset;
+
+        int pixel;
+        switch (bpp) {
+        case 1:
+            pixel = destBuf.readUnsignedByte();
+            break;
+        case 2:
+            pixel = destBuf.readUnsignedShortLE();
+            break;
+        case 3:
+            pixel = destBuf.readUnsignedByte() | (destBuf.readUnsignedShortLE() >> 8);
+            break;
+        case 4:
+            pixel = destBuf.readSignedIntLE();
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+        destBuf.cursor = oldCursor;
+
+        return pixel;
+    }
+
+    /**
+     * Reads a pixel from the specified buffer and advance cursor by bpp value.
+     *
+     * @param bpp
+     *          bytes per pixel
+     */
+    private static int readPixel(int bpp, ByteBuffer srcBuf) {
+        int pixel;
+        switch (bpp) {
+        case 1:
+            pixel = srcBuf.readUnsignedByte();
+            break;
+        case 2:
+            pixel = srcBuf.readUnsignedShortLE();
+            break;
+        case 3:
+            pixel = srcBuf.readUnsignedByte() | (srcBuf.readUnsignedShortLE() >> 8);
+            break;
+        case 4:
+            pixel = srcBuf.readSignedIntLE();
+            break;
+        default:
+            throw new RuntimeException("Unsupported color depth.");
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Returns the size of a pixel in bytes.
+     */
+    private static int getPixelSize(int colorDepth) {
+        switch (colorDepth) {
+        case 8:
+            return 1;
+        case 15:
+        case 16:
+            return 2;
+        case 24:
+            return 3;
+        default:
+            throw new RuntimeException("Unsupported pixel color depth: " + colorDepth + " bpp.");
+        }
+    }
+
+    /**
+     * Reads the supplied order header & extracts the compression order code ID.
+     */
+    private static int extractCodeId(int orderHeader) {
+        // Taken from FreeRDP code, bitmap.c
+        switch (orderHeader) {
+        case MEGA_MEGA_BG_RUN:
+        case MEGA_MEGA_FG_RUN:
+        case MEGA_MEGA_SET_FG_RUN:
+        case MEGA_MEGA_DITHERED_RUN:
+        case MEGA_MEGA_COLOR_RUN:
+        case MEGA_MEGA_FGBG_IMAGE:
+        case MEGA_MEGA_SET_FGBG_IMAGE:
+        case MEGA_MEGA_COLOR_IMAGE:
+        case SPECIAL_FGBG_1:
+        case SPECIAL_FGBG_2:
+        case SPECIAL_WHITE:
+        case SPECIAL_BLACK:
+            return orderHeader;
+        }
+
+        int code = orderHeader >> 5;
+        switch (code) {
+        case REGULAR_BG_RUN:
+        case REGULAR_FG_RUN:
+        case REGULAR_COLOR_RUN:
+        case REGULAR_FGBG_IMAGE:
+        case REGULAR_COLOR_IMAGE:
+            return code;
+        }
+
+        return orderHeader >> 4;
+    }
+
+    /**
+     * Returns a black pixel.
+     */
+    private static int getColorBlack() {
+        return 0x000000;
+    }
+
+    /**
+     * Returns a white pixel.
+     */
+    private static int getColorWhite(int colorDepth) {
+        if (colorDepth == 8) {
+            //
+            // Palette entry #255 holds white.
+            //
+            return 0xFF;
+        } else if (colorDepth == 15) {
+            //
+            // 5 bits per RGB component:
+            // 0111 1111 1111 1111 (binary)
+            //
+            return 0x7FFF;
+        } else if (colorDepth == 16) {
+            //
+            // 5 bits for red, 6 bits for green, 5 bits for green:
+            // 1111 1111 1111 1111 (binary)
+            //
+            return 0xFFFF;
+        } else if (colorDepth == 24) {
+            //
+            // 8 bits per RGB component:
+            // 1111 1111 1111 1111 1111 1111 (binary)
+            //
+            return 0xFFFFFF;
+        } else
+            throw new RuntimeException("Unsupported color depth.");
+    }
+
+    /**
+     * Extract the run length of a compression order.
+     */
+    private static int extractRunLength(int code, int orderHeader, ByteBuffer srcBuf) {
+        switch (code) {
+        case REGULAR_FGBG_IMAGE: {
+            int runLength = orderHeader & g_MaskRegularRunLength;
+            if (runLength == 0)
+                runLength = srcBuf.readUnsignedByte() + 1;
+            else
+                runLength = runLength * 8;
+            return runLength;
+        }
+        case LITE_SET_FG_FGBG_IMAGE: {
+            int runLength = orderHeader & g_MaskLiteRunLength;
+            if (runLength == 0)
+                runLength = srcBuf.readUnsignedByte() + 1;
+            else
+                runLength = runLength * 8;
+            return runLength;
+        }
+        case REGULAR_BG_RUN:
+        case REGULAR_COLOR_IMAGE:
+        case REGULAR_COLOR_RUN:
+        case REGULAR_FG_RUN: {
+            int runLength = orderHeader & g_MaskRegularRunLength;
+            if (runLength == 0)
+                // An extended (MEGA) run.
+                runLength = srcBuf.readUnsignedByte() + 32;
+            return runLength;
+        }
+        case LITE_DITHERED_RUN:
+        case LITE_SET_FG_FG_RUN: {
+            int runLength = orderHeader & g_MaskLiteRunLength;
+            if (runLength == 0)
+                // An extended (MEGA) run.
+                runLength = srcBuf.readUnsignedByte() + 16;
+            return runLength;
+        }
+        case MEGA_MEGA_BG_RUN:
+        case MEGA_MEGA_COLOR_IMAGE:
+        case MEGA_MEGA_COLOR_RUN:
+        case MEGA_MEGA_DITHERED_RUN:
+        case MEGA_MEGA_FG_RUN:
+        case MEGA_MEGA_FGBG_IMAGE:
+        case MEGA_MEGA_SET_FG_RUN:
+        case MEGA_MEGA_SET_FGBG_IMAGE: {
+            return srcBuf.readUnsignedShortLE();
+        }
+        default:
+            return 0;
+        }
+
+    }
+
+    /**
+     * Write a foreground/background image to a destination buffer.
+     */
+    private static void writeFgBgImage(int bpp, ByteBuffer destBuf, int rowDelta, int bitmask, int fgPel, int cBits) {
+        for (; cBits > 0; cBits--, bitmask >>= 1) {
+            int xorPixel = peekPixel(bpp, destBuf, -rowDelta);
+            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? xorPixel ^ fgPel : xorPixel);
+        }
+    }
+
+    /**
+     * Write a foreground/background image to a destination buffer for the first
+     * line of compressed data.
+     */
+    private static void writeFirstLineFgBgImage(int bpp, ByteBuffer destBuf, int bitmask, int fgPel, int cBits) {
+        for (; cBits > 0; cBits--, bitmask >>= 1) {
+            writePixel(bpp, destBuf, ((bitmask & 0x1) > 0) ? fgPel : getColorBlack());
+        }
+    }
+
+    /**
+     * Decompress a RLE compressed bitmap and flip decompressed image.
+     *
+     * @param srcBuf
+     *          source buffer containing compressed bitmap
+     * @param imageWidth
+     *          width of destination image in pixels
+     * @param imageHeight
+     *          height of destination image in pixels
+     * @param colorDepth
+     *          bits per pixel
+     * @return destination image buffer
+     */
+    public static ByteBuffer rleDecompress(ByteBuffer srcBuf, int imageWidth, int imageHeight, int colorDepth) {
+        int bpp = getPixelSize(colorDepth);
+
+        // Decompress image
+        ByteBuffer destBuf = new ByteBuffer(new byte[imageWidth * imageHeight * bpp]);
+        rleDecompress(srcBuf, destBuf, imageWidth, imageHeight, colorDepth);
+
+        // Flip image
+        return flipRawImage(destBuf, imageWidth, imageHeight, bpp);
+    }
+
+    /**
+     * Decompress a RLE compressed bitmap.
+     *
+     * @param srcBuf
+     *          source buffer containing compressed bitmap
+     * @param destBuf
+     *          destination buffer
+     * @param imageWidth
+     *          width of destination image in pixels
+     * @param imageHeight
+     *          height of destination image in pixels
+     * @param colorDepth
+     *          bits per pixel
+     */
+    protected static void rleDecompress(final ByteBuffer srcBuf, final ByteBuffer destBuf, final int imageWidth, final int imageHeight, final int colorDepth) {
+        final int bpp = getPixelSize(colorDepth);
+        final int rowDelta = imageWidth * bpp;
+        final int whitePixel = getColorWhite(colorDepth);
+        final int blackPixel = getColorBlack();
+
+        int fgPel = whitePixel;
+        boolean insertFgPel = false;
+        boolean firstLine = true;
+
+        if (destBuf.length != imageWidth * imageHeight * bpp)
+            throw new RuntimeException("Incorrect size of destination buffer. Expected size (imageWidth*imageHeight*bpp): " + (imageWidth * imageHeight * bpp)
+                    + ", actual size: " + destBuf.length + ".");
+
+        while (srcBuf.cursor < srcBuf.length) {
+            // Watch out for the end of the first scanline in destination buffer.
+            if (firstLine) {
+                if (destBuf.cursor >= rowDelta) {
+                    firstLine = false;
+                    insertFgPel = false;
+                }
+            }
+
+            // Extract the compression order code ID from the compression
+            // order header.
+            int orderHeader = srcBuf.readUnsignedByte();
+            int code = extractCodeId(orderHeader);
+
+            // Handle Background Run Orders.
+            if (code == REGULAR_BG_RUN | code == MEGA_MEGA_BG_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (firstLine) {
+                    if (insertFgPel) {
+                        writePixel(bpp, destBuf, fgPel);
+                        runLength--;
+                    }
+
+                    for (; runLength > 0; runLength--)
+                        writePixel(bpp, destBuf, blackPixel);
+
+                } else {
+                    if (insertFgPel) {
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
+                        runLength--;
+                    }
+
+                    // Copy pixels from previous row of destination image
+                    for (; runLength > 0; runLength--)
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta));
+                }
+
+                //
+                // A follow-on background run order will need a
+                // foreground pel inserted.
+                //
+                insertFgPel = true;
+                continue;
+            }
+
+            //
+            // For any of the other run-types a follow-on background run
+            // order does not need a foreground pel inserted.
+            //
+            insertFgPel = false;
+
+            //
+            // Handle Foreground Run Orders.
+            //
+            if (code == REGULAR_FG_RUN | code == MEGA_MEGA_FG_RUN | code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (code == LITE_SET_FG_FG_RUN | code == MEGA_MEGA_SET_FG_RUN)
+                    fgPel = readPixel(bpp, srcBuf);
+
+                if (firstLine) {
+                    for (; runLength > 0; runLength--) {
+                        writePixel(bpp, destBuf, fgPel);
+                    }
+                } else {
+                    for (; runLength > 0; runLength--) {
+                        writePixel(bpp, destBuf, peekPixel(bpp, destBuf, -rowDelta) ^ fgPel);
+                    }
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Dithered Run Orders.
+            //
+            if (code == LITE_DITHERED_RUN | code == MEGA_MEGA_DITHERED_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                int pixelA = readPixel(bpp, srcBuf);
+                int pixelB = readPixel(bpp, srcBuf);
+
+                for (; runLength > 0; runLength--) {
+                    writePixel(bpp, destBuf, pixelA);
+                    writePixel(bpp, destBuf, pixelB);
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Color Run Orders.
+            //
+            if (code == REGULAR_COLOR_RUN | code == MEGA_MEGA_COLOR_RUN) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                int pixelA = readPixel(bpp, srcBuf);
+
+                for (; runLength > 0; runLength--)
+                    writePixel(bpp, destBuf, pixelA);
+
+                continue;
+            }
+
+            //
+            // Handle Foreground/Background Image Orders.
+            //
+            if (code == REGULAR_FGBG_IMAGE | code == MEGA_MEGA_FGBG_IMAGE | code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                if (code == LITE_SET_FG_FGBG_IMAGE | code == MEGA_MEGA_SET_FGBG_IMAGE) {
+                    fgPel = readPixel(bpp, srcBuf);
+                }
+
+                for (; runLength > 8; runLength -= 8) {
+                    int bitmask = srcBuf.readUnsignedByte();
+
+                    if (firstLine)
+                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, 8);
+                    else
+                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, 8);
+                }
+
+                if (runLength > 0) {
+                    int bitmask = srcBuf.readUnsignedByte();
+
+                    if (firstLine)
+                        writeFirstLineFgBgImage(bpp, destBuf, bitmask, fgPel, runLength);
+                    else
+                        writeFgBgImage(bpp, destBuf, rowDelta, bitmask, fgPel, runLength);
+                }
+
+                continue;
+            }
+
+            //
+            // Handle Color Image Orders.
+            //
+            if (code == REGULAR_COLOR_IMAGE | code == MEGA_MEGA_COLOR_IMAGE) {
+                int runLength = extractRunLength(code, orderHeader, srcBuf);
+
+                //* DEBUG */
+                // Copy bytes from source to destination using writeByte(readByte())
+                // for (int byteCount = runLength * bpp; byteCount > 0; byteCount--) {
+                // destBuf.writeByte(srcBuf.readUnsignedByte());
+                // }
+                //* DEBUG */
+
+                // Copy bytes from source to destination directly using arraycopy()
+                int lengthInBytes = runLength * bpp;
+                System.arraycopy(srcBuf.data, srcBuf.offset + srcBuf.cursor, destBuf.data, destBuf.offset + destBuf.cursor, lengthInBytes);
+                srcBuf.cursor += lengthInBytes;
+                destBuf.cursor += lengthInBytes;
+
+                continue;
+            }
+
+            //
+            // Handle Special Order 1.
+            //
+            if (code == SPECIAL_FGBG_1) {
+                if (firstLine)
+                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg1, fgPel, 8);
+                else
+                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
+
+                continue;
+            }
+
+            //
+            // Handle Special Order 2.
+            //
+            if (code == SPECIAL_FGBG_2) {
+                if (firstLine)
+                    writeFirstLineFgBgImage(bpp, destBuf, g_MaskSpecialFgBg2, fgPel, 8);
+                else
+                    writeFgBgImage(bpp, destBuf, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
+
+                continue;
+            }
+
+            //
+            // Handle White Order.
+            //
+            if (code == SPECIAL_WHITE) {
+                writePixel(bpp, destBuf, whitePixel);
+
+                continue;
+            }
+
+            //
+            // Handle Black Order.
+            //
+            if (code == SPECIAL_BLACK) {
+                writePixel(bpp, destBuf, blackPixel);
+
+                continue;
+            }
+
+            throw new RuntimeException("Unknown code: " + code + ".");
+        }
+    }
+
+    /**
+     * Flip image in vertical direction.
+     */
+    public static ByteBuffer flipRawImage(ByteBuffer src, int width, int height, int bpp) {
+        if (width * height * bpp != src.length)
+            throw new RuntimeException("Incorrect size of buffer. Expected size (imageWidth*imageHeight*bpp): " + (width * height * bpp) + ", actual size: "
+                    + src.length + ".");
+        ByteBuffer dest = new ByteBuffer(new byte[src.length]);
+
+        int scanLine = width * bpp;
+
+        for (int i = 0; i < height; i++) {
+            // Copy one row
+            System.arraycopy(src.data, (height - i - 1) * scanLine, dest.data, i * scanLine, scanLine);
+        }
+
+        return dest;
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        if (true) {
+            // 16x1@8bpp, all black
+            int width = 16, height = 1, depth = 8, bpp = depth / 8;
+            ByteBuffer src = new ByteBuffer(new byte[] {0x10});
+            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
+            rleDecompress(src, dest, width, height, depth);
+        }
+
+        if (true) {
+            // 16x1@16bpp, all black
+            int width = 16, height = 1, depth = 16, bpp = depth / 8;
+            ByteBuffer src = new ByteBuffer(new byte[] {0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+            ByteBuffer dest = new AssertingByteBuffer(new byte[width * height * bpp]);
+            rleDecompress(src, dest, width, height, depth);
+        }
+
+        if (true) {
+            // 32x32@8
+            int width = 32, height = 32, depth = 8, bpp = depth / 8;
+
+            ByteBuffer src = new ByteBuffer(new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x06, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e,
+                    (byte)0x0e, (byte)0x44, (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe4, (byte)0x04, (byte)0x06,
+                    (byte)0x8e, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c, (byte)0xb4, (byte)0xb5, (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4,
+                    (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0xe4, (byte)0x04, (byte)0x06, (byte)0x02, (byte)0x8b, (byte)0x06, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66, (byte)0xb4, (byte)0xdc, (byte)0x68, (byte)0xe2,
+                    (byte)0x97, (byte)0xdd, (byte)0xb4, (byte)0xa7, (byte)0x16, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x0b, (byte)0xae,
+                    (byte)0xdc, (byte)0xe9, (byte)0x6a, (byte)0xdc, (byte)0x96, (byte)0xe9, (byte)0xe9, (byte)0xb4, (byte)0x0e, (byte)0x00, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06,
+                    (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xd0, (byte)0x09, (byte)0x07, (byte)0xcf, (byte)0x03, (byte)0x95,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5, (byte)0x6c,
+                    (byte)0xdb, (byte)0x80, (byte)0xaf, (byte)0xd5, (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5, (byte)0xad, (byte)0xd4,
+                    (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xd5,
+                    (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5, (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x60, (byte)0xa7, (byte)0xb4, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3,
+                    (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c, (byte)0xb6, (byte)0x07, (byte)0xb6, (byte)0x8c, (byte)0xb3, (byte)0xd4,
+                    (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4, (byte)0xad, (byte)0x66, (byte)0x00, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07, (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7, (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x04, (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xad, (byte)0xb5, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xbd, (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad,
+                    (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0xc8, (byte)0xc8, (byte)0x60, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x66, (byte)0xc8, (byte)0xa7, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad,
+                    (byte)0x8b, (byte)0x92, (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b,
+                    (byte)0xa7, (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0xc8, (byte)0x66, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b,
+                    (byte)0xa7, (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07, (byte)0x66, (byte)0xa7, (byte)0xa7,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0x04, (byte)0xa7,
+                    (byte)0x60, (byte)0x6b, (byte)0x66, (byte)0x99, (byte)0xb6, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xef,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0x6e, (byte)0xff, (byte)0x85, (byte)0xbd,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x60, (byte)0x05, (byte)0x87, (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0xf4, (byte)0x70, (byte)0xff, (byte)0x84, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x05, (byte)0x85,
+                    (byte)0x0b, (byte)0xa7, (byte)0xb5, (byte)0xae, (byte)0x8c, (byte)0xd0, (byte)0x13, (byte)0xc1, (byte)0x01, (byte)0x00, (byte)0x08,
+                    (byte)0x8e, (byte)0x8c, (byte)0xae, (byte)0xb5, (byte)0xae, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae, (byte)0xbc,
+                    (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xd0, (byte)0x0e, (byte)0x0c, (byte)0x01, (byte)0x00, (byte)0x90, (byte)0xf2,
+                    (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae,
+                    (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x68, (byte)0xae, (byte)0x82, (byte)0x8c, (byte)0x0a, (byte)0x05, (byte)0x8c,
+                    (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x6c, (byte)0x00, (byte)0x00,
+                    (byte)0x06, (byte)0x05, (byte)0x81, (byte)0xd0, (byte)0x06, (byte)0x9a, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a, (byte)0xb5,
+                    (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b, (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x06,
+                    (byte)0x9b, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a, (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c,
+                    (byte)0xb5, (byte)0x0a, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x05, (byte)0x80, (byte)0x7d, (byte)0xbc, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6,
+                    (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a, (byte)0xbc,
+                    (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x1a,
+                    (byte)0xb5, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0x6e, (byte)0xb5, (byte)0x0a, (byte)0xbc,
+                    (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xf4, (byte)0xff, (byte)0xf2,
+                    (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc, (byte)0x0a, (byte)0x0a, (byte)0x8b,
+                    (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a, (byte)0x0a,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc, (byte)0xf2, (byte)0x0a,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a,
+                    (byte)0x0a, (byte)0x6a, (byte)0xb6, (byte)0x96, (byte)0x0a, (byte)0x0a, (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2, (byte)0xd0, (byte)0x09, (byte)0xbc, (byte)0x87, (byte)0x03, (byte)0x80, (byte)0x2c,
+                    (byte)0xde, (byte)0xf4, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x87, (byte)0x0a,
+                    (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2, (byte)0xf4, (byte)0xf4, (byte)0x0a,
+                    (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x6c, (byte)0x8c,
+                    (byte)0xb5, (byte)0xbc, (byte)0x0a, (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5, (byte)0x8c, (byte)0x6c, (byte)0x06,
+                    (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xe6,
+                    (byte)0x04, (byte)0x06, (byte)0x86, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c, (byte)0xe6, (byte)0x04,
+                    (byte)0x06, (byte)0x82, (byte)0x00, (byte)0x00
+
+            });
+
+            ByteBuffer flippedImage = new ByteBuffer(new byte[] {(byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x04, (byte)0x8b, (byte)0x04, (byte)0x6c,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06,
+                    (byte)0x06, (byte)0x6c, (byte)0x8c, (byte)0xb5, (byte)0xbc, (byte)0x0a, (byte)0xde, (byte)0xf2, (byte)0xbd, (byte)0x0a, (byte)0xb5,
+                    (byte)0x8c, (byte)0x6c, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x6c, (byte)0x87,
+                    (byte)0x0a, (byte)0xf4, (byte)0xf4, (byte)0xf2, (byte)0xde, (byte)0xbd, (byte)0xbd, (byte)0xde, (byte)0xf2, (byte)0xf4, (byte)0xf4,
+                    (byte)0x0a, (byte)0xd0, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8c, (byte)0xb6, (byte)0xf4, (byte)0xf2,
+                    (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a, (byte)0x0a, (byte)0xde,
+                    (byte)0xf4, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0xa7, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0x0a, (byte)0xb6,
+                    (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a, (byte)0x0a,
+                    (byte)0xf2, (byte)0x0a, (byte)0x87, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x8b, (byte)0xbc, (byte)0xf2, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0xb6, (byte)0x0a,
+                    (byte)0xf2, (byte)0x1a, (byte)0x8c, (byte)0xec, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x04, (byte)0x8b, (byte)0xbc, (byte)0x1a, (byte)0x0a, (byte)0xb6, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xb6, (byte)0x0a,
+                    (byte)0xde, (byte)0x0a, (byte)0xa7, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0x6e,
+                    (byte)0xb5, (byte)0x0a, (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5,
+                    (byte)0xf4, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xd0, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc,
+                    (byte)0x0a, (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x87, (byte)0x0a,
+                    (byte)0xbc, (byte)0xb6, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xd0, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0xbc,
+                    (byte)0x1a, (byte)0xb5, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x6c, (byte)0xb5, (byte)0x0a, (byte)0xb6,
+                    (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xbc, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a,
+                    (byte)0x0a, (byte)0x8b, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x8b, (byte)0x0a, (byte)0xbc, (byte)0xb5, (byte)0xb5,
+                    (byte)0xb5, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xb6, (byte)0x0a,
+                    (byte)0x8c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xd0,
+                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xd0, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0x0a, (byte)0xb5,
+                    (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xae, (byte)0x0a, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xae,
+                    (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0xae, (byte)0x8c, (byte)0x0a, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x6c,
+                    (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0xae, (byte)0xbc, (byte)0xb5, (byte)0xb5, (byte)0xae, (byte)0xb5, (byte)0xf3, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xf2, (byte)0xae, (byte)0xae, (byte)0xb5, (byte)0xb5, (byte)0xbc, (byte)0xb5, (byte)0x66, (byte)0x00,
+                    (byte)0x00, (byte)0x0b, (byte)0xa7, (byte)0xb5, (byte)0xae, (byte)0x8c, (byte)0xa7, (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xbd, (byte)0xa7, (byte)0x8c, (byte)0xae, (byte)0xb5, (byte)0xae, (byte)0x66, (byte)0x00, (byte)0x00,
+                    (byte)0x13, (byte)0x04, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xf4, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xbd, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x60,
+                    (byte)0xa7, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x8c, (byte)0xf1, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xbd,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x60, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x6c, (byte)0x04,
+                    (byte)0xa7, (byte)0x60, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0xb6, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xf5, (byte)0xef, (byte)0x66, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0x66, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x60, (byte)0xa7,
+                    (byte)0x66, (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xa7,
+                    (byte)0xb6, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0xf3, (byte)0x07, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x66,
+                    (byte)0x66, (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x6c, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x66, (byte)0xc8, (byte)0xa7,
+                    (byte)0x66, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x92, (byte)0xf1,
+                    (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf2, (byte)0x07, (byte)0xa7, (byte)0xa7, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0x66,
+                    (byte)0x66, (byte)0xc8, (byte)0x66, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x6c, (byte)0xa7, (byte)0xad, (byte)0xa7,
+                    (byte)0xa7, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb5, (byte)0xbd, (byte)0xbd,
+                    (byte)0xbd, (byte)0xbd, (byte)0xf0, (byte)0x8b, (byte)0x8b, (byte)0xad, (byte)0x8b, (byte)0x8b, (byte)0xa7, (byte)0xa7, (byte)0xc8,
+                    (byte)0xc8, (byte)0x60, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0x66, (byte)0xae, (byte)0xad, (byte)0x8b,
+                    (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb3, (byte)0xad, (byte)0xb5, (byte)0x07, (byte)0x07, (byte)0x07,
+                    (byte)0xf0, (byte)0x8b, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0x8b, (byte)0xa7, (byte)0xae, (byte)0xa7,
+                    (byte)0x6c, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x60, (byte)0xa7, (byte)0xb4, (byte)0xad, (byte)0xad,
+                    (byte)0xad, (byte)0xb3, (byte)0xb3, (byte)0xd4, (byte)0xd4, (byte)0xb3, (byte)0x8c, (byte)0xb6, (byte)0x07, (byte)0xb6, (byte)0x8c,
+                    (byte)0xb3, (byte)0xd4, (byte)0xb3, (byte)0xb3, (byte)0xad, (byte)0xad, (byte)0xad, (byte)0xb4, (byte)0xad, (byte)0x66, (byte)0x00,
+                    (byte)0x06, (byte)0x00, (byte)0x00, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x66, (byte)0xae, (byte)0xd5, (byte)0xad, (byte)0xd4,
+                    (byte)0xd4, (byte)0xd5, (byte)0xd5, (byte)0xd5, (byte)0xdb, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xb4, (byte)0xd5,
+                    (byte)0xd5, (byte)0xd5, (byte)0xd4, (byte)0xd4, (byte)0xad, (byte)0xd5, (byte)0xb4, (byte)0x0e, (byte)0x06, (byte)0x06, (byte)0x06,
+                    (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdb, (byte)0xd4, (byte)0xd5,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xd5, (byte)0xd4, (byte)0xdb, (byte)0xb4, (byte)0x66, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x0e, (byte)0xae, (byte)0xdc, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdc, (byte)0xdc, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb,
+                    (byte)0xdb, (byte)0xdc, (byte)0xb4, (byte)0x66, (byte)0x6c, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x0b, (byte)0xae, (byte)0xdc, (byte)0xe9, (byte)0xdc,
+                    (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xdc, (byte)0xe9, (byte)0xe9,
+                    (byte)0xb4, (byte)0x0e, (byte)0x00, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xf8, (byte)0x0e, (byte)0x66, (byte)0xb4, (byte)0xdc, (byte)0xe2,
+                    (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xe2, (byte)0xdd, (byte)0xb4, (byte)0xa7, (byte)0x16,
+                    (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x60, (byte)0x0e, (byte)0x60, (byte)0x8c, (byte)0xb4,
+                    (byte)0xb5, (byte)0xdc, (byte)0xdc, (byte)0xbb, (byte)0xb4, (byte)0x8c, (byte)0x66, (byte)0x0b, (byte)0x6c, (byte)0x04, (byte)0x06,
+                    (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x04, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x06, (byte)0xed,
+                    (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xec, (byte)0x6c, (byte)0x0e, (byte)0x0e,
+                    (byte)0x44, (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x13, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06,
+                    (byte)0x06, (byte)0xed, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00});
+            ByteBuffer dest = new AssertingByteBuffer(flipRawImage(flippedImage, width, height, bpp).data);
+
+            rleDecompress(src, dest, width, height, depth);
+
+        }
+
+        if (true) {
+            // 32x32@16
+            int width = 32, height = 32, depth = 16;
+
+            ByteBuffer src = new ByteBuffer(new byte[] {(byte)0x85, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x8b, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0x16, (byte)0x69, (byte)0x99, (byte)0xd6, (byte)0x06, (byte)0x69, (byte)0x99,
+                    (byte)0xd6, (byte)0x04, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x6e,
+                    (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71, (byte)0xff, (byte)0xff, (byte)0xce, (byte)0x18,
+                    (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66, (byte)0x29, (byte)0x02, (byte)0xcd, (byte)0x89,
+                    (byte)0x52, (byte)0x03, (byte)0x88, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xd8, (byte)0x99, (byte)0xd6,
+                    (byte)0x03, (byte)0xf8, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x66, (byte)0x99, (byte)0xd6,
+                    (byte)0x05, (byte)0x6a, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0xc4, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e,
+                    (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x6e, (byte)0x08, (byte)0x42, (byte)0x01, (byte)0x70, (byte)0x08, (byte)0x42, (byte)0x71,
+                    (byte)0xff, (byte)0xff, (byte)0xce, (byte)0x18, (byte)0xc6, (byte)0x01, (byte)0x81, (byte)0x08, (byte)0x42, (byte)0xce, (byte)0x66,
+                    (byte)0x29, (byte)0x02, (byte)0xcd, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x00, (byte)0x04, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xc3, (byte)0x80, (byte)0x61, (byte)0x00, (byte)0xa5, (byte)0x80, (byte)0x40, (byte)0xec, (byte)0x52, (byte)0x00, (byte)0x5a,
+                    (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x12, (byte)0x00,
+                    (byte)0x5a, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0xa5, (byte)0x80, (byte)0x52, (byte)0x00, (byte)0xc3, (byte)0x80, (byte)0x61,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xcc, (byte)0x89, (byte)0x52, (byte)0x03, (byte)0x6e, (byte)0xff,
+                    (byte)0xff, (byte)0x02, (byte)0xcb, (byte)0x18, (byte)0xc6, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0xff, (byte)0xff,});
+
+            ByteBuffer dest = new AssertingByteBuffer(new byte[] {(byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10,
+                    (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff,
+                    (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10,
+                    (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10,
+                    (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6,
+                    (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99,
+                    (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x99, (byte)0xd6, (byte)0x10, (byte)0x84, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10,
+                    (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84,
+                    (byte)0x10, (byte)0x84, (byte)0x10, (byte)0x84, (byte)0x99, (byte)0xd6, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
+                    (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08,
+                    (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42,
+                    (byte)0x08, (byte)0x42, (byte)0x08, (byte)0x42, (byte)0xff, (byte)0xff,});
+
+            rleDecompress(src, dest, width, height, depth);
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
new file mode 100755
index 0000000..147d0a7
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpConstants.java
@@ -0,0 +1,91 @@
+// 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.rdp;
+
+import java.nio.charset.Charset;
+
+public interface RdpConstants {
+
+    /**
+     * Default charset to use when communicating with server using 8 bit strings.
+     */
+    public static final Charset CHARSET_8 = Charset.availableCharsets().get("US-ASCII");
+
+    /**
+     * Default charset to use when communicating with server using 16 bit strings.
+     */
+    public static final Charset CHARSET_16 = Charset.availableCharsets().get("UTF-16LE");
+
+    /**
+     * Negotiate SSL protocol to use to protect RDP connection.
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     */
+    public static final int RDP_NEG_REQ_PROTOCOL_SSL = 1;
+
+    /**
+     * Negotiate CredSSP protocol to use to protect RDP connection.
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     * When used, client must set @see RDP_NEG_REQ_PROTOCOL_SSL too.
+     */
+    public static final int RDP_NEG_REQ_PROTOCOL_HYBRID = 2;
+
+    /**
+     * RDP negotiation: flags (not used, always 0).
+     */
+    public static final int RDP_NEG_REQ_FLAGS = 0;
+
+    /**
+     * RDP Negotiation: request.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_REQ = 1;
+
+    /**
+     * RDP Negotiation: response.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_RSP = 2;
+
+    /**
+     * RDP Negotiation: failure.
+     */
+    public static final int RDP_NEG_REQ_TYPE_NEG_FAILURE = 3;
+
+    /**
+     * I/O Channel.
+     */
+    public static final int CHANNEL_IO = 1003;
+
+    /**
+     * RDP channel.
+     */
+    public static final int CHANNEL_RDPRDR = 1004;
+
+    /**
+     * Clipboard channel.
+     */
+    public static final int CHANNEL_CLIPRDR = 1005;
+
+    /**
+     * RDP sound channel.
+     */
+    public static final int CHANNEL_RDPSND = 1006;
+
+    /**
+     * User channel.
+     */
+    public static final int CHANNEL_USER = 1007;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
new file mode 100755
index 0000000..1113d14
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/RdpState.java
@@ -0,0 +1,33 @@
+// 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.rdp;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class RdpState {
+
+    public long serverShareId;
+    public int serverUserChannelId;
+
+    public Set<Integer> channels = new HashSet<Integer>();
+
+    public void channelJoined(int actualChannel) {
+        channels.add(actualChannel);
+    }
+
+}


[16/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
old mode 100644
new mode 100755
index ef05eda..afde706
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java
@@ -16,13 +16,50 @@
 // under the License.
 package rdpclient;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import rdpclient.adapter.AwtRdpKeyboardAdapter;
+import rdpclient.adapter.AwtRdpMouseAdapter;
+import rdpclient.hyperv.ClientPreConnectionBlob;
+import rdpclient.ntlmssp.ClientNtlmsspNegotiate;
+import rdpclient.ntlmssp.ClientNtlmsspPubKeyAuth;
+import rdpclient.ntlmssp.ClientNtlmsspUserCredentials;
+import rdpclient.ntlmssp.NtlmState;
+import rdpclient.ntlmssp.ServerNtlmsspChallenge;
+import rdpclient.ntlmssp.ServerNtlmsspPubKeyPlus1;
+import rdpclient.rdp.ClientConfirmActivePDU;
+import rdpclient.rdp.ClientFastPathPDU;
+import rdpclient.rdp.ClientInfoPDU;
+import rdpclient.rdp.ClientMCSAttachUserRequest;
+import rdpclient.rdp.ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs;
+import rdpclient.rdp.ClientMCSConnectInitial;
+import rdpclient.rdp.ClientMCSErectDomainRequest;
+import rdpclient.rdp.ClientTpkt;
+import rdpclient.rdp.ClientX224ConnectionRequestPDU;
+import rdpclient.rdp.ClientX224DataPDU;
+import rdpclient.rdp.RdpConstants;
+import rdpclient.rdp.RdpState;
+import rdpclient.rdp.ServerBitmapUpdate;
+import rdpclient.rdp.ServerDemandActivePDU;
+import rdpclient.rdp.ServerFastPath;
+import rdpclient.rdp.ServerIOChannelRouter;
+import rdpclient.rdp.ServerLicenseErrorPDUValidClient;
+import rdpclient.rdp.ServerMCSAttachUserConfirmPDU;
+import rdpclient.rdp.ServerMCSConnectResponse;
+import rdpclient.rdp.ServerMCSPDU;
+import rdpclient.rdp.ServerPaletteUpdate;
+import rdpclient.rdp.ServerX224ConnectionConfirmPDU;
+import rdpclient.rdp.ServerX224DataPdu;
 import streamer.PipelineImpl;
 import streamer.Queue;
-import common.AwtCanvasAdapter;
+import streamer.ssl.SSLState;
+import streamer.ssl.UpgradeSocketToSSL;
 import common.AwtKeyEventSource;
 import common.AwtMouseEventSource;
 import common.BufferedImageCanvas;
 import common.ScreenDescription;
+import common.adapter.AwtCanvasAdapter;
 
 public class RdpClient extends PipelineImpl {
 
@@ -31,12 +68,32 @@ public class RdpClient extends PipelineImpl {
      */
     private static final String HANDSHAKE_END = "server_valid_client";
 
-    public RdpClient(String id, String userName, ScreenDescription screen, BufferedImageCanvas canvas) {
+    /**
+     * Create new RDP or HyperV cli
+     *
+     * @param id
+     *          id of this element
+     * @param userName
+     *          user name
+     * @param password
+     *          password
+     * @param pcb
+     *          pre-connection blob for HyperV server or null/empty string to
+     *          disable. Usually, HyperV VM ID, e.g.
+     *          "39418F90-6D03-468E-B796-91C60DD6653A".
+     * @param screen
+     *          screen description to fill
+     * @param canvas
+     *          canvas to draw on
+     * @param sslState
+     */
+    public RdpClient(String id, String serverHostName, String domain, String userName, String password, String pcb, ScreenDescription screen,
+            BufferedImageCanvas canvas, SSLState sslState) {
         super(id);
-        assembleRDPPipeline(userName, screen, canvas);
+        assembleRDPPipeline(serverHostName, domain, userName, password, pcb, screen, canvas, sslState);
     }
 
-//  /* DEBUG */
+    // /* DEBUG */
 //  @Override
 //  protected HashMap<String, streamer.Element> initElementMap(String id) {
 //    HashMap<String, streamer.Element> map = new HashMap<String, streamer.Element>();
@@ -45,72 +102,195 @@ public class RdpClient extends PipelineImpl {
 //    return map;
 //  }
 
-    private void assembleRDPPipeline(String userName, ScreenDescription screen, BufferedImageCanvas canvas) {
+    /**
+     * Assemble connection sequence and main pipeline.
+     *
+     * Connection sequence for RDP w/o NLA: cookie(TPKT) SSL x224(TPKT)
+     * main(FastPath).
+     *
+     * Connection sequence for RDP w NLA: cookie(TPKT) SSL credssp x224(TPKT)
+     * main(FastPath).
+     *
+     * Connection sequence for HyperV w NLA: pcb SSL credssp cookie(TPKT)
+     * x224(TPKT) main(FastPath).
+     */
+    protected void assembleRDPPipeline(String serverHostName, String domain, String userName, String password, String pcb, ScreenDescription screen,
+            BufferedImageCanvas canvas, SSLState sslState) {
+        // If preconnection blob with VM ID is specified, then we are connecting to
+        // HyperV server
+        boolean hyperv = (pcb != null && !pcb.isEmpty());
+        // HyperV server requires NLA (CredSSP/SPNEGO/NTLMSSP) to connect, because
+        // it cannot display login screen
+        boolean credssp = hyperv || (password != null && !password.isEmpty());
+
+        String workstation;
+        try {
+            workstation = InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+            workstation = "workstation";
+        }
+
         //
         // Handshake chain
         //
 
         RdpState state = new RdpState();
-        int[] channelsToJoin = new int[] {RdpConstants.CHANNEL_RDPRDR, RdpConstants.CHANNEL_IO};
+        NtlmState ntlmState = new NtlmState();
+
+        int[] channelsToJoin = new int[] {RdpConstants.CHANNEL_IO,
+                // RdpConstants.CHANNEL_RDPRDR, // RDPRDR channel is not used in current
+                // version
+
+                // RdpConstants .CHANNEL_CLIPRDR // Clipboard channel is refused to join :-/
+        };
 
         // Add elements
 
-        add(
+        // If pre-connection blob is specified, then add element to send it as
+        // first packet
+        if (hyperv) {
+            add(new ClientPreConnectionBlob("pcb", pcb));
+        }
+
+        // If password is specified, then use CredSSP/NTLM (NTLMSSP)
+        int protocol = RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL;
+        if (credssp) {
+            protocol = RdpConstants.RDP_NEG_REQ_PROTOCOL_HYBRID;
+
+            add(
+                    new ClientNtlmsspNegotiate("client_ntlmssp_nego", ntlmState),
+
+                    new ServerNtlmsspChallenge("server_ntlmssp_challenge", ntlmState),
+
+                    new ClientNtlmsspPubKeyAuth("client_ntlmssp_auth", ntlmState, sslState, serverHostName, domain, workstation, userName, password),
+
+                    new ServerNtlmsspPubKeyPlus1("server_ntlmssp_confirm", ntlmState),
+
+                    new ClientNtlmsspUserCredentials("client_ntlmssp_finish", ntlmState)
+
+                    );
+        }
+
+        add(new ClientX224ConnectionRequestPDU("client_connection_req", userName, protocol), new ServerX224ConnectionConfirmPDU("server_connection_conf"),
+                new UpgradeSocketToSSL("upgrade_to_ssl"),
+
+                new ClientMCSConnectInitial("client_initial_conference_create"), new ServerMCSConnectResponse("server_initial_conference_create"),
 
-            new ClientX224ConnectionRequestPDU("client_connection_req", userName), new ServerX224ConnectionConfirmPDU("server_connection_conf"),
+                new ClientMCSErectDomainRequest("client_erect_domain"),
 
-            new UpgradeSocketToSSL("upgrade_to_ssl"),
+                new ClientMCSAttachUserRequest("client_atach_user"), new ServerMCSAttachUserConfirmPDU("server_atach_user_confirm", state),
 
-            new ClientMCSConnectInitial("client_initial_conference_create"), new ServerMCSConnectResponse("server_initial_conference_create"),
+                new ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs("client_channel_join_rdprdr", channelsToJoin, state),
 
-            new ClientMCSErectDomainRequest("client_erect_domain"),
+                new ClientInfoPDU("client_info_req", userName),
 
-            new ClientMCSAttachUserRequest("client_atach_user"), new ServerMCSAttachUserConfirmPDU("server_atach_user_confirm", state),
+                new ServerLicenseErrorPDUValidClient("server_valid_client"),
 
-            new ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs("client_channel_join_rdprdr", channelsToJoin, state),
+                new ServerFastPath("server_fastpath"),
 
-            new ClientInfoPDU("client_info_req", userName),
+                // new ServerTpkt("server_tpkt"),
 
-            new ServerLicenseErrorPDUValidClient("server_valid_client"),
+                new ServerX224DataPdu("server_x224_data"),
 
-            new ServerFastPath("server_fastpath"),
+                // These TPKT and X224 wrappers are connected directly to OUT for
+                // handshake sequence
+                new ClientTpkt("client_tpkt_ot"),
 
-            new ServerTpkt("server_tpkt"),
+                new ClientX224DataPDU("client_x224_data_ot")
 
-            new ServerX224DataPdu("server_x224_data"),
+                );
 
-            // These TPKT and X224 wrappers are connected directly to OUT for handshake
-            // sequence
-            new ClientTpkt("client_tpkt_ot"),
+        // If HyperV VM ID is set, then insert element which will send VM ID as
+        // first packet of connection, before other packets
+        if (hyperv) {
 
-            new ClientX224DataPdu("client_x224_data_ot")
+            // HyperV: pcb SSL credssp cookie x224 main.
 
-        );
+            link("IN",
 
-        // Handshake sequence (via SlowPath)
-        link("IN",
+                    // Pre Connection Blob
+                    "pcb",
 
-            "server_fastpath >tpkt", "server_tpkt",
+                    // Main (will be used after connection seq) or tpkt (to X224)
+                    "server_fastpath >tpkt",
 
-            "client_connection_req", "server_connection_conf",
+                    // SSL
+                    "upgrade_to_ssl",
 
-            "upgrade_to_ssl",
+                    // CredSSP
+                    "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm", "client_ntlmssp_finish",
+
+                    // Cookie
+                    "client_connection_req", "server_connection_conf",
+
+                    // X224
+                    "client_initial_conference_create");
+
+            for (String element : new String[] {"pcb", "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm",
+            "client_ntlmssp_finish"}) {
+                link(element + " >otout", element + "< OUT");
+
+            }
+
+        } else {
+
+            // RDP: cookie SSL (credssp) x224 main.
+
+            link("IN",
+
+                    // Main or tpkt
+                    "server_fastpath >tpkt",
+
+                    // Cookie
+                    "client_connection_req", "server_connection_conf",
+
+                    // SSL
+                    "upgrade_to_ssl");
+
+            if (credssp) {
+                // SSL
+                link("upgrade_to_ssl",
+
+                        // CredSSP
+                        "client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm", "client_ntlmssp_finish",
+
+                        // X224
+                        "client_initial_conference_create");
+
+                for (String element : new String[] {"client_ntlmssp_nego", "server_ntlmssp_challenge", "client_ntlmssp_auth", "server_ntlmssp_confirm",
+                "client_ntlmssp_finish"}) {
+                    link(element + " >otout", element + "< OUT");
+
+                }
+
+            } else {
+
+                link(
+                        // SSL
+                        "upgrade_to_ssl",
+
+                        // X224
+                        "client_initial_conference_create");
+            }
+        }
 
-            "client_initial_conference_create", "server_initial_conference_create",
+        link(
+                // X224
+                "client_initial_conference_create", "server_initial_conference_create",
 
-            "client_erect_domain",
+                "client_erect_domain",
 
-            "server_x224_data",
+                "server_x224_data",
 
-            "client_atach_user", "server_atach_user_confirm",
+                "client_atach_user", "server_atach_user_confirm",
 
-            "client_channel_join_rdprdr",
+                "client_channel_join_rdprdr",
 
-            "client_info_req",
+                "client_info_req",
 
-            "server_valid_client"
+                "server_valid_client"
 
-        );
+                );
 
         // Chain for direct handshake responses (without involving of queue)
         link("client_x224_data_ot", "client_tpkt_ot", "client_tpkt_ot< OUT");
@@ -122,8 +302,7 @@ public class RdpClient extends PipelineImpl {
         }
 
         // Connect one time outputs to client X224 input
-        String x224_peers[] =
-            new String[] {"client_initial_conference_create", "server_initial_conference_create", "client_erect_domain", "client_atach_user",
+        String x224_peers[] = new String[] {"client_initial_conference_create", "server_initial_conference_create", "client_erect_domain", "client_atach_user",
                 "server_atach_user_confirm", "client_channel_join_rdprdr", "client_info_req", "server_valid_client"};
         for (String element : x224_peers) {
             link(element + " >otout", element + "< client_x224_data_ot");
@@ -134,13 +313,13 @@ public class RdpClient extends PipelineImpl {
         //
 
         add(
-            // To transfer packets between input threads and output thread.
-            new Queue("queue"),
+                // To transfer packets between input threads and output thread.
+                new Queue("queue"),
 
-            // Slow path: MultiChannel Support
-            new ServerMCSPDU("server_mcs")
+                // Slow path: MultiChannel Support
+                new ServerMCSPDU("server_mcs")
 
-        );
+                );
 
         // Last element of handshake sequence will wake up queue and and socket
         // output pull loop, which will switch links, between socket output and
@@ -165,38 +344,38 @@ public class RdpClient extends PipelineImpl {
         // Add elements
         add(
 
-            new ServerChannel1003Router("server_channel_1003", state),
+                new ServerIOChannelRouter("server_io_channel", state),
 
-            new ServerDemandActivePDU("server_demand_active", screen, state),
+                new ServerDemandActivePDU("server_demand_active", screen, state),
 
-            new ClientConfirmActivePDU("client_confirm_active", screen, state),
+                new ClientConfirmActivePDU("client_confirm_active", screen, state),
 
-            new ServerBitmapUpdate("server_bitmap_update"),
+                new ServerBitmapUpdate("server_bitmap_update"),
 
-            new AwtCanvasAdapter("canvas_adapter", canvas, screen),
+                new AwtCanvasAdapter("canvas_adapter", canvas, screen),
 
-            new ServerPaletteUpdate("server_palette", screen),
+                new ServerPaletteUpdate("server_palette", screen),
 
-            keyEventSource, new AwtRdpKeyboardAdapter("keyboard_adapter"),
+                keyEventSource, new AwtRdpKeyboardAdapter("keyboard_adapter"),
 
-            mouseEventSource, new AwtRdpMouseAdapter("mouse_adapter"),
+                mouseEventSource, new AwtRdpMouseAdapter("mouse_adapter"),
 
-            // These FastPath, TPKT, and X224 wrappers are connected to queue
-            new ClientTpkt("client_tpkt_queue"),
+                // These FastPath, TPKT, and X224 wrappers are connected to queue
+                new ClientTpkt("client_tpkt_queue"),
 
-            new ClientX224DataPdu("client_x224_data_queue"),
+                new ClientX224DataPDU("client_x224_data_queue"),
 
-            new ClientFastPathPDU("client_fastpath_queue"));
+                new ClientFastPathPDU("client_fastpath_queue"));
 
         // Server packet handlers
-        link("server_mcs >channel_1003", "server_channel_1003");
+        link("server_mcs >channel_1003", "server_io_channel");
         link("server_fastpath >bitmap", "fastpath< server_bitmap_update", "server_bitmap_update< canvas_adapter");
-        link("server_channel_1003 >bitmap", "slowpath< server_bitmap_update");
+        link("server_io_channel >bitmap", "slowpath< server_bitmap_update");
 
         link("server_fastpath >palette", "fastpath< server_palette");
-        link("server_channel_1003 >palette", "slowpath< server_palette");
+        link("server_io_channel >palette", "slowpath< server_palette");
 
-        link("server_channel_1003 >demand_active", "slowpath< server_demand_active");
+        link("server_io_channel >demand_active", "slowpath< server_demand_active");
         // link("server_demand_active >confirm_active", "client_confirm_active",
         // "confirm_active< client_channel_1003");
         link("server_demand_active >confirm_active", "client_confirm_active", "confirm_active< client_x224_data_queue");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
deleted file mode 100644
index 3da1328..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpConstants.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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;
-
-import java.nio.charset.Charset;
-
-public interface RdpConstants {
-
-    /**
-     * Default charset to use when communicating with server using 8 bit strings.
-     */
-    public static final Charset CHARSET_8 = Charset.availableCharsets().get("US-ASCII");
-
-    /**
-     * Default charset to use when communicating with server using 16 bit strings.
-     */
-    public static final Charset CHARSET_16 = Charset.availableCharsets().get("UTF-16LE");
-
-    /**
-     * Negotiate SSL protocol to use to protect RDP connection.
-     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-     */
-    public static final int RDP_NEG_REQ_PROTOCOL_SSL = 1;
-
-    /**
-     * Negotiate CredSSP protocol to use to protect RDP connection.
-     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-     * When used, client must set @see RDP_NEG_REQ_PROTOCOL_SSL too.
-     */
-    public static final int RDP_NEG_REQ_PROTOCOL_HYBRID = 2;
-
-    /**
-     * RDP negotiation: flags (not used, always 0).
-     */
-    public static final int RDP_NEG_REQ_FLAGS = 0;
-
-    /**
-     * RDP Negotiation: request.
-     */
-    public static final int RDP_NEG_REQ_TYPE_NEG_REQ = 1;
-
-    /**
-     * RDP Negotiation: response.
-     */
-    public static final int RDP_NEG_REQ_TYPE_NEG_RSP = 2;
-
-    /**
-     * RDP Negotiation: failure.
-     */
-    public static final int RDP_NEG_REQ_TYPE_NEG_FAILURE = 3;
-
-    public static final int CHANNEL_IO = 1003;
-
-    public static final int CHANNEL_RDPRDR = 1004;
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
deleted file mode 100644
index 951f0be..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpState.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class RdpState {
-
-    public long serverShareId;
-    public int serverUserChannelId;
-
-    public Set<Integer> channels = new HashSet<Integer>();
-
-    public void channelJoined(int actualChannel) {
-        channels.add(actualChannel);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
deleted file mode 100644
index 5c30b69..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerBitmapUpdate.java
+++ /dev/null
@@ -1,200 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.BitmapOrder;
-import common.BitmapRectangle;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240624.aspx
- */
-public class ServerBitmapUpdate extends BaseElement {
-    public static final int UPDATETYPE_BITMAP = 0x0001;
-
-    /**
-     * Indicates that the bitmap data is compressed. The bitmapComprHdr field MUST
-     * be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not set.
-     */
-    public static final int BITMAP_COMPRESSION = 0x0001;
-
-    /**
-     * Indicates that the bitmapComprHdr field is not present (removed for
-     * bandwidth efficiency to save 8 bytes).
-     */
-    private static final int NO_BITMAP_COMPRESSION_HDR = 0x0400;
-
-    public ServerBitmapUpdate(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // * DEBUG */System.out.println(buf.toHexString(buf.length));
-
-        BitmapOrder order = new BitmapOrder();
-
-        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
-        // be set to UPDATETYPE_BITMAP (0x0001).
-        int updateType = buf.readSignedShortLE();
-        if (updateType != UPDATETYPE_BITMAP)
-            throw new RuntimeException("Unknown update type. Expected update type: UPDATETYPE_BITMAP (0x1). Actual update type: " + updateType + ", buf: " + buf + ".");
-
-        // (2 bytes): A 16-bit, unsigned integer. The number of screen rectangles
-        // present in the rectangles field.
-        int numberRectangles = buf.readSignedShortLE();
-
-        // (variable): Variable-length array of TS_BITMAP_DATA structures, each of
-        // which contains a rectangular clipping taken from the server-side screen
-        // frame buffer. The number of screen clippings in the array is specified by
-        // the numberRectangles field.
-        BitmapRectangle[] rectangles = new BitmapRectangle[numberRectangles];
-        for (int i = 0; i < numberRectangles; i++) {
-            rectangles[i] = readRectangle(buf);
-        }
-        order.rectangles = rectangles;
-
-        buf.assertThatBufferIsFullyRead();
-
-        ByteBuffer data = new ByteBuffer(0);
-        data.setOrder(order);
-        pushDataToAllOuts(data);
-
-        buf.unref();
-    }
-
-    public BitmapRectangle readRectangle(ByteBuffer buf) {
-
-        BitmapRectangle rectangle = new BitmapRectangle();
-
-        // (2 bytes): A 16-bit, unsigned integer. Left bound of the rectangle.
-        rectangle.x = buf.readSignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. Top bound of the rectangle.
-        rectangle.y = buf.readSignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. Inclusive right bound of the
-        // rectangle.
-        int destRight = buf.readSignedShortLE();
-        rectangle.width = destRight - rectangle.x + 1;
-
-        // (2 bytes): A 16-bit, unsigned integer. Inclusive bottom bound of the
-        // rectangle.
-        int destBottom = buf.readSignedShortLE();
-        rectangle.height = destBottom - rectangle.y + 1;
-
-        // (2 bytes): A 16-bit, unsigned integer. The width of the rectangle.
-        rectangle.bufferWidth = buf.readSignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. The height of the rectangle.
-        rectangle.bufferHeight = buf.readSignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. The color depth of the rectangle
-        // data in bits-per-pixel.
-        rectangle.colorDepth = buf.readSignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. The flags describing the format of
-        // the bitmap data in the bitmapDataStream field.
-        int flags = buf.readSignedShortLE();
-
-        // BITMAP_COMPRESSION 0x0001
-        // Indicates that the bitmap data is compressed. The bitmapComprHdr field
-        // MUST be present if the NO_BITMAP_COMPRESSION_HDR (0x0400) flag is not
-        // set.
-        boolean compressed = ((flags & BITMAP_COMPRESSION) > 0);
-
-        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the data in
-        // the bitmapComprHdr and bitmapDataStream fields.
-        int bitmapLength = buf.readSignedShortLE();
-
-        // NO_BITMAP_COMPRESSION_HDR 0x0400
-        // Indicates that the bitmapComprHdr field is not present (removed for
-        // bandwidth efficiency to save 8 bytes).
-        if (compressed && (flags & NO_BITMAP_COMPRESSION_HDR) == 0) {
-            // (8 bytes): Optional Compressed Data Header structure specifying the
-            // bitmap data in the bitmapDataStream.
-            // This field MUST be present if the BITMAP_COMPRESSION (0x0001) flag is
-            // present in the Flags field, but the NO_BITMAP_COMPRESSION_HDR (0x0400)
-            // flag is not.
-
-            // Note: Even when compression header is enabled, server sends nothing.
-            // rectangle.compressedBitmapHeader = buf.readBytes(8);
-        }
-
-        // (variable): A variable-length array of bytes describing a bitmap image.
-        // Bitmap data is either compressed or uncompressed, depending on whether
-        // the BITMAP_COMPRESSION flag is present in the Flags field. Uncompressed
-        // bitmap data is formatted as a bottom-up, left-to-right series of pixels.
-        // Each pixel is a whole number of bytes. Each row contains a multiple of
-        // four bytes (including up to three bytes of padding, as necessary).
-        // Compressed bitmaps not in 32 bpp format are compressed using Interleaved
-        // RLE and encapsulated in an RLE Compressed Bitmap Stream structure,
-        // while compressed bitmaps at a color depth of 32 bpp are compressed
-        // using RDP 6.0 Bitmap Compression and stored inside
-        // an RDP 6.0 Bitmap Compressed Stream structure.
-        if (!compressed) {
-            rectangle.bitmapDataStream = buf.readBytes(bitmapLength);
-        } else {
-            ByteBuffer compressedImage = buf.readBytes(bitmapLength);
-            //* DEBUG */System.out.println("Compressed image: " + compressedImage + ", depth: " + rectangle.bitsPerPixel + ".");
-            rectangle.bitmapDataStream = RLEBitmapDecompression.rleDecompress(compressedImage, rectangle.bufferWidth, rectangle.bufferHeight, rectangle.colorDepth);
-            compressedImage.unref();
-        }
-
-        return rectangle;
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-        ByteBuffer packet =
-            new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x04, 0x0a,
-                0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
-
-        Element bitmap = new ServerBitmapUpdate("bitmap") {
-            {
-                verbose = true;
-            }
-        };
-        FakeSink fakeSink = new FakeSink("sink") {
-            {
-                verbose = true;
-            }
-        };
-        Pipeline pipeline = new PipelineImpl("test");
-
-        // BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
-        // Element adapter = new AwtRdpAdapter("test",canvas );
-        // pipeline.addAndLink(bitmap, adapter);
-        pipeline.addAndLink(bitmap, fakeSink);
-
-        bitmap.handleData(packet, null);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
deleted file mode 100644
index 1526edf..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerChannel1003Router.java
+++ /dev/null
@@ -1,533 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ServerChannel1003Router extends BaseElement {
-
-    /**
-     * Demand Active PDU.
-     */
-    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
-
-    /**
-     * Confirm Active PDU.
-     */
-    public static final int PDUTYPE_CONFIRMACTIVEPDU = 0x3;
-
-    /**
-     * Deactivate All PDU.
-     */
-    public static final int PDUTYPE_DEACTIVATEALLPDU = 0x6;
-
-    /**
-     * Data PDU (actual type is revealed by the pduType2 field in the Share Data
-     * Header).
-     */
-    public static final int PDUTYPE_DATAPDU = 0x7;
-
-    /**
-     * Enhanced Security Server Redirection PDU.
-     */
-    public static final int PDUTYPE_SERVER_REDIR_PKT = 0xA;
-
-    protected RdpState state;
-
-    public ServerChannel1003Router(String id, RdpState state) {
-        super(id);
-        this.state = state;
-    }
-
-    /**
-     * @see http://msdn.microsoft.com/en-us/library/cc240576.aspx
-     */
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        int length = buf.readUnsignedShortLE();
-        if (buf.length != length) {
-            // It is ServerErrorAlert-ValidClient
-            // Ignore it
-            //throw new RuntimeException("[" + this + "] ERROR: Incorrect PDU length: " + length + ", data: " + buf + ".");
-        }
-
-        int type = buf.readUnsignedShortLE() & 0xf;
-
-        // int sourceId = buf.readUnsignedShortLE();
-        buf.skipBytes(2);
-
-        switch (type) {
-            case PDUTYPE_DEMANDACTIVEPDU:
-                pushDataToPad("demand_active", buf);
-                break;
-            case PDUTYPE_CONFIRMACTIVEPDU:
-                throw new RuntimeException("Unexpected client CONFIRM ACTIVE PDU. Data: " + buf + ".");
-            case PDUTYPE_DEACTIVATEALLPDU:
-                // pushDataToPad("deactivate_all", buf);
-                /* ignore */buf.unref();
-                break;
-            case PDUTYPE_DATAPDU:
-                handleDataPdu(buf);
-                break;
-            case PDUTYPE_SERVER_REDIR_PKT:
-                // pushDataToPad("server_redir", buf);
-                /* ignore */buf.unref();
-                break;
-            default:
-                throw new RuntimeException("[" + this + "] ERROR: Unknown PDU type: " + type + ", data: " + buf + ".");
-        }
-
-    }
-
-    /**
-     * Graphics Update PDU.
-     */
-    public static final int PDUTYPE2_UPDATE = 0x02;
-
-    /**
-     * Control PDU.
-     */
-    public static final int PDUTYPE2_CONTROL = 0x14;
-
-    /**
-     * Pointer Update PDU.
-     */
-    public static final int PDUTYPE2_POINTER = 0x1B;
-
-    /**
-     * Input Event PDU.
-     */
-    public static final int PDUTYPE2_INPUT = 0x1C;
-
-    /**
-     * Synchronize PDU.
-     */
-    public static final int PDUTYPE2_SYNCHRONIZE = 0x1F;
-
-    /**
-     * Refresh Rect PDU.
-     */
-    public static final int PDUTYPE2_REFRESH_RECT = 0x21;
-
-    /**
-     * Play Sound PDU.
-     */
-    public static final int PDUTYPE2_PLAY_SOUND = 0x22;
-
-    /**
-     * Suppress Output PDU.
-     */
-    public static final int PDUTYPE2_SUPPRESS_OUTPUT = 0x23;
-
-    /**
-     * Shutdown Request PDU.
-     */
-    public static final int PDUTYPE2_SHUTDOWN_REQUEST = 0x24;
-
-    /**
-     * Shutdown Request Denied PDU.
-     */
-    public static final int PDUTYPE2_SHUTDOWN_DENIED = 0x25;
-
-    /**
-     * Save Session Info PDU.
-     */
-    public static final int PDUTYPE2_SAVE_SESSION_INFO = 0x26;
-
-    /**
-     * Font List PDU.
-     */
-    public static final int PDUTYPE2_FONTLIST = 0x27;
-
-    /**
-     * Font Map PDU.
-     */
-    public static final int PDUTYPE2_FONTMAP = 0x28;
-
-    /**
-     * Set Keyboard Indicators PDU.
-     */
-    public static final int PDUTYPE2_SET_KEYBOARD_INDICATORS = 0x29;
-
-    /**
-     * Persistent Key List PDU.
-     */
-    public static final int PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST = 0x2B;
-
-    /**
-     * Bitmap Cache Error PDU.
-     */
-    public static final int PDUTYPE2_BITMAPCACHE_ERROR_PDU = 0x2C;
-
-    /**
-     * Set Keyboard IME Status PDU.
-     */
-    public static final int PDUTYPE2_SET_KEYBOARD_IME_STATUS = 0x2D;
-
-    /**
-     * Offscreen Bitmap Cache Error PDU.
-     */
-    public static final int PDUTYPE2_OFFSCRCACHE_ERROR_PDU = 0x2E;
-
-    /**
-     * Set Error Info PDU.
-     */
-    public static final int PDUTYPE2_SET_ERROR_INFO_PDU = 0x2F;
-
-    /**
-     * DrawNineGrid Cache Error PDU.
-     */
-    public static final int PDUTYPE2_DRAWNINEGRID_ERROR_PDU = 0x30;
-
-    /**
-     * GDI+ Error PDU.
-     */
-    public static final int PDUTYPE2_DRAWGDIPLUS_ERROR_PDU = 0x31;
-
-    /**
-     * Auto-Reconnect Status PDU.
-     */
-    public static final int PDUTYPE2_ARC_STATUS_PDU = 0x32;
-
-    /**
-     * Status Info PDU.
-     */
-    public static final int PDUTYPE2_STATUS_INFO_PDU = 0x36;
-
-    /**
-     * Monitor Layout PDU.
-     */
-    public static final int PDUTYPE2_MONITOR_LAYOUT_PDU = 0x37;
-
-    /**
-     * Indicates an Orders Update.
-     */
-    public static final int UPDATETYPE_ORDERS = 0x0000;
-
-    /**
-     * Indicates a Bitmap Graphics Update.
-     */
-    public static final int UPDATETYPE_BITMAP = 0x0001;
-
-    /**
-     * Indicates a Palette Update.
-     */
-    public static final int UPDATETYPE_PALETTE = 0x0002;
-
-    /**
-     * Indicates a Synchronize Update.
-     */
-    public static final int UPDATETYPE_SYNCHRONIZE = 0x0003;
-
-    /**
-     * @see http://msdn.microsoft.com/en-us/library/cc240577.aspx
-     */
-    protected void handleDataPdu(ByteBuffer buf) {
-
-        // (4 bytes): A 32-bit, unsigned integer. Share identifier for the packet.
-        long shareId = buf.readUnsignedIntLE();
-        if (shareId != state.serverShareId)
-            throw new RuntimeException("Unexpected share ID: " + shareId + ".");
-//    buf.skipBytes(4);
-
-        // Padding.
-        buf.skipBytes(1);
-
-        // (1 byte): An 8-bit, unsigned integer. The stream identifier for the
-        // packet.
-        // int streamId = buf.readUnsignedByte();
-        buf.skipBytes(1);
-
-        // (2 bytes): A 16-bit, unsigned integer. The uncompressed length of the
-        // packet in bytes.
-        int uncompressedLength = buf.readUnsignedShortLE();
-
-        // (1 byte): An 8-bit, unsigned integer. The type of Data PDU.
-        int type2 = buf.readUnsignedByte();
-
-        // (1 byte): An 8-bit, unsigned integer. The compression type and flags
-        // specifying the data following the Share Data Header
-        int compressedType = buf.readUnsignedByte();
-        if (compressedType != 0)
-            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
-
-        // (2 bytes): A 16-bit, unsigned integer. The compressed length of the
-        // packet in bytes.
-        int compressedLength = buf.readUnsignedShortLE();
-        if (compressedLength != 0)
-            throw new RuntimeException("Compression of protocol packets is not supported. Data: " + buf + ".");
-
-        ByteBuffer data = buf.readBytes(uncompressedLength - 18);
-        buf.unref();
-
-        switch (type2) {
-
-            case PDUTYPE2_UPDATE: {
-
-                // (2 bytes): A 16-bit, unsigned integer. Type of the graphics update.
-                int updateType = data.readUnsignedShortLE();
-                ByteBuffer data2 = data.readBytes(data.length - data.cursor);
-                data.unref();
-
-                switch (updateType) {
-                    case UPDATETYPE_ORDERS:
-                        pushDataToPad("orders", data2);
-                        break;
-                    case UPDATETYPE_BITMAP:
-                        pushDataToPad("bitmap", data2);
-                        break;
-                    case UPDATETYPE_PALETTE:
-                        pushDataToPad("palette", data2);
-                        break;
-                    case UPDATETYPE_SYNCHRONIZE:
-                        // Ignore
-                        data2.unref();
-                        break;
-                }
-
-                break;
-            }
-            case PDUTYPE2_CONTROL:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_CONTROL ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_POINTER:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_POINTER ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_INPUT:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_INPUT ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SYNCHRONIZE:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SYNCHRONIZE ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_REFRESH_RECT:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_REFRESH_RECT ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_PLAY_SOUND:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_PLAY_SOUND ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SUPPRESS_OUTPUT:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SUPPRESS_OUTPUT ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SHUTDOWN_REQUEST:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_REQUEST ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SHUTDOWN_DENIED:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SHUTDOWN_DENIED ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SAVE_SESSION_INFO:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SAVE_SESSION_INFO ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_FONTLIST:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTLIST ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_FONTMAP:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_FONTMAP ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SET_KEYBOARD_INDICATORS:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_INDICATORS ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_BITMAPCACHE_ERROR_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_BITMAPCACHE_ERROR_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SET_KEYBOARD_IME_STATUS:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_KEYBOARD_IME_STATUS ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_OFFSCRCACHE_ERROR_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_OFFSCRCACHE_ERROR_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_SET_ERROR_INFO_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_SET_ERROR_INFO_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_DRAWNINEGRID_ERROR_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWNINEGRID_ERROR_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_DRAWGDIPLUS_ERROR_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_DRAWGDIPLUS_ERROR_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_ARC_STATUS_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_ARC_STATUS_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_STATUS_INFO_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_STATUS_INFO_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-            case PDUTYPE2_MONITOR_LAYOUT_PDU:
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Packet PDUTYPE2_MONITOR_LAYOUT_PDU ignored.");
-                // Ignore
-                data.unref();
-                break;
-
-            default:
-                throw new RuntimeException("Unknow data PDU type: " + type2 + ", data: " + buf + ".");
-        }
-    }
-
-    /**
-     * 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");
-
-        byte[] packet = new byte[] {
-            // TPKT
-            (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
-            (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
-
-            // X224
-            (byte)0x02, // X224 Length: 2 bytes
-            (byte)0xF0, // X224 Type: Data
-            (byte)0x80, // X224 EOT
-
-            // MCS
-            // Type: send data indication: 26 (0x1a, top 6 bits)
-            (byte)0x68, // ??
-
-            (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
-            (byte)0x03, (byte)0xEB, // Channel ID: 1003
-            (byte)0x70, // Data priority: high, segmentation: begin|end
-            (byte)0x0D, // Payload length: 13 bytes
-
-            // Deactivate all PDU
-            (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
-
-            // - PDUType: (0x16, LE)
-            // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-            // ProtocolVersion: (000000000001....) 1
-            (byte)0x16, (byte)0x00,
-
-            (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
-            (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
-
-            (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
-            (byte)0x00, // Source descriptor (should be set to 0): 0
-        };
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        RdpState rdpState = new RdpState() {
-            {
-                serverShareId = 66538;
-            }
-        };
-        Element channel1003 = new ServerChannel1003Router("channel_1003", rdpState);
-        Element mcs = new ServerMCSPDU("mcs");
-        Element tpkt = new ServerTpkt("tpkt");
-        Element x224 = new ServerX224DataPdu("x224");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-            // Deactivate all PDU
-            (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
-
-            // - PDUType: 22 (0x16, LE)
-            // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-            // ProtocolVersion: (000000000001....) 1
-            (byte)0x16, (byte)0x00,
-
-            (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
-            (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
-
-            (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
-            (byte)0x00, // Source descriptor (should be set to 0): 0
-        }));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, tpkt, x224, mcs, channel1003, sink);
-        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "channel_1003 >deactivate_all", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
deleted file mode 100644
index 7bbe0c3..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUCooperate.java
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerControlPDUCooperate extends OneTimeSwitch {
-
-    public ServerControlPDUCooperate(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-}
-
-/* @formatter:off */
-/*
-03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 9A 02 1A 00 14 00 00 00 04 00 00 00 00 00 00 00
-
-
-  Frame: Number = 38, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 40
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 40 (0x28)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 26
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 26
-    RDP: RDPBCGR
-- RDPBCGR: TsControlPDU
-  - SlowPathPacket: TsControlPDU
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 26 (0x1A)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_CONTROL
-        ShareID: 66538 (0x103EA)
-        Pad1: 154 (0x9A)
-        StreamID: TS_STREAM_MED
-        UncompressedLength: 26 (0x1A)
-        PDUType2: TS_PDUTYPE2_CONTROL
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsControlPDU: Action = Cooperate
-        Action: Cooperate
-        GrantID: 0 (0x0)
-        ControlID: 0 (0x0)
-
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
deleted file mode 100644
index 62cbd6c..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerControlPDUGrantedControl.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerControlPDUGrantedControl extends OneTimeSwitch {
-
-    public ServerControlPDUGrantedControl(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-}
-/* @formatter:off */
-/*
-03 00 00 28 02 F0 80 68 00 01 03 EB 70 1A 1A 00 17 00 EA 03 EA 03 01 00 50 02 1A 00 14 00 00 00 02 00 EC 03 EA 03 00 00
-
-  Frame: Number = 45, Captured Frame Length = 97, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 40
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 40 (0x28)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 26
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 26
-    RDP: RDPBCGR
-- RDPBCGR: TsControlPDU
-  - SlowPathPacket: TsControlPDU
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 26 (0x1A)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_CONTROL
-        ShareID: 66538 (0x103EA)
-        Pad1: 80 (0x50)
-        StreamID: TS_STREAM_MED
-        UncompressedLength: 26 (0x1A)
-        PDUType2: TS_PDUTYPE2_CONTROL
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsControlPDU: Action = Granted Control
-        Action: Granted Control
-        GrantID: 1004 (0x3EC)
-        ControlID: 1002 (0x3EA)
- */


[11/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
new file mode 100755
index 0000000..248f166
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmState.java
@@ -0,0 +1,887 @@
+// 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 javax.crypto.Cipher;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+
+public class NtlmState implements NtlmConstants {
+
+    /**
+     * The set of configuration flags (section 2.2.2.5) that specifies the
+     * negotiated capabilities of the client and server for the current NTLM
+     * session.
+     */
+    public NegoFlags negotiatedFlags;
+
+    /**
+     * Target Information extracted from Type2 server response.
+     */
+    public byte[] serverTargetInfo;
+
+    /**
+     * Challenge extracted from Type2 server response.
+     */
+    public byte[] serverChallenge;
+
+    public byte[] clientChallenge;
+
+    public byte[] keyExchangeKey;
+
+    /**
+     * A 128-bit (16-byte) session key used to derive ClientSigningKey,
+     * ClientSealingKey, ServerSealingKey, and ServerSigningKey.
+     */
+    public byte[] exportedSessionKey;
+
+    /**
+     * The signing key used by the client to sign messages and used by the server
+     * to verify signed client messages. It is generated after the client is
+     * authenticated by the server and is not passed over the wire.
+     */
+    public byte[] clientSigningKey;
+
+    /**
+     * The sealing key used by the client to seal messages and used by the server
+     * to unseal client messages. It is generated after the client is
+     * authenticated by the server and is not passed over the wire.
+     */
+    public byte[] clientSealingKey;
+
+    public byte[] encryptedRandomSessionKey;
+
+    public byte[] sessionBaseKey;
+
+    public byte[] responseKeyNT;
+
+    public byte[] ntProofStr1;
+
+    public String domain;
+
+    public String user;
+
+    public String workstation;
+
+    public String password;
+
+    public String serverNetbiosDomainName;
+
+    public String serverNetbiosComputerName;
+
+    public String serverDnsDomainName;
+
+    public String serverDnsComputerName;
+
+    public String serverDnsTreeName;
+
+    public String serverTargetName;
+
+    public byte[] serverTimestamp;
+    public byte[] clientChallengeTimestamp;
+
+    public byte[] lmChallengeResponse;
+
+    public byte[] ntChallengeResponse;
+
+    public byte[] ntProofStr2;
+
+    public byte[] randomSessionKey;
+
+    public byte[] serverSigningKey;
+
+    public byte[] serverSealingKey;
+
+    public byte[] sendSigningKey;
+
+    public byte[] recvSigningKey;
+
+    public byte[] sendSealingKey;
+
+    public byte[] recvSealingKey;
+
+    public Cipher sendRc4Seal;
+
+    public Cipher recvRc4Seal;
+
+    public byte[] messageIntegrityCheck;
+
+    public byte[] negotiateMessage;
+
+    public byte[] challengeMessage;
+
+    public byte[] authenticateMessage;
+
+    /**
+     * A 4-byte sequence number.
+     *
+     * In the case of connection-oriented authentication, the SeqNum parameter
+     * MUST start at 0 and is incremented by one for each message sent. The
+     * receiver expects the first received message to have SeqNum equal to 0, and
+     * to be one greater for each subsequent message received. If a received
+     * message does not contain the expected SeqNum, an error MUST be returned to
+     * the receiving application, and SeqNum is not incremented.
+     */
+    public int sendSeqNum;
+    public int recvSeqNum;
+
+    public byte[] authenticateTargetInfo;
+
+    public String servicePrincipalName;
+
+    private byte[] channelBindingsHash = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+    public byte[] subjectPublicKey;
+
+    public byte[] ntlm_generate_timestamp() {
+        clientChallengeTimestamp = serverTimestamp;
+        return clientChallengeTimestamp;
+    }
+
+    /**
+     * MD4(UNICODE(Password))
+     */
+    public byte[] NTOWFv1W(String password) {
+        return CryptoAlgos.MD4(password.getBytes(RdpConstants.CHARSET_16));
+    }
+
+    public void testNTOWFv1W() {
+        byte[] expected = new byte[] {(byte)0x25, (byte)0xf3, (byte)0x39, (byte)0xc9, (byte)0x86, (byte)0xb5, (byte)0xc2, (byte)0x6f, (byte)0xdc,
+                (byte)0xab, (byte)0x91, (byte)0x34, (byte)0x93, (byte)0xa2, (byte)0x18, (byte)0x2a};
+        byte[] actual = NTOWFv1W("R2Preview!");
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    /**
+     * HMAC_MD5(NTOWFv1W(Password), UNICODE(ConcatenationOf(UpperCase(User),
+     * Domain)))
+     */
+    public byte[] NTOWFv2W(String password, String user, String domain) {
+        return CryptoAlgos.HMAC_MD5(NTOWFv1W(password), (user.toUpperCase() + domain).getBytes(RdpConstants.CHARSET_16));
+    }
+
+    public void testNTOWFv2W() {
+        byte[] expected = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] actual = NTOWFv2W("R2Preview!", "Administrator", "workgroup");
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_compute_ntlm_v2_hash() {
+        return NTOWFv2W(password, user, domain);
+    }
+
+    public byte[] ntlm_generate_client_challenge() {
+        if (clientChallenge == null) {
+            clientChallenge = CryptoAlgos.NONCE(8);
+        }
+        return clientChallenge;
+    }
+
+    public byte[] ntlm_compute_lm_v2_response() {
+        if (lmChallengeResponse == null) {
+
+            byte[] ntlm_v2_hash = ntlm_compute_ntlm_v2_hash();
+
+            ntlm_generate_client_challenge();
+
+            byte[] challenges = CryptoAlgos.concatenationOf(serverChallenge, clientChallenge);
+
+            lmChallengeResponse = CryptoAlgos.concatenationOf(CryptoAlgos.HMAC_MD5(ntlm_v2_hash, challenges), clientChallenge);
+        }
+
+        return lmChallengeResponse;
+    }
+
+    public void testComputeLmV2Response() {
+        serverChallenge = new byte[] {(byte)0x34, (byte)0xe4, (byte)0x4c, (byte)0xd5, (byte)0x75, (byte)0xe3, (byte)0x43, (byte)0x0f};
+        clientChallenge = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+        password = "R2Preview!";
+        user = "Administrator";
+        domain = "workgroup";
+        byte[] expected = new byte[] {(byte)0xa8, (byte)0xae, (byte)0xd7, (byte)0x46, (byte)0x06, (byte)0x32, (byte)0x02, (byte)0x35, (byte)0x1d,
+                (byte)0x95, (byte)0x99, (byte)0x36, (byte)0x20, (byte)0x36, (byte)0xac, (byte)0xc3, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,};
+        byte[] actual = ntlm_compute_lm_v2_response();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] computeNtProofStr(byte[] ntlmV2Hash, byte[] data) {
+        return CryptoAlgos.HMAC_MD5(ntlmV2Hash, data);
+    }
+
+    public void testComputeNtProofStr() {
+        byte[] ntlm_v2_hash = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] data = new byte[] {(byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6, (byte)0x16, (byte)0x01,
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c,
+                (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07,
+                (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57,
+                (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00,
+                (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c,
+                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00,
+                (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f,
+                (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e,
+                (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00,
+                (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06,
+                (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00,
+                (byte)0x45, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56,
+                (byte)0x00, (byte)0x2f, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x36, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e,
+                (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        byte[] expected = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e,};
+        byte[] actual = computeNtProofStr(ntlm_v2_hash, data);
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] computeSessionBaseKey(byte[] ntlmV2Hash, byte[] ntProofStr) {
+        return CryptoAlgos.HMAC_MD5(ntlmV2Hash, ntProofStr);
+    }
+
+    public void testComputeSessionBaseKey() {
+        byte[] ntlm_v2_hash = new byte[] {(byte)0x5f, (byte)0xcc, (byte)0x4c, (byte)0x48, (byte)0x74, (byte)0x6b, (byte)0x94, (byte)0xce, (byte)0xb7,
+                (byte)0xae, (byte)0xf1, (byte)0x0d, (byte)0xc9, (byte)0x11, (byte)0x22, (byte)0x8f,};
+        byte[] nt_proof_str = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e,};
+
+        byte[] expected = new byte[] {(byte)0x8e, (byte)0x0f, (byte)0xdd, (byte)0x12, (byte)0x4c, (byte)0x3b, (byte)0x11, (byte)0x7f, (byte)0x22,
+                (byte)0xb9, (byte)0x4b, (byte)0x59, (byte)0x52, (byte)0xbc, (byte)0xa7, (byte)0x18,};
+        byte[] actual = computeSessionBaseKey(ntlm_v2_hash, nt_proof_str);
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public String generateServicePrincipalName(String serverHostName) {
+        servicePrincipalName = GSS_RDP_SERVICE_NAME + "/" + serverHostName;
+        return servicePrincipalName;
+    }
+
+    public void writeAVPair(ByteBuffer buf, int avPairType, byte[] value) {
+        if (value != null) {
+            buf.writeShortLE(avPairType);
+            buf.writeShortLE(value.length);
+            buf.writeBytes(value);
+        }
+    }
+
+    public void writeAVPair(ByteBuffer buf, int avPairType, String value) {
+        if (value != null) {
+            writeAVPair(buf, avPairType, value.getBytes(RdpConstants.CHARSET_16));
+        }
+    }
+
+    public byte[] ntlm_construct_authenticate_target_info() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        writeAVPair(buf, MSV_AV_NETBIOS_DOMAIN_NAME, serverNetbiosDomainName);
+
+        writeAVPair(buf, MSV_AV_NETBIOS_COMPUTER_NAME, serverNetbiosComputerName);
+
+        writeAVPair(buf, MSV_AV_DNS_DOMAIN_NAME, serverDnsDomainName);
+
+        writeAVPair(buf, MSV_AV_DNS_COMPUTER_NAME, serverDnsComputerName);
+
+        writeAVPair(buf, MSV_AV_DNS_TREE_NAME, serverDnsTreeName);
+
+        writeAVPair(buf, MSV_AV_TIMESTAMP, serverTimestamp);
+
+        byte[] flags = new byte[] {(byte)MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK, 0, 0, 0};
+        writeAVPair(buf, MSV_AV_FLAGS, flags);
+
+        writeAVPair(buf, MSV_AV_CHANNEL_BINDINGS, channelBindingsHash);
+
+        writeAVPair(buf, MSV_AV_TARGET_NAME, servicePrincipalName);
+
+        writeAVPair(buf, MSV_AV_EOL, "");
+        // DEBUG: put EOL 4 times, for compatibility with FreeRDP output
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        //*DEBUG*/writeAVPair(buf, MSV_AV_EOL, "");
+        buf.trimAtCursor();
+
+        authenticateTargetInfo = buf.toByteArray();
+        buf.unref();
+
+        return authenticateTargetInfo;
+    }
+
+    public void testConstructAuthenticateTargetInfo() {
+        serverNetbiosDomainName = "WIN-LO419B2LSR0";
+        serverNetbiosComputerName = "WIN-LO419B2LSR0";
+        serverDnsDomainName = "WIN-LO419B2LSR0";
+        serverDnsComputerName = "WIN-LO419B2LSR0";
+        serverTimestamp = new byte[] {(byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01,};
+        servicePrincipalName = "TERMSRV/192.168.1.3";
+
+        byte[] expected = new byte[] {(byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+        byte[] actual = ntlm_construct_authenticate_target_info();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_compute_ntlm_v2_response() {
+        ByteBuffer buf = new ByteBuffer(4096);
+
+        byte[] ntlm_v2_hash = ntlm_compute_ntlm_v2_hash();
+
+        buf.writeByte(0x1); // RespType
+        buf.writeByte(0x1); // HighRespType
+        buf.writeShort(0); // reserved
+        buf.writeInt(0); // reserved
+        buf.writeBytes(clientChallengeTimestamp); // Timestamp, 8 bytes
+        buf.writeBytes(clientChallenge); // Client nonce, 8 bytes
+        buf.writeInt(0); // reserved
+        buf.writeBytes(authenticateTargetInfo); // Target Info block
+        buf.trimAtCursor();
+        byte[] bufBytes = buf.toByteArray();
+        buf.unref();
+
+        ntProofStr2 = computeNtProofStr(ntlm_v2_hash, CryptoAlgos.concatenationOf(serverChallenge, bufBytes));
+
+        ntChallengeResponse = CryptoAlgos.concatenationOf(ntProofStr2, bufBytes);
+
+        sessionBaseKey = computeSessionBaseKey(ntlm_v2_hash, ntProofStr2);
+
+        return ntChallengeResponse;
+    }
+
+    public void testComputeNtlmV2Response() {
+        serverChallenge = new byte[] {(byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6, (byte)0x16,};
+        clientChallenge = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+        password = "R2Preview!";
+        user = "Administrator";
+        domain = "workgroup";
+        clientChallengeTimestamp = new byte[] {(byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01,};
+        authenticateTargetInfo = new byte[] {(byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        byte[] expected = new byte[] {(byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24, (byte)0xd5, (byte)0x96, (byte)0x85,
+                (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce,
+                (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49,
+                (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53,
+                (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0,
+                (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06, (byte)0x00, (byte)0x04, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00, (byte)0x45, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x2f, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x36,
+                (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x33, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+        byte[] actual = ntlm_compute_ntlm_v2_response();
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_key_exchange_key() {
+        keyExchangeKey = sessionBaseKey;
+        return keyExchangeKey;
+    }
+
+    public byte[] ntlm_generate_random_session_key() {
+        randomSessionKey = CryptoAlgos.NONCE(16);
+        return randomSessionKey;
+    }
+
+    public byte[] ntlm_generate_exported_session_key() {
+        exportedSessionKey = randomSessionKey;
+        return exportedSessionKey;
+    }
+
+    public byte[] ntlm_encrypt_random_session_key() {
+        encryptedRandomSessionKey = CryptoAlgos.RC4K(keyExchangeKey, randomSessionKey);
+        return encryptedRandomSessionKey;
+    }
+
+    public void testComputeEncryptedRandomSessionKey() {
+        keyExchangeKey = new byte[] {(byte)0x8e, (byte)0x0f, (byte)0xdd, (byte)0x12, (byte)0x4c, (byte)0x3b, (byte)0x11, (byte)0x7f, (byte)0x22,
+                (byte)0xb9, (byte)0x4b, (byte)0x59, (byte)0x52, (byte)0xbc, (byte)0xa7, (byte)0x18,};
+        randomSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+
+        byte[] expected = new byte[] {(byte)0xe4, (byte)0xe9, (byte)0xc2, (byte)0xad, (byte)0x41, (byte)0x02, (byte)0x2f, (byte)0x3c, (byte)0xf9,
+                (byte)0x4c, (byte)0x72, (byte)0x84, (byte)0xc5, (byte)0x2a, (byte)0x7c, (byte)0x6f,};
+        byte[] actual = ntlm_encrypt_random_session_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_signing_key(String signMagic) {
+        return CryptoAlgos.MD5(CryptoAlgos.concatenationOf(exportedSessionKey, signMagic.getBytes(RdpConstants.CHARSET_8), new byte[] {0}));
+    }
+
+    public void testGenerateSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        byte[] actual = ntlm_generate_signing_key(CLIENT_SIGN_MAGIC);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_client_signing_key() {
+        clientSigningKey = ntlm_generate_signing_key(CLIENT_SIGN_MAGIC);
+        return clientSigningKey;
+    }
+
+    public void testGenerateClientSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        byte[] actual = ntlm_generate_client_signing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_server_signing_key() {
+        serverSigningKey = ntlm_generate_signing_key(SERVER_SIGN_MAGIC);
+        return serverSigningKey;
+    }
+
+    public void testGenerateServerSigningKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0xb6, (byte)0x58, (byte)0xc5, (byte)0x98, (byte)0x7a, (byte)0x25, (byte)0xf8, (byte)0x6e, (byte)0xd8,
+                (byte)0xe5, (byte)0x6c, (byte)0xe9, (byte)0x3e, (byte)0x3c, (byte)0xc0, (byte)0x88,};
+        byte[] actual = ntlm_generate_server_signing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_client_sealing_key() {
+        clientSealingKey = ntlm_generate_signing_key(CLIENT_SEAL_MAGIC);
+        return clientSealingKey;
+    }
+
+    public void testGenerateClientSealingKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0x58, (byte)0x19, (byte)0x44, (byte)0xc2, (byte)0x7a, (byte)0xc6, (byte)0x34, (byte)0x45, (byte)0xe4,
+                (byte)0xb8, (byte)0x2b, (byte)0x55, (byte)0xb9, (byte)0x0b, (byte)0x1f, (byte)0xb5,};
+        byte[] actual = ntlm_generate_client_sealing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_generate_server_sealing_key() {
+        serverSealingKey = ntlm_generate_signing_key(SERVER_SEAL_MAGIC);
+        return serverSealingKey;
+    }
+
+    public void testGenerateServerSealingKey() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+        byte[] expected = new byte[] {(byte)0x92, (byte)0x3a, (byte)0x73, (byte)0x5c, (byte)0x92, (byte)0xa7, (byte)0x04, (byte)0x34, (byte)0xbe,
+                (byte)0x9a, (byte)0xa2, (byte)0x9f, (byte)0xed, (byte)0xc1, (byte)0xe6, (byte)0x13,};
+        byte[] actual = ntlm_generate_server_sealing_key();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public void ntlm_init_rc4_seal_states() {
+        ntlm_generate_client_signing_key();
+        ntlm_generate_server_signing_key();
+        ntlm_generate_client_sealing_key();
+        ntlm_generate_server_sealing_key();
+
+        sendSigningKey = clientSigningKey;
+        recvSigningKey = serverSigningKey;
+        sendSealingKey = clientSealingKey;
+        recvSealingKey = serverSealingKey;
+
+        sendRc4Seal = CryptoAlgos.initRC4(sendSealingKey);
+        recvRc4Seal = CryptoAlgos.initRC4(recvSealingKey);
+    }
+
+    public byte[] ntlm_compute_message_integrity_check() {
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: exportedSessionKey:\n" + new ByteBuffer(exportedSessionKey).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: negotiateMessage:\n" + new ByteBuffer(negotiateMessage).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: challengeMessage:\n" + new ByteBuffer(challengeMessage).dump() + "\n");
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: authenticateMessage:\n" + new ByteBuffer(authenticateMessage).dump() + "\n");
+        messageIntegrityCheck = CryptoAlgos.HMAC_MD5(exportedSessionKey, CryptoAlgos.concatenationOf(negotiateMessage, challengeMessage, authenticateMessage));
+        //* DEBUG */System.out.println("ntlm_compute_message_integrity_check: messageIntegrityCheck:\n" + new ByteBuffer(messageIntegrityCheck).dump() + "\n");
+        return messageIntegrityCheck;
+    }
+
+    public void testComputeMessageIntegrityCheck() {
+        exportedSessionKey = new byte[] {(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x09,
+                (byte)0x0a, (byte)0x0b, (byte)0x0c, (byte)0x0d, (byte)0x0e, (byte)0x0f, (byte)0x10,};
+
+        negotiateMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x01,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xb7, (byte)0x82, (byte)0x08, (byte)0xe2, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f,};
+
+        challengeMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x02,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x35, (byte)0x82, (byte)0x8a, (byte)0xe2, (byte)0x4a, (byte)0x25, (byte)0x50, (byte)0xa5, (byte)0x11, (byte)0x9b, (byte)0xd6,
+                (byte)0x16, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x98, (byte)0x00,
+                (byte)0x98, (byte)0x00, (byte)0x56, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x03, (byte)0xd7, (byte)0x24, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x0f, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42,
+                (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00,
+                (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00,
+                (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30,
+                (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00,
+                (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39,
+                (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00,
+                (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e,
+                (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00,
+                (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52,
+                (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00,
+                (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31,
+                (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00,
+                (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85,
+                (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,};
+
+        authenticateMessage = new byte[] {(byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x03,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x18, (byte)0x00, (byte)0x18, (byte)0x00, (byte)0x90, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x16, (byte)0x01, (byte)0x16, (byte)0x01, (byte)0xa8, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0x00, (byte)0x12,
+                (byte)0x00, (byte)0x58, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x1a, (byte)0x00, (byte)0x1a, (byte)0x00, (byte)0x6a, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10,
+                (byte)0x00, (byte)0x10, (byte)0x00, (byte)0xbe, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x35, (byte)0xb2, (byte)0x88, (byte)0xe2,
+                (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x77, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x6b, (byte)0x00, (byte)0x67,
+                (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x75, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x41, (byte)0x00,
+                (byte)0x64, (byte)0x00, (byte)0x6d, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x6e, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x73,
+                (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x6f, (byte)0x00,
+                (byte)0x72, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c,
+                (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x7c, (byte)0xc0, (byte)0xfd, (byte)0x08, (byte)0xc5, (byte)0x14, (byte)0x05, (byte)0x34,
+                (byte)0xf3, (byte)0x12, (byte)0x9e, (byte)0x3e, (byte)0xa3, (byte)0x09, (byte)0xbc, (byte)0xc6, (byte)0x01, (byte)0x02, (byte)0x03,
+                (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, (byte)0x19, (byte)0x4b, (byte)0xeb, (byte)0xad, (byte)0xda, (byte)0x24,
+                (byte)0xd5, (byte)0x96, (byte)0x85, (byte)0x2e, (byte)0x24, (byte)0x94, (byte)0xd6, (byte)0x4a, (byte)0xb8, (byte)0x5e, (byte)0x01,
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c,
+                (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07,
+                (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57, (byte)0x00,
+                (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00, (byte)0x34,
+                (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x1e, (byte)0x00, (byte)0x57,
+                (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f, (byte)0x00,
+                (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x4c,
+                (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x1e, (byte)0x00,
+                (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x4f,
+                (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32, (byte)0x00,
+                (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x1e,
+                (byte)0x00, (byte)0x57, (byte)0x00, (byte)0x49, (byte)0x00, (byte)0x4e, (byte)0x00, (byte)0x2d, (byte)0x00, (byte)0x4c, (byte)0x00,
+                (byte)0x4f, (byte)0x00, (byte)0x34, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x42, (byte)0x00, (byte)0x32,
+                (byte)0x00, (byte)0x4c, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x30, (byte)0x00, (byte)0x07, (byte)0x00,
+                (byte)0x08, (byte)0x00, (byte)0xa0, (byte)0xe8, (byte)0x85, (byte)0x2c, (byte)0xe4, (byte)0xc9, (byte)0xce, (byte)0x01, (byte)0x06,
+                (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x10, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x26, (byte)0x00, (byte)0x54, (byte)0x00,
+                (byte)0x45, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x4d, (byte)0x00, (byte)0x53, (byte)0x00, (byte)0x52, (byte)0x00, (byte)0x56,
+                (byte)0x00, (byte)0x2f, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x39, (byte)0x00, (byte)0x32, (byte)0x00, (byte)0x2e, (byte)0x00,
+                (byte)0x31, (byte)0x00, (byte)0x36, (byte)0x00, (byte)0x38, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x31, (byte)0x00, (byte)0x2e,
+                (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xe4, (byte)0xe9, (byte)0xc2,
+                (byte)0xad, (byte)0x41, (byte)0x02, (byte)0x2f, (byte)0x3c, (byte)0xf9, (byte)0x4c, (byte)0x72, (byte)0x84, (byte)0xc5, (byte)0x2a,
+                (byte)0x7c, (byte)0x6f,};
+
+        byte[] expected = new byte[] {(byte)0xd9, (byte)0xe9, (byte)0xbc, (byte)0x9b, (byte)0x6f, (byte)0xa5, (byte)0xf9, (byte)0xc8, (byte)0x70,
+                (byte)0x16, (byte)0x10, (byte)0x20, (byte)0xf8, (byte)0xf1, (byte)0x61, (byte)0x42,};
+        byte[] actual = ntlm_compute_message_integrity_check();
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_EncryptMessage(byte[] message) {
+        byte[] versionBytes = new byte[] {0x01, 0x00, 0x00, 0x00}; // 0x00000001
+        // LE
+        byte[] seqNumBytes = new byte[] {(byte)(sendSeqNum & 0xff), (byte)((sendSeqNum >> 8) & 0xff), (byte)((sendSeqNum >> 16) & 0xff),
+                (byte)((sendSeqNum >> 24) & 0xff)};
+
+        byte[] digest = CryptoAlgos.HMAC_MD5(sendSigningKey, CryptoAlgos.concatenationOf(seqNumBytes, message));
+
+        byte[] encrypted = CryptoAlgos.RC4(sendRc4Seal, message);
+
+        // Encrypt first 8 bytes of digest only
+        byte[] checksum = CryptoAlgos.RC4(sendRc4Seal, Arrays.copyOf(digest, 8));
+
+        byte[] signature = CryptoAlgos.concatenationOf(versionBytes, checksum, seqNumBytes);
+
+        sendSeqNum++;
+
+        return CryptoAlgos.concatenationOf(signature, encrypted);
+    }
+
+    public void testNtlmEncryptMessage() {
+        sendSigningKey = new byte[] {(byte)0xf6, (byte)0xae, (byte)0x96, (byte)0xcb, (byte)0x05, (byte)0xe2, (byte)0xab, (byte)0x54, (byte)0xf6,
+                (byte)0xdd, (byte)0x59, (byte)0xf3, (byte)0xc9, (byte)0xd9, (byte)0xa0, (byte)0x43,};
+        sendRc4Seal = CryptoAlgos.initRC4(new byte[] {(byte)0x58, (byte)0x19, (byte)0x44, (byte)0xc2, (byte)0x7a, (byte)0xc6, (byte)0x34, (byte)0x45,
+                (byte)0xe4, (byte)0xb8, (byte)0x2b, (byte)0x55, (byte)0xb9, (byte)0x0b, (byte)0x1f, (byte)0xb5,});
+        sendSeqNum = 0;
+        byte[] serverPublicKey = new byte[] {(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a, (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, (byte)0x00,
+                (byte)0xa8, (byte)0x56, (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0, (byte)0x84,
+                (byte)0x31, (byte)0x19, (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb, (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13,
+                (byte)0xa1, (byte)0xb9, (byte)0x72, (byte)0xbb, (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65,
+                (byte)0x03, (byte)0xd1, (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69, (byte)0x89, (byte)0x5e,
+                (byte)0xfe, (byte)0xe0, (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b, (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd,
+                (byte)0x77, (byte)0x5d, (byte)0xf3, (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2,
+                (byte)0xcf, (byte)0xb1, (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17, (byte)0x7c, (byte)0xb7, (byte)0xd6,
+                (byte)0xc7, (byte)0xc7, (byte)0xbf, (byte)0x90, (byte)0x4e, (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0,
+                (byte)0xc2, (byte)0x33, (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91, (byte)0x32,
+                (byte)0xb7, (byte)0xd4, (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b, (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea,
+                (byte)0x8c, (byte)0x97, (byte)0x5f, (byte)0x51, (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71,
+                (byte)0xa7, (byte)0xc7, (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69, (byte)0xc8, (byte)0xd3,
+                (byte)0xd9, (byte)0x4e, (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3, (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca,
+                (byte)0xda, (byte)0xc2, (byte)0x7f, (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f,
+                (byte)0xea, (byte)0xcf, (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2, (byte)0x19, (byte)0xc3, (byte)0xe0,
+                (byte)0xe1, (byte)0x7a, (byte)0x45, (byte)0x71, (byte)0x12, (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c,
+                (byte)0x46, (byte)0x68, (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22, (byte)0x65,
+                (byte)0x2d, (byte)0x43, (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae, (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e,
+                (byte)0x0c, (byte)0xbd, (byte)0xf5, (byte)0x46, (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60,
+                (byte)0xae, (byte)0x45, (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e, (byte)0xfb, (byte)0xb2,
+                (byte)0xb6, (byte)0x78, (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a, (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68,
+                (byte)0x30, (byte)0x93, (byte)0x78, (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe,
+                (byte)0x59, (byte)0x33, (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44, (byte)0x3a, (byte)0x12, (byte)0xf4,
+                (byte)0x07, (byte)0xa0, (byte)0x8d, (byte)0x02, (byte)0x03, (byte)0x01, (byte)0x00, (byte)0x01,};
+
+        byte[] expected = new byte[] {(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x72, (byte)0x76, (byte)0x1e, (byte)0x57, (byte)0x49,
+                (byte)0xb5, (byte)0x0f, (byte)0xad, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x15, (byte)0xf7, (byte)0xf2, (byte)0x54,
+                (byte)0xda, (byte)0xa9, (byte)0xe5, (byte)0xad, (byte)0x85, (byte)0x04, (byte)0x67, (byte)0x4d, (byte)0x0b, (byte)0xcb, (byte)0xf9,
+                (byte)0xb1, (byte)0xf8, (byte)0x02, (byte)0x8a, (byte)0x77, (byte)0xc2, (byte)0x63, (byte)0xab, (byte)0xd5, (byte)0x74, (byte)0x23,
+                (byte)0x9f, (byte)0x9d, (byte)0x5d, (byte)0x1f, (byte)0xd3, (byte)0xb3, (byte)0xa0, (byte)0xac, (byte)0x16, (byte)0x8a, (byte)0x4b,
+                (byte)0x08, (byte)0xf5, (byte)0x47, (byte)0x70, (byte)0x58, (byte)0x10, (byte)0xb4, (byte)0xe7, (byte)0x87, (byte)0xb3, (byte)0x4b,
+                (byte)0xc9, (byte)0xa2, (byte)0xd5, (byte)0xd1, (byte)0xca, (byte)0x0f, (byte)0xd4, (byte)0xe3, (byte)0x8d, (byte)0x76, (byte)0x5a,
+                (byte)0x60, (byte)0x28, (byte)0xf8, (byte)0x06, (byte)0x5d, (byte)0xe4, (byte)0x7e, (byte)0x21, (byte)0xc8, (byte)0xbb, (byte)0xac,
+                (byte)0xe5, (byte)0x79, (byte)0x85, (byte)0x30, (byte)0x9b, (byte)0x88, (byte)0x13, (byte)0x2f, (byte)0x8f, (byte)0xfc, (byte)0x04,
+                (byte)0x52, (byte)0xfe, (byte)0x87, (byte)0x94, (byte)0xcf, (byte)0xcb, (byte)0x49, (byte)0x4a, (byte)0xda, (byte)0x6f, (byte)0xdd,
+                (byte)0xee, (byte)0x57, (byte)0xa5, (byte)0xe4, (byte)0x4d, (byte)0x0e, (byte)0x5c, (byte)0x3d, (byte)0x0b, (byte)0x63, (byte)0x1f,
+                (byte)0xf6, (byte)0x3d, (byte)0x1b, (byte)0xae, (byte)0x5a, (byte)0xf6, (byte)0x42, (byte)0x2a, (byte)0x46, (byte)0xfa, (byte)0x42,
+                (byte)0x71, (byte)0x67, (byte)0x46, (byte)0x02, (byte)0x71, (byte)0xea, (byte)0x51, (byte)0x98, (byte)0xf7, (byte)0xd4, (byte)0x43,
+                (byte)0xbf, (byte)0x8e, (byte)0xe8, (byte)0x3c, (byte)0xc8, (byte)0xfa, (byte)0x79, (byte)0x9d, (byte)0x8c, (byte)0xfc, (byte)0xc2,
+                (byte)0x42, (byte)0xc9, (byte)0xbb, (byte)0xd0, (byte)0xab, (byte)0x81, (byte)0xc4, (byte)0x53, (byte)0xfd, (byte)0x41, (byte)0xda,
+                (byte)0xab, (byte)0x0f, (byte)0x25, (byte)0x79, (byte)0x5f, (byte)0xbd, (byte)0xa3, (byte)0x8c, (byte)0xd3, (byte)0xf5, (byte)0x1b,
+                (byte)0xab, (byte)0x20, (byte)0xd1, (byte)0xf4, (byte)0xd8, (byte)0x81, (byte)0x9c, (byte)0x18, (byte)0x4a, (byte)0xa4, (byte)0x77,
+                (byte)0xee, (byte)0xe1, (byte)0x51, (byte)0xee, (byte)0x2a, (byte)0xc1, (byte)0x94, (byte)0x37, (byte)0xc5, (byte)0x06, (byte)0x7a,
+                (byte)0x3f, (byte)0x0f, (byte)0x25, (byte)0x5b, (byte)0x4e, (byte)0x6a, (byte)0xdc, (byte)0x0b, (byte)0x62, (byte)0x6f, (byte)0x12,
+                (byte)0x83, (byte)0x03, (byte)0xae, (byte)0x4e, (byte)0xce, (byte)0x2b, (byte)0x6e, (byte)0xd4, (byte)0xd5, (byte)0x23, (byte)0x27,
+                (byte)0xf6, (byte)0xa6, (byte)0x38, (byte)0x67, (byte)0xec, (byte)0x95, (byte)0x82, (byte)0xc6, (byte)0xba, (byte)0xd4, (byte)0xf6,
+                (byte)0xe6, (byte)0x22, (byte)0x7d, (byte)0xb9, (byte)0xe4, (byte)0x81, (byte)0x97, (byte)0x24, (byte)0xff, (byte)0x40, (byte)0xb2,
+                (byte)0x42, (byte)0x3c, (byte)0x11, (byte)0x24, (byte)0xd0, (byte)0x3a, (byte)0x96, (byte)0xd9, (byte)0xc1, (byte)0x13, (byte)0xd6,
+                (byte)0x62, (byte)0x45, (byte)0x21, (byte)0x60, (byte)0x5b, (byte)0x7b, (byte)0x2b, (byte)0x62, (byte)0x44, (byte)0xf7, (byte)0x40,
+                (byte)0x93, (byte)0x29, (byte)0x5b, (byte)0x44, (byte)0xb7, (byte)0xda, (byte)0x9c, (byte)0xa6, (byte)0xa9, (byte)0x3b, (byte)0xe1,
+                (byte)0x3b, (byte)0x9d, (byte)0x31, (byte)0xf2, (byte)0x21, (byte)0x53, (byte)0x0f, (byte)0xb3, (byte)0x70, (byte)0x55, (byte)0x84,
+                (byte)0x2c, (byte)0xb4,};
+        byte[] actual = ntlm_EncryptMessage(serverPublicKey);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public byte[] ntlm_DecryptMessage(byte[] wrappedMssage) {
+
+        byte[] versionBytes = new byte[] {0x01, 0x00, 0x00, 0x00}; // 0x00000001
+        // LE
+        byte[] seqNumBytes = new byte[] {(byte)(recvSeqNum & 0xff), (byte)((recvSeqNum >> 8) & 0xff), (byte)((recvSeqNum >> 16) & 0xff),
+                (byte)((recvSeqNum >> 24) & 0xff)};
+
+        // Unwrap message
+        byte[] actualSignature = Arrays.copyOf(wrappedMssage, 16);
+        byte[] encryptedMessage = Arrays.copyOfRange(wrappedMssage, 16, wrappedMssage.length);
+
+        // Decrypt message
+        byte[] decryptedMessage = CryptoAlgos.RC4(recvRc4Seal, encryptedMessage);
+
+        // Compare actual signature with expected signature
+        byte[] digest = CryptoAlgos.HMAC_MD5(recvSigningKey, CryptoAlgos.concatenationOf(seqNumBytes, decryptedMessage));
+
+        // Encrypt first 8 bytes of digest only
+        byte[] checksum = CryptoAlgos.RC4(recvRc4Seal, Arrays.copyOf(digest, 8));
+
+        byte[] expectedSignature = CryptoAlgos.concatenationOf(versionBytes, checksum, seqNumBytes);
+
+        if (!Arrays.equals(expectedSignature, actualSignature))
+            throw new RuntimeException("Unexpected signature of message:\nExpected signature: " + new ByteBuffer(expectedSignature).toPlainHexString()
+                    + "\n  Actual signature: " + new ByteBuffer(actualSignature).toPlainHexString());
+
+        recvSeqNum++;
+
+        return decryptedMessage;
+    }
+
+    public void testNtlmDecryptMessage() {
+        recvSigningKey = new byte[] {(byte)0xb6, (byte)0x58, (byte)0xc5, (byte)0x98, (byte)0x7a, (byte)0x25, (byte)0xf8, (byte)0x6e, (byte)0xd8,
+                (byte)0xe5, (byte)0x6c, (byte)0xe9, (byte)0x3e, (byte)0x3c, (byte)0xc0, (byte)0x88,};
+        recvRc4Seal = CryptoAlgos.initRC4(new byte[] {(byte)0x92, (byte)0x3a, (byte)0x73, (byte)0x5c, (byte)0x92, (byte)0xa7, (byte)0x04, (byte)0x34,
+                (byte)0xbe, (byte)0x9a, (byte)0xa2, (byte)0x9f, (byte)0xed, (byte)0xc1, (byte)0xe6, (byte)0x13,});
+        recvSeqNum = 0;
+        byte[] encryptedMessage = new byte[] {(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0xf8, (byte)0x2d, (byte)0x1e, (byte)0x4e,
+                (byte)0x6a, (byte)0xec, (byte)0x4f, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03, (byte)0x12, (byte)0xdd, (byte)0xea,
+                (byte)0x47, (byte)0xb3, (byte)0xff, (byte)0xe1, (byte)0x66, (byte)0x08, (byte)0xf6, (byte)0x6b, (byte)0xa0, (byte)0x62, (byte)0x42,
+                (byte)0x67, (byte)0xbf, (byte)0x3d, (byte)0x59, (byte)0x60, (byte)0xef, (byte)0x52, (byte)0xb0, (byte)0x26, (byte)0x95, (byte)0xed,
+                (byte)0x84, (byte)0x48, (byte)0x44, (byte)0xbb, (byte)0x8d, (byte)0x65, (byte)0xcf, (byte)0xe4, (byte)0x8e, (byte)0x6f, (byte)0x69,
+                (byte)0xae, (byte)0xed, (byte)0x44, (byte)0xbb, (byte)0x49, (byte)0x1d, (byte)0x2a, (byte)0x40, (byte)0x29, (byte)0x2b, (byte)0x13,
+                (byte)0x42, (byte)0x1c, (byte)0xeb, (byte)0xb1, (byte)0x6c, (byte)0x8a, (byte)0x3b, (byte)0x80, (byte)0xd1, (byte)0x70, (byte)0xfd,
+                (byte)0xdd, (byte)0x79, (byte)0xe4, (byte)0x93, (byte)0x0b, (byte)0x47, (byte)0xbd, (byte)0x3a, (byte)0x7e, (byte)0x31, (byte)0x66,
+                (byte)0x4b, (byte)0x65, (byte)0x8d, (byte)0x5c, (byte)0x2a, (byte)0xcd, (byte)0xc2, (byte)0x09, (byte)0x7a, (byte)0x3b, (byte)0xb2,
+                (byte)0xfd, (byte)0x09, (byte)0x52, (byte)0x09, (byte)0x47, (byte)0x05, (byte)0xa4, (byte)0x6f, (byte)0x32, (byte)0xd1, (byte)0x76,
+                (byte)0xb2, (byte)0xd4, (byte)0x59, (byte)0xe0, (byte)0x85, (byte)0xf1, (byte)0x36, (byte)0x7d, (byte)0x76, (byte)0x50, (byte)0x21,
+                (byte)0x0e, (byte)0x20, (byte)0x22, (byte)0x83, (byte)0x1a, (byte)0x08, (byte)0xc0, (byte)0x85, (byte)0x5d, (byte)0x4f, (byte)0x5c,
+                (byte)0x77, (byte)0x68, (byte)0x32, (byte)0x95, (byte)0xa9, (byte)0xa2, (byte)0x59, (byte)0x69, (byte)0xea, (byte)0x19, (byte)0x34,
+                (byte)0x08, (byte)0xed, (byte)0x76, (byte)0xa3, (byte)0x58, (byte)0x37, (byte)0xf2, (byte)0x0a, (byte)0x0c, (byte)0xba, (byte)0x4d,
+                (byte)0xbb, (byte)0x6f, (byte)0x82, (byte)0x94, (byte)0xd3, (byte)0x87, (byte)0xde, (byte)0xc9, (byte)0x8f, (byte)0xef, (byte)0x34,
+                (byte)0x2d, (byte)0x8f, (byte)0xd0, (byte)0x0c, (byte)0x91, (byte)0x59, (byte)0xfd, (byte)0xea, (byte)0x6b, (byte)0xcb, (byte)0xbd,
+                (byte)0xa2, (byte)0x20, (byte)0xed, (byte)0xb9, (byte)0x76, (byte)0xd3, (byte)0x64, (byte)0x1b, (byte)0xb3, (byte)0x3b, (byte)0xf5,
+                (byte)0x9b, (byte)0x61, (byte)0xd7, (byte)0xab, (byte)0x26, (byte)0x9b, (byte)0x0d, (byte)0xa0, (byte)0xea, (byte)0xbf, (byte)0xad,
+                (byte)0x2c, (byte)0xad, (byte)0x63, (byte)0x65, (byte)0xc6, (byte)0x70, (byte)0xc4, (byte)0xe5, (byte)0x8d, (byte)0x40, (byte)0xaa,
+                (byte)0x08, (byte)0x45, (byte)0x66, (byte)0xe2, (byte)0x4d, (byte)0xc9, (byte)0x46, (byte)0x00, (byte)0x33, (byte)0x43, (byte)0xe0,
+                (byte)0xba, (byte)0xd6, (byte)0x80, (byte)0x29, (byte)0x21, (byte)0x5e, (byte)0xd1, (byte)0x9a, (byte)0xbc, (byte)0x44, (byte)0xfa,
+                (byte)0x4d, (byte)0x46, (byte)0xf9, (byte)0x25, (byte)0x80, (byte)0x40, (byte)0xb5, (byte)0x27, (byte)0xdd, (byte)0xc5, (byte)0x02,
+                (byte)0xf8, (byte)0xa4, (byte)0x9a, (byte)0xcb, (byte)0xcf, (byte)0x3f, (byte)0xef, (byte)0xc7, (byte)0xcd, (byte)0x71, (byte)0x45,
+                (byte)0xa5, (byte)0x35, (byte)0xb1, (byte)0x21, (byte)0x14, (byte)0x39, (byte)0x57, (byte)0xf8, (byte)0x0a, (byte)0x24, (byte)0x98,
+                (byte)0xea, (byte)0x15, (byte)0xe1, (byte)0xe3, (byte)0xcb, (byte)0x9d, (byte)0xf2, (byte)0x4e, (byte)0xef, (byte)0x89, (byte)0x97,
+                (byte)0xc0, (byte)0xb2, (byte)0x96, (byte)0x9a, (byte)0x1e, (byte)0xad, (byte)0xd0, (byte)0x9a, (byte)0x99, (byte)0x62, (byte)0x9f,
+                (byte)0x13, (byte)0x2e,};
+
+        byte[] expected = new byte[] {
+                // First byte is increased by 1
+                (byte)0x31, (byte)0x82, (byte)0x01, (byte)0x0a, (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0xa8, (byte)0x56,
+                (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0, (byte)0x84, (byte)0x31, (byte)0x19,
+                (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb, (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13, (byte)0xa1, (byte)0xb9,
+                (byte)0x72, (byte)0xbb, (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65, (byte)0x03, (byte)0xd1,
+                (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69, (byte)0x89, (byte)0x5e, (byte)0xfe, (byte)0xe0,
+                (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b, (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd, (byte)0x77, (byte)0x5d,
+                (byte)0xf3, (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2, (byte)0xcf, (byte)0xb1,
+                (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17, (byte)0x7c, (byte)0xb7, (byte)0xd6, (byte)0xc7, (byte)0xc7,
+                (byte)0xbf, (byte)0x90, (byte)0x4e, (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0, (byte)0xc2, (byte)0x33,
+                (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91, (byte)0x32, (byte)0xb7, (byte)0xd4,
+                (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b, (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea, (byte)0x8c, (byte)0x97,
+                (byte)0x5f, (byte)0x51, (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71, (byte)0xa7, (byte)0xc7,
+                (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69, (byte)0xc8, (byte)0xd3, (byte)0xd9, (byte)0x4e,
+                (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3, (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca, (byte)0xda, (byte)0xc2,
+                (byte)0x7f, (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f, (byte)0xea, (byte)0xcf,
+                (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2, (byte)0x19, (byte)0xc3, (byte)0xe0, (byte)0xe1, (byte)0x7a,
+                (byte)0x45, (byte)0x71, (byte)0x12, (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c, (byte)0x46, (byte)0x68,
+                (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22, (byte)0x65, (byte)0x2d, (byte)0x43,
+                (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae, (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e, (byte)0x0c, (byte)0xbd,
+                (byte)0xf5, (byte)0x46, (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60, (byte)0xae, (byte)0x45,
+                (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e, (byte)0xfb, (byte)0xb2, (byte)0xb6, (byte)0x78,
+                (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a, (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68, (byte)0x30, (byte)0x93,
+                (byte)0x78, (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe, (byte)0x59, (byte)0x33,
+                (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44, (byte)0x3a, (byte)0x12, (byte)0xf4, (byte)0x07, (byte)0xa0,
+                (byte)0x8d, (byte)0x02, (byte)0x03, (byte)0x01, (byte)0x00, (byte)0x01,};
+        byte[] actual = ntlm_DecryptMessage(encryptedMessage);
+
+        if (!Arrays.equals(expected, actual))
+            throw new RuntimeException("Incorrect result.\nExpected:\n" + new ByteBuffer(expected).toPlainHexString() + "\n  actual:\n"
+                    + new ByteBuffer(actual).toPlainHexString() + ".");
+    }
+
+    public static void main(String args[]) {
+        CryptoAlgos.callAll(new NtlmState());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
new file mode 100755
index 0000000..6aeb39b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/SecBuffer.java
@@ -0,0 +1,21 @@
+// 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;
+
+public class SecBuffer {
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/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..eaac62b
--- /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);
+        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 + ".");
+
+    }
+
+}


[03/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
new file mode 100755
index 0000000..15449c3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
@@ -0,0 +1,109 @@
+// 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 streamer.debug;
+
+import java.nio.charset.Charset;
+
+import streamer.ByteBuffer;
+
+/**
+ * Assert that writes to this buffer are matching expected data.
+ */
+public class AssertingByteBuffer extends ByteBuffer {
+
+    public AssertingByteBuffer(byte[] expectedData) {
+        super(expectedData);
+    }
+
+    private void assertEquals(int expected, int actual) {
+        if (expected != actual)
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ", buf: " + this + ".");
+    }
+
+    @Override
+    public void writeByte(int b) {
+        if (b < 0)
+            throw new RuntimeException();
+        //*DEBUG*/System.out.println("WriteByte: "+b+", cursor:"+cursor+".");
+        assertEquals(readUnsignedByte(), b & 0xff);
+    }
+
+    @Override
+    public void writeShort(int x) {
+        //*DEBUG*/System.out.println("WriteShort: "+x+", cursor:"+cursor+".");
+        assertEquals(readUnsignedShort(), x & 0xFFff);
+    }
+
+    @Override
+    public void writeShortLE(int x) {
+        //*DEBUG*/System.out.println("WriteShortLE: "+x+", cursor:"+cursor+".");
+        assertEquals(readUnsignedShortLE(), x & 0xFFff);
+    }
+
+    @Override
+    public void writeInt(int i) {
+        //*DEBUG*/System.out.println("WriteInt: "+i+", cursor:"+cursor+".");
+        assertEquals(readSignedInt(), i);
+    }
+
+    @Override
+    public void writeIntLE(int i) {
+        //*DEBUG*/System.out.println("WriteIntLE: "+i+", cursor:"+cursor+".");
+        assertEquals(readSignedIntLE(), i);
+    }
+
+    @Override
+    public void writeVariableIntLE(int i) {
+        //*DEBUG*/System.out.println("WriteVariableIntLE: "+i+", cursor:"+cursor+".");
+        assertEquals(readVariableSignedIntLE(), i);
+    }
+
+    @Override
+    public void writeString(String actual, Charset charset) {
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        String expected = readString(actual.length(), charset);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(ByteBuffer actual) {
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(byte[] actualData) {
+        ByteBuffer actual = new ByteBuffer(actualData);
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+    @Override
+    public void writeBytes(byte[] actualData, int offset, int length) {
+        ByteBuffer actual = new ByteBuffer(actualData, offset, length);
+        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
+        ByteBuffer expected = readBytes(actual.length);
+        if (!actual.equals(expected))
+            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
new file mode 100755
index 0000000..c884cfb
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/Dumper.java
@@ -0,0 +1,28 @@
+// 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 streamer.debug;
+
+import streamer.ByteBuffer;
+
+public interface Dumper {
+
+    /**
+     * Parse and dump content of buffer.
+     */
+    void dump(ByteBuffer buf);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
new file mode 100755
index 0000000..9315488
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
@@ -0,0 +1,77 @@
+// 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 streamer.debug;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class FakeSink extends BaseElement {
+
+    public FakeSink(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        // Use packetNumber variable to count incoming packets
+        packetNumber++;
+
+        buf.unref();
+    }
+
+    @Override
+    public String toString() {
+        return "FakeSink(" + id + ")";
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
+
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element sink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        byte[] data = new byte[] {1, 2, 3};
+        ByteBuffer buf = new ByteBuffer(data);
+        sink.setLink(STDIN, new SyncLink(), Direction.IN);
+        sink.getLink(STDIN).sendData(buf);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
new file mode 100755
index 0000000..7f0c554
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
@@ -0,0 +1,138 @@
+// 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 streamer.debug;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class FakeSource extends BaseElement {
+
+    /**
+     * Delay for null packets in poll method when blocking is requested, in
+     * milliseconds.
+     */
+    protected long delay = SyncLink.STANDARD_DELAY_FOR_EMPTY_PACKET;
+
+    public FakeSource(String id) {
+        super(id);
+    }
+
+    @Override
+    public void poll(boolean block) {
+        if (numBuffers > 0 && packetNumber >= numBuffers) {
+            // Close stream when limit of packets is reached
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+            return;
+        }
+
+        // Prepare new packet
+        ByteBuffer buf = initializeData();
+
+        // Push it to output(s)
+        if (buf != null)
+            pushDataToAllOuts(buf);
+
+        // Make slight delay when blocking input was requested (to avoid
+        // consuming of 100% in parent loop)
+        if (block)
+            delay();
+
+    }
+
+    /**
+     * Make slight delay. Should be used when blocking input is requested in pull
+     * mode, but null packed was returned by input.
+     */
+    protected void delay() {
+        try {
+            Thread.sleep(delay);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    /**
+     * Initialize data.
+     */
+    public ByteBuffer initializeData() {
+        ByteBuffer buf = new ByteBuffer(incommingBufLength);
+
+        // Set first byte of package to it sequance number
+        buf.data[buf.offset] = (byte)(packetNumber % 128);
+
+        // Initialize rest of bytes with sequential values, which are
+        // corresponding with their position in byte buffer
+        for (int i = buf.offset + 1; i < buf.length; i++)
+            buf.data[i] = (byte)(i % 128);
+
+        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
+        buf.putMetadata("src", id);
+
+        return buf;
+    }
+
+    @Override
+    public String toString() {
+        return "FakeSource(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element fakeSource = new FakeSource("source 3/10/100") {
+            {
+                verbose = true;
+                incommingBufLength = 3;
+                numBuffers = 10;
+                delay = 100;
+            }
+        };
+
+        Element fakeSink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        Element fakeSink2 = new FakeSink("sink2") {
+            {
+                verbose = true;
+            }
+        };
+
+        Link link = new SyncLink();
+
+        fakeSource.setLink(STDOUT, link, Direction.OUT);
+        fakeSink.setLink(STDIN, link, Direction.IN);
+
+        Link link2 = new SyncLink();
+
+        fakeSource.setLink("out2", link2, Direction.OUT);
+        fakeSink2.setLink(STDIN, link2, Direction.IN);
+
+        link.sendEvent(Event.STREAM_START, Direction.IN);
+        link.run();
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
new file mode 100755
index 0000000..348a006
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
@@ -0,0 +1,203 @@
+// 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 streamer.debug;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class MockServer implements Runnable {
+
+    private boolean shutdown = false;
+    private ServerSocket serverSocket;
+    private Packet[] packets;
+    private Throwable exception;
+    private boolean shutdowned;
+
+    /**
+     * Set to true to enable debugging messages.
+     */
+    protected boolean verbose = System.getProperty("rdpclient.MockServer.debug", "false").equals("true");
+
+    public MockServer(Packet packets[]) {
+        this.packets = packets;
+    }
+
+    public void start() throws IOException {
+        serverSocket = new ServerSocket(0);
+
+        shutdown = false;
+        exception = null;
+        shutdowned = false;
+
+        Thread thread = new Thread(this);
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    @Override
+    public void run() {
+
+        try {
+            Socket socket = serverSocket.accept();
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Clien connected: " + socket.getRemoteSocketAddress() + ".");
+
+            InputStream is = socket.getInputStream();
+            OutputStream os = socket.getOutputStream();
+
+            try {
+                for (int i = 0; i < packets.length && !shutdown; i++) {
+
+                    Packet packet = packets[i];
+                    switch (packet.type) {
+                    case CLIENT: {
+                        // Read client data and compare it with mock data
+                        // (unless "ignore" option is set)
+                        byte actualData[] = new byte[packet.data.length];
+                        int actualDataLength = is.read(actualData);
+
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: Data is read: {" + Arrays.toString(Arrays.copyOf(actualData, actualDataLength)) + "}.");
+
+                        if (!packet.ignore) {
+                            // Compare actual data with expected data
+                            if (actualDataLength != packet.data.length) {
+                                throw new AssertionError("Actual length of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")"
+                                        + " does not match length of expected client request. Actual length: " + actualDataLength + ", expected legnth: " + packet.data.length
+                                        + ".");
+                            }
+
+                            for (int j = 0; j < packet.data.length; j++) {
+
+                                if (packet.data[j] != actualData[j]) {
+                                    throw new AssertionError("Actual byte #" + (j + 1) + " of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")"
+                                            + " does not match corresponding byte of expected client request. Actual byte: " + actualData[j] + ", expected byte: " + packet.data[j]
+                                                    + ".");
+                                }
+                            }
+                        }
+                        break;
+                    }
+                    case SERVER: {
+                        // Send mock data to client
+                        os.write(packet.data);
+
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: Data is written: {" + Arrays.toString(packet.data) + "}.");
+
+                        break;
+                    }
+                    case UPGRADE_TO_SSL: {
+                        // Attach SSL context to socket
+
+                        final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
+                        SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, null, serverSocket.getLocalPort(), true);
+                        sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
+                        sslSocket.setUseClientMode(false);
+                        sslSocket.startHandshake();
+                        is = sslSocket.getInputStream();
+                        os = sslSocket.getOutputStream();
+
+                        break;
+                    }
+                    default:
+                        throw new RuntimeException("Unknown packet type: " + packet.type);
+                    }
+
+                }
+            } finally {
+                try {
+                    is.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    os.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    socket.close();
+                } catch (Throwable e) {
+                }
+                try {
+                    serverSocket.close();
+                } catch (Throwable e) {
+                }
+            }
+        } catch (Throwable e) {
+            System.err.println("Error in mock server: " + e.getMessage());
+            e.printStackTrace(System.err);
+            exception = e;
+        }
+        shutdowned = true;
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Mock server shutdowned.");
+
+    }
+
+    public void shutdown() {
+        shutdown = true;
+    }
+
+    public InetSocketAddress getAddress() {
+        return (InetSocketAddress)serverSocket.getLocalSocketAddress();
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    public static class Packet {
+        public static enum PacketType {
+            SERVER, CLIENT, UPGRADE_TO_SSL;
+        }
+
+        public String id = "";
+
+        public Packet() {
+        }
+
+        public Packet(String id) {
+            this.id = id;
+        }
+
+        public PacketType type;
+
+        public boolean ignore = false;
+
+        public byte data[];
+    }
+
+    public boolean isShutdowned() {
+        return shutdowned;
+    }
+
+    public void waitUntilShutdowned(long timeToWaitMiliseconds) throws InterruptedException {
+        long deadline = System.currentTimeMillis() + timeToWaitMiliseconds;
+        while (!shutdowned && System.currentTimeMillis() < deadline) {
+            Thread.sleep(10);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
new file mode 100755
index 0000000..fe038a9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSink.java
@@ -0,0 +1,154 @@
+// 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 streamer.debug;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Link;
+import streamer.SyncLink;
+
+/**
+ * Compare incoming packets with expected packets.
+ */
+public class MockSink extends BaseElement {
+
+    protected ByteBuffer bufs[];
+    protected Dumper dumper;
+
+    public MockSink(String id) {
+        super(id);
+    }
+
+    public MockSink(String id, ByteBuffer bufs[]) {
+        super(id);
+        this.bufs = bufs;
+    }
+
+    public MockSink(String id, ByteBuffer bufs[], Dumper dumper) {
+        super(id);
+        this.bufs = bufs;
+        this.dumper = dumper;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        if (packetNumber >= bufs.length)
+            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not expected. Number of expected buffers: " + bufs.length
+                    + ", unexpected buffer: " + buf + ".");
+
+        // Compare incoming buffer with expected buffer
+        ByteBuffer expectedBuf = bufs[packetNumber];
+        if (!Arrays.equals(expectedBuf.toByteArray(), buf.toByteArray())) {
+            dump(buf, expectedBuf);
+            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer.\n  Actual bufer: " + buf
+                    + ",\n  expected buffer: " + expectedBuf + ".");
+        }
+
+        // If expected buffer has metadata, then compare it too
+        Set<String> metadataKeys = expectedBuf.getMetadataKeys();
+        if (metadataKeys.size() > 0) {
+            for (String key : metadataKeys) {
+                Object expectedValue = expectedBuf.getMetadata(key);
+                Object actualValue = buf.getMetadata(key);
+                if (actualValue == null)
+                    throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer in metadata for key \"" + key
+                            + "\".\n  Actual metadata value: " + actualValue + ",\n  expected value: \"" + expectedValue + "\".");
+
+                if (!expectedValue.equals(actualValue))
+                    throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer in metadata for key \"" + key
+                            + "\".\n  Actual metadata value: \"" + actualValue + "\",\n  expected value: \"" + expectedValue + "\".");
+            }
+        }
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: buffers are equal.");
+
+        // Use packetNumber variable to count incoming packets
+        packetNumber++;
+
+        buf.unref();
+    }
+
+    private void dump(ByteBuffer actualData, ByteBuffer expectedData) {
+        if (dumper != null) {
+            System.out.println("[" + this + "] INFO: Actual data:");
+            dumper.dump(actualData);
+            System.out.println("[" + this + "] INFO: Expected data:");
+            dumper.dump(expectedData);
+        }
+    }
+
+    @Override
+    protected void onClose() {
+        super.onClose();
+
+        if (packetNumber != bufs.length)
+            throw new AssertionError("[" + this + "] Number of expected buffers: " + bufs.length + ", number of actual buffers: " + packetNumber + ".");
+    }
+
+    @Override
+    public String toString() {
+        return "MockSink(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element mockSource = new MockSource("source") {
+            {
+                bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                verbose = true;
+                delay = 100;
+                numBuffers = bufs.length;
+            }
+        };
+
+        Element mockSink = new MockSink("sink") {
+            {
+                bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                verbose = true;
+            }
+        };
+
+        Link link = new SyncLink() {
+            {
+                verbose = true;
+            }
+        };
+
+        mockSource.setLink(STDOUT, link, Direction.OUT);
+        mockSink.setLink(STDIN, link, Direction.IN);
+
+        link.run();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
new file mode 100755
index 0000000..a77f1d4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
@@ -0,0 +1,95 @@
+// 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 streamer.debug;
+
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Link;
+import streamer.SyncLink;
+
+public class MockSource extends FakeSource {
+
+    protected ByteBuffer bufs[] = null;
+
+    public MockSource(String id) {
+        super(id);
+    }
+
+    public MockSource(String id, ByteBuffer bufs[]) {
+        super(id);
+        this.bufs = bufs;
+    }
+
+    /**
+     * Initialize data.
+     */
+    @Override
+    public ByteBuffer initializeData() {
+        if (packetNumber >= bufs.length) {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+            return null;
+        }
+
+        ByteBuffer buf = bufs[packetNumber];
+
+        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
+        return buf;
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
+
+    }
+
+    @Override
+    public String toString() {
+        return "MockSource(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        Element mockSource = new MockSource("source") {
+            {
+                bufs = new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}),
+                        new ByteBuffer(new byte[] {3, 1, 2, 3}), new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
+                verbose = true;
+                delay = 100;
+                // this.numBuffers = this.bufs.length;
+            }
+        };
+
+        Element fakeSink = new FakeSink("sink") {
+            {
+                verbose = true;
+            }
+        };
+
+        Link link = new SyncLink();
+
+        mockSource.setLink(STDOUT, link, Direction.OUT);
+        fakeSink.setLink(STDIN, link, Direction.IN);
+
+        link.run();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
new file mode 100755
index 0000000..f405088
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/SSLState.java
@@ -0,0 +1,26 @@
+// 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 streamer.ssl;
+
+public class SSLState {
+
+    /**
+     * Server public certificate in ASN.1 BER format.
+     */
+    public byte[] serverCertificateSubjectPublicKeyInfo;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
new file mode 100755
index 0000000..4d9eac2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
@@ -0,0 +1,52 @@
+// 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 streamer.ssl;
+
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509TrustManager;
+
+public class TrustAllX509TrustManager implements X509TrustManager {
+    private SSLState sslState;
+
+    public TrustAllX509TrustManager(SSLState sslState) {
+        this.sslState = sslState;
+    }
+
+    @Override
+    public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
+        // TODO: ask user to confirm self-signed certificates
+        // Trust all (insecure)
+    }
+
+    @Override
+    public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
+        // TODO: ask user to confirm self-signed certificates
+        // Trust all (insecure)
+
+        // Store public certificates to use for NTLMSSP negotiation
+        if (sslState != null)
+            sslState.serverCertificateSubjectPublicKeyInfo = chain[0].getPublicKey().getEncoded();
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        // TODO: use system CA certificates here
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
new file mode 100755
index 0000000..9d7c708
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
@@ -0,0 +1,44 @@
+// 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 streamer.ssl;
+
+import streamer.ByteBuffer;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class UpgradeSocketToSSL extends OneTimeSwitch {
+
+    public UpgradeSocketToSSL(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void onStart() {
+
+        sendEventToAllPads(Event.SOCKET_UPGRADE_TO_SSL, Direction.IN);
+        switchOff();
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        throw new RuntimeException("Unexpected data: " + buf + ".");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
deleted file mode 100644
index a804e26..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtKeyboardEventToVncAdapter.java
+++ /dev/null
@@ -1,368 +0,0 @@
-// 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 vncclient;
-
-import java.awt.event.KeyEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.KeyOrder;
-
-public class AwtKeyboardEventToVncAdapter extends BaseElement {
-
-    protected boolean sh = false;
-    protected boolean caps = false;
-    protected boolean num = false;
-
-    public AwtKeyboardEventToVncAdapter(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        KeyOrder order = (KeyOrder)buf.getOrder();
-        buf.unref();
-
-        ByteBuffer outBuf = new ByteBuffer(8);
-        outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
-
-        outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
-        outBuf.writeShort(0); // padding
-        outBuf.writeInt(map_en_us(order));
-
-        pushDataToAllOuts(outBuf);
-    }
-
-    /**
-     * Return key scan code (in lower byte) and extended flags (in second byte).
-     */
-    private int map_en_us(KeyOrder order) {
-
-        switch (order.event.getKeyCode()) {
-        // Functional keys
-            case KeyEvent.VK_ESCAPE:
-                return 0xff1b;
-            case KeyEvent.VK_F1:
-                return 0xffbe;
-            case KeyEvent.VK_F2:
-                return 0xffbf;
-            case KeyEvent.VK_F3:
-                return 0xffc0;
-            case KeyEvent.VK_F4:
-                return 0xffc1;
-            case KeyEvent.VK_F5:
-                return 0xffc2;
-            case KeyEvent.VK_F6:
-                return 0xffc3;
-            case KeyEvent.VK_F7:
-                return 0xffc4;
-            case KeyEvent.VK_F8:
-                return 0xffc5;
-            case KeyEvent.VK_F9:
-                return 0xffc6;
-            case KeyEvent.VK_F10:
-                return 0xffc7;
-            case KeyEvent.VK_F11:
-                return 0xffc8;
-            case KeyEvent.VK_F12:
-                return 0xffc9;
-
-                // Row #1
-            case KeyEvent.VK_BACK_QUOTE:
-                return (sh) ? '~' : '`';
-            case KeyEvent.VK_1:
-                return (sh) ? '!' : '1';
-            case KeyEvent.VK_2:
-                return (sh) ? '@' : '2';
-            case KeyEvent.VK_3:
-                return (sh) ? '#' : '3';
-            case KeyEvent.VK_4:
-                return (sh) ? '$' : '4';
-            case KeyEvent.VK_5:
-                return (sh) ? '%' : '5';
-            case KeyEvent.VK_6:
-                return (sh) ? '^' : '6';
-            case KeyEvent.VK_7:
-                return (sh) ? '&' : '7';
-            case KeyEvent.VK_8:
-                return (sh) ? '*' : '8';
-            case KeyEvent.VK_9:
-                return (sh) ? '(' : '9';
-            case KeyEvent.VK_0:
-                return (sh) ? ')' : '0';
-            case KeyEvent.VK_MINUS:
-                return (sh) ? '_' : '-';
-            case KeyEvent.VK_EQUALS:
-                return (sh) ? '+' : '=';
-            case KeyEvent.VK_BACK_SPACE:
-                return 0xff08;
-
-                // Row #2
-            case KeyEvent.VK_TAB:
-                return 0xff09;
-            case KeyEvent.VK_Q:
-                return (sh ^ caps) ? 'Q' : 'q';
-            case KeyEvent.VK_W:
-                return (sh ^ caps) ? 'W' : 'w';
-            case KeyEvent.VK_E:
-                return (sh ^ caps) ? 'E' : 'e';
-            case KeyEvent.VK_R:
-                return (sh ^ caps) ? 'R' : 'r';
-            case KeyEvent.VK_T:
-                return (sh ^ caps) ? 'T' : 't';
-            case KeyEvent.VK_Y:
-                return (sh ^ caps) ? 'Y' : 'y';
-            case KeyEvent.VK_U:
-                return (sh ^ caps) ? 'U' : 'u';
-            case KeyEvent.VK_I:
-                return (sh ^ caps) ? 'I' : 'i';
-            case KeyEvent.VK_O:
-                return (sh ^ caps) ? 'O' : 'o';
-            case KeyEvent.VK_P:
-                return (sh ^ caps) ? 'P' : 'p';
-            case KeyEvent.VK_OPEN_BRACKET:
-                return (sh) ? '{' : '[';
-            case KeyEvent.VK_CLOSE_BRACKET:
-                return (sh) ? '{' : ']';
-            case KeyEvent.VK_ENTER:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_STANDARD:
-                        return 0xff0d;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return 0xff8d;
-                }
-
-                // Row #3
-            case KeyEvent.VK_CAPS_LOCK:
-                if (order.pressed)
-                    caps = !caps;
-                return 0xFFE5;
-            case KeyEvent.VK_A:
-                return (sh ^ caps) ? 'A' : 'a';
-            case KeyEvent.VK_S:
-                return (sh ^ caps) ? 'S' : 's';
-            case KeyEvent.VK_D:
-                return (sh ^ caps) ? 'D' : 'd';
-            case KeyEvent.VK_F:
-                return (sh ^ caps) ? 'F' : 'f';
-            case KeyEvent.VK_G:
-                return (sh ^ caps) ? 'G' : 'g';
-            case KeyEvent.VK_H:
-                return (sh ^ caps) ? 'H' : 'h';
-            case KeyEvent.VK_J:
-                return (sh ^ caps) ? 'J' : 'j';
-            case KeyEvent.VK_K:
-                return (sh ^ caps) ? 'K' : 'k';
-            case KeyEvent.VK_L:
-                return (sh ^ caps) ? 'L' : 'l';
-            case KeyEvent.VK_SEMICOLON:
-                return (sh) ? ':' : ';';
-            case KeyEvent.VK_QUOTE:
-                return (sh) ? '"' : '\'';
-
-                // Row #4
-            case KeyEvent.VK_SHIFT:
-                sh = !sh;
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xffe1;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 0xffe2;
-                }
-            case KeyEvent.VK_BACK_SLASH:
-                return (sh) ? '|' : '\\';
-            case KeyEvent.VK_Z:
-                return (sh ^ caps) ? 'Z' : 'z';
-            case KeyEvent.VK_X:
-                return (sh ^ caps) ? 'X' : 'x';
-            case KeyEvent.VK_C:
-                return (sh ^ caps) ? 'C' : 'c';
-            case KeyEvent.VK_V:
-                return (sh ^ caps) ? 'V' : 'v';
-            case KeyEvent.VK_B:
-                return (sh ^ caps) ? 'B' : 'b';
-            case KeyEvent.VK_N:
-                return (sh ^ caps) ? 'N' : 'n';
-            case KeyEvent.VK_M:
-                return (sh ^ caps) ? 'M' : 'M';
-            case KeyEvent.VK_COMMA:
-                return (sh) ? '<' : ',';
-            case KeyEvent.VK_PERIOD:
-                return (sh) ? '>' : '.';
-            case KeyEvent.VK_SLASH:
-                return (sh) ? '?' : '/';
-
-                //
-                // Bottom row
-            case KeyEvent.VK_CONTROL:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xFFE3;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 0xFFE4;
-                }
-            case KeyEvent.VK_WINDOWS:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xFFED; // HyperL
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 0xFFEE; // HyperR
-                }
-            case KeyEvent.VK_META:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xFFE7; // MetaL
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 0xFFE8; // MetaR
-                }
-
-            case KeyEvent.VK_ALT:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xFFE9;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 0xFFEA;
-                }
-            case KeyEvent.VK_ALT_GRAPH:
-                return 0xfe03;
-
-            case KeyEvent.VK_SPACE:
-                return ' ';
-
-            case KeyEvent.VK_CONTEXT_MENU:
-                return 0xff67;
-
-                //
-                // Special keys
-            case KeyEvent.VK_PRINTSCREEN:
-                return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
-            case KeyEvent.VK_SCROLL_LOCK:
-                return 0xFF14;
-            case KeyEvent.VK_PAUSE:
-                return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
-
-                // Text navigation keys
-            case KeyEvent.VK_INSERT:
-                return 0xff63;
-            case KeyEvent.VK_DELETE:
-                return 0xffff;
-            case KeyEvent.VK_HOME:
-                return 0xff50;
-            case KeyEvent.VK_END:
-                return 0xff57;
-            case KeyEvent.VK_PAGE_UP:
-                return 0xff55;
-            case KeyEvent.VK_PAGE_DOWN:
-                return 0xff56;
-
-                // Cursor keys
-            case KeyEvent.VK_LEFT:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xff51;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return 0xFF96;
-                }
-            case KeyEvent.VK_UP:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xff52;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return 0xFF97;
-                }
-            case KeyEvent.VK_RIGHT:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xff53;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return 0xFF98;
-                }
-            case KeyEvent.VK_DOWN:
-                switch (order.event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 0xff54;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return 0xFF99;
-                }
-
-                // Keypad
-            case KeyEvent.VK_NUM_LOCK:
-                if (order.pressed)
-                    num = !num;
-                return 0xFF6F;
-            case KeyEvent.VK_DIVIDE:
-                return 0xFFAF;
-            case KeyEvent.VK_MULTIPLY:
-                return 0xFFAA;
-            case KeyEvent.VK_SUBTRACT:
-                return 0xFFAD;
-            case KeyEvent.VK_ADD:
-                return 0xFFAB;
-
-            case KeyEvent.VK_KP_LEFT:
-                return 0xFF96;
-            case KeyEvent.VK_KP_UP:
-                return 0xFF97;
-            case KeyEvent.VK_KP_RIGHT:
-                return 0xFF98;
-            case KeyEvent.VK_KP_DOWN:
-                return 0xFF99;
-
-            case KeyEvent.VK_NUMPAD0:
-                return 0xFFB0;
-            case KeyEvent.VK_NUMPAD1:
-                return 0xFFB1;
-            case KeyEvent.VK_NUMPAD2:
-                return 0xFFB2;
-            case KeyEvent.VK_NUMPAD3:
-                return 0xFFB3;
-            case KeyEvent.VK_NUMPAD4:
-                return 0xFFB4;
-            case KeyEvent.VK_NUMPAD5:
-                return 0xFFB5;
-            case KeyEvent.VK_NUMPAD6:
-                return 0xFFB6;
-            case KeyEvent.VK_NUMPAD7:
-                return 0xFFB7;
-            case KeyEvent.VK_NUMPAD8:
-                return 0xFFB8;
-            case KeyEvent.VK_NUMPAD9:
-                return 0xFFB9;
-            case KeyEvent.VK_DECIMAL:
-                return 0xFFAE;
-
-            default:
-                System.err.println("Key is not mapped: " + order + ".");
-                return ' '; // Space
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
deleted file mode 100644
index 8af0195..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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 vncclient;
-
-import java.awt.event.InputEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.MouseOrder;
-
-public class AwtMouseEventToVncAdapter extends BaseElement {
-
-    public AwtMouseEventToVncAdapter(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Get mouse event
-        MouseOrder order = (MouseOrder)buf.getOrder();
-
-        ByteBuffer outBuf = new ByteBuffer(6);
-
-        outBuf.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
-
-        int buttonMask = mapAwtModifiersToVncButtonMask(order.event.getModifiersEx());
-        outBuf.writeByte(buttonMask);
-        outBuf.writeShort(order.event.getX());
-        outBuf.writeShort(order.event.getY());
-
-        pushDataToAllOuts(outBuf);
-    }
-
-    /**
-     * Current state of buttons 1 to 8 are represented by bits 0 to 7 of
-     * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
-     * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
-     * right buttons on the mouse. On a wheel mouse, each step of the wheel
-     * upwards is represented by a press and release of button 4, and each step
-     * downwards is represented by a press and release of button 5.
-     *
-     * @param modifiers
-     *          extended modifiers from AWT mouse event
-     * @return VNC mouse button mask
-     */
-    public static int mapAwtModifiersToVncButtonMask(int modifiers) {
-        int mask =
-            (((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0) |
-                (((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
-        return mask;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
deleted file mode 100644
index 81540d6..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class EncodingsMessage extends BaseElement {
-
-    protected final int[] encodings;
-
-    public EncodingsMessage(String id, int[] encodings) {
-        super(id);
-        this.encodings = encodings;
-        declarePads();
-    }
-
-    protected void declarePads() {
-        inputPads.put(STDIN, null);
-        outputPads.put(STDOUT, null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-        buf.unref();
-
-        ByteBuffer outBuf = new ByteBuffer(4 + encodings.length * 4);
-
-        outBuf.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
-
-        outBuf.writeByte(0);// padding
-
-        outBuf.writeShort(encodings.length);
-
-        for (int i = 0; i < encodings.length; i++) {
-            outBuf.writeInt(encodings[i]);
-        }
-
-        pushDataToAllOuts(outBuf);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
deleted file mode 100644
index 0081827..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.ScreenDescription;
-
-public class FrameBufferUpdateRequest extends BaseElement {
-    // TODO: use object with fields instead of raw values in map
-    public static final String INCREMENTAL_UPDATE = "incremental";
-    public static final String TARGET_X = "x";
-    public static final String TARGET_Y = "y";
-    public static final String WIDTH = "width";
-    public static final String HEIGHT = "height";
-
-    protected ScreenDescription screen;
-
-    public FrameBufferUpdateRequest(String id, ScreenDescription screen) {
-        super(id);
-        this.screen = screen;
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        Boolean incremental = (Boolean)buf.getMetadata(INCREMENTAL_UPDATE);
-        Integer x = (Integer)buf.getMetadata(TARGET_X);
-        Integer y = (Integer)buf.getMetadata(TARGET_Y);
-        Integer width = (Integer)buf.getMetadata(WIDTH);
-        Integer height = (Integer)buf.getMetadata(HEIGHT);
-        buf.unref();
-
-        // Set default values when parameters are not set
-        if (incremental == null)
-            incremental = false;
-
-        if (x == null)
-            x = 0;
-        if (y == null)
-            y = 0;
-
-        if (width == null)
-            width = screen.getFramebufferWidth();
-        if (height == null)
-            height = screen.getFramebufferHeight();
-
-        ByteBuffer outBuf = new ByteBuffer(10);
-
-        outBuf.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
-        outBuf.writeByte((incremental) ? RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST : RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST);
-        outBuf.writeShort(x);
-        outBuf.writeShort(y);
-        outBuf.writeShort(width);
-        outBuf.writeShort(height);
-
-        if (verbose) {
-            outBuf.putMetadata("sender", this);
-            outBuf.putMetadata("dimensions", width + "x" + height + "@" + x + "x" + y);
-        }
-
-        pushDataToAllOuts(outBuf);
-    }
-
-    public static void main(String args[]) {
-        System.setProperty("streamer.Element.debug", "true");
-
-        ScreenDescription screen = new ScreenDescription();
-        screen.setFramebufferSize(120, 80);
-        Element adapter = new FrameBufferUpdateRequest("renderer", screen);
-
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-            // Request
-            RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST,
-            // Full update (redraw area)
-            RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST,
-            // X
-            0, 1,
-            // Y
-            0, 2,
-            // Width
-            0, 3,
-            // Height
-            0, 4}));
-
-        ByteBuffer buf = new ByteBuffer(new byte[0]);
-        buf.putMetadata(TARGET_X, 1);
-        buf.putMetadata(TARGET_Y, 2);
-        buf.putMetadata(WIDTH, 3);
-        buf.putMetadata(HEIGHT, 4);
-
-        Element source = new MockSource("source", new ByteBuffer[] {buf});
-
-        Pipeline pipeline = new PipelineImpl("test");
-
-        pipeline.addAndLink(source, adapter, sink);
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
deleted file mode 100644
index 32de903..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.ScreenDescription;
-
-public class RGB888LE32PixelFormatRequest extends BaseElement {
-    protected int bitsPerPixel = 32;
-    protected int depth = 24;
-    protected int bigEndianFlag = RfbConstants.LITTLE_ENDIAN;
-    protected int trueColourFlag = RfbConstants.TRUE_COLOR;
-    protected int redMax = 255;
-    protected int greenMax = 255;
-    protected int blueMax = 255;
-    protected int redShift = 0;
-    protected int greenShift = 8;
-    protected int blueShift = 16;
-
-    protected ScreenDescription screen;
-
-    public RGB888LE32PixelFormatRequest(String id, ScreenDescription screen) {
-        super(id);
-        this.screen = screen;
-    }
-
-    protected void declarePads() {
-        inputPads.put(STDIN, null);
-        outputPads.put(STDOUT, null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-        buf.unref();
-
-        ByteBuffer outBuf = new ByteBuffer(20);
-
-        outBuf.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
-
-        // Padding
-        outBuf.writeByte(0);
-        outBuf.writeByte(0);
-        outBuf.writeByte(0);
-
-        // Send pixel format
-        outBuf.writeByte(bitsPerPixel);
-        outBuf.writeByte(depth);
-        outBuf.writeByte(bigEndianFlag);
-        outBuf.writeByte(trueColourFlag);
-        outBuf.writeShort(redMax);
-        outBuf.writeShort(greenMax);
-        outBuf.writeShort(blueMax);
-        outBuf.writeByte(redShift);
-        outBuf.writeByte(greenShift);
-        outBuf.writeByte(blueShift);
-
-        // Padding
-        outBuf.writeByte(0);
-        outBuf.writeByte(0);
-        outBuf.writeByte(0);
-
-        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax,
-            redShift, greenShift, blueShift);
-
-        pushDataToAllOuts(outBuf);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
deleted file mode 100644
index 7359cd3..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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 vncclient;
-
-import java.nio.charset.Charset;
-
-public interface RfbConstants {
-
-    public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
-    public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
-    public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
-
-    /**
-     * Server message types.
-     */
-    final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
-
-    /**
-     * Client message types.
-     */
-    public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
-            CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
-
-    /**
-     * Server authorization type
-     */
-    public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
-
-    /**
-     * Server authorization reply.
-     */
-    public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
-
-    /**
-     * Encodings.
-     */
-    public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
-
-    /**
-     * Pseudo-encodings.
-     */
-    public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
-
-    /**
-     * Encodings, which we support.
-     */
-    public final static int[] SUPPORTED_ENCODINGS_ARRAY = {ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE};
-
-    /**
-     * Frame buffer update request type: update of whole screen or partial update.
-     */
-    public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
-
-    public static final int KEY_UP = 0, KEY_DOWN = 1;
-
-    public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
-
-    public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
-
-    public static final int PALETTE = 0, TRUE_COLOR = 1;
-
-    /**
-     * Default 8 bit charset to use when communicating with server.
-     */
-    public static final Charset US_ASCII_CHARSET = Charset.availableCharsets().get("US-ASCII");
-
-    /**
-     * Default 16 bit charset to use when communicating with server.
-     */
-    public static final Charset UCS2_CHARSET = Charset.availableCharsets().get("UTF-16LE");
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java
deleted file mode 100644
index de1036c..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java
+++ /dev/null
@@ -1,292 +0,0 @@
-// 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 vncclient;
-
-import java.security.spec.KeySpec;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.DESKeySpec;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class Vnc33Authentication extends OneTimeSwitch {
-
-    /**
-     * Password to use when authentication is required.
-     */
-    protected String password = null;
-
-    /**
-     * Authentication stage:
-     * <ul>
-     * <li>0 - challenge received, response must be sent
-     * <li>1 - authentication result received.
-     * </ul>
-     */
-    protected int stage = 0;
-
-    public Vnc33Authentication(String id) {
-        super(id);
-    }
-
-    public Vnc33Authentication(String id, String password) {
-        super(id);
-        this.password = password;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        switch (stage) {
-            case 0: // Read security with optional challenge and response
-                stage0(buf, link);
-
-                break;
-            case 1: // Read authentication response
-                stage1(buf, link);
-                break;
-        }
-
-    }
-
-    /**
-     * Read security type. If connection type is @see
-     * RfbConstants.CONNECTION_FAILED, then throw exception. If connection type is @see
-     * RfbConstants.NO_AUTH, then switch off this element. If connection type is @see
-     * RfbConstants.VNC_AUTH, then read challenge, send encoded password, and read
-     * authentication response.
-     */
-    private void stage0(ByteBuffer buf, Link link) {
-        // At least 4 bytes are necessary
-        if (!cap(buf, 4, UNLIMITED, link, true))
-            return;
-
-        // Read security type
-        int authType = buf.readSignedInt();
-
-        switch (authType) {
-            case RfbConstants.CONNECTION_FAILED: {
-                // Server forbids to connect. Read reason and throw exception
-
-                int length = buf.readSignedInt();
-                String reason = new String(buf.data, buf.offset, length, RfbConstants.US_ASCII_CHARSET);
-
-                throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
-            }
-
-            case RfbConstants.NO_AUTH: {
-                // Client can connect without authorization. Nothing to do.
-                // Switch off this element from circuit
-                switchOff();
-                break;
-            }
-
-            case RfbConstants.VNC_AUTH: {
-                // Read challenge and generate response
-                responseToChallenge(buf, link);
-                break;
-            }
-
-            default:
-                throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
-        }
-
-    }
-
-    private void responseToChallenge(ByteBuffer buf, Link link) {
-        // Challenge is exactly 16 bytes long
-        if (!cap(buf, 16, 16, link, true))
-            return;
-
-        ByteBuffer challenge = buf.slice(buf.cursor, 16, true);
-        buf.unref();
-
-        // Encode challenge with password
-        ByteBuffer response;
-        try {
-            response = encodePassword(challenge, password);
-            challenge.unref();
-        } catch (Exception e) {
-            throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
-        }
-
-        if (verbose) {
-            response.putMetadata("sender", this);
-        }
-
-        // Send encoded challenge
-        nextStage();
-        pushDataToOTOut(response);
-
-    }
-
-    private void nextStage() {
-        stage++;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Next stage: " + stage + ".");
-    }
-
-    /**
-     * Encode password using DES encryption with given challenge.
-     *
-     * @param challenge
-     *          a random set of bytes.
-     * @param password
-     *          a password
-     * @return DES hash of password and challenge
-     */
-    public ByteBuffer encodePassword(ByteBuffer challenge, String password) {
-        if (challenge.length != 16)
-            throw new RuntimeException("Challenge must be exactly 16 bytes long.");
-
-        // VNC password consist of up to eight ASCII characters.
-        byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; // Padding
-        byte[] passwordAsciiBytes = password.getBytes(RfbConstants.US_ASCII_CHARSET);
-        System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
-
-        // Flip bytes (reverse bits) in key
-        for (int i = 0; i < key.length; i++) {
-            key[i] = flipByte(key[i]);
-        }
-
-        try {
-            KeySpec desKeySpec = new DESKeySpec(key);
-            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
-            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
-            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
-            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
-
-            ByteBuffer buf = new ByteBuffer(cipher.doFinal(challenge.data, challenge.offset, challenge.length));
-
-            return buf;
-        } catch (Exception e) {
-            throw new RuntimeException("Cannot encode password.", e);
-        }
-    }
-
-    /**
-     * Reverse bits in byte, so least significant bit will be most significant
-     * bit. E.g. 01001100 will become 00110010.
-     *
-     * See also: http://www.vidarholen.net/contents/junk/vnc.html ,
-     * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
-     *
-     * @param b
-     *          a byte
-     * @return byte in reverse order
-     */
-    private static byte flipByte(byte b) {
-        int b1_8 = (b & 0x1) << 7;
-        int b2_7 = (b & 0x2) << 5;
-        int b3_6 = (b & 0x4) << 3;
-        int b4_5 = (b & 0x8) << 1;
-        int b5_4 = (b & 0x10) >>> 1;
-        int b6_3 = (b & 0x20) >>> 3;
-        int b7_2 = (b & 0x40) >>> 5;
-        int b8_1 = (b & 0x80) >>> 7;
-        byte c = (byte)(b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
-        return c;
-    }
-
-    /**
-     * Read authentication result, send nothing.
-     */
-    private void stage1(ByteBuffer buf, Link link) {
-        // Read authentication response
-        if (!cap(buf, 4, 4, link, false))
-            return;
-
-        int authResult = buf.readSignedInt();
-
-        switch (authResult) {
-            case RfbConstants.VNC_AUTH_OK: {
-                // Nothing to do
-                if (verbose)
-                    System.out.println("[" + this + "] INFO: Authentication successfull.");
-                break;
-            }
-
-            case RfbConstants.VNC_AUTH_TOO_MANY:
-                throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
-
-            case RfbConstants.VNC_AUTH_FAILED:
-                throw new RuntimeException("Connection to VNC server failed: wrong password.");
-
-            default:
-                throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
-        }
-
-        switchOff();
-
-    }
-
-    @Override
-    public String toString() {
-        return "VNC3.3 Authentication(" + id + ")";
-    }
-
-    /**
-     * 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");
-
-        final String password = "test";
-
-        Element source = new MockSource("source") {
-            {
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(
-                    // Request authentication and send 16 byte challenge
-                    new byte[] {0, 0, 0, RfbConstants.VNC_AUTH, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
-                    // Respond to challenge with AUTH_OK
-                    new byte[] {0, 0, 0, RfbConstants.VNC_AUTH_OK});
-            }
-        };
-
-        Element mainSink = new FakeSink("mainSink");
-        final Vnc33Authentication auth = new Vnc33Authentication("auth", password);
-        Element initSink = new MockSink("initSink") {
-            {
-                // Expect encoded password
-                bufs = new ByteBuffer[] {auth.encodePassword(new ByteBuffer(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), password)};
-            }
-        };
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, auth, mainSink);
-        pipeline.add(initSink);
-        pipeline.link("auth >otout", "initSink");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java
deleted file mode 100644
index 63d0caa..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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 vncclient;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-
-import streamer.ByteBuffer;
-import streamer.InputStreamSource;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-import streamer.OutputStreamSink;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * VNC server sends hello packet with RFB protocol version, e.g.
- * "RFB 003.007\n". We need to send response packet with supported protocol
- * version, e.g. "RFB 003.003\n".
- */
-public class Vnc33Hello extends OneTimeSwitch {
-
-    public Vnc33Hello(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Initial packet is exactly 12 bytes long
-        if (!cap(buf, 12, 12, link, false))
-            return;
-
-        // Read protocol version
-        String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
-        buf.unref();
-
-        // Server should use RFB protocol 3.x
-        if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
-            throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
-
-        // Send response: we support RFB 3.3 only
-        String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
-
-        ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
-
-        if (verbose) {
-            outBuf.putMetadata("sender", this);
-            outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
-        }
-
-        pushDataToOTOut(outBuf);
-
-        // Switch off this element from circuit
-        switchOff();
-
-    }
-
-    @Override
-    public String toString() {
-        return "Vnc3.3 Hello(" + id + ")";
-    }
-
-    /**
-     * 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");
-
-        InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
-        ByteArrayOutputStream initOS = new ByteArrayOutputStream();
-        ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
-        InputStreamSource inputStreamSource = new InputStreamSource("source", is);
-        OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
-
-        Vnc33Hello hello = new Vnc33Hello("hello");
-
-        Pipeline pipeline = new PipelineImpl("test");
-
-        pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
-        pipeline.add(new OutputStreamSink("initSink", initOS));
-
-        pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-        String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
-        String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
-
-        if (!"RFB 003.003\n".equals(initOut))
-            System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
-
-        if (!"test".equals(mainOut))
-            System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
old mode 100644
new mode 100755
index c035b52..1c76656
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncClient.java
@@ -18,13 +18,23 @@ package vncclient;
 
 import streamer.PipelineImpl;
 import streamer.Queue;
-import common.AwtBellAdapter;
-import common.AwtCanvasAdapter;
-import common.AwtClipboardAdapter;
+import vncclient.adapter.AwtVncKeyboardAdapter;
+import vncclient.adapter.AwtVncMouseAdapter;
+import vncclient.vnc.EncodingsMessage;
+import vncclient.vnc.FrameBufferUpdateRequest;
+import vncclient.vnc.RGB888LE32PixelFormatRequest;
+import vncclient.vnc.RfbConstants;
+import vncclient.vnc.VncInitializer;
+import vncclient.vnc.VncMessageHandler;
+import vncclient.vnc.Vnc33Authentication;
+import vncclient.vnc.Vnc33Hello;
 import common.AwtKeyEventSource;
 import common.AwtMouseEventSource;
 import common.BufferedImageCanvas;
 import common.ScreenDescription;
+import common.adapter.AwtBellAdapter;
+import common.adapter.AwtCanvasAdapter;
+import common.adapter.AwtClipboardAdapter;
 
 public class VncClient extends PipelineImpl {
 
@@ -44,41 +54,41 @@ public class VncClient extends PipelineImpl {
         canvas.addKeyListener(keyEventSource);
 
         add(
-            // Handshake
+                // Handshake
 
-            // RFB protocol version exchanger
-            new Vnc33Hello("hello"),
-            // Authenticator
-            new Vnc33Authentication("auth", password),
-            // Initializer
-            new VncInitializer("init", true, screen),
+                // RFB protocol version exchanger
+                new Vnc33Hello("hello"),
+                // Authenticator
+                new Vnc33Authentication("auth", password),
+                // Initializer
+                new VncInitializer("init", true, screen),
 
-            new EncodingsMessage("encodings", RfbConstants.SUPPORTED_ENCODINGS_ARRAY),
+                new EncodingsMessage("encodings", RfbConstants.SUPPORTED_ENCODINGS_ARRAY),
 
-            new RGB888LE32PixelFormatRequest("pixel_format", screen),
+                new RGB888LE32PixelFormatRequest("pixel_format", screen),
 
-            // Main
+                // Main
 
-            // Packet receiver
-            new VncMessageHandler("message_handler", screen),
+                // Packet receiver
+                new VncMessageHandler("message_handler", screen),
 
-            new AwtBellAdapter("bell"),
+                new AwtBellAdapter("bell"),
 
-            new AwtClipboardAdapter("clipboard"),
+                new AwtClipboardAdapter("clipboard"),
 
-            new AwtCanvasAdapter("pixels", canvas, screen),
+                new AwtCanvasAdapter("pixels", canvas, screen),
 
-            new Queue("queue"),
+                new Queue("queue"),
 
-            new FrameBufferUpdateRequest("fbur", screen),
+                new FrameBufferUpdateRequest("fbur", screen),
 
-            new AwtKeyboardEventToVncAdapter("keyboard_adapter"),
+                new AwtVncKeyboardAdapter("keyboard_adapter"),
 
-            new AwtMouseEventToVncAdapter("mouse_adapter"),
+                new AwtVncMouseAdapter("mouse_adapter"),
 
-            mouseEventSource, keyEventSource
+                mouseEventSource, keyEventSource
 
-        );
+                );
 
         // Link handshake elements
         link("IN", "hello", "auth", "init", "message_handler");


[08/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
new file mode 100755
index 0000000..12d9438
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs.java
@@ -0,0 +1,223 @@
+// 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.rdp;
+
+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;
+
+/**
+ * The MCS Channel Join Request PDUs are sent sequentially. The first PDU is
+ * sent after receiving the MCS Attach User Confirm PDU and subsequent PDUs are
+ * sent after receiving the MCS Channel Join Confirm PDU for the previous
+ * request. Sending of the MCS Channel Join Request PDUs MUST continue until all
+ * channels have been successfully joined.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc240686.aspx
+ */
+public class ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs extends OneTimeSwitch {
+
+    private static final int MCS_CHANNEL_CONFIRM_PDU = 15;
+
+    protected int[] channels;
+    protected int channelRequestsSent = 0;
+
+    protected RdpState state;
+
+    public ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs(String id, int[] channels, RdpState state) {
+        super(id);
+        this.channels = channels;
+        this.state = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        // Parse channel confirm response
+        int typeAndFlags = buf.readUnsignedByte();
+        int type = typeAndFlags >> 2;
+        // int flags = typeAndFlags & 0x3;
+
+        if (type != MCS_CHANNEL_CONFIRM_PDU)
+            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 15, actual value: " + type + ", data: " + buf + ".");
+
+        int rtSuccess = buf.readUnsignedByte() >> 4;
+        if (rtSuccess != 0)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot connect to channel: request failed. Error code: " + rtSuccess + ", channel ID: "
+                    + channels[channelRequestsSent - 1]
+                            + ", data: " + buf + ".");
+
+        // Initiator and requested fields MAY be ignored, however, the channelId
+        // field MUST be examined. If the value of the channelId field does not
+        // correspond with the value of the channelId field sent in the previous MCS
+        // Channel Join Request PDU the connection SHOULD be dropped.
+
+        // Initiator: 1007 (6+1001)
+        // int initator=buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Requested channel
+        // int requestedChannel=buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Actual channel
+        int actualChannel = buf.readUnsignedShort();
+        if (actualChannel != channels[channelRequestsSent - 1])
+            throw new RuntimeException("Unexpeceted channeld ID returned. Expected channeld ID: " + channels[channelRequestsSent - 1] + ", actual channel ID: "
+                    + actualChannel + ", data: " + buf + ".");
+
+        state.channelJoined(actualChannel);
+
+        buf.unref();
+
+        if (channelRequestsSent < channels.length)
+            sendChannelRequest(channels[channelRequestsSent++]);
+        else
+            switchOff();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        sendChannelRequest(channels[channelRequestsSent++]);
+
+        // Switch off after receiving response(s)
+    }
+
+    private void sendChannelRequest(int channel) {
+        ByteBuffer buf = new ByteBuffer(5, true);
+
+        buf.writeByte(0x38); // Channel Join request
+
+        buf.writeShort(state.serverUserChannelId - 1001); // ChannelJoinRequest::initiator: 1004
+        buf.writeShort(channel);
+
+        pushDataToOTOut(buf);
+    }
+
+    /**
+     * Example.
+     *
+     * @see http://msdn.microsoft.com/en-us/library/cc240834.aspx
+     */
+    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[] clientRequestPacket = new byte[] {
+                0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
+                0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+
+                // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+                0x38, 0x00, 0x03, 0x03, (byte) 0xef,
+
+                // 0x38:
+                // 0 - --\
+                // 0 -   |
+                // 1 -   | CHOICE: From DomainMCSPDU select channelJoinRequest (14)
+                // 1 -   | of type ChannelJoinRequest
+                // 1 -   |
+                // 0 - --/
+                // 0 - padding
+                // 0 - padding
+
+                // 0x00:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                //       | ChannelJoinRequest::initiator = 0x03 + 1001 = 1004
+                // 0x03: |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 1 -   |
+                // 1 -   |
+                // 0 - --/
+
+                // 0x03:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 1 -   |
+                // 1 -   |
+                //       | ChannelJoinRequest::channelId = 0x03ef = 1007
+                // 0xef: |
+                // 1 -   |
+                // 1 -   |
+                // 1 -   |
+                // 0 -   |
+                // 1 -   |
+                // 1 -   |
+                // 1 -   |
+                // 1 - --/
+        };
+
+        byte[] serverResponsePacket = new byte[] {
+                // MCS Channel Confirm
+                (byte)0x3e,
+
+                // result: rt-successful (0)
+                (byte)0x00,
+
+                // Initiator: 1007 (6+1001)
+                (byte)0x00, (byte)0x06,
+
+                // Requested channel
+                (byte)0x03, (byte)0xef,
+
+                // Actual channel
+                (byte)0x03, (byte)0xef,
+        };
+        /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        rdpState.serverUserChannelId = 1004;
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverResponsePacket, new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSChannelJoinRequestServerMCSChannelConfirmPDUs("channels", new int[] {1007}, rdpState);
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientRequestPacket));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "channels", "mainSink");
+        pipeline.link("channels >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
new file mode 100755
index 0000000..37730aa
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSConnectInitial.java
@@ -0,0 +1,696 @@
+// 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.rdp;
+
+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;
+
+public class ClientMCSConnectInitial extends OneTimeSwitch {
+
+    public ClientMCSConnectInitial(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+        buf.writeBytes(new byte[] {
+                (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6d, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a,
+                (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02,
+                (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+                (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02,
+                (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x20, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xfc,
+                (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+                (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c,
+                (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01, (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61,
+                (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca,
+                (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00,
+                (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x2e, (byte)0x00, (byte)0x76, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x69, (byte)0x00, (byte)0x73, (byte)0x00,
+                (byte)0x69, (byte)0x00, (byte)0x76, (byte)0x00, (byte)0x6b, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
+                (byte)0x07, (byte)0x00, (byte)0x21, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00,
+        });
+//
+//    buf.writeBytes(new byte[] {
+////        - T125: MCSConnect Initial
+////        - MCSConnectInitial: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
+////         - ConnectInitialHeader:
+//      (byte)0x7F, (byte)0x65,
+////          - AsnId: Application Constructed Tag (101)
+////           - HighTag:
+////              Class:     (01......) Application (1)
+////              Type:      (..1.....) Constructed
+////              TagNumber: (...11111)
+////              TagValueEnd: 101 (0x65)
+//      (byte)0x82, (byte)0x01, (byte)0x6C,
+////          - AsnLen: Length = 364, LengthOfLength = 2
+////             LengthType: LengthOfLength = 2
+////             Length: 364 bytes
+//      (byte)0x04, (byte)0x01, (byte)0x01,
+////         - CallingDomainSelector: 0x1
+////          - AsnOctetStringHeader:
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            OctetStream: 0x1
+//      (byte)0x04, (byte)0x01, (byte)0x01,
+////         - CalledDomainSelector: 0x1
+////          - AsnOctetStringHeader:
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            OctetStream: 0x1
+//      (byte)0x01, (byte)0x01, (byte)0xFF,
+////         - UpwardFlag: True
+////          - AsnBooleanHeader:
+////           - AsnId: Boolean type (Universal 1)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00001) 1
+////           - AsnLen: Length = 1, LengthOfLength = 0
+////              Length: 1 bytes, LengthOfLength = 0
+////            Tf: 255 (0xFF)
+//
+////
+////         - TargetParameters: Length = 26, LengthOfLength = 0
+//      (byte)0x30, (byte)0x1A,
+////          - DomainParametersHeader: 0x1
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 26, LengthOfLength = 0
+////              Length: 26 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x01, (byte)0x22,
+////          - ChannelIds: 34
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 34 (0x22)
+//      (byte)0x02, (byte)0x01, (byte)0x02,
+////          - UserIDs: 2
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - TokenIds: 0
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - NumPriorities: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - MinThroughput: 0
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - Height: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - MCSPDUsize: 65535
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x02,
+////          - protocolVersion: 2
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+//
+////
+////         - MinimumParameters: Length = 25, LengthOfLength = 0
+//      (byte)0x30, (byte)0x19,
+////          - DomainParametersHeader: 0x1
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 25, LengthOfLength = 0
+////              Length: 25 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - ChannelIds: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - UserIDs: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - TokenIds: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - NumPriorities: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - MinThroughput: 0
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - Height: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20,
+////          - MCSPDUsize: 1056
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 2, LengthOfLength = 0
+////               Length: 2 bytes, LengthOfLength = 0
+////             AsnInt: 1056 (0x420)
+//      (byte)0x02, (byte)0x01, (byte)0x02,
+////          - protocolVersion: 2
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+////         - MaximumParameters: Length = 31, LengthOfLength = 0
+////          - DomainParametersHeader: 0x1
+//      (byte)0x30, (byte)0x1F,
+////           - AsnId: Sequence and SequenceOf types (Universal 16)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..1.....) Constructed
+////               TagValue: (...10000) 16
+////           - AsnLen: Length = 31, LengthOfLength = 0
+////              Length: 31 bytes, LengthOfLength = 0
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - ChannelIds: 65535
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x02, (byte)0xFC, (byte)0x17,
+////          - UserIDs: 64535
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 2, LengthOfLength = 0
+////               Length: 2 bytes, LengthOfLength = 0
+////             AsnInt: 64535 (0xFC17)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - TokenIds: 65535
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - NumPriorities: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x01, (byte)0x00,
+////          - MinThroughput: 0
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 0 (0x0)
+//      (byte)0x02, (byte)0x01, (byte)0x01,
+////          - Height: 1
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 1 (0x1)
+//      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
+////          - MCSPDUsize: 65535
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 3, LengthOfLength = 0
+////               Length: 3 bytes, LengthOfLength = 0
+////             AsnInt: 65535 (0xFFFF)
+//      (byte)0x02, (byte)0x01, (byte)0x02,
+////          - protocolVersion: 2
+////           - AsnIntegerHeader:
+////            - AsnId: Integer type (Universal 2)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00010) 2
+////            - AsnLen: Length = 1, LengthOfLength = 0
+////               Length: 1 bytes, LengthOfLength = 0
+////             AsnInt: 2 (0x2)
+////         - UserData: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
+////          - UserDataHeader:
+//      (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07,
+////           - AsnId: OctetString type (Universal 4)
+////            - LowTag:
+////               Class:    (00......) Universal (0)
+////               Type:     (..0.....) Primitive
+////               TagValue: (...00100) 4
+////           - AsnLen: Length = 263, LengthOfLength = 2
+////              LengthType: LengthOfLength = 2
+////              Length: 263 bytes
+//      (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7C, (byte)0x00, (byte)0x01,
+////          - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
+////           - AsnObjectIdentifierHeader:
+////            - AsnId: Reserved for use by the encoding rules (Universal 0)
+////             - LowTag:
+////                Class:    (00......) Universal (0)
+////                Type:     (..0.....) Primitive
+////                TagValue: (...00000) 0
+////            - AsnLen: Length = 5, LengthOfLength = 0
+////               Length: 5 bytes, LengthOfLength = 0
+////             First: 0 (0x0)
+////             Final: 20 (0x14)
+////             Final: 124 (0x7C)
+////             Final: 0 (0x0)
+////             Final: 1 (0x1)
+//      (byte)0x80, (byte)0xFE,
+////          - ConnectPDULength: 254
+////             Align: No Padding
+////             Length: 254
+//      (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10,
+////          - ConnectGCCPDU: conferenceCreateRequest
+////             ExtensionBit: 0 (0x0)
+////           - ChoiceValue: conferenceCreateRequest
+////              Value: (000.....) 0x0
+////           - conferenceCreateRequest:
+////              ExtensionBit: 0 (0x0)
+////              convenerPasswordPresent: 0 (0x0)
+////              passwordPresent: 0 (0x0)
+////              conductorPrivilegesPresent: 0 (0x0)
+////              conductedPrivilegesPresent: 0 (0x0)
+////              nonConductedPrivilegesPresent: 0 (0x0)
+////              conferenceDescriptionPresent: 0 (0x0)
+////              callerIdentifierPresent: 0 (0x0)
+////              userDataPresent: 1 (0x1)
+////            - conferenceName:
+////               ExtensionBit: 0 (0x0)
+////               textPresent: 0 (0x0)
+////             - numeric: 1
+////              - SimpleNumericString: 1
+////               - NumericString: 1
+////                - Align: No Padding
+////                   Padding1: (0.......) 0x0
+////                - Length: 1
+////                   Value: (00000000) 0x0
+////                - Restrictedstr: 1
+////                   FourBits: (0001....) 0x1
+////            - lockedConference: False
+////               Value: False 0.......
+////            - listedConference: False
+////               Value: False 0.......
+////            - conductibleConference: False
+////               Value: False 0.......
+////            - TerminationMethod: automatic
+////               ExtensionBit: 0 (0x0)
+////             - RootIndex: 0
+////                Value: (0.......) 0x0
+////            - userData:
+//      (byte)0x00, (byte)0x01,
+////             - Size: 1
+////              - Align: No Padding
+////                 Padding7: (0000000.) 0x0
+////                Length: 1
+////             - UserData: 0x44756361
+//      (byte)0xC0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61,
+////                valuePresent: 1 (0x1)
+////              - key: h221NonStandard "Duca"
+////               - ChoiceValue: h221NonStandard
+////                  Value: (1.......) 0x1
+////               - h221NonStandard:
+////                - H221NonStandardIdentifier: length: 4
+////                 - ConstrainedLength: 4
+////                    Value: (00000000) 0x0
+////                 - Align: No Padding
+////                    Padding6: (000000..) 0x0
+////                   Value: Binary Large Object (4 Bytes) "Duca"
+////              - ClientMcsConnectInitialPdu:
+//      (byte)0x80, (byte)0xF0,
+////               - RDPGCCUserDataRequestLength: 240
+////                  Align: No Padding
+////                  Length: 240
+////               - TsUd: CS_CORE
+//      (byte)0x01, (byte)0xC0, (byte)0xD8, (byte)0x00,
+////                - TsUdHeader: Type = CS_CORE, Length = 216
+////                   Type: CS_CORE
+////                   Length: 216 (0xD8)
+////                - TsUdCsCore:
+//      (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
+////                   Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
+//      (byte)0x00, (byte)0x04,
+////                   DesktopWidth: 1024 (0x400)
+//      (byte)0x00, (byte)0x03,
+////                   DesktopHeight: 768 (0x300)
+//      (byte)0x01, (byte)0xCA,
+////                   ColorDepth: 8 bpp
+//      (byte)0x03, (byte)0xAA,
+////                   SASSequence: 0xaa03, SHOULD be set to RNS_UD_SAS_DEL(0xAA03)
+//      (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00,
+////                   KeyboardLayout: Language: English, Location: United States
+//      (byte)0x28, (byte)0x0A, (byte)0x00, (byte)0x00,
+////                   ClientBuild: 2600 (0xA28)
+//      (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   ClientName: apollo3
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   KeyboardType: Undefined value: 0
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   KeyboardSubType: 0 (0x0)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   KeyboardFunctionKey: 0 (0x0)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   ImeFileName:
+//      (byte)0x01, (byte)0xCA,
+////                   PostBeta2ColorDepth: 8 bpp
+//      (byte)0x01, (byte)0x00,
+////                   ClientProductId: 0x1, SHOULD be set to initialized to 1
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////                   SerialNumber: 0x0, SHOULD be set to 0
+//      (byte)0x10, (byte)0x00,
+////                   HighColorDepth: 16-bit 565 RGB
+//      (byte)0x07, (byte)0x00,
+////                 - SupportedColorDepth: 7 (0x7)
+////                    Support24BPP: (...............1) Support 24BPP
+////                    Support16BPP: (..............1.) Support 16BPP
+////                    Support15BPP: (.............1..) Support 15BPP
+////                    Support32BPP: (............0...) Not Support 32BPP
+////                    Reserved:     (000000000000....)
+//      (byte)0x01, (byte)0x00,
+////                 - EarlyCapabilityFlags: 1 (0x1)
+////                    SupportSetErrorPdu:      (...............1) Indicates that the client supports the Set Error Info PDU
+////                    Want32BppSession:        (..............0.) Client is not requesting 32BPP session
+////                    SupportStatusInfoPdu:    (.............0..) Client not supports the Server Status Info PDU
+////                    StrongAsymmetricKeys:    (............0...) Not support asymmetric keys larger than 512-bits
+////                    Unused:                  (...........0....)
+////                    ValidConnection:         (..........0.....) Not Indicates ConnectionType field contains valid data
+////                    SupportMonitorLayoutPdu: (.........0......) Not Indicates that the client supports the Monitor Layout PDU
+////                    Unused2:                 (000000000.......)
+//      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////      ClientDigProductId:
+//(byte)0x00,
+////      connectionType: invalid connection type
+//(byte)0x00,
+////      pad1octet: 0 (0x0)
+//(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+////      ServerSelectedProtocols: TLS 1.0
+////
+////  - TsUd: CS_CLUSTER
+////   - TsUdHeader: Type = CS_CLUSTER, Length = 12
+//(byte)0x04, (byte)0xC0,
+////      Type: CS_CLUSTER
+//(byte)0x0C, (byte)0x00,
+////      Length: 12 (0xC)
+//(byte)0x0D, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////   - TsUdCsCluster:
+////    - Flags: 13 (0xD)
+////       RedirectedSupported: (...............................1) Support Redirected
+////       SessionIDFieldValid: (..............................0.) SessionID Field not Valid
+////       SupportedVersion:    (..........................0011..) REDIRECTION_VERSION4
+////       RedirectedSmartcard: (.........................0......) Not Logon with Smartcard
+////       Unused:           (0000000000000000000000000.......)
+////      RedirectedSessionID: 0 (0x0)
+////
+////  - TsUd: CS_SECURITY
+////   - TsUdHeader: Type = CS_SECURITY, Length = 12
+//(byte)0x02, (byte)0xC0,
+////      Type: CS_SECURITY
+//(byte)0x0C, (byte)0x00,
+////      Length: 12 (0xC)
+////
+////   - TsUdCsSec:
+//(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////    - EncryptionMethod:
+////       Support40Bit:  (...............................0) Not Support
+////       Support128Bit: (..............................0.) Not Support 128-bit
+////       Reserved1:     (.............................0..)
+////       Support56Bit:  (............................0...) Not Support 56-bit
+////       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+////       Reserved2:     (000000000000000000000000000.....)
+//(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+////    - ExtEncryptionMethod:
+////       Support40Bit:  (...............................0) Not Support
+////       Support128Bit: (..............................0.) Not Support 128-bit
+////       Reserved1:     (.............................0..)
+////       Support56Bit:  (............................0...) Not Support 56-bit
+////       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+////       Reserved2:     (000000000000000000000000000.....)
+//    });
+        /* @formatter:on */
+
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     *
+     * @see http://msdn.microsoft.com/en-us/library/cc240836.aspx
+     */
+    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[] {
+                // TPKT: TPKT version = 3
+                (byte) 0x03,  (byte) 0x00,
+                // TPKT: Packet length: 378 bytes
+                (byte) 0x01,  (byte) 0x78,
+
+                // X.224: Length indicator = 2
+                (byte) 0x02,
+                // X.224: Type: Data TPDU
+                (byte) 0xf0,
+                // X.224: EOT
+                (byte) 0x80,
+
+                // Captured packet
+                (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6c, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04,
+                (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a, (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00,
+                (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01,
+                (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+                (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x1f, (byte)0x02, (byte)0x03,
+                (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x02, (byte)0xfc, (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
+                (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01,
+                (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c, (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01,
+                (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
+                (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca, (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00,
+                (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSConnectInitial("ClientMCSConnectInitial");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "ClientMCSConnectInitial", "mainSink");
+        pipeline.link("ClientMCSConnectInitial >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
new file mode 100755
index 0000000..a6ea406
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSErectDomainRequest.java
@@ -0,0 +1,189 @@
+// 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.rdp;
+
+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/cc240683.aspx
+ */
+public class ClientMCSErectDomainRequest extends OneTimeSwitch {
+
+    public ClientMCSErectDomainRequest(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 5;
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        buf.writeByte(0x04); // Erect Domain Request
+
+        // Client SHOULD initialize both the subHeight and subinterval fields of the MCS Erect Domain Request PDU to zero.
+
+        buf.writeByte(1); // ErectDomainRequest::subHeight length = 1 byte
+        buf.writeByte(0); // ErectDomainRequest::subHeight
+
+        buf.writeByte(1); // ErectDomainRequest::subInterval length = 1 byte
+        buf.writeByte(0); // ErectDomainRequest::subInterval
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     * @see http://msdn.microsoft.com/en-us/library/cc240837.aspx
+     */
+    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[] {
+
+                0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
+                0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+
+                // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+                0x04, 0x01, 0x00, 0x01, 0x00,
+
+                // 0x04:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   | CHOICE: From DomainMCSPDU select erectDomainRequest (1)
+                // 0 -   | of type ErectDomainRequest
+                // 0 -   |
+                // 1 - --/
+                // 0 - padding
+                // 0 - padding
+
+                // 0x01:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   | ErectDomainRequest::subHeight length = 1 byte
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 1 - --/
+
+                // 0x00:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   | ErectDomainRequest::subHeight = 0
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 - --/
+
+                // 0x01:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   | ErectDomainRequest::subInterval length = 1 byte
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 1 - --/
+
+                // 0x00:
+                // 0 - --\
+                // 0 -   |
+                // 0 -   |
+                // 0 -   | ErectDomainRequest::subInterval = 0
+                // 0 -   |
+                // 0 -   |
+                // 0 -   |
+                // 0 - --/
+
+
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSErectDomainRequest("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}
+
+/*
+ * 03 00 00 0C 02 F0 80 04 01 00 01 00
+
+  Frame: Number = 14, Captured Frame Length = 69, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 12
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 12 (0xC)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Erect Domain Request, SubHeight = 0, SubInterval = 0
+  - MCSHeader: Type=Erect Domain Request
+   - Type: Erect Domain Request
+    - RootIndex: 1
+       Value: (000001..) 0x1
+  - MCSErectDomainRequest: SubHeight = 0, SubInterval = 0
+   - SubHeight: 0x0
+    - Length: 1
+     - Align: No Padding
+        Padding2: (00......) 0x0
+       Length: 1
+      Value: 0 (0x0)
+   - SubInterval: 0x0
+    - Length: 1
+       Align: No Padding
+       Length: 1
+      Value: 0 (0x0)
+
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
new file mode 100755
index 0000000..c9d8d0c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientSynchronizePDU.java
@@ -0,0 +1,248 @@
+// 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.rdp;
+
+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/cc240489.aspx
+ */
+public class ClientSynchronizePDU extends OneTimeSwitch {
+
+    public ClientSynchronizePDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+        buf.writeBytes(new byte[] {
+                // MCS send data request
+                (byte)0x64,
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+                // Channel ID: 1003 (I/O Channel)
+                (byte)0x03, (byte)0xeb,
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+                // Data length:  22 bytes (0x16, variable length field)
+                (byte)0x80,  (byte)0x16,
+
+                // RDP: total length: 22 bytes (LE)
+                (byte)0x16, (byte)0x00,
+
+                // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+                (byte)0x17, (byte)0x00,
+
+                // PDU source: 1007 (LE)
+                (byte)0xec, (byte)0x03,
+                // Share ID: 0x000103ea (LE)
+                (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
+                // Padding: 1 byte
+                (byte)0x00,
+                // Stream ID: STREAM_LOW (1)
+                (byte)0x01,
+                // uncompressedLength : 8 bytes (LE)
+                (byte)0x08, (byte)0x00,
+                // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+                (byte)0x1f,
+                // generalCompressedType: 0
+                (byte)0x00,
+                // generalCompressedLength: 0 (LE?)
+                (byte)0x00, (byte)0x00,
+                //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+                (byte)0x01, (byte)0x00,
+                // targetUser: 0x03ea
+                (byte)0xea, (byte)0x03,
+        });
+        /* @formatter:on */
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     *
+     * @see http://msdn.microsoft.com/en-us/library/cc240841.aspx
+     */
+    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[] {
+                // TPKT
+                (byte)0x03, (byte)0x00,
+                // TPKT length: 37 bytes
+                (byte)0x00, (byte)0x25,
+                // X224 Data PDU
+                (byte)0x02, (byte)0xf0, (byte)0x80,
+
+                // MCS send data request
+                (byte)0x64,
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+                // Channel ID: 1003 (I/O Channel)
+                (byte)0x03, (byte)0xeb,
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+                // Data length:  22 bytes (0x16, variable length field)
+                (byte)0x80,  (byte)0x16,
+
+                // RDP: total length: 22 bytes (LE)
+                (byte)0x16, (byte)0x00,
+                // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+                (byte)0x17, (byte)0x00,
+                // PDU source: 1007 (LE)
+                (byte)0xec, (byte)0x03,
+                // Share ID: 0x000103ea (LE)
+                (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
+                // Padding: 1 byte
+                (byte)0x00,
+                // Stream ID: STREAM_LOW (1)
+                (byte)0x01,
+                // uncompressedLength : 8 bytes (LE)
+                (byte)0x08, (byte)0x00,
+                // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+                (byte)0x1f,
+                // generalCompressedType: 0
+                (byte)0x00,
+                // generalCompressedLength: 0 (LE?)
+                (byte)0x00, (byte)0x00,
+                //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+                (byte)0x01, (byte)0x00,
+                // targetUser: 0x03ea
+                (byte)0xea, (byte)0x03,
+
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientSynchronizePDU("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}
+
+/*
+ * @formatting:off
+
+ * 03 00 00 25 02 F0 80 64 00 03 03 EB 70 80 16 16 00 17 00 EC 03 EA 03 01 00 00 01 08 00 1F 00 00 00 01 00 EA 03
+
+  Frame: Number = 40, Captured Frame Length = 94, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 37
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 37 (0x25)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Request, UserID=1004, ChannelID=1003
+   - Type: Send Data Request
+    - RootIndex: 25
+       Value: (011001..) 0x19
+   - UserID: 0x3ec
+    - UserID: 0x3ec
+     - ChannelId: 1004
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 3 (0x3)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 22
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 22
+    RDP: RDPBCGR
+- RDPBCGR: SynchronizePDU
+  - SlowPathPacket: SynchronizePDU
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 22 (0x16)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1004 (0x3EC)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
+        ShareID: 66538 (0x103EA)
+        Pad1: 0 (0x0)
+        StreamID: TS_STREAM_LOW
+        UncompressedLength: 8 (0x8)
+        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsSynchronizePDU: 0x1
+        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
+        TargetUser: 1002 (0x3EA)
+ */
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
new file mode 100755
index 0000000..926c807
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientTpkt.java
@@ -0,0 +1,54 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ClientTpkt extends BaseElement {
+
+    public ClientTpkt(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf.length + 4 > 65535)
+            throw new RuntimeException("Packet is too long for TPKT (max length 65535-4): " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(4);
+        // TPKT version
+        data.writeByte(3);
+        // Reserved
+        data.writeByte(0);
+        // Packet length, including length of the header
+        data.writeShort(buf.length + 4);
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
new file mode 100755
index 0000000..6413432
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224ConnectionRequestPDU.java
@@ -0,0 +1,162 @@
+// 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.rdp;
+
+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/cc240470.aspx
+ * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
+ */
+public class ClientX224ConnectionRequestPDU extends OneTimeSwitch {
+
+    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
+    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
+    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
+    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
+    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
+    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
+    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
+    public static final int X224_TPDU_REJECT = 0x51;
+    public static final int X224_TPDU_ERROR = 0x70;
+    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
+
+    /**
+     * Reconnection cookie.
+     */
+    protected String userName;
+
+    /**
+     * Protocol to use:  RDP_NEG_REQ_PROTOCOL_SSL or RDP_NEG_REQ_PROTOCOL_HYBRID.
+     */
+    protected int protocol;
+
+    public ClientX224ConnectionRequestPDU(String id, String userName, int protocol) {
+        super(id);
+        this.userName = userName;
+        this.protocol = protocol;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        // Length of packet without length field
+        int length = 33 + userName.length();
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        // Type (high nibble) = 0xe = CR TPDU; credit (low nibble) = 0
+        buf.writeByte(X224_TPDU_CONNECTION_REQUEST);
+
+        buf.writeShort(0); // Destination reference = 0
+        buf.writeShort(0); // Source reference = 0
+        buf.writeByte(0); // Class and options = 0
+        buf.writeString("Cookie: mstshash=" + userName + "\r\n", RdpConstants.CHARSET_8); // Cookie
+
+        // RDP_NEG_REQ::type
+        buf.writeByte(RdpConstants.RDP_NEG_REQ_TYPE_NEG_REQ);
+        // RDP_NEG_REQ::flags (0)
+        buf.writeByte(RdpConstants.RDP_NEG_REQ_FLAGS);
+        // RDP_NEG_REQ::length (constant: 8) short int in LE format
+        buf.writeByte(0x08);
+        buf.writeByte(0x00);
+
+        // RDP_NEG_REQ: Requested protocols: PROTOCOL_SSL
+        buf.writeIntLE(protocol);
+
+        // Calculate length of packet and prepend it to buffer
+        ByteBuffer data = new ByteBuffer(5);
+
+        // Write length
+        data.writeVariableIntLE(buf.length);
+
+        // Reset length of buffer to actual length of data written
+        data.length = data.cursor;
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * Example.
+     *
+     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        String cookie = "eltons";
+
+        byte[] packet = new byte[] {
+
+                0x03, // TPKT Header: version = 3
+                0x00, // TPKT Header: Reserved = 0
+                0x00, // TPKT Header: Packet length - high part
+                0x2c, // TPKT Header: Packet length - low part (total = 44 bytes)
+                0x27, // X.224: Length indicator (39 bytes)
+                (byte)0xe0, // X.224: Type (high nibble) = 0xe = CR TPDU;
+                // credit (low nibble) = 0
+                0x00, 0x00, // X.224: Destination reference = 0
+                0x00, 0x00, // X.224: Source reference = 0
+                0x00, // X.224: Class and options = 0
+
+                'C', 'o', 'o', 'k', 'i', 'e', ':', ' ', 'm', 's', 't', 's', 'h', 'a', 's', 'h', '=', 'e', 'l', 't', 'o', 'n', 's', // "Cookie: mstshash=eltons"
+                '\r', '\n', // -Cookie terminator sequence
+
+                0x01, // RDP_NEG_REQ::type (TYPE_RDP_NEG_REQ)
+                0x00, // RDP_NEG_REQ::flags (0)
+                0x08, 0x00, // RDP_NEG_REQ::length (8 bytes)
+                0x01, 0x00, 0x00, 0x00 // RDP_NEG_REQ: Requested protocols
+                // (PROTOCOL_SSL in little endian format)
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element cr = new ClientX224ConnectionRequestPDU("cr", cookie, RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL);
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, cr, tpkt, sink, mainSink);
+        pipeline.link("source", "cr", "mainSink");
+        pipeline.link("cr >" + OTOUT, "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
new file mode 100755
index 0000000..b0373ad
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientX224DataPDU.java
@@ -0,0 +1,52 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ClientX224DataPDU extends BaseElement {
+
+    public static final int X224_TPDU_DATA = 0xF0;
+    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
+
+    public ClientX224DataPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(3);
+        // X224 header
+        data.writeByte(2); // Header length indicator
+        data.writeByte(X224_TPDU_DATA);
+        data.writeByte(X224_TPDU_LAST_DATA_UNIT);
+
+        buf.prepend(data);
+        data.unref();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+}


[09/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
new file mode 100755
index 0000000..b77f201
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientConfirmActivePDU.java
@@ -0,0 +1,1131 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.ScreenDescription;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240488.aspx
+ */
+public class ClientConfirmActivePDU extends BaseElement {
+
+    public static final String SOURCE_DESC = "MSTSC";
+
+    public static final int CAPSTYPE_BITMAP = 0x2;
+
+    protected int numberCapabilities;
+
+    protected RdpState state;
+    protected ScreenDescription screen;
+
+    protected boolean desktopResize = false;
+    protected int prefferedBitsPerPixel = 16;
+
+    public ClientConfirmActivePDU(String id, ScreenDescription screen, RdpState state) {
+        super(id);
+        this.state = state;
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer aBuf, Link link) {
+
+        // Body
+        ByteBuffer buf = new ByteBuffer(1024, true);
+        numberCapabilities = 0;
+        writeCapabilities(buf);
+        buf.trimAtCursor();
+
+        // Header
+        ByteBuffer header = createMCSHeader(buf);
+
+        // Length of source descriptor, including NULL character (LE)
+        header.writeShortLE(SOURCE_DESC.length() + 1);
+
+        // Length of combined capabilities + 4 bytes (number of capabilities and
+        // padding) (LE)
+        header.writeShortLE(buf.length + 4);
+
+        header.writeString(SOURCE_DESC, RdpConstants.CHARSET_8);
+        header.writeByte(0);
+
+        // Number of capabilities
+        header.writeShortLE(numberCapabilities);
+
+        // Padding 2 bytes
+        header.writeShortLE(0);
+
+        header.trimAtCursor();
+
+        // Prepend header to capabilities
+        buf.prepend(header);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+
+        sendOtherRequredPackets();
+
+    }
+
+    private ByteBuffer createMCSHeader(ByteBuffer buf) {
+        ByteBuffer header = new ByteBuffer(100);
+        // MCS Send Data Request
+        header.writeByte(0x64);
+
+        // Initiator: 1004 (1001+3)
+        header.writeShort(3);
+
+        // Channel ID: 1003 (I/O channel)
+        header.writeShort(RdpConstants.CHANNEL_IO);
+
+        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+        header.writeByte(0x70);
+
+        int length = buf.length + 26;
+
+        // User data length: (variable length field, LE)
+        header.writeVariableShort(length);
+
+        // Total length: (LE)
+        header.writeShortLE(length);
+
+        // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
+        header.writeShortLE(0x13);
+
+        // PDU source: 1004 (LE)
+        header.writeShortLE(1004);
+
+        // Share ID, e.g. 0x000103ea (LE)
+        header.writeIntLE((int)state.serverShareId);
+
+        // Originator ID: 1002 (LE)
+        header.writeShortLE(1002);
+        return header;
+    }
+
+    private void sendOtherRequredPackets() {
+        // Send sequence in bulk
+
+        sendSynchronizePDU();
+        sendControlPDUActionCooperate();
+        sendControlPDUActionRequestControl();
+        // sendBitmapCachePersistentListPDU();
+        sendFontListPDU();
+    }
+
+    private void sendFontListPDU() {
+        {
+            int length = 1024; // Large enough
+            ByteBuffer buf = new ByteBuffer(length, true);
+
+            /* @formatter:off */
+            buf.writeBytes(new byte[] {
+                    // MCS Send Data Request
+                    (byte)0x64,
+                    // Initiator: 1004 (1001+3)
+                    (byte)0x00, (byte)0x03,
+                    // Channel ID: 1003 (I/O channel)
+                    (byte)0x03, (byte)0xeb,
+                    // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                    (byte)0x70,
+                    // User data length: 26 bytes (0x1a, variable length field)
+                    (byte)0x80, (byte)0x1a,
+
+                    // Total length: 26 bytes (0x1a, LE)
+                    (byte)0x1a, (byte)0x00,
+                    // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+                    (byte)0x17, (byte)0x00,
+                    // PDU source: 1004 (LE)
+                    (byte)0xec, (byte)0x03,
+            });
+            // Share ID, 4 bytes  (LE)
+            buf.writeIntLE((int)state.serverShareId);
+
+            buf.writeBytes(new byte[] {
+                    // Padding 1 byte
+                    (byte)0x00,
+                    // Stream ID: STREAM_LOW (1)
+                    (byte)0x01,
+                    // uncompressedLength : 12 bytes (LE)
+                    (byte)0x0c, (byte)0x00,
+
+                    // pduType2: PDUTYPE2_FONTLIST (39)
+                    (byte)0x27,
+                    // generalCompressedType: 0
+                    (byte)0x00,
+                    // generalCompressedLength: 0 (LE)
+                    (byte)0x00, (byte)0x00,
+
+                    // numberEntries (should be set to zero): 0 (LE)
+                    (byte)0x00, (byte)0x00,
+                    // totalNumEntries (should be set to zero): 0 (LE)
+                    (byte)0x00, (byte)0x00,
+                    // listFlags  (should be set to 0x3): 0x0003 (LE), FONTLIST_LAST(0x2) | FONTLIST_FIRST(0x1)
+                    (byte)0x03, (byte)0x00,
+                    // entrySize: 50 bytes (0x0032, LE)
+                    (byte)0x32, (byte)0x00,
+            });
+            /* @formatter:on */
+
+            // Trim buffer to actual length of data written
+            buf.trimAtCursor();
+
+            pushDataToPad(STDOUT, buf);
+        }
+    }
+
+    private void sendControlPDUActionRequestControl() {
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+        buf.writeBytes(new byte[] {
+                // MCS Send Data Request
+                (byte)0x64,
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+                // Channel ID: 1003 (I/O channel)
+                (byte)0x03, (byte)0xeb,
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+                // User data length: 26 bytes (0x1a, variable length field)
+                (byte)0x80, (byte)0x1a,
+
+                // Total length: 26 bytes (0x1a, LE)
+                (byte)0x1a, (byte)0x00,
+                // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+                (byte)0x17, (byte)0x00,
+                // PDU source: 1004 (LE)
+                (byte)0xec, (byte)0x03,
+        });
+        // Share ID, 4 bytes  (LE)
+        buf.writeIntLE((int)state.serverShareId);
+
+        buf.writeBytes(new byte[] {
+                // Padding 1 byte
+                (byte)0x00,
+                // Stream ID: STREAM_LOW (1)
+                (byte)0x01,
+                // uncompressedLength : 12 bytes (LE)
+                (byte)0x0c, (byte)0x00,
+                // pduType2: PDUTYPE2_CONTROL (20)
+                (byte)0x14,
+                // generalCompressedType: 0
+                (byte)0x00,
+                // generalCompressedLength: 0 (LE)
+                (byte)0x00, (byte)0x00,
+
+                // action: CTRLACTION_REQUEST_CONTROL (1) (LE)
+                (byte)0x01, (byte)0x00,
+                // grantId: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // controlId: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        });
+        /* @formatter:on */
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void sendControlPDUActionCooperate() {
+        int length = 1024; // Large enough
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        /* @formatter:off */
+        buf.writeBytes(new byte[] {
+                // MCS Send Data Request
+                (byte)0x64,
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+                // Channel ID: 1003 (I/O channel)
+                (byte)0x03, (byte)0xeb,
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+                // User data length: 26 bytes (0x1a, variable length field)
+                (byte)0x80, (byte)0x1a,
+
+                // Total length: 26 bytes (0x1a, LE)
+                (byte)0x1a,(byte)0x00,
+                // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE)
+                (byte)0x17, (byte)0x00,
+                // PDU source: 1004 (LE)
+                (byte)0xec, (byte)0x03,
+        });
+        // Share ID, 4 bytes  (LE)
+        buf.writeIntLE((int)state.serverShareId);
+
+        buf.writeBytes(new byte[] {
+                // Padding 1 byte
+                (byte)0x00,
+                // Stream ID: STREAM_LOW (1)
+                (byte)0x01,
+                // uncompressedLength : 12 bytes (LE)
+                (byte)0x0c, (byte)0x00,
+                // pduType2: PDUTYPE2_CONTROL (20)
+                (byte)0x14,
+                // generalCompressedType: 0
+                (byte)0x00,
+                // generalCompressedLength: 0 (LE?)
+                (byte)0x00, (byte)0x00,
+                // action: CTRLACTION_COOPERATE (4) (LE)
+                (byte)0x04, (byte)0x00,
+                // grantId: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // controlId: 0
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+        });
+        /* @formatter:on */
+
+        buf.trimAtCursor();
+
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void sendSynchronizePDU() {
+
+        ByteBuffer buf = new ByteBuffer(1024, true);
+        /* @formatter:off */
+        buf.writeBytes(new byte[] {
+                // MCS send data request
+                (byte)0x64,
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+                // Channel ID: 1003 (I/O Channel)
+                (byte)0x03, (byte)0xeb,
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+                // Data length:  22 bytes (0x16, variable length field)
+                (byte)0x80,  (byte)0x16,
+
+                // RDP: total length: 22 bytes (LE)
+                (byte)0x16, (byte)0x00,
+
+                // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
+                (byte)0x17, (byte)0x00,
+
+                // PDU source: 1007 (LE)
+                (byte)0xec, (byte)0x03,
+        });
+        // Share ID, 4 bytes  (LE)
+        buf.writeIntLE((int)state.serverShareId);
+
+        buf.writeBytes(new byte[] {
+                // Padding: 1 byte
+                (byte)0x00,
+                // Stream ID: STREAM_LOW (1)
+                (byte)0x01,
+                // uncompressedLength : 8 bytes (LE)
+                (byte)0x08, (byte)0x00,
+                // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
+                (byte)0x1f,
+                // generalCompressedType: 0
+                (byte)0x00,
+                // generalCompressedLength: 0 (LE?)
+                (byte)0x00, (byte)0x00,
+                //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
+                (byte)0x01, (byte)0x00,
+                // targetUser: 0x03ea
+                (byte)0xea, (byte)0x03,
+        });
+        /* @formatter:on */
+        buf.trimAtCursor();
+        pushDataToPad(STDOUT, buf);
+    }
+
+    private void writeCapabilities(ByteBuffer buf) {
+        writeGeneralCS(buf);
+
+        writeBitmapCS(buf);
+
+        writeOrderCS(buf);
+
+        writeBitmapCache2CS(buf);
+
+        writeColorTableCacheCS(buf);
+
+        writeWindowActivationCS(buf);
+
+        writeControlCS(buf);
+
+        writePointerCS(buf);
+
+        writeShareCS(buf);
+
+        writeInputCS(buf);
+
+        writeBrushCS(buf);
+
+        writeSoundCS(buf);
+
+        writeFontCS(buf);
+
+        writeOffscreenBitmapCS(buf);
+
+        writeGlyphCacheCS(buf);
+    }
+
+    private void writeBrushCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Brush Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240564.aspx
+                (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15,
+                // LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel:
+                // BRUSH_DEFAULT
+                // (0x0, LE)
+
+        });
+    }
+
+    private void writeInputCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Input Capability Set (88 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240563.aspx
+                (byte)0x0d,
+                (byte)0x00, // capability set type: CAPSTYPE_INPUT (13, LE)
+                (byte)0x58,
+                (byte)0x00, // length of capability set: 88 bytes (LE)
+                (byte)0x35,
+                (byte)0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2
+                // (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX
+                // (0x4), INPUT_FLAG_SCANCODES (0x1)
+                (byte)0x00,
+                (byte)0x00, // Padding 2 bytes
+                (byte)0x09,
+                (byte)0x04,
+                (byte)0x00,
+                (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardType: unknown (LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardSubType: unknown (LE)
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00,
+                (byte)0x00, // keyboardFunctionKey: unknown (LE)
+                // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+        });
+    }
+
+    private void writeShareCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Share Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240570.aspx
+                (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
+
+        });
+    }
+
+    private void writePointerCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Pointer Capability Set (10 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240562.aspx
+                (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8,
+                // LE)
+                (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
+                (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
+                (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
+                (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
+
+        });
+    }
+
+    private void writeControlCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Control Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240568.aspx
+                (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
+                // (7)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0
+                // (LE)
+                (byte)0x02, (byte)0x00, // controlInterest (should be set to
+                // CONTROLPRIORITY_NEVER):
+                // CONTROLPRIORITY_NEVER (2) (LE)
+                (byte)0x02, (byte)0x00, // detachInterest (should be set to
+                // CONTROLPRIORITY_NEVER):
+                // CONTROLPRIORITY_NEVER (2) (LE)
+
+        });
+    }
+
+    private void writeWindowActivationCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Window Activation Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240569.aspx
+                (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION
+                // (7) (LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)):
+                // FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE
+                // (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE
+                // (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to
+                // FALSE (0)): FALSE (0, LE)
+
+        });
+    }
+
+    private void writeColorTableCacheCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+
+                //
+                // Color Table Cache Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc241564.aspx
+                (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE
+                // (10) (LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x06, (byte)0x00, // Color table cache size (must be ignored
+                // during capability exchange and is assumed
+                // to be 0x0006): 6 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeBitmapCache2CS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Bitmap Cache Rev. 2 Capability Set (40 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240560.aspx
+                (byte)0x13, (byte)0x00, // capability set type:
+                // CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
+                (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
+                (byte)0x00, (byte)0x00, // Cache flags: 0 (LE)
+                (byte)0x00, // Padding 1 byte
+                (byte)0x00, // Number of cell caches: 0
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0
+                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1
+                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2
+                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3
+                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4
+                // cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+        });
+    }
+
+    private void writeGeneralCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                // Capabilities, see
+                // http://msdn.microsoft.com/en-us/library/cc240486.aspx
+
+                //
+                // General capability set (24 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240549.aspx
+                (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1)
+                // (LE)
+                (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
+                (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
+                (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
+                (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
+
+                // Extra flags: 0x040d (LE)
+                // FastPathOutput: (...............1) Advertiser supports fast-path
+                // output
+                // ShadowCompression: (..............0.) Advertiser NOT supports shadow
+                // compression
+                // LongLengthCredentials: (.............1..) Advertiser supports
+                // long-length credentials for the user name, password, or domain name
+                // SessionAutoreconnection: (............1...) Advertiser supports
+                // session auto-reconnection
+                // ImprovedEncryptionChecksum: (...........0....) Client and server NOT
+                // support improved encryption checksum
+                // Reserved1: (......00000.....)
+                // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is
+                // present for compressed bitmap data
+                // Reserved2: (00000...........)
+                (byte)0x0d, (byte)0x04,
+
+                (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
+                (byte)0x00, // refreshRectSupport: FALSE (0)
+                (byte)0x00, // suppressOutputSupport: FALSE (0)
+
+        });
+    }
+
+    private void writeBitmapCS(ByteBuffer buf) {
+        // Bitmap capability set (28 bytes), see
+        // http://msdn.microsoft.com/en-us/library/cc240554.aspx
+
+        numberCapabilities++;
+
+        // Capability set type: CAPSTYPE_BITMAP (2) (LE)
+        buf.writeShortLE(CAPSTYPE_BITMAP);
+
+        // Length of capability set: 28 bytes (LE)
+        buf.writeShortLE(28);
+
+        // preferredBitsPerPixel: 16 bpp (LE)
+        buf.writeShortLE(prefferedBitsPerPixel);
+
+        // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+        buf.writeShortLE(1);
+
+        // Desktop width and height (LE)
+        buf.writeShortLE(screen.getFramebufferWidth());
+        buf.writeShortLE(screen.getFramebufferHeight());
+
+        // Padding 2 bytes
+        buf.writeShortLE(0);
+
+        // desktopResizeFlag (LE)
+        buf.writeShortLE((desktopResize) ? 1 : 0);
+
+        buf.writeBytes(new byte[] {
+                (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE
+                // (0x1)): TRUE (0x1) (LE)
+                (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to
+                // zero): 0
+                (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
+                (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeOrderCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Order Capability Set (88 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240556.aspx
+                (byte)0x03,
+                (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
+                (byte)0x58,
+                (byte)0x00, // length of capability set: 88 bytes (LE)
+                // terminalDescriptor = "" (16 bytes, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA
+                (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
+                (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
+                (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
+                (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
+                (byte)0x00, (byte)0x00, // number of fonts (ignored): 0
+                (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE),
+                // SOLIDPATTERNBRUSHONLY (0x40),
+                // ZEROBOUNDSDELTASSUPPORT (0x8, MUST),
+                // NEGOTIATEORDERSUPPORT (0x2, MUST)
+                // Order support: 32 bytes (no primary drawing orders are supported, so
+                // this array MUST be initialized to all zeros, use 0x01 for TRUE).
+                (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, (byte)0x00, // Text flags (ignored): 0 (LE)
+                (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size
+                // (ignored): 0
+                // (assumed to be
+                // 230400 bytes
+                // (480*480,
+                // 0x38400, LE))
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252, ANSI - Latin I
+                // (0x04e4, LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+        });
+    }
+
+    private void writeSoundCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Sound Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240552.aspx
+                (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12,
+                // LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags:
+                // 0x0000 (LE) //
+                // SOUND_FLAG_BEEPS
+                // (0x1)
+
+        });
+    }
+
+    private void writeFontCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Font Capability Set (8 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240571.aspx
+                (byte)0x0e, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+
+        });
+    }
+
+    private void writeOffscreenBitmapCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Offscreen Bitmap Cache Capability Set (12 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240550.aspx
+                (byte)0x11, (byte)0x00, // capability set type:
+                // CAPSTYPE_OFFSCREENCACHE (17, LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel:
+                // FALSE (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
+
+        });
+    }
+
+    private void writeGlyphCacheCS(ByteBuffer buf) {
+        numberCapabilities++;
+        buf.writeBytes(new byte[] {
+                //
+                // Glyph Cache Capability Set (52 bytes), see
+                // http://msdn.microsoft.com/en-us/library/cc240565.aspx
+                (byte)0x10, (byte)0x00, // capability set type:
+                // CAPSTYPE_OFFSCREENCACHE (16, LE)
+                (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
+                // Glyph Cache (40 bytes)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
+                (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
+                (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
+                // FragCache
+                (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
+                //
+                (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0,
+                // LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+        });
+    }
+
+    /**
+     * 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[] {
+                // MCS Send Data Request
+                (byte)0x64,
+
+                // Initiator: 1004 (1001+3)
+                (byte)0x00, (byte)0x03,
+
+                // Channel ID: 1003 (I/O channel)
+                (byte)0x03, (byte)0xeb,
+
+                // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
+                (byte)0x70,
+
+                // User data length: 432 bytes (0x1b0, variable length field)
+                (byte)0x81, (byte)0xb0,
+
+                // Total length: 432 bytes (0x1b0, LE)
+                (byte)0xb0, (byte)0x01,
+
+                // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE)
+                (byte)0x13, (byte)0x00,
+
+                // PDU source: 1004 (LE)
+                (byte)0xec, (byte)0x03,
+
+                // Share ID: 0x000103ea (LE)
+                (byte)0xea, (byte)0x03, (byte)0x01, (byte)0x00,
+
+                // Originator ID: 1002 (LE)
+                (byte)0xea, (byte)0x03,
+
+                // Length of source descriptor: 6 bytes (including NULL character) (LE)
+                (byte)0x06, (byte)0x00,
+
+                // Length of combined capabilities: 410 bytes (LE)
+                (byte)0x9a, (byte)0x01,
+
+                // Source descriptor: "MSTSC" ???
+                (byte)0x4d, (byte)0x53, (byte)0x54, (byte)0x53, (byte)0x43, (byte)0x00,
+
+                // Number of capabilities: 15 (LE)
+                (byte)0x0f, (byte)0x00,
+
+                // Padding 2 bytes
+                (byte)0x00, (byte)0x00,
+
+                // Capabilities, see http://msdn.microsoft.com/en-us/library/cc240486.aspx
+
+                //
+                // General capability set (24 bytes), see http://msdn.microsoft.com/en-us/library/cc240549.aspx
+                (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) (LE)
+                (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE)
+                (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE)
+                (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE)
+                (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE)
+
+                // Extra flags: 0x040d (LE)
+//        FastPathOutput:             (...............1) Advertiser supports fast-path output
+//        ShadowCompression:          (..............0.) Advertiser NOT supports shadow compression
+//        LongLengthCredentials:      (.............1..) Advertiser supports long-length credentials for the user name, password, or domain name
+//        SessionAutoreconnection:    (............1...) Advertiser supports session auto-reconnection
+//        ImprovedEncryptionChecksum: (...........0....) Client and server NOT support improved encryption checksum
+//        Reserved1:                  (......00000.....)
+//        CompressedBitMapDataFlag:   (.....1..........) No 8-UINT8 header is present for compressed bitmap data
+//        Reserved2:                  (00000...........)
+                (byte)0x0d, (byte)0x04,
+
+                (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE)
+                (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE)
+                (byte)0x00, // refreshRectSupport: FALSE (0)
+                (byte)0x00, // suppressOutputSupport: FALSE (0)
+
+                //
+                // Bitmap capability set (28 bytes), see http://msdn.microsoft.com/en-us/library/cc240554.aspx
+                (byte)0x02, (byte)0x00, // capability set type: CAPSTYPE_BITMAP (2) (LE)
+                (byte)0x1c, (byte)0x00, // length of capability set: 28 bytes (LE)
+                (byte)0x10, (byte)0x00, // preferredBitsPerPixel: 16 bpp (LE)
+                (byte)0x01, (byte)0x00, // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+                (byte)0x01, (byte)0x00, // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+                (byte)0x01, (byte)0x00, // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE)
+                (byte)0x00, (byte)0x04, // desktopWidth = 1024 pixels (LE)
+                (byte)0x00, (byte)0x03, // desktopHeight = 768 pixels (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // desktopResizeFlag: FALSE (0x0) (LE)
+                (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE (0x1)): TRUE (0x1) (LE)
+                (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to zero): 0
+                (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ???
+                (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+                //
+                // Order Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240556.aspx
+                (byte)0x03, (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE)
+                (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
+                // terminalDescriptor = "" (16 bytes, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA
+                (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE)
+                (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE)
+                (byte)0x00, (byte)0x00, // pad2octetsA (ignored)
+                (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1)
+                (byte)0x00, (byte)0x00, // number of fonts (ignored): 0
+                (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), SOLIDPATTERNBRUSHONLY (0x40), ZEROBOUNDSDELTASSUPPORT (0x8, MUST), NEGOTIATEORDERSUPPORT (0x2, MUST)
+                // Order support: 32 bytes (no primary drawing orders are supported, so this array MUST be initialized to all zeros, use 0x01 for TRUE).
+                (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE
+                (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE
+                (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE
+                (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE
+                (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE
+                (byte)0x00, // Unused: 0
+                (byte)0x00, (byte)0x00, // Text flags (ignored): 0  (LE)
+                (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size (ignored): 0 (assumed to be 230400 bytes (480*480, 0x38400, LE))
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252,  ANSI - Latin I (0x04e4, LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+                //
+                // Bitmap Cache Rev. 2 Capability Set (40 bytes), see http://msdn.microsoft.com/en-us/library/cc240560.aspx
+                (byte)0x13, (byte)0x00, // capability set type: CAPSTYPE_BITMAPCACHE_REV2 (19) (LE)
+                (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE)
+                (byte)0x00, (byte)0x00, // Cache flags: 0 (LE)
+                (byte)0x00, // Padding 1 byte
+                (byte)0x00, // Number of cell caches: 0
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 cell info: 0 (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding
+
+                //
+                // Color Table Cache Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc241564.aspx
+                (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE (10) (LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x06, (byte)0x00, // Color table cache size (must be ignored during capability exchange and is assumed to be 0x0006): 6 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+
+                //
+                // Window Activation Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240569.aspx
+                (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) (LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+                (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to FALSE (0)): FALSE (0, LE)
+
+                //
+                // Control Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240568.aspx
+                (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE)
+                (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 (LE)
+                (byte)0x02, (byte)0x00, // controlInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
+                (byte)0x02, (byte)0x00, // detachInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE)
+
+                //
+                // Pointer Capability Set (10 bytes), see http://msdn.microsoft.com/en-us/library/cc240562.aspx
+                (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, LE)
+                (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE)
+                (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE)
+                (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE)
+                (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE)
+
+                //
+                // Share Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240570.aspx
+                (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes (LE)
+
+                //
+                // Input Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240563.aspx
+                (byte)0x0d, (byte)0x00, // capability set type:  CAPSTYPE_INPUT (13, LE)
+                (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE)
+                (byte)0x35, (byte)0x00, // inputFlags: 0x0035  (LE),  INPUT_FLAG_FASTPATH_INPUT2 (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX (0x4), INPUT_FLAG_SCANCODES (0x1)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+                (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardType: unknown (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardSubType: unknown (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardFunctionKey: unknown (LE)
+                // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+                //
+                // Brush Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240564.aspx
+                (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: BRUSH_DEFAULT (0x0, LE)
+
+                //
+                // Sound Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240552.aspx
+                (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, LE)
+                (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: 0x0000 (LE) // SOUND_FLAG_BEEPS (0x1)
+
+                //
+                // Font Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240571.aspx
+                (byte)0x0e, (byte)0x00,
+                (byte)0x08, (byte)0x00,
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+
+                //
+                // Offscreen Bitmap Cache Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240550.aspx
+                (byte)0x11, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (17, LE)
+                (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE)
+                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: FALSE (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE)
+                (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE)
+
+                //
+                // Glyph Cache Capability Set (52 bytes), see http://msdn.microsoft.com/en-us/library/cc240565.aspx
+                (byte)0x10, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (16, LE)
+                (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE)
+                // Glyph Cache (40 bytes)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE)
+                (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE)
+                (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE)
+                (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE)
+                // FragCache
+                (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE)
+                (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE)
+                //
+                (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, LE)
+                (byte)0x00, (byte)0x00, // Padding 2 bytes
+        };
+        /* @formatter:on */
+
+        RdpState rdpState = new RdpState();
+        ScreenDescription screenDescription = new ScreenDescription();
+        screenDescription.setFramebufferSize(1024, 768);
+
+        rdpState.serverShareId = 0x000103ea;
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}));
+        Element confirm_active = new ClientConfirmActivePDU("confirm_active", screenDescription, rdpState);
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, confirm_active, sink);
+        pipeline.link("source", "confirm_active", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
new file mode 100755
index 0000000..108429c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientFastPathPDU.java
@@ -0,0 +1,55 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240589.aspx
+ */
+public class ClientFastPathPDU extends BaseElement {
+
+    public ClientFastPathPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf.length > 32767 - 3)
+            throw new RuntimeException("Packet is too long: " + buf + ".");
+
+        ByteBuffer data = new ByteBuffer(6);
+
+        // FastPath, 1 event, no checksum, not encrypted
+        data.writeByte(0x4);
+
+        // Length of full packet, including length field, in network order.
+        // Topmost bit of first byte indicates that field has 2 bytes
+        data.writeShort((1 + 2 + buf.length) | 0x8000);
+        data.trimAtCursor();
+
+        buf.prepend(data);
+
+        pushDataToAllOuts(buf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
new file mode 100755
index 0000000..6196004
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientInfoPDU.java
@@ -0,0 +1,456 @@
+// 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.rdp;
+
+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/cc240475.aspx
+ */
+public class ClientInfoPDU extends OneTimeSwitch {
+
+    public static final int INFO_MOUSE = 0x1;
+    public static final int INFO_DISABLECTRLALTDEL = 0x2;
+    public static final int INFO_UNICODE = 0x10;
+
+    public static final int INFO_MAXIMIZESHELL = 0x20;
+    public static final int INFO_LOGONNOTIFY = 0x40;
+    public static final int INFO_ENABLEWINDOWSKEY = 0x100;
+    public static final int INFO_MOUSE_HAS_WHEEL = 0x00020000;
+    public static final int INFO_NOAUDIOPLAYBACK = 0x00080000;
+
+    public static final int PERF_DISABLE_WALLPAPER = 0x1;
+    public static final int PERF_DISABLE_FULLWINDOWDRAG = 0x2;
+    public static final int PERF_DISABLE_MENUANIMATIONS = 0x4;
+
+    protected byte[] userName = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] password = "".getBytes(RdpConstants.CHARSET_16); // No effect
+    protected byte[] alternateShell = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] domain = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] workingDir = "".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] clientAddress = "192.168.0.100".getBytes(RdpConstants.CHARSET_16);
+    protected byte[] clientDir = "C:\\Windows\\System32\\mstscax.dll".getBytes(RdpConstants.CHARSET_16);
+
+    protected String standardTimeZoneName = "EET, Standard Time";
+    protected String daylightTimeZoneName = "EET, Summer Time";
+    protected int standardTimeZoneBias = 0; /* in minutes */
+    protected int daylightTimeZoneBias = 60; /* in minutes */
+
+    public ClientInfoPDU(String id, String userName) {
+        super(id);
+        this.userName = userName.getBytes(RdpConstants.CHARSET_16);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        // Length of packet
+        ByteBuffer buf = new ByteBuffer(1024, true);
+
+        // MCS Send Data Request PDU
+        buf.writeByte(0x64);
+
+        // Initiator: 0x03 + 1001 = 1004
+        buf.writeShort(3);
+
+        // Channel ID: 1003
+        buf.writeShort(1003);
+
+        // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
+        buf.writeByte(0x70);
+
+        // User data length: (variable length field)
+        int length = 224 + userName.length + password.length + alternateShell.length + domain.length + workingDir.length + clientAddress.length + clientDir.length;
+        buf.writeShort(length | 0x8000);
+
+        // Flags: SEC_INFO_PKT (0x4000)
+        buf.writeShort(0x4000);
+
+        // TS_SECURITY_HEADER::flagsHi - ignored
+        buf.writeShort(0x0000);
+
+        // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)
+        buf.writeIntLE(0x0000);
+
+        // Flags
+        buf.writeIntLE(INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE |
+                INFO_MAXIMIZESHELL | INFO_LOGONNOTIFY | INFO_ENABLEWINDOWSKEY |
+                INFO_MOUSE_HAS_WHEEL | INFO_NOAUDIOPLAYBACK);
+
+        //
+        // Lengths
+        //
+
+        // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(domain.length);
+
+        // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(userName.length);
+
+        // cbPassword length: (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(password.length);
+
+        // cbAlternateShell:  (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(alternateShell.length);
+
+        // cbWorkingDir: (LE) (NOT including size of mandatory NULL terminator)
+        buf.writeShortLE(workingDir.length);
+
+        //
+        // Values
+        //
+
+        // Domain: (UCS2), see cbDomain
+        buf.writeBytes(domain);
+        buf.writeShort(0);
+
+        // User name: (UCS2), see cbUserName
+        buf.writeBytes(userName);
+        buf.writeShort(0);
+
+        // Password: (UCS2), see cbPassword
+        buf.writeBytes(password);
+        buf.writeShort(0);
+
+        // Alternate shell: (UCS2), see cbAlternateShell
+        buf.writeBytes(alternateShell);
+        buf.writeShort(0);
+
+        // Working directory: (UCS2), see cbWorkingDir
+        buf.writeBytes(workingDir);
+        buf.writeShort(0);
+
+        // Client address family: 2 (AF_INET, LE)
+        buf.writeShortLE(2);
+
+        // cbClientAddress: ( LE) (including the size of the mandatory NULL terminator)
+        buf.writeShortLE(clientAddress.length + 2);
+
+        // Client address: (UCS2)
+        buf.writeBytes(clientAddress);
+        buf.writeShort(0);
+
+        // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
+        buf.writeShortLE(clientDir.length + 2);
+
+        // Client directory: (UCS2)
+        buf.writeBytes(clientDir);
+        buf.writeShort(0);
+
+        //
+        // Client time zone:
+        //
+
+        // Bias: 0 minutes (LE)
+        buf.writeIntLE(0);
+
+        // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
+        buf.writeFixedString(62, standardTimeZoneName, RdpConstants.CHARSET_16);
+        buf.writeShort(0);
+
+        // Standard date
+        buf.writeBytes(new byte[] {
+                // wYear: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMonth: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte)0x00, (byte)0x00,
+                // wDay: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wHour: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMinute: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wSecond: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMilliseconds: 0
+                (byte)0x00, (byte)0x00,
+
+        });
+
+        // StandardBias: 0 minutes (LE)
+        buf.writeIntLE(standardTimeZoneBias);
+
+        // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
+        buf.writeFixedString(62, daylightTimeZoneName, RdpConstants.CHARSET_16);
+        buf.writeShort(0);
+
+        // Daylight date
+        buf.writeBytes(new byte[] {
+                // wYear: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMonth: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte)0x00, (byte)0x00,
+                // wDay: unknown (LE)
+                (byte)0x00, (byte)0x00,
+                // wHour: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMinute: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wSecond: 0 (LE)
+                (byte)0x00, (byte)0x00,
+                // wMilliseconds: 0
+                (byte)0x00, (byte)0x00,
+
+        });
+
+        // Daylight bias: 60 minutes (LE)
+        buf.writeIntLE(daylightTimeZoneBias);
+
+        // Client session ID: 0x00000000 (LE)
+        buf.writeIntLE(0);
+
+        // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
+        buf.writeIntLE(PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS);
+
+        // cbAutoReconnectCookie: 0 bytes (LE)
+        buf.writeShortLE(0);
+
+        // Trim buffer to actual length of data written
+        buf.trimAtCursor();
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * 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[] {
+
+                // TPKT
+                (byte) 0x03, (byte) 0x00,
+
+                // TPKT length: 343 bytes
+                (byte) 0x01, (byte) 0x57,
+
+                // X224 Data PDU
+                (byte) 0x02, (byte) 0xf0, (byte) 0x80,
+
+
+                // MCS Send Data Request PDU
+                (byte) 0x64,
+
+                // Initiator: 0x03 + 1001 = 1004
+                (byte) 0x00, (byte) 0x03,
+
+                // Channel ID: 1003 (IO Channel)
+                (byte) 0x03, (byte) 0xeb,
+
+                // Data priority: high, segmentation: begin | end (0x40 | 0x20 | 0x10 = 0x70)
+                (byte) 0x70,
+
+                // User data length: 328  (0x148) bytes, variable length field
+                (byte) 0x81, (byte) 0x48,
+
+                // Flags: SEC_INFO_PKT (0x4000)
+                (byte) 0x40, (byte) 0x00,
+
+                // TS_SECURITY_HEADER::flagsHi - ignored
+                (byte) 0x00, (byte) 0x00,
+
+                // Codepage: 0 (UNKNOWN, LE) (use  0x04090409  (1033,1033) for EN_US)
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Flags: 0xa0173 (LE), INFO_MOUSE (0x1), INFO_DISABLECTRLALTDEL (0x2), INFO_UNICODE (0x10),
+                // INFO_MAXIMIZESHELL (0x20), INFO_LOGONNOTIFY (0x40), INFO_ENABLEWINDOWSKEY (0x100),
+                // INFO_MOUSE_HAS_WHEEL (0x00020000), INFO_NOAUDIOPLAYBACK (0x00080000),
+                (byte) 0x73, (byte) 0x01, (byte) 0x0a, (byte) 0x00,
+
+                // Lengths
+
+                // cbDomain length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+                (byte) 0x00, (byte) 0x00,
+
+                // cbUserName length: 16 bytes (0x10, LE) (NOT including size of mandatory NULL terminator)
+                (byte) 0x10, (byte) 0x00,
+
+                // cbPassword length: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+                (byte) 0x00, (byte) 0x00,
+
+                // cbAlternateShell:  0 bytes (LE) (NOT including size of mandatory NULL terminator)
+                (byte) 0x00, (byte) 0x00,
+
+                // cbWorkingDir: 0 bytes (LE) (NOT including size of mandatory NULL terminator)
+                (byte) 0x00, (byte) 0x00,
+
+                // Values
+
+                // Domain: "" (UCS2), see cbDomain
+                (byte) 0x00, (byte) 0x00,
+
+                // User name: "vlisivka" (UCS2), see cbUserName
+                (byte) 0x76, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x73, (byte) 0x00,
+                (byte) 0x69, (byte) 0x00, (byte) 0x76, (byte) 0x00, (byte) 0x6b, (byte) 0x00, (byte) 0x61, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00,
+
+                // Password: "" (UCS2), see cbPassword
+                (byte) 0x00, (byte) 0x00,
+
+                // Alternate shell: "" (UCS2), see cbAlternateShell
+                (byte) 0x00, (byte) 0x00,
+
+                // Working directory: "" (UCS2), see cbWorkingDir
+                (byte) 0x00, (byte) 0x00,
+
+                // Client address family: 2 (AF_INET, LE)
+                (byte) 0x02, (byte) 0x00,
+
+                // cbClientAddress = 28 bytes (0x1c, LE) (including the size of the mandatory NULL terminator)
+                (byte) 0x1c, (byte) 0x00,
+
+                // Client address: "192.168.0.100" (UCS2)
+                (byte) 0x31, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
+                (byte) 0x31, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
+                (byte) 0x30, (byte) 0x00, (byte) 0x2e, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x30, (byte) 0x00,
+                (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // cbClientDir: 64 bytes (0x40, LE) (including the size of the mandatory NULL terminator)
+                (byte) 0x40, (byte) 0x00,
+
+                // Client directory: "C:\Windows\System32\mstscax.dll" (UCS2)
+                (byte) 0x43, (byte) 0x00, (byte) 0x3a, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x57, (byte) 0x00,
+                (byte) 0x69, (byte) 0x00, (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x6f, (byte) 0x00,
+                (byte) 0x77, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x5c, (byte) 0x00, (byte) 0x53, (byte) 0x00,
+                (byte) 0x79, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x65, (byte) 0x00,
+                (byte) 0x6d, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x32, (byte) 0x00, (byte) 0x5c, (byte) 0x00,
+                (byte) 0x6d, (byte) 0x00, (byte) 0x73, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x73, (byte) 0x00,
+                (byte) 0x63, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x78, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
+                (byte) 0x64, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x6c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                //
+                // Client time zone:
+
+                // Bias: 0 minutes (LE)
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Standard name: "EET, Standard Time" (fixed string: 64 bytes, UCS2)
+                (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00,
+                (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x74, (byte) 0x00, (byte) 0x61, (byte) 0x00,
+                (byte) 0x6e, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x61, (byte) 0x00, (byte) 0x72, (byte) 0x00,
+                (byte) 0x64, (byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00,
+                (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                //
+                // Standard date
+                // wYear: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMonth: unknown (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wDay: unknown (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wHour: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMinute: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wSecond: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMilliseconds: 0
+                (byte) 0x00, (byte) 0x00,
+
+                // StandardBias: 0 minutes (LE)
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Daylight name: "EET, Summer Time" (fixed string: 64 bytes, UCS2)
+                (byte) 0x45, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x54, (byte) 0x00, (byte) 0x2c, (byte) 0x00,
+                (byte) 0x20, (byte) 0x00, (byte) 0x53, (byte) 0x00, (byte) 0x75, (byte) 0x00, (byte) 0x6d, (byte) 0x00,
+                (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00, (byte) 0x72, (byte) 0x00, (byte) 0x20, (byte) 0x00,
+                (byte) 0x54, (byte) 0x00, (byte) 0x69, (byte) 0x00, (byte) 0x6d, (byte) 0x00, (byte) 0x65, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Daylight date
+                // wYear: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMonth: unknown (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wDayOfWeek: Sunday (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wDay: unknown (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wHour: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMinute: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wSecond: 0 (LE)
+                (byte) 0x00, (byte) 0x00,
+                // wMilliseconds: 0
+                (byte) 0x00, (byte) 0x00,
+
+                // Daylight bias: 60 minutes (LE)
+                (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+
+                // Client session ID: 0x00000000 (LE)
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // Performance flags: 0x7 (LE) = PERF_DISABLE_WALLPAPER (0x1), PERF_DISABLE_FULLWINDOWDRAG (0x2), PERF_DISABLE_MENUANIMATIONS (0x4)
+                (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // cbAutoReconnectCookie: 0 bytes (LE)
+                (byte) 0x00, (byte) 0x00,
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element client_info = new ClientInfoPDU("client_info", "vlisivka");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, client_info, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "client_info", "mainSink");
+        pipeline.link("client_info >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
new file mode 100755
index 0000000..47a07da
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ClientMCSAttachUserRequest.java
@@ -0,0 +1,103 @@
+// 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.rdp;
+
+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/cc240684.aspx
+ */
+public class ClientMCSAttachUserRequest extends OneTimeSwitch {
+
+    public ClientMCSAttachUserRequest(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        throw new RuntimeException("Unexpected packet: " + buf + ".");
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        int length = 1;
+        ByteBuffer buf = new ByteBuffer(length, true);
+
+        buf.writeByte(0x28); // AttachUserRequest
+
+        pushDataToOTOut(buf);
+
+        switchOff();
+    }
+
+    /**
+     * 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[] {
+
+                0x03, 0x00, 0x00, 0x08,  //  TPKT Header (length = 8 bytes)
+                0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
+
+                // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
+                0x28,
+
+                // 0x28:
+                // 0 - --\
+                // 0 -   |
+                // 1 -   | CHOICE: From DomainMCSPDU select attachUserRequest (10)
+                // 0 -   | of type AttachUserRequest
+                // 1 -   |
+                // 0 - --/
+                // 0 - padding
+                // 0 - padding
+
+        };
+        /* @formatter:on */
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+        Element todo = new ClientMCSAttachUserRequest("TODO");
+        Element x224 = new ClientX224DataPDU("x224");
+        Element tpkt = new ClientTpkt("tpkt");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
+        pipeline.link("source", "TODO", "mainSink");
+        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}


[02/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
deleted file mode 100644
index 25631c2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
+++ /dev/null
@@ -1,245 +0,0 @@
-// 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 vncclient;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.ScreenDescription;
-
-public class VncInitializer extends OneTimeSwitch {
-
-    // Pad names
-    public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
-    public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
-
-    protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-
-    /**
-     * Properties of remote screen .
-     */
-    protected ScreenDescription screen;
-
-    public VncInitializer(String id, boolean shared, ScreenDescription screen) {
-        super(id);
-
-        setSharedFlag(shared);
-        this.screen = screen;
-
-        declarePads();
-    }
-
-    @Override
-    protected void declarePads() {
-        super.declarePads();
-        outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
-        outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
-    }
-
-    public ScreenDescription getScreen() {
-        return screen;
-    }
-
-    public void setScreen(ScreenDescription screen) {
-        this.screen = screen;
-    }
-
-    public void setSharedFlag(boolean shared) {
-        if (shared)
-            sharedFlag = RfbConstants.SHARED_ACCESS;
-        else
-            sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Server initialization message is at least 24 bytes long + length of
-        // desktop name
-        if (!cap(buf, 24, UNLIMITED, link, false))
-            return;
-
-        // Read server initialization message
-        // Read frame buffer size
-        int framebufferWidth = buf.readUnsignedShort();
-        int framebufferHeight = buf.readUnsignedShort();
-
-        // Read pixel format
-        int bitsPerPixel = buf.readUnsignedByte();
-        int depth = buf.readUnsignedByte();
-
-        int bigEndianFlag = buf.readUnsignedByte();
-        int trueColorFlag = buf.readUnsignedByte();
-
-        int redMax = buf.readUnsignedShort();
-        int greenMax = buf.readUnsignedShort();
-        int blueMax = buf.readUnsignedShort();
-
-        int redShift = buf.readUnsignedByte();
-        int greenShift = buf.readUnsignedByte();
-        int blueShift = buf.readUnsignedByte();
-
-        // Skip padding
-        buf.skipBytes(3);
-
-        // Read desktop name
-        int length = buf.readSignedInt();
-
-        // Consume exactly $length bytes, push back any extra bytes
-        if (!cap(buf, length, length, link, true))
-            return;
-
-        String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-        buf.unref();
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: " +
-                framebufferWidth + "x" + framebufferHeight + ".");
-
-        // Set screen properties
-        screen.setFramebufferSize(framebufferWidth, framebufferHeight);
-        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColorFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax,
-            redShift, greenShift, blueShift);
-        screen.setDesktopName(desktopName);
-
-        // If sever screen has different parameters than ours, then change it
-        if (!screen.isRGB888_32_LE()) {
-            // Send client pixel format
-            sendClientPixelFormat();
-        }
-
-        // Send encodings supported by client
-        sendSupportedEncodings();
-
-        switchOff();
-
-    }
-
-    @Override
-    protected void onStart() {
-        ByteBuffer buf = new ByteBuffer(new byte[] {sharedFlag});
-        pushDataToOTOut(buf);
-    }
-
-    private void sendClientPixelFormat() {
-        pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
-    }
-
-    private void sendSupportedEncodings() {
-        pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
-    }
-
-    @Override
-    public String toString() {
-        return "VncInit(" + id + ")";
-    }
-
-    /**
-     * 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");
-
-        final String desktopName = "test";
-
-        Element source = new MockSource("source") {
-            {
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(
-                    // Send screen description
-                    new byte[] {
-                        // Framebuffer width (short)
-                        0, (byte)200,
-                        // Framebuffer height (short)
-                        0, 100,
-                        // Bits per pixel
-                        32,
-                        // Depth,
-                        24,
-                        // Endianness flag
-                        RfbConstants.LITTLE_ENDIAN,
-                        // Truecolor flag
-                        RfbConstants.TRUE_COLOR,
-                        // Red max (short)
-                        0, (byte)255,
-                        // Green max (short)
-                        0, (byte)255,
-                        // Blue max (short)
-                        0, (byte)255,
-                        // Red shift
-                        16,
-                        // Green shift
-                        8,
-                        // Blue shift
-                        0,
-                        // Padding
-                        0, 0, 0,
-                        // Desktop name length (int)
-                        0, 0, 0, 4,
-                        // Desktop name ("test", 4 bytes)
-                        't', 'e', 's', 't',
-
-                        // Tail
-                        1, 2, 3
-
-                    },
-                    // Tail packet
-                    new byte[] {4, 5, 6});
-            }
-        };
-
-        ScreenDescription screen = new ScreenDescription();
-        final VncInitializer init = new VncInitializer("init", true, screen);
-        Element initSink = new MockSink("initSink") {
-            {
-                // Expect shared flag
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {RfbConstants.SHARED_ACCESS});
-            }
-        };
-        Element mainSink = new MockSink("mainSink") {
-            {
-                // Expect two tail packets
-                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}, new byte[] {4, 5, 6});
-            }
-        };
-        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-        Element encodingsSink = new MockSink("encodings", emptyBuf);
-        Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, init, mainSink);
-        pipeline.add(encodingsSink, pixelFormatSink, initSink);
-        pipeline.link("init >otout", "initSink");
-        pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
-        pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-        if (!screen.isRGB888_32_LE())
-            System.err.println("Screen description was read incorrectly: " + screen + ".");
-        if (!desktopName.equals(screen.getDesktopName()))
-            System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
deleted file mode 100644
index 6421fb2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
+++ /dev/null
@@ -1,420 +0,0 @@
-// 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 vncclient;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.BitmapOrder;
-import common.BitmapRectangle;
-import common.CopyRectOrder;
-import common.ScreenDescription;
-
-public class VncMessageHandler extends BaseElement {
-    protected ScreenDescription screen = null;
-
-    // Pad names
-    public static final String SERVER_BELL_ADAPTER_PAD = "bell";
-    public static final String SERVER_CLIPBOARD_ADAPTER_PAD = "clipboard";
-    public static final String PIXEL_ADAPTER_PAD = "pixels";
-    public static final String FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD = "fbur";
-
-    // Keys for metadata
-    public static final String CLIPBOARD_CONTENT = "content";
-    public static final String TARGET_X = "x";
-    public static final String TARGET_Y = "y";
-    public static final String WIDTH = "width";
-    public static final String HEIGHT = "height";
-    public static final String SOURCE_X = "srcX";
-    public static final String SOURCE_Y = "srcY";
-    public static final String PIXEL_FORMAT = "pixel_format";
-
-    private static final String NUM_OF_PROCESSED_RECTANGLES = "rects";
-    private static final String SAVED_CURSOR_POSITION = "cursor";
-
-    // Pixel format: RGB888 LE 32
-    public static final String RGB888LE32 = "RGB888LE32";
-
-    public VncMessageHandler(String id, ScreenDescription screen) {
-        super(id);
-        this.screen = screen;
-        declarePads();
-    }
-
-    private void declarePads() {
-        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-        outputPads.put(SERVER_BELL_ADAPTER_PAD, null);
-        outputPads.put(SERVER_CLIPBOARD_ADAPTER_PAD, null);
-        outputPads.put(PIXEL_ADAPTER_PAD, null);
-        outputPads.put(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, null);
-
-        inputPads.put("stdin", null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        try {
-            if (verbose)
-                System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-            if (!cap(buf, 1, UNLIMITED, link, false))
-                return;
-
-            // Read server message type
-            int messageType = buf.readUnsignedByte();
-
-            // Invoke packet handler by packet type.
-            switch (messageType) {
-
-                case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
-                    // Handle frame buffer update
-                    if (!handleFBU(buf, link))
-                        return;
-
-                    // Frame buffer update is received and fully processed, send request for
-                    // another frame buffer update to server.
-                    sendFBUR();
-
-                    break;
-                }
-
-                case RfbConstants.SERVER_BELL: {
-                    if (!handleBell(buf, link))
-                        return;
-                    break;
-                }
-
-                case RfbConstants.SERVER_CUT_TEXT: {
-                    if (!handleClipboard(buf, link))
-                        return;
-                    break;
-                }
-
-                default:
-                    // TODO: allow to extend functionality
-                    throw new RuntimeException("Unknown server packet type: " + messageType + ".");
-            }
-
-            // Cut tail, if any
-            cap(buf, 0, 0, link, true);
-        } finally {
-
-            // Return processed buffer back to pool
-            buf.unref();
-        }
-    }
-
-    private boolean handleClipboard(ByteBuffer buf, Link link) {
-        if (!cap(buf, 3 + 4, UNLIMITED, link, true))
-            return false;
-
-        // Skip padding
-        buf.skipBytes(3);
-
-        // Read text length
-        int length = buf.readSignedInt();
-
-        // We need full string to parse it
-        if (!cap(buf, length, UNLIMITED, link, true))
-            return false;
-
-        String content = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
-
-        // Send content in metadata
-        ByteBuffer outBuf = new ByteBuffer(0);
-        outBuf.putMetadata(CLIPBOARD_CONTENT, content);
-
-        pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
-
-        return true;
-    }
-
-    private boolean handleBell(ByteBuffer buf, Link link) {
-        // Send empty packet to bell adapter to produce bell
-        pushDataToPad(SERVER_BELL_ADAPTER_PAD, new ByteBuffer(0));
-
-        return true;
-    }
-
-    // FIXME: this method is too complex
-    private boolean handleFBU(ByteBuffer buf, Link link) {
-
-        // We need at least 3 bytes here, 1 - padding, 2 - number of rectangles
-        if (!cap(buf, 3, UNLIMITED, link, true))
-            return false;
-
-        buf.skipBytes(1);// Skip padding
-
-        // Read number of rectangles
-        int numberOfRectangles = buf.readUnsignedShort();
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Frame buffer update. Number of rectangles: " + numberOfRectangles + ".");
-
-        // Each rectangle must have header at least, header length is 12 bytes.
-        if (!cap(buf, 12 * numberOfRectangles, UNLIMITED, link, true))
-            return false;
-
-        // For all rectangles
-
-        // Restore saved point, to avoid flickering and performance problems when
-        // frame buffer update is split between few incoming packets.
-        int numberOfProcessedRectangles = (buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) != null) ? (Integer)buf.getMetadata(NUM_OF_PROCESSED_RECTANGLES) : 0;
-        if (buf.getMetadata(SAVED_CURSOR_POSITION) != null)
-            buf.cursor = (Integer)buf.getMetadata(SAVED_CURSOR_POSITION);
-
-        if (verbose && numberOfProcessedRectangles > 0)
-            System.out.println("[" + this + "] INFO: Restarting from saved point. Number of already processed rectangles: " + numberOfRectangles + ", cursor: " +
-                buf.cursor + ".");
-
-        // For all new rectangles
-        for (int i = numberOfProcessedRectangles; i < numberOfRectangles; i++) {
-
-            // We need coordinates of rectangle (2x4 bytes) and encoding type (4
-            // bytes)
-            if (!cap(buf, 12, UNLIMITED, link, true))
-                return false;
-
-            // Read coordinates of rectangle
-            int x = buf.readUnsignedShort();
-            int y = buf.readUnsignedShort();
-            int width = buf.readUnsignedShort();
-            int height = buf.readUnsignedShort();
-
-            // Read rectangle encoding
-            int encodingType = buf.readSignedInt();
-
-            // Process rectangle
-            switch (encodingType) {
-
-                case RfbConstants.ENCODING_RAW: {
-                    if (!handleRawRectangle(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                case RfbConstants.ENCODING_COPY_RECT: {
-                    if (!handleCopyRect(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                case RfbConstants.ENCODING_DESKTOP_SIZE: {
-                    if (!handleScreenSizeChangeRect(buf, link, x, y, width, height))
-                        return false;
-                    break;
-                }
-
-                default:
-                    // TODO: allow to extend functionality
-                    throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
-            }
-
-            // Update information about processed rectangles to avoid handling of same
-            // rectangle multiple times.
-            // TODO: push back partial rectangle only instead
-            buf.putMetadata(NUM_OF_PROCESSED_RECTANGLES, ++numberOfProcessedRectangles);
-            buf.putMetadata(SAVED_CURSOR_POSITION, buf.cursor);
-        }
-
-        return true;
-    }
-
-    private boolean handleScreenSizeChangeRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Remote screen size is changed
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Screen size rect. Width: " + width + ", height: " + height + ".");
-
-        screen.setFramebufferSize(width, height);
-
-        return true;
-    }
-
-    private boolean handleCopyRect(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Copy rectangle from one part of screen to another.
-        // Areas may overlap. Antialiasing may cause visible artifacts.
-
-        // We need 4 bytes with coordinates of source rectangle
-        if (!cap(buf, 4, UNLIMITED, link, true))
-            return false;
-
-        CopyRectOrder order = new CopyRectOrder();
-
-        order.srcX = buf.readUnsignedShort();
-        order.srcY = buf.readUnsignedShort();
-        order.x = x;
-        order.y = y;
-        order.width = width;
-        order.height = height;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Copy rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", srcX: " + order.srcX +
-                ", srcY: " + order.srcY + ".");
-
-        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-
-        return true;
-    }
-
-    private boolean handleRawRectangle(ByteBuffer buf, Link link, int x, int y, int width, int height) {
-        // Raw rectangle is just array of pixels to draw on screen.
-        int rectDataLength = width * height * screen.getBytesPerPixel();
-
-        // We need at least rectDataLength bytes. Extra bytes may contain other
-        // rectangles.
-        if (!cap(buf, rectDataLength, UNLIMITED, link, true))
-            return false;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: " + rectDataLength +
-                ".");
-
-        BitmapRectangle rectangle = new BitmapRectangle();
-        rectangle.x = x;
-        rectangle.y = y;
-        rectangle.width = width;
-        rectangle.height = height;
-        rectangle.bufferWidth = width;
-        rectangle.bufferHeight = height;
-        rectangle.bitmapDataStream = buf.readBytes(rectDataLength);
-        rectangle.colorDepth = screen.getColorDeph();
-
-        BitmapOrder order = new BitmapOrder();
-        order.rectangles = new BitmapRectangle[] {rectangle};
-
-        pushDataToPad(PIXEL_ADAPTER_PAD, new ByteBuffer(order));
-        return true;
-    }
-
-    @Override
-    public void onStart() {
-        // Send Frame Buffer Update request
-        sendFBUR();
-    }
-
-    private void sendFBUR() {
-        ByteBuffer buf = new ByteBuffer(0);
-        buf.putMetadata("incremental", true);
-        pushDataToPad(FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, buf);
-    }
-
-    @Override
-    public String toString() {
-        return "VNCMessageHandler(" + id + ")";
-    }
-
-    /**
-     * 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");
-
-        Element source = new MockSource("source") {
-            {
-                // Split messages at random boundaries to check "pushback" logic
-                bufs =
-                    ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-                        // Message type: server bell
-                        RfbConstants.SERVER_BELL,
-
-                        // Message type: clipboard text
-                        RfbConstants.SERVER_CUT_TEXT,
-                        // Padding
-                        0, 0, 0,
-                        // Length (test)
-                        0, 0, 0, 4,
-
-                    }, new byte[] {
-                        // Clipboard text
-                        't', 'e', 's', 't',
-
-                        // Message type: frame buffer update
-                        RfbConstants.SERVER_FRAMEBUFFER_UPDATE,
-                        // Padding
-                        0,
-                        // Number of rectangles
-                        0, 3,},
-
-                        new byte[] {
-
-                            // x, y, width, height: 0x0@4x4
-                            0, 0, 0, 0, 0, 4, 0, 4,
-                            // Encoding: desktop size
-                            (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 24) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 8) & 0xff), (byte)((RfbConstants.ENCODING_DESKTOP_SIZE >> 0) & 0xff),},
-
-                        new byte[] {
-
-                            // x, y, width, height: 0x0@4x4
-                            0, 0, 0, 0, 0, 4, 0, 4,
-                            // Encoding: raw rect
-                            (byte)((RfbConstants.ENCODING_RAW >> 24) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_RAW >> 8) & 0xff), (byte)((RfbConstants.ENCODING_RAW >> 0) & 0xff),
-                            // Raw pixel data 4x4x1 bpp
-                            1, 2, 3, 4, 5, 6, 7, 8, 9, 10,}, new byte[] {11, 12, 13, 14, 15, 16,
-
-                            // x, y, width, height: 0x0@2x2
-                            0, 0, 0, 0, 0, 2, 0, 2,
-                            // Encoding: copy rect
-                            (byte)((RfbConstants.ENCODING_COPY_RECT >> 24) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 16) & 0xff),
-                            (byte)((RfbConstants.ENCODING_COPY_RECT >> 8) & 0xff), (byte)((RfbConstants.ENCODING_COPY_RECT >> 0) & 0xff),
-                            // srcX, srcY: 2x2
-                            0, 2, 0, 2,});
-            }
-        };
-
-        ScreenDescription screen = new ScreenDescription() {
-            {
-                this.bytesPerPixel = 1;
-            }
-        };
-
-        final Element handler = new VncMessageHandler("handler", screen);
-
-        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
-        Element fburSink = new MockSink("fbur", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {}, new byte[] {}));
-        Element bellSink = new MockSink("bell", emptyBuf);
-        Element clipboardSink = new MockSink("clipboard", emptyBuf);
-        Element desktopSizeChangeSink = new MockSink("desktop_size", emptyBuf);
-        Element pixelsSink = new MockSink("pixels", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,}));
-        Element copyRectSink = new MockSink("copy_rect", emptyBuf);
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, handler);
-        pipeline.add(fburSink, bellSink, clipboardSink, desktopSizeChangeSink, pixelsSink, copyRectSink);
-
-        pipeline.link("handler >" + FRAME_BUFFER_UPDATE_REQUEST_ADAPTER_PAD, "fbur");
-        pipeline.link("handler >" + SERVER_BELL_ADAPTER_PAD, "bell");
-        pipeline.link("handler >" + SERVER_CLIPBOARD_ADAPTER_PAD, "clipboard");
-        pipeline.link("handler >" + PIXEL_ADAPTER_PAD, "pixels");
-
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
new file mode 100755
index 0000000..6b50e35
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncKeyboardAdapter.java
@@ -0,0 +1,369 @@
+// 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 vncclient.adapter;
+
+import java.awt.event.KeyEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+import common.KeyOrder;
+
+public class AwtVncKeyboardAdapter extends BaseElement {
+
+    protected boolean sh = false;
+    protected boolean caps = false;
+    protected boolean num = false;
+
+    public AwtVncKeyboardAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        KeyOrder order = (KeyOrder)buf.getOrder();
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(8);
+        outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
+
+        outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
+        outBuf.writeShort(0); // padding
+        outBuf.writeInt(map_en_us(order));
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Return key scan code (in lower byte) and extended flags (in second byte).
+     */
+    private int map_en_us(KeyOrder order) {
+
+        switch (order.event.getKeyCode()) {
+        // Functional keys
+        case KeyEvent.VK_ESCAPE:
+            return 0xff1b;
+        case KeyEvent.VK_F1:
+            return 0xffbe;
+        case KeyEvent.VK_F2:
+            return 0xffbf;
+        case KeyEvent.VK_F3:
+            return 0xffc0;
+        case KeyEvent.VK_F4:
+            return 0xffc1;
+        case KeyEvent.VK_F5:
+            return 0xffc2;
+        case KeyEvent.VK_F6:
+            return 0xffc3;
+        case KeyEvent.VK_F7:
+            return 0xffc4;
+        case KeyEvent.VK_F8:
+            return 0xffc5;
+        case KeyEvent.VK_F9:
+            return 0xffc6;
+        case KeyEvent.VK_F10:
+            return 0xffc7;
+        case KeyEvent.VK_F11:
+            return 0xffc8;
+        case KeyEvent.VK_F12:
+            return 0xffc9;
+
+            // Row #1
+        case KeyEvent.VK_BACK_QUOTE:
+            return (sh) ? '~' : '`';
+        case KeyEvent.VK_1:
+            return (sh) ? '!' : '1';
+        case KeyEvent.VK_2:
+            return (sh) ? '@' : '2';
+        case KeyEvent.VK_3:
+            return (sh) ? '#' : '3';
+        case KeyEvent.VK_4:
+            return (sh) ? '$' : '4';
+        case KeyEvent.VK_5:
+            return (sh) ? '%' : '5';
+        case KeyEvent.VK_6:
+            return (sh) ? '^' : '6';
+        case KeyEvent.VK_7:
+            return (sh) ? '&' : '7';
+        case KeyEvent.VK_8:
+            return (sh) ? '*' : '8';
+        case KeyEvent.VK_9:
+            return (sh) ? '(' : '9';
+        case KeyEvent.VK_0:
+            return (sh) ? ')' : '0';
+        case KeyEvent.VK_MINUS:
+            return (sh) ? '_' : '-';
+        case KeyEvent.VK_EQUALS:
+            return (sh) ? '+' : '=';
+        case KeyEvent.VK_BACK_SPACE:
+            return 0xff08;
+
+            // Row #2
+        case KeyEvent.VK_TAB:
+            return 0xff09;
+        case KeyEvent.VK_Q:
+            return (sh ^ caps) ? 'Q' : 'q';
+        case KeyEvent.VK_W:
+            return (sh ^ caps) ? 'W' : 'w';
+        case KeyEvent.VK_E:
+            return (sh ^ caps) ? 'E' : 'e';
+        case KeyEvent.VK_R:
+            return (sh ^ caps) ? 'R' : 'r';
+        case KeyEvent.VK_T:
+            return (sh ^ caps) ? 'T' : 't';
+        case KeyEvent.VK_Y:
+            return (sh ^ caps) ? 'Y' : 'y';
+        case KeyEvent.VK_U:
+            return (sh ^ caps) ? 'U' : 'u';
+        case KeyEvent.VK_I:
+            return (sh ^ caps) ? 'I' : 'i';
+        case KeyEvent.VK_O:
+            return (sh ^ caps) ? 'O' : 'o';
+        case KeyEvent.VK_P:
+            return (sh ^ caps) ? 'P' : 'p';
+        case KeyEvent.VK_OPEN_BRACKET:
+            return (sh) ? '{' : '[';
+        case KeyEvent.VK_CLOSE_BRACKET:
+            return (sh) ? '{' : ']';
+        case KeyEvent.VK_ENTER:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_STANDARD:
+                return 0xff0d;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xff8d;
+            }
+
+            // Row #3
+        case KeyEvent.VK_CAPS_LOCK:
+            if (order.pressed)
+                caps = !caps;
+            return 0xFFE5;
+        case KeyEvent.VK_A:
+            return (sh ^ caps) ? 'A' : 'a';
+        case KeyEvent.VK_S:
+            return (sh ^ caps) ? 'S' : 's';
+        case KeyEvent.VK_D:
+            return (sh ^ caps) ? 'D' : 'd';
+        case KeyEvent.VK_F:
+            return (sh ^ caps) ? 'F' : 'f';
+        case KeyEvent.VK_G:
+            return (sh ^ caps) ? 'G' : 'g';
+        case KeyEvent.VK_H:
+            return (sh ^ caps) ? 'H' : 'h';
+        case KeyEvent.VK_J:
+            return (sh ^ caps) ? 'J' : 'j';
+        case KeyEvent.VK_K:
+            return (sh ^ caps) ? 'K' : 'k';
+        case KeyEvent.VK_L:
+            return (sh ^ caps) ? 'L' : 'l';
+        case KeyEvent.VK_SEMICOLON:
+            return (sh) ? ':' : ';';
+        case KeyEvent.VK_QUOTE:
+            return (sh) ? '"' : '\'';
+
+            // Row #4
+        case KeyEvent.VK_SHIFT:
+            sh = !sh;
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xffe1;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xffe2;
+            }
+        case KeyEvent.VK_BACK_SLASH:
+            return (sh) ? '|' : '\\';
+        case KeyEvent.VK_Z:
+            return (sh ^ caps) ? 'Z' : 'z';
+        case KeyEvent.VK_X:
+            return (sh ^ caps) ? 'X' : 'x';
+        case KeyEvent.VK_C:
+            return (sh ^ caps) ? 'C' : 'c';
+        case KeyEvent.VK_V:
+            return (sh ^ caps) ? 'V' : 'v';
+        case KeyEvent.VK_B:
+            return (sh ^ caps) ? 'B' : 'b';
+        case KeyEvent.VK_N:
+            return (sh ^ caps) ? 'N' : 'n';
+        case KeyEvent.VK_M:
+            return (sh ^ caps) ? 'M' : 'M';
+        case KeyEvent.VK_COMMA:
+            return (sh) ? '<' : ',';
+        case KeyEvent.VK_PERIOD:
+            return (sh) ? '>' : '.';
+        case KeyEvent.VK_SLASH:
+            return (sh) ? '?' : '/';
+
+            //
+            // Bottom row
+        case KeyEvent.VK_CONTROL:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE3;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE4;
+            }
+        case KeyEvent.VK_WINDOWS:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFED; // HyperL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEE; // HyperR
+            }
+        case KeyEvent.VK_META:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE7; // MetaL
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFE8; // MetaR
+            }
+
+        case KeyEvent.VK_ALT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xFFE9;
+            case KeyEvent.KEY_LOCATION_RIGHT:
+                return 0xFFEA;
+            }
+        case KeyEvent.VK_ALT_GRAPH:
+            return 0xfe03;
+
+        case KeyEvent.VK_SPACE:
+            return ' ';
+
+        case KeyEvent.VK_CONTEXT_MENU:
+            return 0xff67;
+
+            //
+            // Special keys
+        case KeyEvent.VK_PRINTSCREEN:
+            return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
+        case KeyEvent.VK_SCROLL_LOCK:
+            return 0xFF14;
+        case KeyEvent.VK_PAUSE:
+            return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
+
+            // Text navigation keys
+        case KeyEvent.VK_INSERT:
+            return 0xff63;
+        case KeyEvent.VK_DELETE:
+            return 0xffff;
+        case KeyEvent.VK_HOME:
+            return 0xff50;
+        case KeyEvent.VK_END:
+            return 0xff57;
+        case KeyEvent.VK_PAGE_UP:
+            return 0xff55;
+        case KeyEvent.VK_PAGE_DOWN:
+            return 0xff56;
+
+            // Cursor keys
+        case KeyEvent.VK_LEFT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff51;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF96;
+            }
+        case KeyEvent.VK_UP:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff52;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF97;
+            }
+        case KeyEvent.VK_RIGHT:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff53;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF98;
+            }
+        case KeyEvent.VK_DOWN:
+            switch (order.event.getKeyLocation()) {
+            default:
+            case KeyEvent.KEY_LOCATION_LEFT:
+                return 0xff54;
+            case KeyEvent.KEY_LOCATION_NUMPAD:
+                return 0xFF99;
+            }
+
+            // Keypad
+        case KeyEvent.VK_NUM_LOCK:
+            if (order.pressed)
+                num = !num;
+            return 0xFF6F;
+        case KeyEvent.VK_DIVIDE:
+            return 0xFFAF;
+        case KeyEvent.VK_MULTIPLY:
+            return 0xFFAA;
+        case KeyEvent.VK_SUBTRACT:
+            return 0xFFAD;
+        case KeyEvent.VK_ADD:
+            return 0xFFAB;
+
+        case KeyEvent.VK_KP_LEFT:
+            return 0xFF96;
+        case KeyEvent.VK_KP_UP:
+            return 0xFF97;
+        case KeyEvent.VK_KP_RIGHT:
+            return 0xFF98;
+        case KeyEvent.VK_KP_DOWN:
+            return 0xFF99;
+
+        case KeyEvent.VK_NUMPAD0:
+            return 0xFFB0;
+        case KeyEvent.VK_NUMPAD1:
+            return 0xFFB1;
+        case KeyEvent.VK_NUMPAD2:
+            return 0xFFB2;
+        case KeyEvent.VK_NUMPAD3:
+            return 0xFFB3;
+        case KeyEvent.VK_NUMPAD4:
+            return 0xFFB4;
+        case KeyEvent.VK_NUMPAD5:
+            return 0xFFB5;
+        case KeyEvent.VK_NUMPAD6:
+            return 0xFFB6;
+        case KeyEvent.VK_NUMPAD7:
+            return 0xFFB7;
+        case KeyEvent.VK_NUMPAD8:
+            return 0xFFB8;
+        case KeyEvent.VK_NUMPAD9:
+            return 0xFFB9;
+        case KeyEvent.VK_DECIMAL:
+            return 0xFFAE;
+
+        default:
+            System.err.println("Key is not mapped: " + order + ".");
+            return ' '; // Space
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
new file mode 100755
index 0000000..59216d3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.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.
+package vncclient.adapter;
+
+import java.awt.event.InputEvent;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import vncclient.vnc.RfbConstants;
+import common.MouseOrder;
+
+public class AwtVncMouseAdapter extends BaseElement {
+
+    public AwtVncMouseAdapter(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Get mouse event
+        MouseOrder order = (MouseOrder)buf.getOrder();
+
+        ByteBuffer outBuf = new ByteBuffer(6);
+
+        outBuf.writeByte(RfbConstants.CLIENT_POINTER_EVENT);
+
+        int buttonMask = mapAwtModifiersToVncButtonMask(order.event.getModifiersEx());
+        outBuf.writeByte(buttonMask);
+        outBuf.writeShort(order.event.getX());
+        outBuf.writeShort(order.event.getY());
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    /**
+     * Current state of buttons 1 to 8 are represented by bits 0 to 7 of
+     * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a
+     * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and
+     * right buttons on the mouse. On a wheel mouse, each step of the wheel
+     * upwards is represented by a press and release of button 4, and each step
+     * downwards is represented by a press and release of button 5.
+     *
+     * @param modifiers
+     *          extended modifiers from AWT mouse event
+     * @return VNC mouse button mask
+     */
+    public static int mapAwtModifiersToVncButtonMask(int modifiers) {
+        int mask = (((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0)
+                | (((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0);
+        return mask;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
new file mode 100755
index 0000000..5dfa831
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
@@ -0,0 +1,63 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class EncodingsMessage extends BaseElement {
+
+    protected final int[] encodings;
+
+    public EncodingsMessage(String id, int[] encodings) {
+        super(id);
+        this.encodings = encodings;
+        declarePads();
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(4 + encodings.length * 4);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_ENCODINGS);
+
+        outBuf.writeByte(0);// padding
+
+        outBuf.writeShort(encodings.length);
+
+        for (int i = 0; i < encodings.length; i++) {
+            outBuf.writeInt(encodings[i]);
+        }
+
+        pushDataToAllOuts(outBuf);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
new file mode 100755
index 0000000..ee94c60
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
@@ -0,0 +1,126 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import common.ScreenDescription;
+
+public class FrameBufferUpdateRequest extends BaseElement {
+    // TODO: use object with fields instead of raw values in map
+    public static final String INCREMENTAL_UPDATE = "incremental";
+    public static final String TARGET_X = "x";
+    public static final String TARGET_Y = "y";
+    public static final String WIDTH = "width";
+    public static final String HEIGHT = "height";
+
+    protected ScreenDescription screen;
+
+    public FrameBufferUpdateRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        Boolean incremental = (Boolean)buf.getMetadata(INCREMENTAL_UPDATE);
+        Integer x = (Integer)buf.getMetadata(TARGET_X);
+        Integer y = (Integer)buf.getMetadata(TARGET_Y);
+        Integer width = (Integer)buf.getMetadata(WIDTH);
+        Integer height = (Integer)buf.getMetadata(HEIGHT);
+        buf.unref();
+
+        // Set default values when parameters are not set
+        if (incremental == null)
+            incremental = false;
+
+        if (x == null)
+            x = 0;
+        if (y == null)
+            y = 0;
+
+        if (width == null)
+            width = screen.getFramebufferWidth();
+        if (height == null)
+            height = screen.getFramebufferHeight();
+
+        ByteBuffer outBuf = new ByteBuffer(10);
+
+        outBuf.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST);
+        outBuf.writeByte((incremental) ? RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST : RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST);
+        outBuf.writeShort(x);
+        outBuf.writeShort(y);
+        outBuf.writeShort(width);
+        outBuf.writeShort(height);
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("dimensions", width + "x" + height + "@" + x + "x" + y);
+        }
+
+        pushDataToAllOuts(outBuf);
+    }
+
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        ScreenDescription screen = new ScreenDescription();
+        screen.setFramebufferSize(120, 80);
+        Element adapter = new FrameBufferUpdateRequest("renderer", screen);
+
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Request
+                RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST,
+                // Full update (redraw area)
+                RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST,
+                // X
+                0, 1,
+                // Y
+                0, 2,
+                // Width
+                0, 3,
+                // Height
+                0, 4}));
+
+        ByteBuffer buf = new ByteBuffer(new byte[0]);
+        buf.putMetadata(TARGET_X, 1);
+        buf.putMetadata(TARGET_Y, 2);
+        buf.putMetadata(WIDTH, 3);
+        buf.putMetadata(HEIGHT, 4);
+
+        Element source = new MockSource("source", new ByteBuffer[] {buf});
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(source, adapter, sink);
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
new file mode 100755
index 0000000..2350f14
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
@@ -0,0 +1,89 @@
+// 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 vncclient.vnc;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import common.ScreenDescription;
+
+public class RGB888LE32PixelFormatRequest extends BaseElement {
+    protected int bitsPerPixel = 32;
+    protected int depth = 24;
+    protected int bigEndianFlag = RfbConstants.LITTLE_ENDIAN;
+    protected int trueColourFlag = RfbConstants.TRUE_COLOR;
+    protected int redMax = 255;
+    protected int greenMax = 255;
+    protected int blueMax = 255;
+    protected int redShift = 0;
+    protected int greenShift = 8;
+    protected int blueShift = 16;
+
+    protected ScreenDescription screen;
+
+    public RGB888LE32PixelFormatRequest(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    protected void declarePads() {
+        inputPads.put(STDIN, null);
+        outputPads.put(STDOUT, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+        buf.unref();
+
+        ByteBuffer outBuf = new ByteBuffer(20);
+
+        outBuf.writeByte(RfbConstants.CLIENT_SET_PIXEL_FORMAT);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        // Send pixel format
+        outBuf.writeByte(bitsPerPixel);
+        outBuf.writeByte(depth);
+        outBuf.writeByte(bigEndianFlag);
+        outBuf.writeByte(trueColourFlag);
+        outBuf.writeShort(redMax);
+        outBuf.writeShort(greenMax);
+        outBuf.writeShort(blueMax);
+        outBuf.writeByte(redShift);
+        outBuf.writeByte(greenShift);
+        outBuf.writeByte(blueShift);
+
+        // Padding
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+        outBuf.writeByte(0);
+
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax,
+                blueMax, redShift, greenShift, blueShift);
+
+        pushDataToAllOuts(outBuf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
new file mode 100755
index 0000000..a3895d4
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
@@ -0,0 +1,85 @@
+// 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 vncclient.vnc;
+
+import java.nio.charset.Charset;
+
+public interface RfbConstants {
+
+    public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003.";
+    public static final String VNC_PROTOCOL_VERSION_MINOR = "003";
+    public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR;
+
+    /**
+     * Server message types.
+     */
+    final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3;
+
+    /**
+     * Client message types.
+     */
+    public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3,
+            CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6;
+
+    /**
+     * Server authorization type
+     */
+    public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2;
+
+    /**
+     * Server authorization reply.
+     */
+    public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2;
+
+    /**
+     * Encodings.
+     */
+    public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16;
+
+    /**
+     * Pseudo-encodings.
+     */
+    public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/;
+
+    /**
+     * Encodings, which we support.
+     */
+    public final static int[] SUPPORTED_ENCODINGS_ARRAY = {ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE};
+
+    /**
+     * Frame buffer update request type: update of whole screen or partial update.
+     */
+    public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1;
+
+    public static final int KEY_UP = 0, KEY_DOWN = 1;
+
+    public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1;
+
+    public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1;
+
+    public static final int PALETTE = 0, TRUE_COLOR = 1;
+
+    /**
+     * Default 8 bit charset to use when communicating with server.
+     */
+    public static final Charset US_ASCII_CHARSET = Charset.availableCharsets().get("US-ASCII");
+
+    /**
+     * Default 16 bit charset to use when communicating with server.
+     */
+    public static final Charset UCS2_CHARSET = Charset.availableCharsets().get("UTF-16LE");
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
new file mode 100755
index 0000000..6fdb3b1
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
@@ -0,0 +1,292 @@
+// 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 vncclient.vnc;
+
+import java.security.spec.KeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class Vnc33Authentication extends OneTimeSwitch {
+
+    /**
+     * Password to use when authentication is required.
+     */
+    protected String password = null;
+
+    /**
+     * Authentication stage:
+     * <ul>
+     * <li>0 - challenge received, response must be sent
+     * <li>1 - authentication result received.
+     * </ul>
+     */
+    protected int stage = 0;
+
+    public Vnc33Authentication(String id) {
+        super(id);
+    }
+
+    public Vnc33Authentication(String id, String password) {
+        super(id);
+        this.password = password;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        switch (stage) {
+        case 0: // Read security with optional challenge and response
+            stage0(buf, link);
+
+            break;
+        case 1: // Read authentication response
+            stage1(buf, link);
+            break;
+        }
+
+    }
+
+    /**
+     * Read security type. If connection type is @see
+     * RfbConstants.CONNECTION_FAILED, then throw exception. If connection type is @see
+     * RfbConstants.NO_AUTH, then switch off this element. If connection type is @see
+     * RfbConstants.VNC_AUTH, then read challenge, send encoded password, and read
+     * authentication response.
+     */
+    private void stage0(ByteBuffer buf, Link link) {
+        // At least 4 bytes are necessary
+        if (!cap(buf, 4, UNLIMITED, link, true))
+            return;
+
+        // Read security type
+        int authType = buf.readSignedInt();
+
+        switch (authType) {
+        case RfbConstants.CONNECTION_FAILED: {
+            // Server forbids to connect. Read reason and throw exception
+
+            int length = buf.readSignedInt();
+            String reason = new String(buf.data, buf.offset, length, RfbConstants.US_ASCII_CHARSET);
+
+            throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason);
+        }
+
+        case RfbConstants.NO_AUTH: {
+            // Client can connect without authorization. Nothing to do.
+            // Switch off this element from circuit
+            switchOff();
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH: {
+            // Read challenge and generate response
+            responseToChallenge(buf, link);
+            break;
+        }
+
+        default:
+            throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
+        }
+
+    }
+
+    private void responseToChallenge(ByteBuffer buf, Link link) {
+        // Challenge is exactly 16 bytes long
+        if (!cap(buf, 16, 16, link, true))
+            return;
+
+        ByteBuffer challenge = buf.slice(buf.cursor, 16, true);
+        buf.unref();
+
+        // Encode challenge with password
+        ByteBuffer response;
+        try {
+            response = encodePassword(challenge, password);
+            challenge.unref();
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage());
+        }
+
+        if (verbose) {
+            response.putMetadata("sender", this);
+        }
+
+        // Send encoded challenge
+        nextStage();
+        pushDataToOTOut(response);
+
+    }
+
+    private void nextStage() {
+        stage++;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Next stage: " + stage + ".");
+    }
+
+    /**
+     * Encode password using DES encryption with given challenge.
+     *
+     * @param challenge
+     *          a random set of bytes.
+     * @param password
+     *          a password
+     * @return DES hash of password and challenge
+     */
+    public ByteBuffer encodePassword(ByteBuffer challenge, String password) {
+        if (challenge.length != 16)
+            throw new RuntimeException("Challenge must be exactly 16 bytes long.");
+
+        // VNC password consist of up to eight ASCII characters.
+        byte[] key = {0, 0, 0, 0, 0, 0, 0, 0}; // Padding
+        byte[] passwordAsciiBytes = password.getBytes(RfbConstants.US_ASCII_CHARSET);
+        System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8));
+
+        // Flip bytes (reverse bits) in key
+        for (int i = 0; i < key.length; i++) {
+            key[i] = flipByte(key[i]);
+        }
+
+        try {
+            KeySpec desKeySpec = new DESKeySpec(key);
+            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
+            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+
+            ByteBuffer buf = new ByteBuffer(cipher.doFinal(challenge.data, challenge.offset, challenge.length));
+
+            return buf;
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot encode password.", e);
+        }
+    }
+
+    /**
+     * Reverse bits in byte, so least significant bit will be most significant
+     * bit. E.g. 01001100 will become 00110010.
+     *
+     * See also: http://www.vidarholen.net/contents/junk/vnc.html ,
+     * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html
+     *
+     * @param b
+     *          a byte
+     * @return byte in reverse order
+     */
+    private static byte flipByte(byte b) {
+        int b1_8 = (b & 0x1) << 7;
+        int b2_7 = (b & 0x2) << 5;
+        int b3_6 = (b & 0x4) << 3;
+        int b4_5 = (b & 0x8) << 1;
+        int b5_4 = (b & 0x10) >>> 1;
+        int b6_3 = (b & 0x20) >>> 3;
+        int b7_2 = (b & 0x40) >>> 5;
+        int b8_1 = (b & 0x80) >>> 7;
+        byte c = (byte)(b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1);
+        return c;
+    }
+
+    /**
+     * Read authentication result, send nothing.
+     */
+    private void stage1(ByteBuffer buf, Link link) {
+        // Read authentication response
+        if (!cap(buf, 4, 4, link, false))
+            return;
+
+        int authResult = buf.readSignedInt();
+
+        switch (authResult) {
+        case RfbConstants.VNC_AUTH_OK: {
+            // Nothing to do
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Authentication successfull.");
+            break;
+        }
+
+        case RfbConstants.VNC_AUTH_TOO_MANY:
+            throw new RuntimeException("Connection to VNC server failed: too many wrong attempts.");
+
+        case RfbConstants.VNC_AUTH_FAILED:
+            throw new RuntimeException("Connection to VNC server failed: wrong password.");
+
+        default:
+            throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
+        }
+
+        switchOff();
+
+    }
+
+    @Override
+    public String toString() {
+        return "VNC3.3 Authentication(" + id + ")";
+    }
+
+    /**
+     * 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");
+
+        final String password = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Request authentication and send 16 byte challenge
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+                        // Respond to challenge with AUTH_OK
+                        new byte[] {0, 0, 0, RfbConstants.VNC_AUTH_OK});
+            }
+        };
+
+        Element mainSink = new FakeSink("mainSink");
+        final Vnc33Authentication auth = new Vnc33Authentication("auth", password);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect encoded password
+                bufs = new ByteBuffer[] {auth.encodePassword(new ByteBuffer(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), password)};
+            }
+        };
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, auth, mainSink);
+        pipeline.add(initSink);
+        pipeline.link("auth >otout", "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
new file mode 100755
index 0000000..812c6a8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
@@ -0,0 +1,116 @@
+// 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 vncclient.vnc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import streamer.ByteBuffer;
+import streamer.InputStreamSource;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.OutputStreamSink;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+
+/**
+ * VNC server sends hello packet with RFB protocol version, e.g.
+ * "RFB 003.007\n". We need to send response packet with supported protocol
+ * version, e.g. "RFB 003.003\n".
+ */
+public class Vnc33Hello extends OneTimeSwitch {
+
+    public Vnc33Hello(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Initial packet is exactly 12 bytes long
+        if (!cap(buf, 12, 12, link, false))
+            return;
+
+        // Read protocol version
+        String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+
+        // Server should use RFB protocol 3.x
+        if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
+            throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
+
+        // Send response: we support RFB 3.3 only
+        String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
+
+        ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
+
+        if (verbose) {
+            outBuf.putMetadata("sender", this);
+            outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
+        }
+
+        pushDataToOTOut(outBuf);
+
+        // Switch off this element from circuit
+        switchOff();
+
+    }
+
+    @Override
+    public String toString() {
+        return "Vnc3.3 Hello(" + id + ")";
+    }
+
+    /**
+     * 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");
+
+        InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
+        ByteArrayOutputStream initOS = new ByteArrayOutputStream();
+        ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
+        InputStreamSource inputStreamSource = new InputStreamSource("source", is);
+        OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
+
+        Vnc33Hello hello = new Vnc33Hello("hello");
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
+        pipeline.add(new OutputStreamSink("initSink", initOS));
+
+        pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+        String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
+
+        if (!"RFB 003.003\n".equals(initOut))
+            System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
+
+        if (!"test".equals(mainOut))
+            System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
new file mode 100755
index 0000000..0b96c73
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
@@ -0,0 +1,245 @@
+// 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 vncclient.vnc;
+
+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;
+import common.ScreenDescription;
+
+public class VncInitializer extends OneTimeSwitch {
+
+    // Pad names
+    public static final String CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD = "encodings";
+    public static final String CLIENT_PIXEL_FORMAT_ADAPTER_PAD = "pixel_format";
+
+    protected byte sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+
+    /**
+     * Properties of remote screen .
+     */
+    protected ScreenDescription screen;
+
+    public VncInitializer(String id, boolean shared, ScreenDescription screen) {
+        super(id);
+
+        setSharedFlag(shared);
+        this.screen = screen;
+
+        declarePads();
+    }
+
+    @Override
+    protected void declarePads() {
+        super.declarePads();
+        outputPads.put(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, null);
+        outputPads.put(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, null);
+    }
+
+    public ScreenDescription getScreen() {
+        return screen;
+    }
+
+    public void setScreen(ScreenDescription screen) {
+        this.screen = screen;
+    }
+
+    public void setSharedFlag(boolean shared) {
+        if (shared)
+            sharedFlag = RfbConstants.SHARED_ACCESS;
+        else
+            sharedFlag = RfbConstants.EXCLUSIVE_ACCESS;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Server initialization message is at least 24 bytes long + length of
+        // desktop name
+        if (!cap(buf, 24, UNLIMITED, link, false))
+            return;
+
+        // Read server initialization message
+        // Read frame buffer size
+        int framebufferWidth = buf.readUnsignedShort();
+        int framebufferHeight = buf.readUnsignedShort();
+
+        // Read pixel format
+        int bitsPerPixel = buf.readUnsignedByte();
+        int depth = buf.readUnsignedByte();
+
+        int bigEndianFlag = buf.readUnsignedByte();
+        int trueColorFlag = buf.readUnsignedByte();
+
+        int redMax = buf.readUnsignedShort();
+        int greenMax = buf.readUnsignedShort();
+        int blueMax = buf.readUnsignedShort();
+
+        int redShift = buf.readUnsignedByte();
+        int greenShift = buf.readUnsignedByte();
+        int blueShift = buf.readUnsignedByte();
+
+        // Skip padding
+        buf.skipBytes(3);
+
+        // Read desktop name
+        int length = buf.readSignedInt();
+
+        // Consume exactly $length bytes, push back any extra bytes
+        if (!cap(buf, length, length, link, true))
+            return;
+
+        String desktopName = buf.readString(length, RfbConstants.US_ASCII_CHARSET);
+        buf.unref();
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Desktop name: \"" + desktopName + "\", bpp: " + bitsPerPixel + ", depth: " + depth + ", screen size: "
+                    + framebufferWidth + "x" + framebufferHeight + ".");
+
+        // Set screen properties
+        screen.setFramebufferSize(framebufferWidth, framebufferHeight);
+        screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColorFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax, redShift,
+                greenShift, blueShift);
+        screen.setDesktopName(desktopName);
+
+        // If sever screen has different parameters than ours, then change it
+        if (!screen.isRGB888_32_LE()) {
+            // Send client pixel format
+            sendClientPixelFormat();
+        }
+
+        // Send encodings supported by client
+        sendSupportedEncodings();
+
+        switchOff();
+
+    }
+
+    @Override
+    protected void onStart() {
+        ByteBuffer buf = new ByteBuffer(new byte[] {sharedFlag});
+        pushDataToOTOut(buf);
+    }
+
+    private void sendClientPixelFormat() {
+        pushDataToPad(CLIENT_PIXEL_FORMAT_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    private void sendSupportedEncodings() {
+        pushDataToPad(CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, new ByteBuffer(0));
+    }
+
+    @Override
+    public String toString() {
+        return "VncInit(" + id + ")";
+    }
+
+    /**
+     * 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");
+
+        final String desktopName = "test";
+
+        Element source = new MockSource("source") {
+            {
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(
+                        // Send screen description
+                        new byte[] {
+                                // Framebuffer width (short)
+                                0, (byte)200,
+                                // Framebuffer height (short)
+                                0, 100,
+                                // Bits per pixel
+                                32,
+                                // Depth,
+                                24,
+                                // Endianness flag
+                                RfbConstants.LITTLE_ENDIAN,
+                                // Truecolor flag
+                                RfbConstants.TRUE_COLOR,
+                                // Red max (short)
+                                0, (byte)255,
+                                // Green max (short)
+                                0, (byte)255,
+                                // Blue max (short)
+                                0, (byte)255,
+                                // Red shift
+                                16,
+                                // Green shift
+                                8,
+                                // Blue shift
+                                0,
+                                // Padding
+                                0, 0, 0,
+                                // Desktop name length (int)
+                                0, 0, 0, 4,
+                                // Desktop name ("test", 4 bytes)
+                                't', 'e', 's', 't',
+
+                                // Tail
+                                1, 2, 3
+
+                        },
+                        // Tail packet
+                        new byte[] {4, 5, 6});
+            }
+        };
+
+        ScreenDescription screen = new ScreenDescription();
+        final VncInitializer init = new VncInitializer("init", true, screen);
+        Element initSink = new MockSink("initSink") {
+            {
+                // Expect shared flag
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {RfbConstants.SHARED_ACCESS});
+            }
+        };
+        Element mainSink = new MockSink("mainSink") {
+            {
+                // Expect two tail packets
+                bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}, new byte[] {4, 5, 6});
+            }
+        };
+        ByteBuffer[] emptyBuf = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {});
+        Element encodingsSink = new MockSink("encodings", emptyBuf);
+        Element pixelFormatSink = new MockSink("pixel_format", emptyBuf);
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, init, mainSink);
+        pipeline.add(encodingsSink, pixelFormatSink, initSink);
+        pipeline.link("init >otout", "initSink");
+        pipeline.link("init >" + CLIENT_SUPPORTED_ENCODINGS_ADAPTER_PAD, "encodings");
+        pipeline.link("init >" + CLIENT_PIXEL_FORMAT_ADAPTER_PAD, "pixel_format");
+
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        if (!screen.isRGB888_32_LE())
+            System.err.println("Screen description was read incorrectly: " + screen + ".");
+        if (!desktopName.equals(screen.getDesktopName()))
+            System.err.println("Screen desktop name was read incorrectly: \"" + screen.getDesktopName() + "\".");
+
+    }
+}


[05/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
new file mode 100755
index 0000000..cbefcb9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSAttachUserConfirmPDU.java
@@ -0,0 +1,116 @@
+// 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.rdp;
+
+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;
+
+/**
+ * Server response to MCS Attach User request.
+ *
+ * Once the User Channel ID has been extracted, the client MUST send an MCS
+ * Channel Join Request PDU for the user channel.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc240685.aspx
+ */
+public class ServerMCSAttachUserConfirmPDU extends OneTimeSwitch {
+
+    public static final int MCS_ATTACH_USER_CONFIRM_PDU = 0xb;
+
+    public static final int INITIATOR_PRESENT = 0x2;
+
+    protected RdpState state;
+
+    public ServerMCSAttachUserConfirmPDU(String id, RdpState state) {
+        super(id);
+        this.state = state;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int typeAndFlags = buf.readUnsignedByte();
+        int type = typeAndFlags >> 2;
+        int flags = typeAndFlags & 0x3;
+
+        if (type != MCS_ATTACH_USER_CONFIRM_PDU)
+            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 11, actual value: " + type + ", data: " + buf + ".");
+
+        if (flags != INITIATOR_PRESENT)
+            throw new RuntimeException("Initator field is not present in MCS AttachUserConfirm PDU. Data: " + buf + ".");
+
+        int rtSuccess = buf.readUnsignedByte() >> 4;
+        if (rtSuccess != 0)
+            throw new RuntimeException("[" + this + "] ERROR: Cannot attach user: request failed. Error code: " + rtSuccess + ", data: " + buf + ".");
+
+        // If the initiator field is present, the client stores the value of the
+        // initiator in the User Channel ID store , because the initiator specifies
+        // the User Channel ID.
+        state.serverUserChannelId = buf.readUnsignedShort() + 1001;
+
+        buf.unref();
+
+        // Next: client MCS Channel Join Request PDU (s)
+        switchOff();
+    }
+
+    /**
+     * Example.
+     */
+    /**
+     * Example.
+     *
+     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
+     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
+     */
+    public static void main(String args[]) {
+        // System.setProperty("streamer.Link.debug", "true");
+        System.setProperty("streamer.Element.debug", "true");
+        // System.setProperty("streamer.Pipeline.debug", "true");
+
+        byte[] packet = new byte[] {(byte)0x2E, // MCS user confirm (001011..,
+                // 0xb), InitiatorPresent: 1
+                // (......01, 0x1)
+                (byte)0x00, // RT successfull (0000...., 0x0)
+                // Initiator: 1001+3 = 1004
+                (byte)0x00, (byte)0x03,};
+
+        RdpState rdpState = new RdpState();
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] {1, 2, 3}));
+        Element atachUserConfirm = new ServerMCSAttachUserConfirmPDU("attach_user_confirm", rdpState);
+        Element sink = new MockSink("sink");
+        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, atachUserConfirm, sink, mainSink);
+        pipeline.link("source", "attach_user_confirm", "mainSink");
+        pipeline.link("attach_user_confirm >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+
+        if (rdpState.serverUserChannelId != 1004)
+            System.err.println("Incorrect user channel ID. Expected value: 1004, actual value: " + rdpState.serverUserChannelId + ".");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
new file mode 100755
index 0000000..d3a5954
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSChannelJoinConfirmPDU.java
@@ -0,0 +1,89 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerMCSChannelJoinConfirmPDU extends OneTimeSwitch {
+
+    protected int channel;
+
+    public ServerMCSChannelJoinConfirmPDU(String id, int channel) {
+        super(id);
+        this.channel = channel;
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/*
+ * 03 00 00 0F 02 F0 80 3E 00 00 03 03 EC 03 EC
+
+  Frame: Number = 22, Captured Frame Length = 72, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 15
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 15 (0xF)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Channel Join Confirm, ChannelId = 1004, Result = rt-successful
+  - MCSHeader: Type=Channel Join Confirm
+   - Type: Channel Join Confirm
+    - RootIndex: 15
+       Value: (001111..) 0xf
+  - MCSChannelJoinConfirm: ChannelId = 1004, Result = rt-successful
+     ChannelIdPresent: 1 (0x1)
+   - Result: rt-successful
+    - Result: rt-successful
+     - RootIndex: 0
+        Value: (0000....) 0x0
+   - Initiator: 0x3ec
+    - UserID: 0x3ec
+     - ChannelId: 1004
+      - Align: No Padding
+         Padding5: (00000...) 0x0
+        Value: 3 (0x3)
+   - Requested: 0x3ec
+    - ChannelId: 1004
+       Align: No Padding
+       Value: 1004 (0x3EC)
+   - ChannelId: 0x3ec
+    - ChannelId: 1004
+       Align: No Padding
+       Value: 1004 (0x3EC)
+
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
new file mode 100755
index 0000000..a62ae8b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSConnectResponse.java
@@ -0,0 +1,283 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+/**
+ * Once the basic server settings data blocks have been processed successfully, the client MUST send the MCS Attach User Request PDU to the server.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc240682.aspx
+ */
+public class ServerMCSConnectResponse extends OneTimeSwitch {
+
+    public ServerMCSConnectResponse(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/*
+ * @formatter:off
+ * 03 00 00 64 02 F0 80 7F 66 5A 0A 01 00 02 01 00 30 1A 02 01 22 02 01 03 02 01 00 02 01 01 02 01 00 02 01 01 02 03 00 FF F8 02 01 02 04 36 00 05 00 14 7C 00 01 2A 14 76 0A 01 01 00 01 C0 00 4D 63 44 6E 20 01 0C 0C 00 04 00 08 00 01 00 00 00 03 0C 08 00 EB 03 00 00 02 0C 0C 00 00 00 00 00 00 00 00 00
+
+  Frame: Number = 12, Captured Frame Length = 157, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 100
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 100 (0x64)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: MCSConnect Response
+  - MCSConnectResponse: Result = rt-successful
+   - ConnectResponseHeader:
+    - AsnId: Application Constructed Tag (102)
+     - HighTag:
+        Class:     (01......) Application (1)
+        Type:      (..1.....) Constructed
+        TagNumber: (...11111)
+        TagValueEnd: 102 (0x66)
+    - AsnLen: Length = 90, LengthOfLength = 0
+       Length: 90 bytes, LengthOfLength = 0
+   - Result: rt-successful
+    - Value: 0
+     - AsnIntegerHeader:
+      - AsnId: Enumerated type (Universal 10)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...01010) 10
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+   - CalledConnectId: 0
+    - AsnIntegerHeader:
+     - AsnId: Integer type (Universal 2)
+      - LowTag:
+         Class:    (00......) Universal (0)
+         Type:     (..0.....) Primitive
+         TagValue: (...00010) 2
+     - AsnLen: Length = 1, LengthOfLength = 0
+        Length: 1 bytes, LengthOfLength = 0
+      AsnInt: 0 (0x0)
+   - DomainParameters: Length = 26, LengthOfLength = 0
+    - DomainParametersHeader: 0x1
+     - AsnId: Sequence and SequenceOf types (Universal 16)
+      - LowTag:
+         Class:    (00......) Universal (0)
+         Type:     (..1.....) Constructed
+         TagValue: (...10000) 16
+     - AsnLen: Length = 26, LengthOfLength = 0
+        Length: 26 bytes, LengthOfLength = 0
+    - ChannelIds: 34
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 34 (0x22)
+    - UserIDs: 3
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 3 (0x3)
+    - TokenIds: 0
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+    - NumPriorities: 1
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 1 (0x1)
+    - MinThroughput: 0
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 0 (0x0)
+    - Height: 1
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 1 (0x1)
+    - MCSPDUsize: 65528
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 3, LengthOfLength = 0
+         Length: 3 bytes, LengthOfLength = 0
+       AsnInt: 65528 (0xFFF8)
+    - protocolVersion: 2
+     - AsnIntegerHeader:
+      - AsnId: Integer type (Universal 2)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00010) 2
+      - AsnLen: Length = 1, LengthOfLength = 0
+         Length: 1 bytes, LengthOfLength = 0
+       AsnInt: 2 (0x2)
+   - UserData: Identifier = Generic Conference Contro (0.0.20.124.0.1)
+    - UserDataHeader:
+     - AsnId: OctetString type (Universal 4)
+      - LowTag:
+         Class:    (00......) Universal (0)
+         Type:     (..0.....) Primitive
+         TagValue: (...00100) 4
+     - AsnLen: Length = 54, LengthOfLength = 0
+        Length: 54 bytes, LengthOfLength = 0
+    - AsnBerObjectIdentifier: Generic Conference Control (0.0.20.124.0.1)
+     - AsnObjectIdentifierHeader:
+      - AsnId: Reserved for use by the encoding rules (Universal 0)
+       - LowTag:
+          Class:    (00......) Universal (0)
+          Type:     (..0.....) Primitive
+          TagValue: (...00000) 0
+      - AsnLen: Length = 5, LengthOfLength = 0
+         Length: 5 bytes, LengthOfLength = 0
+       First: 0 (0x0)
+       Final: 20 (0x14)
+       Final: 124 (0x7C)
+       Final: 0 (0x0)
+       Final: 1 (0x1)
+    - ConnectPDULength: 42
+       Align: No Padding
+       Length: 42
+    - ConnectGCCPDU: conferenceCreateResponse
+       ExtensionBit: 0 (0x0)
+     - ChoiceValue: conferenceCreateResponse
+        Value: (001.....) 0x1
+     - conferenceCreateResponse:
+        ExtensionBit: 0 (0x0)
+        userDataPresent: 1 (0x1)
+      - nodeID: 0x79f3
+       - UserID: 31219
+        - Align: No Padding
+           Padding2: (00......) 0x0
+          Value: 30218 (0x760A)
+      - tag: 1 (0x1)
+       - Length: 1
+          Align: No Padding
+          Length: 1
+         Value: 1 (0x1)
+      - result: success
+         ExtensionBit: 0 (0x0)
+       - RootIndex: 0
+          Value: (000.....) 0x0
+      - userData:
+       - Size: 1
+        - Align: No Padding
+           Padding4: (0000....) 0x0
+          Length: 1
+       - UserData: 0x4d63446e
+          valuePresent: 1 (0x1)
+        - key: h221NonStandard
+         - ChoiceValue: h221NonStandard
+            Value: (1.......) 0x1
+         - h221NonStandard:
+          - H221NonStandardIdentifier: length: 4
+           - ConstrainedLength: 4
+              Value: (00000000) 0x0
+           - Align: No Padding
+              Padding6: (000000..) 0x0
+             Value: Binary Large Object (4 Bytes)
+        - ServerMcsConnectResponsePdu:
+         - RDPGCCUserDataResponseLength: 32
+            Align: No Padding
+            Length: 32
+         - TsUd: SC_CORE
+          - TsUdHeader: Type = SC_CORE, Length = 12
+             Type: SC_CORE
+             Length: 12 (0xC)
+          - TsUdScCore:
+             Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
+             ClientRequestedProtocols: TLS 1.0
+         - TsUd: SC_NET
+          - TsUdHeader: Type = SC_NET, Length = 8
+             Type: SC_NET
+             Length: 8 (0x8)
+          - TsUdScNet:
+             MCSChannelID: 1003 (0x3EB)
+             ChannelCount: 0 (0x0)
+             Pad: 0 Bytes
+         - TsUd: SC_SECURITY
+          - TsUdHeader: Type = SC_SECURITY, Length = 12
+             Type: SC_SECURITY
+             Length: 12 (0xC)
+          - TsUdSCSec1:
+           - EncryptionMethod:
+              Support40Bit:  (...............................0) Not Support
+              Support128Bit: (..............................0.) Not Support 128-bit
+              Reserved1:     (.............................0..)
+              Support56Bit:  (............................0...) Not Support 56-bit
+              SupportFIPS:   (...........................0....) Not Support FIPS Compliant
+              Reserved2:     (000000000000000000000000000.....)
+             EncryptionLevel: TS_ENCRYPTION_NONE
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
new file mode 100755
index 0000000..d28d0a0
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerMCSPDU.java
@@ -0,0 +1,149 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+public class ServerMCSPDU extends BaseElement {
+
+    public ServerMCSPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        byte headerByte = buf.readSignedByte();
+        int type = headerByte >> 2;
+
+        switch (type) {
+        // Expected type: send data indication: 26 (0x1a, top 6 bits, or 0x68)
+        case 0x1a: {
+            // int userId = buf.readUnsignedShort() + 1001; // User ID: 1002 (1001+1)
+            buf.skipBytes(2); // Ignore user ID
+
+            int channelId = buf.readUnsignedShort(); // Channel ID: 1003
+
+            int flags = buf.readSignedByte();
+            if ((flags & 0x30) != 0x30)
+                throw new RuntimeException("Fragmented MCS packets are not supported.");
+
+            int payloadLength = buf.readVariableUnsignedShort();
+
+            ByteBuffer data = buf.readBytes(payloadLength);
+
+            buf.unref();
+
+            pushDataToPad("channel_" + channelId, data);
+            break;
+        }
+
+        case 0x8: {
+            // Disconnection sequence.
+            buf.unref();
+            break;
+        }
+
+        default:
+            throw new RuntimeException("Unsupported MCS packet type: " + type + "(" + headerByte + "), data: " + buf + ".");
+        }
+
+    }
+
+    /**
+     * 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");
+
+        byte[] packet = new byte[] {
+                // TPKT
+                (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
+                (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
+
+                // X224
+                (byte)0x02, // X224 Length: 2 bytes
+                (byte)0xF0, // X224 Type: Data
+                (byte)0x80, // X224 EOT
+
+                // MCS
+                // Type: send data indication: 26 (0x1a, top 6 bits)
+                (byte)0x68, // ??
+
+                (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
+                (byte)0x03, (byte)0xEB, // Channel ID: 1003
+                (byte)0x70, // Data priority: high, segmentation: begin|end
+                (byte)0x0D, // Payload length: 13 bytes
+
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element mcs = new ServerMCSPDU("mcs") {
+            {
+                verbose = true;
+            }
+        };
+        Element tpkt = new ServerTpkt("tpkt");
+        Element x224 = new ServerX224DataPdu("x224");
+        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+                // Deactivate all PDU
+                (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
+
+                // - PDUType: 22 (0x16, LE)
+                // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
+                // ProtocolVersion: (000000000001....) 1
+                (byte)0x16, (byte)0x00,
+
+                (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
+                (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
+
+                (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
+                (byte)0x00, // Source descriptor (should be set to 0): 0
+        }));
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, x224, mcs, sink);
+        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
new file mode 100755
index 0000000..606bd89
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerPaletteUpdate.java
@@ -0,0 +1,77 @@
+// 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.rdp;
+
+import java.awt.image.IndexColorModel;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+import common.ScreenDescription;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc240623.aspx
+ */
+public class ServerPaletteUpdate extends BaseElement {
+
+    public static final int UPDATETYPE_PALETTE = 0x0002;
+    protected ScreenDescription screen;
+
+    public ServerPaletteUpdate(String id, ScreenDescription screen) {
+        super(id);
+        this.screen = screen;
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
+        // be set to UPDATETYPE_PALETTE (0x0002).
+        int updateType = buf.readUnsignedShortLE();
+        if (updateType != UPDATETYPE_PALETTE)
+            throw new RuntimeException("Unexpected update type. Expected type: UPDATETYPE_PALETTE (0x0002), actual value: " + updateType + ", data: " + buf + ".");
+
+        // pad2Octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
+        // field MUST be ignored.
+        buf.skipBytes(2);
+
+        // (4 bytes): A 32-bit, unsigned integer. The number of RGB triplets in the
+        // paletteData field. This field MUST be set to 256 (the number of entries
+        // in an 8 bpp palette).
+        int numberColors = (int)buf.readUnsignedIntLE();
+        if (numberColors != 256)
+            throw new RuntimeException("Unexpected value for number of color field in server Palette Update packet. Expected value: 256 colors, actual value: "
+                    + numberColors + ", data: " + buf + ".");
+
+        // (variable): An array of palette entries in RGB triplet format packed on
+        // byte boundaries. The number of triplet entries is given by the
+        // numberColors field.
+        ByteBuffer paletteEntries = buf.readBytes(numberColors * 3);
+
+        // In the case of a Palette Update, the client MUST update the global
+        // palette on all drawing surfaces
+        screen.colorMap = new IndexColorModel(8, numberColors, paletteEntries.data, paletteEntries.offset, false);
+
+        /* DEBUG */buf.assertThatBufferIsFullyRead();
+
+        buf.unref();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
new file mode 100755
index 0000000..f464a4a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerSynchronizePDU.java
@@ -0,0 +1,115 @@
+// 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.rdp;
+
+import streamer.ByteBuffer;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ServerSynchronizePDU extends OneTimeSwitch {
+
+    public ServerSynchronizePDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // Ignore packet
+        buf.unref();
+        switchOff();
+    }
+
+}
+
+/* @formatter:off */
+/*
+
+ * 03 00 00 24 02 F0 80 68 00 01 03 EB 70 16 16 00 17 00 EA 03 EA 03 01 00 08 00 16 00 1F 00 00 00 01 00 86 A4
+
+  Frame: Number = 36, Captured Frame Length = 93, MediaType = DecryptedPayloadHeader
++ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
+  TLSSSLData: Transport Layer Security (TLS) Payload Data
++ TLS: TLS Rec Layer-1 SSL Application Data
+  ISOTS: TPKTCount = 1
+- TPKT: version: 3, Length: 36
+    version: 3 (0x3)
+    Reserved: 0 (0x0)
+    PacketLength: 36 (0x24)
+- X224: Data
+    Length: 2 (0x2)
+    Type: Data
+    EOT: 128 (0x80)
+- T125: Data Packet
+  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
+   - Type: Send Data Indication
+    - RootIndex: 26
+       Value: (011010..) 0x1a
+   - UserID: 0x3ea
+    - UserID: 0x3ea
+     - ChannelId: 1002
+      - Align: No Padding
+         Padding2: (00......) 0x0
+        Value: 1 (0x1)
+   - Channel: 0x3eb
+    - ChannelId: 1003
+       Align: No Padding
+       Value: 1003 (0x3EB)
+   - DataPriority: high
+    - DataPriority: high
+     - RootIndex: 1
+        Value: (01......) 0x1
+   - Segmentation: Begin End
+      Begin: (1.......) Begin
+      End:   (.1......) End
+   - Length: 22
+    - Align: No Padding
+       Padding4: (0000....) 0x0
+      Length: 22
+    RDP: RDPBCGR
+- RDPBCGR: SynchronizePDU
+  - SlowPathPacket: SynchronizePDU
+   - SlowPath: Type = TS_PDUTYPE_DATAPDU
+    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
+       TotalLength: 22 (0x16)
+     - PDUType: 23 (0x17)
+        Type:            (............0111) TS_PDUTYPE_DATAPDU
+        ProtocolVersion: (000000000001....) 1
+       PDUSource: 1002 (0x3EA)
+    - SlowPathIoPacket: 0x0
+     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
+        ShareID: 66538 (0x103EA)
+        Pad1: 8 (0x8)
+        StreamID: STREAM_UNDEFINED
+        UncompressedLength: 22 (0x16)
+        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
+      - CompressedType: Not Compressed
+         MPPC:       (....0000) MPPC 8K
+         Reserved:   (...0....)
+         Compressed: (..0.....) Not Compressed
+         Front:      (.0......) Not At Front
+         Flush:      (0.......) Not Flushed
+        CompressedLength: 0 (0x0)
+     - TsSynchronizePDU: 0x1
+        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
+        TargetUser: 42118 (0xA486)
+ */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
new file mode 100755
index 0000000..d9662d2
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerTpkt.java
@@ -0,0 +1,70 @@
+// 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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerTpkt extends BaseElement {
+
+    /**
+     * TPKT protocol version (first byte).
+     */
+    public static final int PROTOCOL_TPKT = 3;
+
+    public ServerTpkt(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        // We need at least 4 bytes to get packet length
+        if (!cap(buf, 4, UNLIMITED, link, false))
+            return;
+
+        int version = buf.readUnsignedByte();
+        if (version != PROTOCOL_TPKT)
+            throw new RuntimeException("Unexpected data in TPKT header. Expected TPKT version: 0x03,  actual value: " + buf + ".");
+
+        buf.skipBytes(1); // Reserved byte
+
+        // Length of whole packet, including header
+        int length = buf.readUnsignedShort();
+        if (!cap(buf, length, length, link, false))
+            return;
+
+        int payloadLength = length - buf.cursor;
+
+        // Extract payload
+        ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
+        buf.unref();
+
+        if (verbose) {
+            outBuf.putMetadata("source", this);
+        }
+
+        pushDataToAllOuts(outBuf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
new file mode 100755
index 0000000..5a8dfaf
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224ConnectionConfirmPDU.java
@@ -0,0 +1,234 @@
+// 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.rdp;
+
+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;
+
+/**
+ * Once the External Security Protocol handshake has run to completion, the
+ * client MUST continue with the connection sequence by sending the MCS Connect
+ * Initial PDU to the server over the newly established secure channel.
+ *
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
+ */
+public class ServerX224ConnectionConfirmPDU extends OneTimeSwitch {
+
+    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
+    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
+    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
+    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
+    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
+    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
+    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
+    public static final int X224_TPDU_REJECT = 0x51;
+    public static final int X224_TPDU_ERROR = 0x70;
+    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with
+     * either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then
+     * the server only supports TLS.
+     */
+    public static final int SSL_REQUIRED_BY_SERVER = 0x00000001;
+
+    /**
+     * The server is configured to only use Standard RDP Security mechanisms and
+     * does not support any External Security Protocols.
+     */
+    public static final int SSL_NOT_ALLOWED_BY_SERVER = 0x00000002;
+
+    /**
+     * The server does not possess a valid authentication certificate and cannot
+     * initialize the External Security Protocol Provider.
+     */
+    public static final int SSL_CERT_NOT_ON_SERVER = 0x00000003;
+
+    /**
+     * The list of requested security protocols is not consistent with the current
+     * security protocol in effect. This error is only possible when the Direct
+     * Approach is used and an External Security Protocolis already being used.
+     */
+    public static final int INCONSISTENT_FLAGS = 0x00000004;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with
+     * CredSSP.
+     */
+    public static final int HYBRID_REQUIRED_BY_SERVER = 0x00000005;
+
+    /**
+     * The server requires that the client support Enhanced RDP Security with TLS
+     * 1.0, 1.1 or 1.2 and certificate-based client authentication.
+     */
+    public static final int SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 0x00000006;
+
+    public ServerX224ConnectionConfirmPDU(String id) {
+        super(id);
+    }
+
+    @Override
+    protected void handleOneTimeData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int x224Length = buf.readVariableSignedIntLE();
+
+        int x224Type = buf.readUnsignedByte();
+        if (x224Type != X224_TPDU_CONNECTION_CONFIRM)
+            throw new RuntimeException("Unexpected type of packet. Expected type: " + X224_TPDU_CONNECTION_CONFIRM + " (CONNECTION CONFIRM), actual type: "
+                    + x224Type + ", length: " + x224Length + ", buf: " + buf + ".");
+
+        // Ignore destination reference, because client side has only one node
+        buf.skipBytes(2);
+
+        // Source reference
+        // int srcRef = buf.readUnsignedShort();
+        buf.skipBytes(2);
+
+        // Ignore class and options
+        buf.skipBytes(1);
+
+        // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
+        int negType = buf.readUnsignedByte();
+
+        // RDP_NEG_RSP::flags (0)
+        buf.skipBytes(1); // Ignore: always 0
+
+        // RDP_NEG_RSP::length (always 8 bytes)
+        int length = buf.readUnsignedShortLE();
+
+        if (length != 8)
+            throw new RuntimeException("Unexpected length of buffer. Expected value: 8, actual value: " + length + ", RDP NEG buf: " + buf + ".");
+
+        // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
+        int protocol = buf.readSignedIntLE();
+
+        if (negType != RdpConstants.RDP_NEG_REQ_TYPE_NEG_RSP) {
+            // Parse error code, see
+            // http://msdn.microsoft.com/en-us/library/cc240507.aspx
+            int errorCode = protocol;
+            String message = "Unknown error.";
+            switch (errorCode) {
+            case SSL_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security with either TLS 1.0, 1.1 or 1.2 or CredSSP. If only CredSSP was requested then the server only supports TLS.";
+                break;
+
+            case SSL_NOT_ALLOWED_BY_SERVER:
+                message = "The server is configured to only use Standard RDP Security mechanisms and does not support any External Security Protocols.";
+                break;
+
+            case SSL_CERT_NOT_ON_SERVER:
+                message = "The server does not possess a valid authentication certificate and cannot initialize the External Security Protocol Provider.";
+                break;
+
+            case INCONSISTENT_FLAGS:
+                message = "The list of requested security protocols is not consistent with the current security protocol in effect. This error is only possible when the Direct Approach is used and an External Security Protocolis already being used.";
+                break;
+
+            case HYBRID_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security with CredSSP.";
+                break;
+
+            case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
+                message = "The server requires that the client support Enhanced RDP Security  with TLS 1.0, 1.1 or 1.2 and certificate-based client authentication.";
+                break;
+
+            }
+            throw new RuntimeException("Connection failure: " + message);
+        }
+
+        if (protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL && protocol != RdpConstants.RDP_NEG_REQ_PROTOCOL_HYBRID)
+            throw new RuntimeException("Unexpected protocol type (nor SSL, nor HYBRID (SSL+CredSSP)): " + protocol + ", RDP NEG buf: " + buf + ".");
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: RDP Negotiation response. Type: " + negType + ", protocol: " + protocol + ".");
+
+        // Next: upgrade socket to SSL, send ConnectInitial packet
+        switchOff();
+    }
+
+    /**
+     * 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");
+
+//    byte[] packet = new byte[] {
+//
+//        0x03, // -> TPKT Header: TPKT version = 3
+//        0x00, // TPKT Header: Reserved = 0
+//        0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
+//        0x0e, // X.224: Length indicator (14 bytes)
+//        (byte) 0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
+//                     // (low nibble) = 0
+//        0x00, 0x00, // X.224: Destination reference = 0
+//        0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
+//        0x00, // X.224: Class and options = 0
+//
+//        0x02, // RDP_NEG_RSP::type (TYPE_RDP_NEG_RSP)
+//        0x00, // RDP_NEG_RSP::flags (0)
+//        0x08, 0x00, // RDP_NEG_RSP::length (8 bytes)
+//        0x01, 0x00, 0x00, 0x00 // RDP_NEG_RSP: Selected protocols (PROTOCOL_SSL)
+//    };
+
+        // Connection failure
+        // 03 00 00 13 0e d0 00 00 12 34 00 03 00 08 00 05 00 00 00
+        byte[] packet = new byte[] {
+
+                0x03, // -> TPKT Header: TPKT version = 3
+                0x00, // TPKT Header: Reserved = 0
+                0x00, 0x13, // TPKT Header: Packet length - (total = 19 bytes)
+                0x0e, // X.224: Length indicator (14 bytes)
+                (byte)0xd0, // X.224: Type (high nibble) = 0xd = CC TPDU; credit
+                // (low nibble) = 0
+                0x00, 0x00, // X.224: Destination reference = 0
+                0x12, 0x34, // X.224: Source reference = 0x1234 (bogus value)
+                0x00, // X.224: Class and options = 0
+                (byte)0x03, // Failure
+                (byte)0x00, // RDP_NEG_RSP::flags (0)
+                (byte)0x08, (byte)0x00, // RDP_NEG_RSP::length (8 bytes)
+                (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, // Code:  HYBRID_REQUIRED_BY_SERVER
+
+        };
+
+        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
+        Element cc = new ServerX224ConnectionConfirmPDU("cc");
+        Element tpkt = new ServerTpkt("tpkt");
+        Element sink = new MockSink("sink", new ByteBuffer[] {});
+        Element mainSink = new MockSink("mainSink", new ByteBuffer[] {});
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.add(source, tpkt, cc, sink, mainSink);
+        pipeline.link("source", "tpkt", "cc", "mainSink");
+        pipeline.link("cc >" + OTOUT, "sink");
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.java
new file mode 100755
index 0000000..2c0087e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/rdp/ServerX224DataPdu.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.rdp;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class ServerX224DataPdu extends BaseElement {
+
+    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
+    public static final int X224_TPDU_DATA = 0xF0;
+
+    public ServerX224DataPdu(String id) {
+        super(id);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        int headerLength = buf.readVariableSignedIntLE();
+
+        if (headerLength != 2)
+            throw new RuntimeException("Unexpected X224 Data PDU header length. Expected header length: 2 , actual header length: " + headerLength + ".");
+
+        // Read X224 type and options
+        int type = buf.readUnsignedByte(); // High nibble: type, low nibble:
+
+        if ((type & 0xf0) != X224_TPDU_DATA)
+            throw new RuntimeException("[" + this + "] ERROR: Unexepcted X224 packet type. Expected packet type: " + X224_TPDU_DATA
+                    + " (X224_TPDU_DATA), actual packet type: " + type + ", buf: " + buf + ".");
+
+        int options = buf.readUnsignedByte();
+
+        if ((options & X224_TPDU_LAST_DATA_UNIT) != X224_TPDU_LAST_DATA_UNIT)
+            throw new RuntimeException("Unexepcted X224 packet options. Expected options: " + X224_TPDU_LAST_DATA_UNIT
+                    + " (X224_TPDU_LAST_DATA_UNIT), actual packet options: " + options + ", buf: " + buf + ".");
+
+        ByteBuffer payload = buf.readBytes(buf.length - buf.cursor);
+
+        buf.unref();
+
+        pushDataToAllOuts(payload);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
deleted file mode 100644
index fe9cc50..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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 streamer;
-
-import java.nio.charset.Charset;
-
-/**
- * Assert that writes to this buffer are matching expected data.
- */
-public class AssertingByteBuffer extends ByteBuffer {
-
-    public AssertingByteBuffer(byte[] expectedData) {
-        super(expectedData);
-    }
-
-    private void assertEquals(int expected, int actual) {
-        if (expected != actual)
-            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ", buf: " + this + ".");
-    }
-
-    @Override
-    public void writeByte(int b) {
-        if (b < 0)
-            throw new RuntimeException();
-        //*DEBUG*/System.out.println("WriteByte: "+b+", cursor:"+cursor+".");
-        assertEquals(readUnsignedByte(), b & 0xff);
-    }
-
-    @Override
-    public void writeShort(int x) {
-        //*DEBUG*/System.out.println("WriteShort: "+x+", cursor:"+cursor+".");
-        assertEquals(readUnsignedShort(), x & 0xFFff);
-    }
-
-    @Override
-    public void writeShortLE(int x) {
-        //*DEBUG*/System.out.println("WriteShortLE: "+x+", cursor:"+cursor+".");
-        assertEquals(readUnsignedShortLE(), x & 0xFFff);
-    }
-
-    @Override
-    public void writeInt(int i) {
-        //*DEBUG*/System.out.println("WriteInt: "+i+", cursor:"+cursor+".");
-        assertEquals(readSignedInt(), i);
-    }
-
-    @Override
-    public void writeIntLE(int i) {
-        //*DEBUG*/System.out.println("WriteIntLE: "+i+", cursor:"+cursor+".");
-        assertEquals(readSignedIntLE(), i);
-    }
-
-    @Override
-    public void writeVariableIntLE(int i) {
-        //*DEBUG*/System.out.println("WriteVariableIntLE: "+i+", cursor:"+cursor+".");
-        assertEquals(readVariableSignedIntLE(), i);
-    }
-
-    @Override
-    public void writeString(String actual, Charset charset) {
-        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-        String expected = readString(actual.length(), charset);
-        if (!actual.equals(expected))
-            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-    }
-
-    @Override
-    public void writeBytes(ByteBuffer actual) {
-        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-        ByteBuffer expected = readBytes(actual.length);
-        if (!actual.equals(expected))
-            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-    }
-
-    @Override
-    public void writeBytes(byte[] actualData) {
-        ByteBuffer actual = new ByteBuffer(actualData);
-        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-        ByteBuffer expected = readBytes(actual.length);
-        if (!actual.equals(expected))
-            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-    }
-
-    @Override
-    public void writeBytes(byte[] actualData, int offset, int length) {
-        ByteBuffer actual = new ByteBuffer(actualData, offset, length);
-        //*DEBUG*/System.out.println("WriteString: "+actual+", cursor:"+cursor+".");
-        ByteBuffer expected = readBytes(actual.length);
-        if (!actual.equals(expected))
-            throw new RuntimeException("Expected value does not match actual value. Expected value: " + expected + ", actual value: " + actual + ".");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
old mode 100644
new mode 100755
index dd2b541..1ca68ce
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BaseElement.java
@@ -21,6 +21,9 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 public class BaseElement implements Element {
 
     protected String id;
@@ -78,11 +81,11 @@ public class BaseElement implements Element {
     @Override
     public Set<String> getPads(Direction direction) {
         switch (direction) {
-            case IN:
-                return inputPads.keySet();
+        case IN:
+            return inputPads.keySet();
 
-            case OUT:
-                return outputPads.keySet();
+        case OUT:
+            return outputPads.keySet();
         }
         return null;
     }
@@ -103,24 +106,24 @@ public class BaseElement implements Element {
     @Override
     public void setLink(String padName, Link link, Direction direction) {
         switch (direction) {
-            case IN:
-                if (inputPads.get(padName) != null)
-                    throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: " +
-                        link + ", existing link: " + inputPads.get(padName) + ".");
-                inputPads.put(padName, link);
-                link.setSink(this);
+        case IN:
+            if (inputPads.get(padName) != null)
+                throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
+                        + link + ", existing link: " + inputPads.get(padName) + ".");
+            inputPads.put(padName, link);
+            link.setSink(this);
 
-                break;
+            break;
 
-            case OUT:
-                if (outputPads.get(padName) != null)
-                    throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: " +
-                        link + ", existing link: " + outputPads.get(padName) + ".");
+        case OUT:
+            if (outputPads.get(padName) != null)
+                throw new RuntimeException("Cannot link more than one wire to same pad. Element: " + this + ", pad: " + padName + ":" + direction + ", new link: "
+                        + link + ", existing link: " + outputPads.get(padName) + ".");
 
-                outputPads.put(padName, link);
-                link.setSource(this);
+            outputPads.put(padName, link);
+            link.setSource(this);
 
-                break;
+            break;
         }
     }
 
@@ -162,9 +165,6 @@ public class BaseElement implements Element {
      */
     @Override
     public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
         if (verbose)
             System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
 
@@ -177,7 +177,8 @@ public class BaseElement implements Element {
     protected final void pushDataToAllOuts(ByteBuffer buf) {
 
         if (buf == null)
-            return;
+            throw new NullPointerException();
+        //return;
 
         if (outputPads.size() == 0)
             throw new RuntimeException("Number of outgoing connection is zero. Cannot send data to output. Data: " + buf + ".");
@@ -218,18 +219,19 @@ public class BaseElement implements Element {
      * By default, do nothing with incoming event and retransmit event to all
      * pads.
      */
+    @SuppressWarnings("incomplete-switch")
     @Override
     public void handleEvent(Event event, Direction direction) {
         if (verbose)
             System.out.println("[" + this + "] INFO: Event " + event + ":" + direction + " is received.");
 
         switch (event) {
-            case STREAM_CLOSE:
-                onClose();
-                break;
-            case STREAM_START:
-                onStart();
-                break;
+        case STREAM_CLOSE:
+            onClose();
+            break;
+        case STREAM_START:
+            onStart();
+            break;
         }
 
         sendEventToAllPads(event, direction);
@@ -261,18 +263,18 @@ public class BaseElement implements Element {
             System.out.println("[" + this + "] INFO: Sending event " + event + ":" + direction + ".");
 
         switch (direction) {
-            case IN:
-                // Send event to all pads with IN direction
-                for (DataSource in : inputPads.values()) {
-                    in.sendEvent(event, direction);
-                }
-                break;
-            case OUT:
-                // Send event to all pads with OUT direction
-                for (DataSink out : outputPads.values()) {
-                    out.sendEvent(event, direction);
-                }
-                break;
+        case IN:
+            // Send event to all pads with IN direction
+            for (DataSource in : inputPads.values()) {
+                in.sendEvent(event, direction);
+            }
+            break;
+        case OUT:
+            // Send event to all pads with OUT direction
+            for (DataSink out : outputPads.values()) {
+                out.sendEvent(event, direction);
+            }
+            break;
         }
     }
 
@@ -290,7 +292,7 @@ public class BaseElement implements Element {
      *          source link, to push unnecessary data back
      * @param fromCursor
      *          if true, then position will be included into calculation
-     * @return true,
+     * @return true, if buffer is long enough, false otherwise
      */
     public boolean cap(ByteBuffer buf, int minLength, int maxLength, Link link, boolean fromCursor) {
 
@@ -384,16 +386,16 @@ public class BaseElement implements Element {
     public static void main(String args[]) {
         Element source = new FakeSource("source") {
             {
-                this.verbose = true;
-                this.numBuffers = 10;
-                this.incommingBufLength = 3;
-                this.delay = 100;
+                verbose = true;
+                numBuffers = 10;
+                incommingBufLength = 3;
+                delay = 100;
             }
         };
 
         Element sink = new FakeSink("sink") {
             {
-                this.verbose = true;
+                verbose = true;
             }
         };
 
@@ -411,7 +413,9 @@ public class BaseElement implements Element {
         // Links between t3-t4-sink will operate in push mode.
         // Link between t2-t3 will run main loop (pull from source and push to
         // sink).
-        pipeline.getLink("t3", STDOUT).run();
+        Link link = pipeline.getLink("t3", STDOUT);
+        link.sendEvent(Event.STREAM_START, Direction.IN);
+        link.run();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/BufferPool.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
old mode 100644
new mode 100755
index 8543a5a..3a718ba
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ByteBuffer.java
@@ -19,7 +19,9 @@ package streamer;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * This class represents a slice in a buffer.
@@ -45,9 +47,9 @@ public class ByteBuffer {
      */
     public ByteBuffer(int minLength) {
         // Get buffer of acceptable size from buffer pool
-        this.data = BufferPool.allocateNewBuffer(minLength);
-        this.offset = 0;
-        this.length = minLength;
+        data = BufferPool.allocateNewBuffer(minLength);
+        offset = 0;
+        length = minLength;
     }
 
     public ByteBuffer(byte data[]) {
@@ -55,8 +57,8 @@ public class ByteBuffer {
             throw new NullPointerException("Data must be non-null.");
 
         this.data = data;
-        this.offset = 0;
-        this.length = data.length;
+        offset = 0;
+        length = data.length;
     }
 
     public ByteBuffer(byte[] data, int offset, int length) {
@@ -74,9 +76,9 @@ public class ByteBuffer {
      */
     public ByteBuffer(int minLength, boolean reserveSpaceForHeader) {
         // Get buffer of acceptable size from buffer pool
-        this.data = BufferPool.allocateNewBuffer(128 + minLength);
-        this.offset = 128; // 100 bytes should be enough for headers
-        this.length = minLength;
+        data = BufferPool.allocateNewBuffer(128 + minLength);
+        offset = 128; // 100 bytes should be enough for headers
+        length = minLength;
     }
 
     /**
@@ -96,7 +98,7 @@ public class ByteBuffer {
 
     @Override
     public String toString() {
-        return toString(100);
+        return toString(length);
     }
 
     /**
@@ -106,8 +108,8 @@ public class ByteBuffer {
      *          number of bytes to show in string
      */
     public String toString(int maxLength) {
-        return "ByteRange(){offset=" + offset + ", length=" + length + ", cursor=" + cursor + ", data=" + ((data == null) ? "null" : toHexString(maxLength)) +
-            ((metadata == null || metadata.size() == 0) ? "" : ", metadata=" + metadata) + "}";
+        return "ByteRange(){offset=" + offset + ", length=" + length + ", cursor=" + cursor + ", data=" + ((data == null) ? "null" : toHexString(maxLength))
+                + ((metadata == null || metadata.size() == 0) ? "" : ", metadata=" + metadata) + "}";
     }
 
     /**
@@ -143,13 +145,68 @@ public class ByteBuffer {
             if (i > 0)
                 builder.append(" ");
             int b = data[offset + i] & 0xff;
-            builder.append(((b < 16) ? "0" : "") + Integer.toString(b, 16));
+            builder.append(String.format("%02x", b));
         }
         return builder.toString();
     }
 
-    public void dump() {
-        System.out.println(toString(length));
+    /**
+     * Return string representation of this byte buffer as dump, e.g.
+     * "0000  01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 .................".
+     *
+     * @param maxLength
+     *          number of bytes to show in string
+     */
+    public String dump() {
+        StringBuilder builder = new StringBuilder(length * 4);
+        int i = 0;
+        for (; i < length && i < length; i++) {
+            if (i % 16 == 0) {
+                builder.append(String.format("%04x", i));
+            }
+
+            builder.append(' ');
+            int b = data[offset + i] & 0xff;
+            builder.append(String.format("%02x", b));
+
+            if (i % 16 == 15) {
+                builder.append(' ');
+                builder.append(toASCIIString(i - 15, i));
+                builder.append('\n');
+            }
+        }
+        int end = i - 1;
+        if (end % 16 != 15) {
+            int begin = end & ~0xf;
+            for (int j = 0; j < (15 - (end % 16)); j++) {
+                builder.append("   ");
+            }
+            builder.append(' ');
+            builder.append(toASCIIString(begin, end));
+            builder.append('\n');
+        }
+        return builder.toString();
+    }
+
+    private String toASCIIString(int start, int finish) {
+        StringBuffer sb = new StringBuffer(16);
+        for (int i = start; i <= finish; i++) {
+            char ch = (char)data[offset + i];
+            if (ch < ' ' || ch >= 0x7f) {
+                sb.append('.');
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return string representation of this byte buffer as hexadecimal numbers,
+     * e.g. "01 02".
+     */
+    public String toPlainHexString() {
+        return toPlainHexString(length);
     }
 
     public void extend(int newLength) {
@@ -190,12 +247,12 @@ public class ByteBuffer {
         ref();
 
         if (this.length < (offset + length))
-            throw new RuntimeException("Length of region is larger that length of this buffer. Buffer length: " + this.length + ", offset: " + offset +
-                ", new region length: " + length + ".");
+            throw new RuntimeException("Length of region is larger that length of this buffer. Buffer length: " + this.length + ", offset: " + offset
+                    + ", new region length: " + length + ".");
 
         ByteBuffer slice = new ByteBuffer(data, this.offset + offset, length);
 
-        if (copyMetadata && this.metadata != null)
+        if (copyMetadata && metadata != null)
             slice.metadata = new HashMap<String, Object>(metadata);
 
         return slice;
@@ -251,8 +308,8 @@ public class ByteBuffer {
 
     public short[] toShortArray() {
         if (length % 2 != 0)
-            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 2 without remainder. Array length: " + length + ", remainder: " +
-                (length % 2) + ".");
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 2 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 2) + ".");
 
         short[] buf = new short[length / 2];
 
@@ -267,8 +324,8 @@ public class ByteBuffer {
      */
     public int[] toIntLEArray() {
         if (length % 4 != 0)
-            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 4 without remainder. Array length: " + length + ", remainder: " +
-                (length % 4) + ".");
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 4 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 4) + ".");
 
         int[] buf = new int[length / 4];
 
@@ -279,12 +336,13 @@ public class ByteBuffer {
     }
 
     /**
-     * Return array of int's in little endian order, but use only 3 bytes per int (3RGB).
+     * Return array of int's in little endian order, but use only 3 bytes per int
+     * (3RGB).
      */
     public int[] toInt3LEArray() {
         if (length % 3 != 0)
-            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 3 without remainder. Array length: " + length + ", remainder: " +
-                (length % 3) + ".");
+            throw new ArrayIndexOutOfBoundsException("Length of byte array must be dividable by 3 without remainder. Array length: " + length + ", remainder: "
+                    + (length % 3) + ".");
 
         int[] buf = new int[length / 3];
 
@@ -315,8 +373,8 @@ public class ByteBuffer {
         if (cursor + 4 > length)
             throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
 
-        int result =
-            (((data[offset + cursor] & 0xff) << 24) + ((data[offset + cursor + 1] & 0xff) << 16) + ((data[offset + cursor + 2] & 0xff) << 8) + (data[offset + cursor + 3] & 0xff));
+        int result = (((data[offset + cursor] & 0xff) << 24) + ((data[offset + cursor + 1] & 0xff) << 16) + ((data[offset + cursor + 2] & 0xff) << 8) + (data[offset
+                                                                                                                                                              + cursor + 3] & 0xff));
         cursor += 4;
         return result;
     }
@@ -328,8 +386,8 @@ public class ByteBuffer {
         if (cursor + 4 > length)
             throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
 
-        int result =
-            (((data[offset + cursor + 3] & 0xff) << 24) + ((data[offset + cursor + 2] & 0xff) << 16) + ((data[offset + cursor + 1] & 0xff) << 8) + (data[offset + cursor] & 0xff));
+        int result = (((data[offset + cursor + 3] & 0xff) << 24) + ((data[offset + cursor + 2] & 0xff) << 16) + ((data[offset + cursor + 1] & 0xff) << 8) + (data[offset
+                                                                                                                                                                  + cursor] & 0xff));
         cursor += 4;
         return result;
     }
@@ -341,9 +399,21 @@ public class ByteBuffer {
         if (cursor + 4 > length)
             throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
 
-        long result =
-            (((long)(data[offset + cursor + 3] & 0xff) << 24) + ((long)(data[offset + cursor + 2] & 0xff) << 16) + ((long)(data[offset + cursor + 1] & 0xff) << 8) + (data[offset +
-                cursor] & 0xff));
+        long result = (((long)(data[offset + cursor + 3] & 0xff) << 24) + ((long)(data[offset + cursor + 2] & 0xff) << 16)
+                + ((long)(data[offset + cursor + 1] & 0xff) << 8) + (data[offset + cursor + 0] & 0xff));
+        cursor += 4;
+        return result;
+    }
+
+    /**
+     * Read unsigned int in network order. Cursor is advanced by 4.
+     */
+    public long readUnsignedInt() {
+        if (cursor + 4 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 4 bytes from this buffer: " + this + ".");
+
+        long result = (((long)(data[offset + cursor + 0] & 0xff) << 24) + ((long)(data[offset + cursor + 1] & 0xff) << 16)
+                + ((long)(data[offset + cursor + 2] & 0xff) << 8) + (data[offset + cursor + 3] & 0xff));
         cursor += 4;
         return result;
     }
@@ -379,19 +449,19 @@ public class ByteBuffer {
         int firstByte = readUnsignedByte();
         int result;
         switch (firstByte & 0xc0) {
-            default:
-            case 0x00:
-                result = firstByte & 0x3f;
-                break;
-            case 0x40:
-                result = (firstByte & 0x3f << 8) | readUnsignedByte();
-                break;
-            case 0x80:
-                result = (((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte();
-                break;
-            case 0xc0:
-                result = ((((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte() << 8) | readUnsignedByte();
-                break;
+        default:
+        case 0x00:
+            result = firstByte & 0x3f;
+            break;
+        case 0x40:
+            result = (firstByte & 0x3f << 8) | readUnsignedByte();
+            break;
+        case 0x80:
+            result = (((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte();
+            break;
+        case 0xc0:
+            result = ((((firstByte & 0x3f << 8) | readUnsignedByte()) << 8) | readUnsignedByte() << 8) | readUnsignedByte();
+            break;
         }
 
         return result;
@@ -446,6 +516,18 @@ public class ByteBuffer {
     }
 
     /**
+     * Read signed short in network order. Cursor is advanced by 2.
+     */
+    public short readSignedShort() {
+        if (cursor + 2 > length)
+            throw new ArrayIndexOutOfBoundsException("Cannot read 2 bytes from this buffer: " + this + ".");
+
+        short result = (short)(((data[offset + cursor + 0] & 0xff) << 8) | (data[offset + cursor + 1] & 0xff));
+        cursor += 2;
+        return result;
+    }
+
+    /**
      * Read unsigned short in network order in variable length format. Cursor is
      * advanced by 1 or 2 bytes.
      *
@@ -456,9 +538,9 @@ public class ByteBuffer {
         int firstByte = readUnsignedByte();
 
         int result;
-        if ((firstByte & 0x80) == 0)
+        if ((firstByte & 0x80) == 0) {
             result = firstByte & 0x7f;
-        else {
+        } else {
             int secondByte = readUnsignedByte();
             result = (((firstByte & 0x7f) << 8) | secondByte);
         }
@@ -467,6 +549,174 @@ public class ByteBuffer {
     }
 
     /**
+     * Read integer in BER format.
+     *
+     * Most significant bit of first byte indicates type of date in first byte: if
+     * 0, then byte contains length (up to 7f), if 1, then byte contains number of
+     * following bytes with value in network order. Value 0x80 means unlimited
+     * length, which ends with two zero bytes (0x00 0x00) sequence.
+     *
+     * If -1 is returned by this method, then caller must seek two consecutive
+     * zeroes in buffer and consume all that data from buffer, including these two
+     * zeroes, but caller should not parse these two zeroes.
+     *
+     * @return length or -1, for unlimited length
+     */
+    public long readBerLength() {
+        int firstByte = readUnsignedByte();
+
+        long result;
+        if ((firstByte & 0x80) == 0) {
+            result = firstByte & 0x7f;
+        } else {
+            int intLength = firstByte & 0x7f;
+            if (intLength != 0)
+                result = readUnsignedVarInt(intLength);
+            else
+                return -1;
+        }
+
+        return result;
+    }
+
+    /**
+     * Read integer in BER format.
+     *
+     * Most significant bit of first byte indicates type of date in first byte: if
+     * 0, then byte contains length (up to 7f), if 1, then byte contains number of
+     * following bytes with value in network order.
+     */
+    public void writeBerLength(long length) {
+        if (length < 0)
+            throw new RuntimeException("Length cannot be less than zero: " + length + ". Data: " + this + ".");
+
+        if (length < 0x80) {
+            writeByte((int)length);
+        } else {
+            if (length < 0xff) {
+                writeByte(0x81);
+                writeByte((int)length);
+            } else if (length <= 0xffFF) {
+                writeByte(0x82);
+                writeShort((int)length);
+            } else if (length <= 0xffFFff) {
+                writeByte(0x83);
+                writeByte((int)(length >> 16));
+                writeShort((int)length);
+            } else if (length <= 0xffFFffFFL) {
+                writeByte(0x84);
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffL) {
+                writeByte(0x85);
+                writeByte((int)(length >> 32));
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffFFL) {
+                writeByte(0x86);
+                writeShort((int)(length >> 32));
+                writeInt((int)length);
+            } else if (length <= 0xffFFffFFffFFffL) {
+                writeByte(0x87);
+                writeByte((int)(length >> (32 + 16)));
+                writeShort((int)(length >> 32));
+                writeInt((int)length);
+            } else {
+                writeByte(0x88);
+                writeInt((int)(length >> 32));
+                writeInt((int)length);
+            }
+        }
+
+    }
+
+    /**
+     * Read signed variable length integers in network order.
+     *
+     * @param len
+     *          length of integer
+     */
+    public long readSignedVarInt(int len) {
+        long value = 0;
+        switch (len) {
+        case 0:
+            value = 0;
+            break;
+        case 1:
+            value = readSignedByte();
+            break;
+        case 2:
+            value = readSignedShort();
+            break;
+        case 3:
+            value = (readSignedByte() << 16) | readUnsignedShort();
+            break;
+        case 4:
+            value = readSignedInt();
+            break;
+        case 5:
+            value = (readSignedByte() << 32) | readUnsignedInt();
+            break;
+        case 6:
+            value = (readSignedShort() << 32) | readUnsignedInt();
+            break;
+        case 7:
+            value = (readSignedByte() << 32 + 24) | (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 8:
+            value = readSignedLong();
+            break;
+        default:
+            throw new RuntimeException("Cannot read integers which are more than 8 bytes long. Length: " + len + ". Data: " + this + ".");
+        }
+
+        return value;
+    }
+
+    /**
+     * Read unsigned variable length integers in network order. Values, which are
+     * larger than 0x7FffFFffFFffFFff cannot be parsed by this method.
+     */
+    public long readUnsignedVarInt(int len) {
+        long value = 0;
+        switch (len) {
+        case 0:
+            value = 0;
+            break;
+        case 1:
+            value = readUnsignedByte();
+            break;
+        case 2:
+            value = readUnsignedShort();
+            break;
+        case 3:
+            value = (readUnsignedByte() << 16) | readUnsignedShort();
+            break;
+        case 4:
+            value = readUnsignedInt();
+            break;
+        case 5:
+            value = (readUnsignedByte() << 32) | readUnsignedInt();
+            break;
+        case 6:
+            value = (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 7:
+            value = (readUnsignedByte() << 32 + 16) | (readUnsignedShort() << 32) | readUnsignedInt();
+            break;
+        case 8:
+            value = readSignedLong();
+            if (value < 0)
+                throw new RuntimeException(
+                        "Cannot read 64 bit integers which are larger than 0x7FffFFffFFffFFff, because of lack of unsinged long type in Java. Value: " + value + ". Data: "
+                                + this + ".");
+            break;
+        default:
+            throw new RuntimeException("Cannot read integers which are more than 8 bytes long. Length: " + len + ". Data: " + this + ".");
+        }
+
+        return value;
+    }
+
+    /**
      * Read unsigned short in little endian order. Cursor is advanced by 2.
      */
     public int readUnsignedShortLE() {
@@ -536,6 +786,13 @@ public class ByteBuffer {
     }
 
     /**
+     * Read signed long in network order. Cursor is advanced by 8 bytes.
+     */
+    public long readSignedLong() {
+        return (((long)readSignedInt()) << 32) | ((readSignedInt()) & 0xffFFffFFL);
+    }
+
+    /**
      * Read string from buffer. Cursor is advanced by string length.
      */
     public String readString(int length, Charset charset) {
@@ -548,6 +805,38 @@ public class ByteBuffer {
     }
 
     /**
+     * Read string with '\0' character at end.
+     */
+    public String readVariableString(Charset charset) {
+
+        int start = cursor;
+
+        // Find end of string
+        while (readUnsignedByte() != 0) {
+        }
+
+        String string = new String(data, offset + start, cursor - start - 1, charset);
+
+        return string;
+    }
+
+    /**
+     * Read wide string with wide '\0' character at end.
+     */
+    public String readVariableWideString(Charset charset) {
+
+        int start = cursor;
+
+        // Find end of string
+        while (readUnsignedShortLE() != 0) {
+        }
+
+        String string = new String(data, offset + start, cursor - start - 2, charset);
+
+        return string;
+    }
+
+    /**
      * Get bytes as lightweight slice. Cursor is advanced by data length.
      */
     public ByteBuffer readBytes(int dataLength) {
@@ -682,8 +971,8 @@ public class ByteBuffer {
      */
     public void prepend(byte[] data, int offset, int length) {
         if (!isSoleOwner()) {
-            throw new RuntimeException("Create full copy of this byte buffer data for modification. refCount: " + refCount + ", parentByteBuffer: " + parentByteBuffer +
-                ".");
+            throw new RuntimeException("Create full copy of this byte buffer data for modification. refCount: " + refCount + ", parentByteBuffer: "
+                    + parentByteBuffer + ".");
         }
 
         // If there is no enough space for header to prepend
@@ -697,9 +986,13 @@ public class ByteBuffer {
         // Extend byte range to include header
         this.offset -= length;
         this.length += length;
-        this.cursor += length;
+        cursor += length;
     }
 
+    /**
+     * Write byte representation of given string, without string terminators (zero
+     * or zeroes at end of string).
+     */
     public void writeString(String str, Charset charset) {
         writeBytes(str.getBytes(charset));
     }
@@ -725,44 +1018,10 @@ public class ByteBuffer {
     }
 
     public void writeBytes(byte[] bytes, int offset, int length) {
-        System.arraycopy(bytes, offset, this.data, this.offset + this.cursor, length);
+        System.arraycopy(bytes, offset, data, this.offset + cursor, length);
         cursor += length;
     }
 
-    // /**
-    // * Write BER encoded definite long variant of the ASN.1 length field.
-    // */
-    // public void writeBerLength(int value) {
-    // int fieldLength;
-    // if (value > 0xFFffFF)
-    // fieldLength = 4;
-    // else if (value > 0xFFff)
-    // fieldLength = 3;
-    // else if (value > 0xFF)
-    // fieldLength = 2;
-    // else
-    // fieldLength = 1;
-    //
-    // if (cursor + fieldLength + 1 > length)
-    // throw new ArrayIndexOutOfBoundsException("Cannot write " + (fieldLength +
-    // 1) + " byte(s) to this buffer: " + this + ".");
-    //
-    // // Write length of length field itself
-    // writeByte(0x80 | fieldLength);
-    //
-    // switch (fieldLength) {
-    // case 4:
-    // data[offset + cursor++] = (byte) (value >> 24);
-    // case 3:
-    // data[offset + cursor++] = (byte) (value >> 16);
-    // case 2:
-    // data[offset + cursor++] = (byte) (value >> 8);
-    // case 1:
-    // data[offset + cursor++] = (byte) value;
-    // }
-    //
-    // }
-
     /**
      * Reduce length of buffer to cursor position.
      */
@@ -771,7 +1030,7 @@ public class ByteBuffer {
     }
 
     /**
-     * Rewind cursor to beginning of buffer.
+     * Rewind cursor to beginning of the buffer.
      */
     public void rewindCursor() {
         cursor = 0;
@@ -808,8 +1067,11 @@ public class ByteBuffer {
     public boolean equals(Object obj) {
         if (this == obj)
             return true;
+
         if (obj == null)
             return false;
+
+        // Does not work in case of anonymous type(s)
         if (getClass() != obj.getClass())
             return false;
 
@@ -824,4 +1086,38 @@ public class ByteBuffer {
         return true;
     }
 
+    /**
+     * Return length of data left after cursor.
+     */
+    public int remainderLength() {
+        if (length >= cursor)
+            return length - cursor;
+        else
+            throw new RuntimeException("Inconsistent state of buffer: cursor is after end of buffer: " + this + ".");
+    }
+
+    public Set<String> getMetadataKeys() {
+        if (metadata != null)
+            return metadata.keySet();
+        else
+            return new HashSet<String>(0);
+    }
+
+    /**
+     * Return unsigned value of byte at given position relative to cursor. Cursor
+     * is not advanced.
+     */
+    public int peekUnsignedByte(int i) {
+        return data[offset + cursor + i] & 0xff;
+    }
+
+    /**
+     * Trim few first bytes.
+     */
+    public void trimHeader(int length) {
+        offset += length;
+        this.length -= length;
+        rewindCursor();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSink.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/DataSource.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Direction.java
old mode 100644
new mode 100755


[15/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
deleted file mode 100644
index 9605b85..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerDemandActivePDU.java
+++ /dev/null
@@ -1,660 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSink;
-import streamer.Link;
-import streamer.MockSource;
-import streamer.Order;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-import common.ScreenDescription;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240669.aspx
- * @see http://msdn.microsoft.com/en-us/library/cc240484.aspx
- */
-public class ServerDemandActivePDU extends BaseElement {
-
-    /**
-     * Demand Active PDU.
-     */
-    public static final int PDUTYPE_DEMANDACTIVEPDU = 0x1;
-
-    protected RdpState state;
-    protected ScreenDescription screen;
-
-    public ServerDemandActivePDU(String id, ScreenDescription screen, RdpState state) {
-        super(id);
-        this.state = state;
-        this.screen = screen;
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Total length of packet
-        int length = buf.readSignedShortLE(); // Ignore
-        if (buf.length != length)
-            throw new RuntimeException("Incorrect length of packet. Length: " + length + ", data: " + buf + ".");
-
-        int type = buf.readSignedShortLE() & 0xf;
-        if (type != PDUTYPE_DEMANDACTIVEPDU)
-            throw new RuntimeException("Unknown PDU type. Expected type: Demand Active PDU (0x1), actual tyoe: " + type + ", data: " + buf + ".");
-
-        // TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
-        int pduSource = buf.readSignedShortLE();
-        if (pduSource != 1002)
-            throw new RuntimeException("Unexepcted source of demand active PDU. Expected source: 1002, actual source: " + pduSource + ".");
-
-        // (4 bytes): A 32-bit, unsigned integer. The share identifier for the
-        // packet (see [T128] section 8.4.2 for more information regarding share
-        // IDs).
-        long shareId = buf.readUnsignedIntLE();
-        state.serverShareId = shareId;
-
-        // Ignore rest of server data because it is not used by this client.
-        // (2 bytes): A 16-bit, unsigned integer. The size in bytes of the
-        // sourceDescriptor field.
-        int lengthSourceDescriptor = buf.readUnsignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. The combined size in bytes of the
-        // numberCapabilities, pad2Octets, and capabilitySets fields.
-        int lengthCombinedCapabilities = buf.readUnsignedShortLE();
-
-        // (variable): A variable-length array of bytes containing a source
-        // descriptor,
-        // ByteBuffer sourceDescriptor = buf.readBytes(lengthSourceDescriptor);
-        buf.skipBytes(lengthSourceDescriptor);
-
-        // (variable): An array of Capability Set (section 2.2.1.13.1.1.1)
-        // structures. The number of capability sets is specified by the
-        // numberCapabilities field.
-        handleCapabiltySets(buf.readBytes(lengthCombinedCapabilities));
-
-        // (4 bytes): A 32-bit, unsigned integer. The session identifier. This field
-        // is ignored by the client.
-        buf.skipBytes(4);
-
-        /* DEBUG */buf.assertThatBufferIsFullyRead();
-
-        buf.unref();
-
-        sendHandshakePackets();
-    }
-
-    /**
-     * General Capability Set
-     */
-    public static final int CAPSTYPE_GENERAL = 0x0001;
-    /**
-     * Bitmap Capability Set
-     */
-    public static final int CAPSTYPE_BITMAP = 0x0002;
-    /**
-     * Order Capability Set
-     */
-    public static final int CAPSTYPE_ORDER = 0x0003;
-    /**
-     * Revision 1 Bitmap Cache Capability Set
-     */
-    public static final int CAPSTYPE_BITMAPCACHE = 0x0004;
-    /**
-     * Control Capability Set
-     */
-    public static final int CAPSTYPE_CONTROL = 0x0005;
-    /**
-     * Window Activation Capability Set
-     */
-    public static final int CAPSTYPE_ACTIVATION = 0x0007;
-    /**
-     * Pointer Capability Set
-     */
-    public static final int CAPSTYPE_POINTER = 0x0008;
-    /**
-     * Share Capability Set
-     */
-    public static final int CAPSTYPE_SHARE = 0x0009;
-    /**
-     * Color Table Cache Capability Set
-     */
-    public static final int CAPSTYPE_COLORCACHE = 0x000A;
-    /**
-     * Sound Capability Set
-     */
-    public static final int CAPSTYPE_SOUND = 0x000C;
-    /**
-     * Input Capability Set
-     */
-    public static final int CAPSTYPE_INPUT = 0x000D;
-    /**
-     * Font Capability Set
-     */
-    public static final int CAPSTYPE_FONT = 0x000E;
-    /**
-     * Brush Capability Set
-     */
-    public static final int CAPSTYPE_BRUSH = 0x000F;
-    /**
-     * Glyph Cache Capability Set
-     */
-    public static final int CAPSTYPE_GLYPHCACHE = 0x0010;
-    /**
-     * Offscreen Bitmap Cache Capability Set
-     */
-    public static final int CAPSTYPE_OFFSCREENCACHE = 0x0011;
-    /**
-     * Bitmap Cache Host Support Capability Set
-     */
-    public static final int CAPSTYPE_BITMAPCACHE_HOSTSUPPORT = 0x0012;
-    /**
-     * Revision 2 Bitmap Cache Capability Set
-     */
-    public static final int CAPSTYPE_BITMAPCACHE_REV2 = 0x0013;
-    /**
-     * Virtual Channel Capability Set
-     */
-    public static final int CAPSTYPE_VIRTUALCHANNEL = 0x0014;
-    /**
-     * DrawNineGrid Cache Capability Set
-     */
-    public static final int CAPSTYPE_DRAWNINEGRIDCACHE = 0x0015;
-    /**
-     * Draw GDI+ Cache Capability Set
-     */
-    public static final int CAPSTYPE_DRAWGDIPLUS = 0x0016;
-    /**
-     * Remote Programs Capability Set
-     */
-    public static final int CAPSTYPE_RAIL = 0x0017;
-    /**
-     * Window List Capability Set
-     */
-    public static final int CAPSTYPE_WINDOW = 0x0018;
-    /**
-     * Desktop Composition Extension Capability Set
-     */
-    public static final int CAPSETTYPE_COMPDESK = 0x0019;
-    /**
-     * Multifragment Update Capability Set
-     */
-    public static final int CAPSETTYPE_MULTIFRAGMENTUPDATE = 0x001A;
-    /**
-     * Large Pointer Capability Set
-     */
-    public static final int CAPSETTYPE_LARGE_POINTER = 0x001B;
-    /**
-     * Surface Commands Capability Set
-     */
-    public static final int CAPSETTYPE_SURFACE_COMMANDS = 0x001C;
-    /**
-     * Bitmap Codecs Capability Set
-     */
-    public static final int CAPSETTYPE_BITMAP_CODECS = 0x001D;
-    /**
-     * Frame Acknowledge Capability Set
-     */
-    public static final int CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E;
-
-    /**
-     * @see http://msdn.microsoft.com/en-us/library/cc240486.aspx
-     */
-    protected void handleCapabiltySets(ByteBuffer buf) {
-        // (2 bytes): A 16-bit, unsigned integer. The number of capability sets
-        // included in the Demand Active PDU.
-        int numberCapabilities = buf.readSignedShortLE();
-
-        // (2 bytes): Padding.
-        buf.skipBytes(2);
-
-        for (int i = 0; i < numberCapabilities; i++) {
-            // (2 bytes): A 16-bit, unsigned integer. The type identifier of the
-            // capability set.
-            int capabilitySetType = buf.readUnsignedShortLE();
-
-            // (2 bytes): A 16-bit, unsigned integer. The length in bytes of the
-            // capability data, including the size of the capabilitySetType and
-            // lengthCapability fields.
-            int lengthCapability = buf.readUnsignedShortLE();
-
-            // (variable): Capability set data which conforms to the structure of the
-            // type given by the capabilitySetType field.
-            ByteBuffer capabilityData = buf.readBytes(lengthCapability - 4);
-
-            switch (capabilitySetType) {
-                case CAPSTYPE_GENERAL:
-                    break;
-                case CAPSTYPE_BITMAP:
-                    handleBitmapCapabilities(capabilityData);
-                    break;
-                case CAPSTYPE_ORDER:
-                    break;
-                case CAPSTYPE_BITMAPCACHE:
-                    break;
-                case CAPSTYPE_CONTROL:
-                    break;
-                case CAPSTYPE_ACTIVATION:
-                    break;
-                case CAPSTYPE_POINTER:
-                    break;
-                case CAPSTYPE_SHARE:
-                    break;
-                case CAPSTYPE_COLORCACHE:
-                    break;
-                case CAPSTYPE_SOUND:
-                    break;
-                case CAPSTYPE_INPUT:
-                    break;
-                case CAPSTYPE_FONT:
-                    break;
-                case CAPSTYPE_BRUSH:
-                    break;
-                case CAPSTYPE_GLYPHCACHE:
-                    break;
-                case CAPSTYPE_OFFSCREENCACHE:
-                    break;
-                case CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:
-                    break;
-                case CAPSTYPE_BITMAPCACHE_REV2:
-                    break;
-                case CAPSTYPE_VIRTUALCHANNEL:
-                    break;
-                case CAPSTYPE_DRAWNINEGRIDCACHE:
-                    break;
-                case CAPSTYPE_DRAWGDIPLUS:
-                    break;
-                case CAPSTYPE_RAIL:
-                    break;
-                case CAPSTYPE_WINDOW:
-                    break;
-                case CAPSETTYPE_COMPDESK:
-                    break;
-                case CAPSETTYPE_MULTIFRAGMENTUPDATE:
-                    break;
-                case CAPSETTYPE_LARGE_POINTER:
-                    break;
-                case CAPSETTYPE_SURFACE_COMMANDS:
-                    break;
-                case CAPSETTYPE_BITMAP_CODECS:
-                    break;
-                case CAPSSETTYPE_FRAME_ACKNOWLEDGE:
-                    break;
-                default:
-                    // Ignore
-                    break;
-            }
-
-            capabilityData.unref();
-        }
-
-        // TODO
-
-        buf.unref();
-    }
-
-    /**
-     * @see http://msdn.microsoft.com/en-us/library/cc240554.aspx
-     */
-    protected void handleBitmapCapabilities(ByteBuffer buf) {
-
-        // (2 bytes): A 16-bit, unsigned integer. The server MUST set this field to
-        // the color depth of the session, while the client SHOULD set this field to
-        // the color depth requested in the Client Core Data (section 2.2.1.3.2).
-        int preferredBitsPerPixel = buf.readUnsignedShortLE();
-        screen.setPixelFormatRGBTrueColor(preferredBitsPerPixel);
-
-        // receive1BitPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether the client can receive 1 bpp. This field is ignored and SHOULD be
-        // set to TRUE (0x0001).
-        buf.skipBytes(2);
-
-        // receive4BitsPerPixel(2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether the client can receive 4 bpp. This field is ignored and SHOULD be
-        // set to TRUE (0x0001).
-        buf.skipBytes(2);
-
-        // receive8BitsPerPixel (2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether the client can receive 8 bpp. This field is ignored and SHOULD be
-        // set to TRUE (0x0001).
-        buf.skipBytes(2);
-
-        // (2 bytes): A 16-bit, unsigned integer. The width of the desktop in the
-        // session.
-        int desktopWidth = buf.readUnsignedShortLE();
-
-        // (2 bytes): A 16-bit, unsigned integer. The height of the desktop in the
-        // session.
-        int desktopHeight = buf.readUnsignedShortLE();
-
-        screen.setFramebufferSize(desktopWidth, desktopHeight);
-
-        // pad2octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
-        // field MUST be ignored.
-
-        // desktopResizeFlag (2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether resizing the desktop by using a Deactivation-Reactivation
-        // Sequence is supported.
-
-        // bitmapCompressionFlag (2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether bitmap compression is supported. This field MUST be set to TRUE
-        // (0x0001) because support for compressed bitmaps is required for a
-        // connection to proceed.
-
-        // highColorFlags (1 byte): An 8-bit, unsigned integer. Client support for
-        // 16 bpp color modes. This field is ignored and SHOULD be set to zero.
-
-        // drawingFlags (1 byte): An 8-bit, unsigned integer. Flags describing
-        // support for 32 bpp bitmaps.
-
-        // multipleRectangleSupport (2 bytes): A 16-bit, unsigned integer. Indicates
-        // whether the use of multiple bitmap rectangles is supported in the Bitmap
-        // Update (section 2.2.9.1.1.3.1.2). This field MUST be set to TRUE (0x0001)
-        // because multiple rectangle support is required for a connection to
-        // proceed.
-
-        // pad2octetsB (2 bytes): A 16-bit, unsigned integer. Padding. Values in
-        // this field MUST be ignored.
-    }
-
-    /**
-     * Send all client requests in one hop, to simplify logic.
-     */
-    protected void sendHandshakePackets() {
-        // Send reactivation sequence in bulk
-        pushDataToPad("confirm_active", new ByteBuffer((Order)null));
-    }
-
-    /**
-     * 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[] {
-        0x67, 0x01,  //  TS_SHARECONTROLHEADER::totalLength = 0x0167 = 359 bytes
-        0x11, 0x00,  //  TS_SHARECONTROLHEADER::pduType = 0x0011 0x0011 = 0x0010 | 0x0001  = TS_PROTOCOL_VERSION | PDUTYPE_DEMANDACTIVEPDU
-
-        (byte) 0xea, 0x03,  //  TS_SHARECONTROLHEADER::pduSource = 0x03ea (1002)
-
-        (byte) 0xea, 0x03, 0x01, 0x00,  //  TS_DEMAND_ACTIVE_PDU::shareId
-        0x04, 0x00,  //  TS_DEMAND_ACTIVE_PDU::lengthSourceDescriptor = 4 bytes
-        0x51, 0x01,  //  TS_DEMAND_ACTIVE_PDU::lengthCombinedCapabilities = 0x151 = 337 bytes
-
-        0x52, 0x44, 0x50, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sourceDescriptor = "RDP"
-
-        0x0d, 0x00,  //  TS_DEMAND_ACTIVE_PDU::numberCapabilities = 13
-        0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::pad2octets
-
-        //  Share Capability Set (8 bytes)
-        // 0x09, 0x00, 0x08, 0x00, (byte) 0xea, 0x03, (byte) 0xdc, (byte) 0xe2,
-        //
-        0x09, 0x00,  //  TS_SHARE_CAPABILITYSET::capabilitySetType = CAPSTYPE_SHARE (9)
-        0x08, 0x00,  //  TS_SHARE_CAPABILITYSET::lengthCapability = 8 bytes
-        (byte) 0xea, 0x03,  //  TS_SHARE_CAPABILITYSET::nodeID = 0x03ea (1002)
-        (byte) 0xdc, (byte) 0xe2,  //  TS_SHARE_CAPABILITYSET::pad2octets
-
-        //  General Capability Set (24 bytes)
-        // 0x01, 0x00, 0x18, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x04,
-        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-        //
-        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::capabilitySetType = CAPSTYPE_GENERAL (1)
-        0x18, 0x00,  //  TS_GENERAL_CAPABILITYSET::lengthCapability = 24 bytes
-
-        0x01, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMajorType = TS_OSMAJORTYPE_WINDOWS (1)
-        0x03, 0x00,  //  TS_GENERAL_CAPABILITYSET::osMinorType = TS_OSMINORTYPE_WINDOWS_NT (3)
-        0x00, 0x02,  //  TS_GENERAL_CAPABILITYSET::protocolVersion = TS_CAPS_PROTOCOLVERSION (0x0200)
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::pad2octetsA
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionTypes = 0
-        0x1d, 0x04,  //  TS_GENERAL_CAPABILITYSET::extraFlags = 0x041d = 0x0400 | 0x0010 | 0x0008 | 0x0004 | 0x0001 = NO_BITMAP_COMPRESSION_HDR | ENC_SALTED_CHECKSUM | AUTORECONNECT_SUPPORTED | LONG_CREDENTIALS_SUPPORTED | FASTPATH_OUTPUT_SUPPORTED
-
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::updateCapabilityFlag = 0
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::remoteUnshareFlag = 0
-        0x00, 0x00,  //  TS_GENERAL_CAPABILITYSET::generalCompressionLevel = 0
-        0x01,  //  TS_GENERAL_CAPABILITYSET::refreshRectSupport = TRUE
-        0x01,  //  TS_GENERAL_CAPABILITYSET::suppressOutputSupport = TRUE
-
-        // Virtual Channel Capability Set (8 bytes)
-        // 0x14, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00,
-        //
-        0x14, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::capabilitySetType = CAPSTYPE_VIRTUALCHANNEL (20)
-        0x08, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x02, 0x00, 0x00, 0x00,  //  TS_VIRTUALCHANNEL_CAPABILITYSET::vccaps1 = 0x00000002 = VCCAPS_COMPR_CS_8K
-
-        //  DrawGdiPlus Capability Set (40 bytes)
-        // 0x16, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, (byte) 0xf6, 0x13, (byte) 0xf3, 0x01, 0x00, 0x00, 0x00,
-        // 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, (byte) 0x9c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x61, (byte) 0xa6, (byte) 0x82, (byte) 0x80,
-        // 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, (byte) 0x91, (byte) 0xbf,
-        //
-        0x16, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::capabilitySetType = CAPSTYPE_DRAWGDIPLUS (22)
-        0x28, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::lengthCapability = 40 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusSupportLevel = TS_DRAW_GDIPLUS_DEFAULT (0)
-        0x70, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::GdipVersion (not initialized by server)
-        0x01, 0x00, 0x00, 0x00,  //  TS_DRAW_GDIPLUS_CAPABILITYSET::drawGdiplusCacheLevel  = TS_DRAW_GDIPLUS_CACHE_LEVEL_ONE (1)
-
-        0x01, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipGraphicsCacheEntries  (not initialized by server)
-        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectBrushCacheEntries (not initialized by server)
-        0x18, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectPenCacheEntries (not initialized by server)
-        0x00, 0x00,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageCacheEntries (not initialized by server)
-        (byte) 0x9c, (byte) 0xf6,  //  TS_GDIPLUS_CACHE_ENTRIES::GdipObjectImageAttributesCacheEntries (not initialized by server)
-
-        0x13, (byte) 0xf3,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipGraphicsCacheChunkSize  (not initialized by server)
-        0x61, (byte) 0xa6,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectBrushCacheChunkSize (not initialized by server)
-        (byte) 0x82, (byte) 0x80,  //  TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectPenCacheChunkSize (not initialized by server)
-        0x00, 0x00,  //   TS_GDIPLUS_CACHE_CHUNK_SIZE::GdipObjectImageAttributesCacheChunkSize (not initialized by server)
-
-        0x00, 0x00,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheChunkSize  (not initialized by server)
-        0x00, 0x50,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheTotalSize  (not initialized by server)
-        (byte) 0x91, (byte) 0xbf,  //  TS_GDIPLUS_IMAGE_CACHE_PROPERTIES::GdipObjectImageCacheMaxSize (not initialized by server)
-
-        //  Font Capability Set (4 bytes)
-        // 0x0e, 0x00, 0x04, 0x00,
-        //
-        // Due to a bug, the TS_FONT_CAPABILITYSET capability set size is incorrectly set to 4 bytes (it must be 8 bytes). As a result of this bug, the fontSupportFlags and pad2octets fields are missing.
-        0x0e, 0x00,  //  TS_FONT_CAPABILITYSET::capabilitySetType = CAPSTYPE_FONT (14)
-        0x04, 0x00,  //  TS_FONT_CAPABILITYSET::lengthCapability = 4 bytes
-
-
-        //  Bitmap Capability Set (28 bytes)
-        // 0x02, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04,
-        // 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-        //
-        0x02, 0x00,  //  TS_BITMAP_CAPABILITYSET::capabilitySetType = CAPSTYPE_BITMAP (2)
-        0x1c, 0x00,  //  TS_BITMAP_CAPABILITYSET::lengthCapability = 28 bytes
-
-        0x18, 0x00,  //  TS_BITMAP_CAPABILITYSET::preferredBitsPerPixel = 24 bpp
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive1BitPerPixel = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive4BitsPerPixel = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::receive8BitsPerPixel = TRUE
-        0x00, 0x05,  //  TS_BITMAP_CAPABILITYSET::desktopWidth = 1280 pixels
-        0x00, 0x04,  //  TS_BITMAP_CAPABILITYSET::desktopHeight = 1024 pixels
-        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octets
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::desktopResizeFlag = TRUE
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::bitmapCompressionFlag = TRUE
-        0x00,  //  TS_BITMAP_CAPABILITYSET::highColorFlags = 0
-        0x00,  //  TS_BITMAP_CAPABILITYSET::pad1octet
-        0x01, 0x00,  //  TS_BITMAP_CAPABILITYSET::multipleRectangleSupport = TRUE
-        0x00, 0x00,  //  TS_BITMAP_CAPABILITYSET::pad2octetsB
-
-        //  Order Capability Set (88 bytes)
-        // 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        // 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00,
-        // 0x00, 0x00, 0x22, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
-        // 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
-        // 0x00, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, 0x40, 0x42, 0x0f, 0x00,
-        // 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        //
-        0x03, 0x00,  //  TS_ORDER_CAPABILITYSET::capabilitySetType = CAPSTYPE_ORDER (3)
-        0x58, 0x00,  //  TS_ORDER_CAPABILITYSET::lengthCapability = 88 bytes
-
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // TS_ORDER_CAPABILITYSET::terminalDescriptor = ""
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsA
-
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveXGranularity = 1
-        0x14, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveYGranularity = 20
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsA
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::maximumOrderLevel = ORD_LEVEL_1_ORDERS (1)
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::numberFonts = 0
-
-        0x22, 0x00,  //  TS_ORDER_CAPABILITYSET::orderFlags = 0x0022 = 0x0020 | 0x0002 = COLORINDEXSUPPORT | NEGOTIATEORDERSUPPORT
-
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DSTBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_PATBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SCRBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ATEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_AEXTTEXTOUT_INDEX] = FALSE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_DRAWNINEGRID_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_LINETO_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_OPAQUERECT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_SAVEBITMAP_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEMBLT_R2_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MEM3BLT_R2_INDEX] = FALSE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIDSTBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIPATBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTISCRBLT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_MULTIOPAQUERECT_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_INDEX_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_SC_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYGON_CB_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_POLYLINE_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[23] = 0
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_FAST_GLYPH_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_SC_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_ELLIPSE_CB_INDEX] = TRUE
-        0x01,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_INDEX_INDEX] = TRUE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WEXTTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[TS_NEG_WLONGEXTTEXTOUT_INDEX] = FALSE
-        0x00,  //  TS_ORDER_CAPABILITYSET::orderSupport[24] = 0
-
-        (byte) 0xa1, 0x06,  //  TS_ORDER_CAPABILITYSET::textFlags = 0x06a1
-
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsB
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::pad4octetsB
-
-        0x40, 0x42, 0x0f, 0x00,  //  TS_ORDER_CAPABILITYSET::desktopSaveSize = 0xf4240 = 1000000
-        0x01, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsC
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsD
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::textANSICodePage
-        0x00, 0x00,  //  TS_ORDER_CAPABILITYSET::pad2octetsE
-
-        // Color Table Cache Capability Set (8 bytes)
-        // 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00,
-        //
-        0x0a, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::capabilitySetType = CAPSTYPE_COLORCACHE (10)
-        0x08, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x06, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::colorTableCacheSize = 6
-        0x00, 0x00,  //  TS_COLORTABLECACHE_CAPABILITYSET::pad2octets
-
-        // Bitmap Cache Host Support Capability Set (8 bytes)
-        // 0x12, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
-        //
-        0x12, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::capabilitySetType  = CAPSTYPE_BITMAPCACHE_HOSTSUPPORT (18)
-        0x08, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::lengthCapability  = 8 bytes
-
-        0x01,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::CacheVersion = 1  (corresponds to rev. 2 capabilities)
-        0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad1
-        0x00, 0x00,  //  TS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT::Pad2
-
-        // Pointer Capability Set (10 bytes)
-        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x19, 0x00,
-        //
-        0x08, 0x00,  //  TS_POINTER_CAPABILITYSET::capabilitySetType = CAPSTYPE_POINTER (8)
-        0x0a, 0x00,  //  TS_POINTER_CAPABILITYSET::lengthCapability = 10 bytes
-
-        0x01, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerFlag = TRUE
-        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::colorPointerCacheSize = 25
-        0x19, 0x00,  //  TS_POINTER_CAPABILITYSET::pointerCacheSize = 25
-
-        //  Input Capability Set (88 bytes)
-        // 0x0d, 0x00, 0x58, 0x00, 0x35, 0x00, 0x00, 0x00, (byte) 0xa1, 0x06, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00,
-        // 0x0c, (byte) 0xf6, 0x13, (byte) 0xf3, (byte) 0x93, 0x5a, 0x37, (byte) 0xf3, 0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3,
-        // 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00, 0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
-        // 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3,
-        // 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00,
-        // 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
-        //
-        0x0d, 0x00,  //  TS_INPUT_CAPABILITYSET::capabilitySetType = CAPSTYPE_INPUT (13)
-        0x58, 0x00,  //  TS_INPUT_CAPABILITYSET::lengthCapability = 88 bytes
-
-        0x35, 0x00,  //  TS_INPUT_CAPABILITYSET::inputFlags = 0x0035 = 0x0020 | 0x0010 | 0x0004 | 0x0001 = INPUT_FLAG_FASTPATH_INPUT2 | INPUT_FLAG_VKPACKET | INPUT_FLAG_MOUSEX | INPUT_FLAG_SCANCODES
-
-        0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::pad2octetsA
-        (byte) 0xa1, 0x06, 0x00, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardLayout (not initialized by server)
-        0x40, 0x42, 0x0f, 0x00,  //  TS_INPUT_CAPABILITYSET::keyboardType (not initialized by server)
-        0x0c, (byte) 0xf6, 0x13, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardSubType  (not initialized by server)
-        (byte) 0x93, 0x5a, 0x37, (byte) 0xf3,  //  TS_INPUT_CAPABILITYSET::keyboardFunctionKey (not initialized by server)
-
-        // TS_INPUT_CAPABILITYSET::imeFileName (not initialized by server)
-        0x00, (byte) 0x90, 0x30, (byte) 0xe1, 0x34, 0x1c, 0x38, (byte) 0xf3, 0x40, (byte) 0xf6, 0x13, (byte) 0xf3, 0x04, 0x00, 0x00, 0x00,
-        0x4c, 0x54, (byte) 0xdc, (byte) 0xe2, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2, 0x01, 0x00, 0x00, 0x00, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
-        0x00, 0x00, 0x00, 0x00, 0x38, (byte) 0xf6, 0x13, (byte) 0xf3, 0x2e, 0x05, 0x38, (byte) 0xf3, 0x08, 0x50, (byte) 0xdc, (byte) 0xe2,
-        0x2c, (byte) 0xf6, 0x13, (byte) 0xf3, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x19, 0x00,
-
-        //  RAIL Capability Set (8 bytes)
-        // 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-        //
-        0x17, 0x00,  //  TS_RAIL_CAPABILITYSET::capabilitySetType = CAPSTYPE_RAIL (23)
-        0x08, 0x00,  //  TS_RAIL_CAPABILITYSET::lengthCapability = 8 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_RAIL_CAPABILITYSET::railSupportLevel = TS_RAIL_LEVEL_DEFAULT (0)
-
-        //  Windowing Capability Set (11 bytes)
-        // 0x18, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        //
-        0x18, 0x00,  //  TS_WINDOW_CAPABILITYSET::capabilitySetType =  CAPSTYPE_WINDOW (24)
-        0x0b, 0x00,  //  TS_WINDOW_CAPABILITYSET::lengthCapability = 11 bytes
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::wndSupportLevel = TS_WINDOW_LEVEL_DEFAULT (0)
-        0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCaches = 0
-        0x00, 0x00,  //  TS_WINDOW_CAPABILITYSET::nIconCacheEntries = 0
-
-        // Remainder of Demand Active PDU:
-
-        0x00, 0x00, 0x00, 0x00,  //  TS_DEMAND_ACTIVE_PDU::sessionId = 0
-    };
-    /* @formatter:on */
-
-        RdpState rdpState = new RdpState();
-        ScreenDescription screenDescription = new ScreenDescription();
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element demandActive = new ServerDemandActivePDU("demand_active", screenDescription, rdpState);
-        Element sink = new FakeSink("sink");
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, demandActive, sink);
-        pipeline.link("source", "demand_active", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
deleted file mode 100644
index 1d7ddc2..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerFastPath.java
+++ /dev/null
@@ -1,258 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240621.aspx
- */
-public class ServerFastPath extends BaseElement {
-
-    /**
-     * TPKT protocol version (first byte).
-     */
-    public static final int PROTOCOL_TPKT = 3;
-
-    /**
-     * Fast path protocol version (first two bits of first byte).
-     */
-    public static final int PROTOCOL_FASTPATH = 0;
-
-    /**
-     * TPKT packets will be pushed to that pad.
-     */
-    public static final String TPKT_PAD = "tpkt";
-
-    private static final String ORDERS_PAD = "orders";
-    private static final String BITMAP_PAD = "bitmap";
-    private static final String PALETTE_PAD = "palette";
-
-    /**
-     * Indicates that packet contains 8 byte secure checksum at top of packet. Top
-     * two bits of first byte.
-     */
-    public static final int FASTPATH_OUTPUT_SECURE_CHECKSUM = 1;
-
-    /**
-     * Indicates that packet contains 8 byte secure checksum at top of packet and
-     * packet content is encrypted. Top two bits of first byte.
-     */
-    public static final int FASTPATH_OUTPUT_ENCRYPTED = 2;
-
-    public static final int FASTPATH_UPDATETYPE_ORDERS = 0;
-    public static final int FASTPATH_UPDATETYPE_BITMAP = 1;
-    public static final int FASTPATH_UPDATETYPE_PALETTE = 2;
-    public static final int FASTPATH_UPDATETYPE_SYNCHRONIZE = 3;
-    public static final int FASTPATH_UPDATETYPE_SURFCMDS = 4;
-    public static final int FASTPATH_UPDATETYPE_PTR_NULL = 5;
-    public static final int FASTPATH_UPDATETYPE_PTR_DEFAULT = 6;
-    public static final int FASTPATH_UPDATETYPE_PTR_POSITION = 8;
-    public static final int FASTPATH_UPDATETYPE_COLOR = 9;
-    public static final int FASTPATH_UPDATETYPE_CACHED = 0xa;
-    public static final int FASTPATH_UPDATETYPE_POINTER = 0xb;
-
-    public static final int FASTPATH_FRAGMENT_SINGLE = 0;
-    public static final int FASTPATH_FRAGMENT_LAST = 1;
-    public static final int FASTPATH_FRAGMENT_FIRST = 2;
-    public static final int FASTPATH_FRAGMENT_NEXT = 3;
-
-    public static final int FASTPATH_OUTPUT_COMPRESSION_USED = 2;
-
-    public ServerFastPath(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        //* DEBUG */System.out.println(buf.toHexString(buf.length));
-
-        // We need at 4 bytes to read packet type (TPKT or FastPath) and packet
-        // length
-        if (!cap(buf, 4, UNLIMITED, link, false))
-            return;
-
-        int typeAndFlags = buf.readUnsignedByte();
-
-        if (typeAndFlags == PROTOCOL_TPKT) {
-            //
-            // TPKT
-            //
-
-            // Reserved
-            buf.skipBytes(1);
-
-            // Read TPKT length
-            int length = buf.readUnsignedShort();
-
-            if (!cap(buf, length, length, link, false))
-                // Wait for full packet to arrive
-                return;
-
-            pushDataToPad(TPKT_PAD, buf);
-
-            // TPKT is handled
-            return;
-        }
-
-        //
-        // FastPath
-        //
-        // Number of bytes in updateData field (including header (1+1 or 2
-        // bytes))
-        int length = buf.readVariableUnsignedShort();
-
-        // Length is the size of payload, so we need to calculate from cursor
-        if (!cap(buf, length, length, link, false))
-            // Wait for full packet to arrive
-            return;
-
-        int type = typeAndFlags & 0x3;
-        int securityFlags = (typeAndFlags >> 6) & 0x3;
-
-        // Assertions
-        {
-            if (type != PROTOCOL_FASTPATH)
-                throw new RuntimeException("Unknown protocol. Expected protocol: 0 (FastPath). Actual protocol: " + type + ", data: " + buf + ".");
-
-            switch (securityFlags) {
-                case FASTPATH_OUTPUT_SECURE_CHECKSUM:
-                    // TODO
-                    throw new RuntimeException("Secure checksum is not supported in FastPath packets.");
-                case FASTPATH_OUTPUT_ENCRYPTED:
-                    // TODO
-                    throw new RuntimeException("Encryption is not supported in FastPath packets.");
-            }
-        }
-
-        // TODO: optional FIPS information, when FIPS is selected
-        // TODO: optional data signature (checksum), when checksum or FIPS is
-        // selected
-
-        // Array of FastPath update fields
-        while (buf.cursor < buf.length) {
-
-            int updateHeader = buf.readUnsignedByte();
-
-            int size = buf.readUnsignedShortLE();
-
-            int updateCode = updateHeader & 0xf;
-            int fragmentation = (updateHeader >> 4) & 0x3;
-            int compression = (updateHeader >> 6) & 0x3;
-
-            if (verbose)
-                System.out.println("[" + this + "] INFO: FastPath update received. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: " +
-                    compression + ", size: " + size + ".");
-
-            ByteBuffer data = buf.readBytes(size);
-            buf.putMetadata("fragmentation", fragmentation);
-            buf.putMetadata("compression", compression);
-
-            switch (updateCode) {
-
-                case FASTPATH_UPDATETYPE_ORDERS:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_ORDERS.");
-                    pushDataToPad(ORDERS_PAD, data);
-                    break;
-
-                case FASTPATH_UPDATETYPE_BITMAP:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_BITMAP.");
-                    pushDataToPad(BITMAP_PAD, data);
-                    break;
-
-                case FASTPATH_UPDATETYPE_PALETTE:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PALETTE.");
-                    pushDataToPad(PALETTE_PAD, data);
-                    break;
-
-                case FASTPATH_UPDATETYPE_SYNCHRONIZE:
-                    // @see http://msdn.microsoft.com/en-us/library/cc240625.aspx
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SYNCHRONIZE.");
-
-                    data.unref();
-
-                    if (size != 0)
-                        throw new RuntimeException("Size of FastPath synchronize packet must be 0. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation +
-                            ", compression: " + compression + ", size: " + size + ", data: " + data + ".");
-                    break;
-
-                case FASTPATH_UPDATETYPE_SURFCMDS:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_SURFCMDS.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_PTR_NULL:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_NULL.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_PTR_DEFAULT:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_DEFAULT.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_PTR_POSITION:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_PTR_POSITION.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_COLOR:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_COLOR.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_CACHED:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_CACHED.");
-
-                    break;
-
-                case FASTPATH_UPDATETYPE_POINTER:
-                    if (verbose)
-                        System.out.println("[" + this + "] INFO: FASTPATH_UPDATETYPE_POINTER.");
-
-                    break;
-
-                default:
-                    throw new RuntimeException("Unknown FastPath update. UpdateCode: " + updateCode + ", fragmentation: " + fragmentation + ", compression: " +
-                        compression + ", size: " + size + ", data: " + data + ".");
-
-            }
-
-        }
-
-        buf.unref();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
deleted file mode 100644
index 7384c95..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerLicenseErrorPDUValidClient.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerLicenseErrorPDUValidClient extends OneTimeSwitch {
-
-    public ServerLicenseErrorPDUValidClient(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-    /* @formatter:off */
-//   * Server Error alert
-//
-//03 00 00 22 02 F0 80 68 00 01 03 EB 70 14 80 00 F1 BC FF 03 10 00 07 00 00 00 02 00 00 00 04 00 00 00
-//
-//
-// Frame: Number = 30, Captured Frame Length = 91, MediaType = DecryptedPayloadHeader
-//+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-// TLSSSLData: Transport Layer Security (TLS) Payload Data
-//+ TLS: TLS Rec Layer-1 SSL Application Data
-// ISOTS: TPKTCount = 1
-//- TPKT: version: 3, Length: 34
-//    version: 3 (0x3)
-//    Reserved: 0 (0x0)
-//    PacketLength: 34 (0x22)
-//- X224: Data
-//    Length: 2 (0x2)
-//    Type: Data
-//    EOT: 128 (0x80)
-//- T125: Data Packet
-// - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-//  - Type: Send Data Indication
-//    - RootIndex: 26
-//      Value: (011010..) 0x1a
-//  - UserID: 0x3ea
-//    - UserID: 0x3ea
-//    - ChannelId: 1002
-//     - Align: No Padding
-//        Padding2: (00......) 0x0
-//       Value: 1 (0x1)
-//  - Channel: 0x3eb
-//    - ChannelId: 1003
-//      Align: No Padding
-//      Value: 1003 (0x3EB)
-//  - DataPriority: high
-//    - DataPriority: high
-//    - RootIndex: 1
-//       Value: (01......) 0x1
-//  - Segmentation: Begin End
-//     Begin: (1.......) Begin
-//     End:   (.1......) End
-//  - Length: 20
-//    - Align: No Padding
-//      Padding4: (0000....) 0x0
-//     Length: 20
-//    RDP: RDPBCGR
-//- RDPBCGR: RDPELE
-// - SecurityHeader: License Packet
-//  - Flags: 128 (0x80)
-//     SecurityExchange:        (...............0) Not Security Exchange PDU
-//     Reserved1:               (.............00.) Reserved
-//     Encrypted:               (............0...) Not Encrypted packet
-//     ResetSeqNumber:          (...........0....) MUST be ignored.
-//     IgnoreSeqNumber:         (..........0.....) MUST be ignored.
-//     InfoPacket:              (.........0......) Not Client Info PDU
-//     LicensePacket:           (........1.......) License Packet
-//     Reserved2:               (.......0........) Reserved
-//     LicensePacketEncryption: (......0.........) Not License Packet Encryption
-//     ServerRedirectionPacket: (.....0..........) Not Standard Security Server Redirection PDU
-//     ImprovedChecksumForMACG: (....0...........) Not Improved Checksum for MAC Generation
-//     Reserved3:               (.000............) Reserved
-//     FlagsHiValid:            (0...............) FlagsHi should be ignored
-//    FlagsHi: Should be ignored
-//- RDPELE: GM_ERROR_ALERT
-// - TsPreambleHeader: Type = GM_ERROR_ALERT
-//    MsgType: GM_ERROR_ALERT
-//  - Flags: 3 (0x3)
-//     LicenseProtocolVersionMask: (....0011) RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
-//     Unused:                     (.000....)
-//     ExtendedErrorMSGsupported:  (0.......) that extended error information using the License Error Message is NOT supported.
-//    MsgSize: 16 (0x10)
-// - TsLicenseErrorMessage: ErrorCode = STATUS_VALID_CLIENT
-//    ErrorCode: STATUS_VALID_CLIENT
-//    StateTransition: ST_NO_TRANSITION
-//  - LiceseBinaryBlob: Type = Not Available
-//     RandomData: This value should be ignored
-//     BlobLen: 0 (0x0)
-//
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
deleted file mode 100644
index b446253..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSAttachUserConfirmPDU.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * Server response to MCS Attach User request.
- *
- * Once the User Channel ID has been extracted, the client MUST send an MCS
- * Channel Join Request PDU for the user channel.
- *
- * @see http://msdn.microsoft.com/en-us/library/cc240685.aspx
- */
-public class ServerMCSAttachUserConfirmPDU extends OneTimeSwitch {
-
-    public static final int MCS_ATTACH_USER_CONFIRM_PDU = 0xb;
-
-    public static final int INITIATOR_PRESENT = 0x2;
-
-    protected RdpState state;
-
-    public ServerMCSAttachUserConfirmPDU(String id, RdpState state) {
-        super(id);
-        this.state = state;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        int typeAndFlags = buf.readUnsignedByte();
-        int type = typeAndFlags >> 2;
-        int flags = typeAndFlags & 0x3;
-
-        if (type != MCS_ATTACH_USER_CONFIRM_PDU)
-            throw new RuntimeException("[" + this + "] ERROR: Incorrect type of MCS AttachUserConfirm PDU. Expected value: 11, actual value: " + type + ", data: " + buf +
-                ".");
-
-        if (flags != INITIATOR_PRESENT)
-            throw new RuntimeException("Initator field is not present in MCS AttachUserConfirm PDU. Data: " + buf + ".");
-
-        int rtSuccess = buf.readUnsignedByte() >> 4;
-        if (rtSuccess != 0)
-            throw new RuntimeException("[" + this + "] ERROR: Cannot attach user: request failed. Error code: " + rtSuccess + ", data: " + buf + ".");
-
-        // If the initiator field is present, the client stores the value of the
-        // initiator in the User Channel ID store , because the initiator specifies
-        // the User Channel ID.
-        state.serverUserChannelId = buf.readUnsignedShort() + 1001;
-
-        buf.unref();
-
-        // Next: client MCS Channel Join Request PDU (s)
-        switchOff();
-    }
-
-    /**
-     * Example.
-     */
-    /**
-     * Example.
-     *
-     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
-     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-     */
-    public static void main(String args[]) {
-        // System.setProperty("streamer.Link.debug", "true");
-        System.setProperty("streamer.Element.debug", "true");
-        // System.setProperty("streamer.Pipeline.debug", "true");
-
-        byte[] packet = new byte[] {(byte)0x2E, // MCS user confirm (001011..,
-                                                // 0xb), InitiatorPresent: 1
-                                                // (......01, 0x1)
-            (byte)0x00, // RT successfull (0000...., 0x0)
-            // Initiator: 1001+3 = 1004
-            (byte)0x00, (byte)0x03,};
-
-        RdpState rdpState = new RdpState();
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet, new byte[] {1, 2, 3}));
-        Element atachUserConfirm = new ServerMCSAttachUserConfirmPDU("attach_user_confirm", rdpState);
-        Element sink = new MockSink("sink");
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, atachUserConfirm, sink, mainSink);
-        pipeline.link("source", "attach_user_confirm", "mainSink");
-        pipeline.link("attach_user_confirm >" + OTOUT, "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-
-        if (rdpState.serverUserChannelId != 1004)
-            System.err.println("Incorrect user channel ID. Expected value: 1004, actual value: " + rdpState.serverUserChannelId + ".");
-    }
-
-}
-
-/*
- * 03 00 00 0B 02 F0 80 2E 00 00 03.
- *
- * Frame: Number = 18, Captured Frame Length = 68, MediaType =
- * DecryptedPayloadHeader + DecryptedPayloadHeader: FrameCount = 1, ErrorStatus
- * = SUCCESS TLSSSLData: Transport Layer Security (TLS) Payload Data + TLS: TLS
- * Rec Layer-1 SSL Application Data ISOTS: TPKTCount = 1 - TPKT: version: 3,
- * Length: 11 version: 3 (0x3) Reserved: 0 (0x0) PacketLength: 11 (0xB) - X224:
- * Data Length: 2 (0x2) Type: Data EOT: 128 (0x80) - T125: Attach User Confirm,
- * Result = rt-successful, Indicator = 0x3ec - MCSHeader: Type=Attach User
- * Confirm - Type: Attach User Confirm - RootIndex: 11 Value: (001011..) 0xb -
- * MCSAttachUserConfirm: Result = rt-successful, Indicator = 0x3ec
- * InitiatorPresent: 1 (0x1) - Result: rt-successful - Result: rt-successful -
- * RootIndex: 0 Value: (0000....) 0x0 - Initiator: 0x3ec - UserID: 0x3ec -
- * ChannelId: 1004 - Align: No Padding Padding5: (00000...) 0x0 Value: 3 (0x3)
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
deleted file mode 100644
index e753cd9..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSChannelJoinConfirmPDU.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerMCSChannelJoinConfirmPDU extends OneTimeSwitch {
-
-    protected int channel;
-
-    public ServerMCSChannelJoinConfirmPDU(String id, int channel) {
-        super(id);
-        this.channel = channel;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-}
-
-/*
- * 03 00 00 0F 02 F0 80 3E 00 00 03 03 EC 03 EC
-
-  Frame: Number = 22, Captured Frame Length = 72, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 15
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 15 (0xF)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Channel Join Confirm, ChannelId = 1004, Result = rt-successful
-  - MCSHeader: Type=Channel Join Confirm
-   - Type: Channel Join Confirm
-    - RootIndex: 15
-       Value: (001111..) 0xf
-  - MCSChannelJoinConfirm: ChannelId = 1004, Result = rt-successful
-     ChannelIdPresent: 1 (0x1)
-   - Result: rt-successful
-    - Result: rt-successful
-     - RootIndex: 0
-        Value: (0000....) 0x0
-   - Initiator: 0x3ec
-    - UserID: 0x3ec
-     - ChannelId: 1004
-      - Align: No Padding
-         Padding5: (00000...) 0x0
-        Value: 3 (0x3)
-   - Requested: 0x3ec
-    - ChannelId: 1004
-       Align: No Padding
-       Value: 1004 (0x3EC)
-   - ChannelId: 0x3ec
-    - ChannelId: 1004
-       Align: No Padding
-       Value: 1004 (0x3EC)
-
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
deleted file mode 100644
index 030edbf..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSConnectResponse.java
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-/**
- * Once the basic server settings data blocks have been processed successfully, the client MUST send the MCS Attach User Request PDU to the server.
- *
- * @see http://msdn.microsoft.com/en-us/library/cc240682.aspx
- */
-public class ServerMCSConnectResponse extends OneTimeSwitch {
-
-    public ServerMCSConnectResponse(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-}
-
-/*
- * @formatter:off
- * 03 00 00 64 02 F0 80 7F 66 5A 0A 01 00 02 01 00 30 1A 02 01 22 02 01 03 02 01 00 02 01 01 02 01 00 02 01 01 02 03 00 FF F8 02 01 02 04 36 00 05 00 14 7C 00 01 2A 14 76 0A 01 01 00 01 C0 00 4D 63 44 6E 20 01 0C 0C 00 04 00 08 00 01 00 00 00 03 0C 08 00 EB 03 00 00 02 0C 0C 00 00 00 00 00 00 00 00 00
-
-  Frame: Number = 12, Captured Frame Length = 157, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 100
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 100 (0x64)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: MCSConnect Response
-  - MCSConnectResponse: Result = rt-successful
-   - ConnectResponseHeader:
-    - AsnId: Application Constructed Tag (102)
-     - HighTag:
-        Class:     (01......) Application (1)
-        Type:      (..1.....) Constructed
-        TagNumber: (...11111)
-        TagValueEnd: 102 (0x66)
-    - AsnLen: Length = 90, LengthOfLength = 0
-       Length: 90 bytes, LengthOfLength = 0
-   - Result: rt-successful
-    - Value: 0
-     - AsnIntegerHeader:
-      - AsnId: Enumerated type (Universal 10)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...01010) 10
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-   - CalledConnectId: 0
-    - AsnIntegerHeader:
-     - AsnId: Integer type (Universal 2)
-      - LowTag:
-         Class:    (00......) Universal (0)
-         Type:     (..0.....) Primitive
-         TagValue: (...00010) 2
-     - AsnLen: Length = 1, LengthOfLength = 0
-        Length: 1 bytes, LengthOfLength = 0
-      AsnInt: 0 (0x0)
-   - DomainParameters: Length = 26, LengthOfLength = 0
-    - DomainParametersHeader: 0x1
-     - AsnId: Sequence and SequenceOf types (Universal 16)
-      - LowTag:
-         Class:    (00......) Universal (0)
-         Type:     (..1.....) Constructed
-         TagValue: (...10000) 16
-     - AsnLen: Length = 26, LengthOfLength = 0
-        Length: 26 bytes, LengthOfLength = 0
-    - ChannelIds: 34
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 34 (0x22)
-    - UserIDs: 3
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 3 (0x3)
-    - TokenIds: 0
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-    - NumPriorities: 1
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 1 (0x1)
-    - MinThroughput: 0
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 0 (0x0)
-    - Height: 1
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 1 (0x1)
-    - MCSPDUsize: 65528
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 3, LengthOfLength = 0
-         Length: 3 bytes, LengthOfLength = 0
-       AsnInt: 65528 (0xFFF8)
-    - protocolVersion: 2
-     - AsnIntegerHeader:
-      - AsnId: Integer type (Universal 2)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00010) 2
-      - AsnLen: Length = 1, LengthOfLength = 0
-         Length: 1 bytes, LengthOfLength = 0
-       AsnInt: 2 (0x2)
-   - UserData: Identifier = Generic Conference Contro (0.0.20.124.0.1)
-    - UserDataHeader:
-     - AsnId: OctetString type (Universal 4)
-      - LowTag:
-         Class:    (00......) Universal (0)
-         Type:     (..0.....) Primitive
-         TagValue: (...00100) 4
-     - AsnLen: Length = 54, LengthOfLength = 0
-        Length: 54 bytes, LengthOfLength = 0
-    - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
-     - AsnObjectIdentifierHeader:
-      - AsnId: Reserved for use by the encoding rules (Universal 0)
-       - LowTag:
-          Class:    (00......) Universal (0)
-          Type:     (..0.....) Primitive
-          TagValue: (...00000) 0
-      - AsnLen: Length = 5, LengthOfLength = 0
-         Length: 5 bytes, LengthOfLength = 0
-       First: 0 (0x0)
-       Final: 20 (0x14)
-       Final: 124 (0x7C)
-       Final: 0 (0x0)
-       Final: 1 (0x1)
-    - ConnectPDULength: 42
-       Align: No Padding
-       Length: 42
-    - ConnectGCCPDU: conferenceCreateResponse
-       ExtensionBit: 0 (0x0)
-     - ChoiceValue: conferenceCreateResponse
-        Value: (001.....) 0x1
-     - conferenceCreateResponse:
-        ExtensionBit: 0 (0x0)
-        userDataPresent: 1 (0x1)
-      - nodeID: 0x79f3
-       - UserID: 31219
-        - Align: No Padding
-           Padding2: (00......) 0x0
-          Value: 30218 (0x760A)
-      - tag: 1 (0x1)
-       - Length: 1
-          Align: No Padding
-          Length: 1
-         Value: 1 (0x1)
-      - result: success
-         ExtensionBit: 0 (0x0)
-       - RootIndex: 0
-          Value: (000.....) 0x0
-      - userData:
-       - Size: 1
-        - Align: No Padding
-           Padding4: (0000....) 0x0
-          Length: 1
-       - UserData: 0x4d63446e
-          valuePresent: 1 (0x1)
-        - key: h221NonStandard
-         - ChoiceValue: h221NonStandard
-            Value: (1.......) 0x1
-         - h221NonStandard:
-          - H221NonStandardIdentifier: length: 4
-           - ConstrainedLength: 4
-              Value: (00000000) 0x0
-           - Align: No Padding
-              Padding6: (000000..) 0x0
-             Value: Binary Large Object (4 Bytes)
-        - ServerMcsConnectResponsePdu:
-         - RDPGCCUserDataResponseLength: 32
-            Align: No Padding
-            Length: 32
-         - TsUd: SC_CORE
-          - TsUdHeader: Type = SC_CORE, Length = 12
-             Type: SC_CORE
-             Length: 12 (0xC)
-          - TsUdScCore:
-             Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
-             ClientRequestedProtocols: TLS 1.0
-         - TsUd: SC_NET
-          - TsUdHeader: Type = SC_NET, Length = 8
-             Type: SC_NET
-             Length: 8 (0x8)
-          - TsUdScNet:
-             MCSChannelID: 1003 (0x3EB)
-             ChannelCount: 0 (0x0)
-             Pad: 0 Bytes
-         - TsUd: SC_SECURITY
-          - TsUdHeader: Type = SC_SECURITY, Length = 12
-             Type: SC_SECURITY
-             Length: 12 (0xC)
-          - TsUdSCSec1:
-           - EncryptionMethod:
-              Support40Bit:  (...............................0) Not Support
-              Support128Bit: (..............................0.) Not Support 128-bit
-              Reserved1:     (.............................0..)
-              Support56Bit:  (............................0...) Not Support 56-bit
-              SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-              Reserved2:     (000000000000000000000000000.....)
-             EncryptionLevel: TS_ENCRYPTION_NONE
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
deleted file mode 100644
index d9e4f42..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerMCSPDU.java
+++ /dev/null
@@ -1,149 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ServerMCSPDU extends BaseElement {
-
-    public ServerMCSPDU(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        byte headerByte = buf.readSignedByte();
-        int type = headerByte >> 2;
-
-        switch (type) {
-        // Expected type: send data indication: 26 (0x1a, top 6 bits, or 0x68)
-            case 0x1a: {
-                // int userId = buf.readUnsignedShort() + 1001; // User ID: 1002 (1001+1)
-                buf.skipBytes(2); // Ignore user ID
-
-                int channelId = buf.readUnsignedShort(); // Channel ID: 1003
-
-                int flags = buf.readSignedByte();
-                if ((flags & 0x30) != 0x30)
-                    throw new RuntimeException("Fragmented MCS packets are not supported.");
-
-                int payloadLength = buf.readVariableUnsignedShort();
-
-                ByteBuffer data = buf.readBytes(payloadLength);
-
-                buf.unref();
-
-                pushDataToPad("channel_" + channelId, data);
-                break;
-            }
-
-            case 0x8: {
-                // Disconnection sequence.
-                buf.unref();
-                break;
-            }
-
-            default:
-                throw new RuntimeException("Unsupported MCS packet type: " + type + "(" + headerByte + "), data: " + buf + ".");
-        }
-
-    }
-
-    /**
-     * 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");
-
-        byte[] packet = new byte[] {
-            // TPKT
-            (byte)0x03, (byte)0x00, // TPKT Header: TPKT version = 3
-            (byte)0x00, (byte)0x1B, // TPKT length: 27 bytes
-
-            // X224
-            (byte)0x02, // X224 Length: 2 bytes
-            (byte)0xF0, // X224 Type: Data
-            (byte)0x80, // X224 EOT
-
-            // MCS
-            // Type: send data indication: 26 (0x1a, top 6 bits)
-            (byte)0x68, // ??
-
-            (byte)0x00, (byte)0x01, // User ID: 1002 (1001+1)
-            (byte)0x03, (byte)0xEB, // Channel ID: 1003
-            (byte)0x70, // Data priority: high, segmentation: begin|end
-            (byte)0x0D, // Payload length: 13 bytes
-
-            // Deactivate all PDU
-            (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
-
-            // - PDUType: 22 (0x16, LE)
-            // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-            // ProtocolVersion: (000000000001....) 1
-            (byte)0x16, (byte)0x00,
-
-            (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
-            (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
-
-            (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
-            (byte)0x00, // Source descriptor (should be set to 0): 0
-        };
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mcs = new ServerMCSPDU("mcs") {
-            {
-                verbose = true;
-            }
-        };
-        Element tpkt = new ServerTpkt("tpkt");
-        Element x224 = new ServerX224DataPdu("x224");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
-            // Deactivate all PDU
-            (byte)0x0D, (byte)0x00, // Length: 13 bytes (LE)
-
-            // - PDUType: 22 (0x16, LE)
-            // Type: (............0110) TS_PDUTYPE_DEACTIVATEALLPDU
-            // ProtocolVersion: (000000000001....) 1
-            (byte)0x16, (byte)0x00,
-
-            (byte)0xEA, (byte)0x03, // PDU source: 1002 (LE)
-            (byte)0xEA, (byte)0x03, (byte)0x01, (byte)0x00, // ShareID = 66538
-
-            (byte)0x01, (byte)0x00, // Length if source descriptor: 1 (LE)
-            (byte)0x00, // Source descriptor (should be set to 0): 0
-        }));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, tpkt, x224, mcs, sink);
-        pipeline.link("source", "tpkt", "x224", "mcs >channel_1003", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
deleted file mode 100644
index 8d50ea4..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPacketSniffer.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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;
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class ServerPacketSniffer extends PacketSniffer {
-
-    private static final Pair[] serverRegexps = new Pair[] {
-// @formatter:off
-  new Pair("Server FastPath update",             "04"),
-  new Pair("Server X224ConnectionRequest",       "03 00 XX XX 0E D0"),
-  new Pair("Server MCSConnectResponse",          "03 00 XX XX 02 F0 80 7F 66 5A"),
-  new Pair("Server AttachUserConfirm",           "03 00 XX XX 02 F0 80 2E"),
-  new Pair("Server ChannelJoinConfirm",          "03 00 XX XX 02 F0 80 3E"),
-  new Pair("Server ErrorAlert",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 14 80 00"),
-  new Pair("Server DemandActivePDU",             "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX XX 11"),
-  new Pair("Server ControlPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 14"),
-  new Pair("Server SynchronizePDU",              "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 1F"),
-  new Pair("Server FontMapPDU",                  "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 17 00 EA 03 EA 03 XX 00 XX XX XX XX 28"),
-  new Pair("Server SET_ERROR_INFO_PDU",          "03 00 XX XX 02 F0 80 68 00 01 03 EB 30 XX XX XX 17 00 00 00 EA 03 XX 00 XX XX XX XX 2F"),
-  new Pair("Server DeactivateAllPDU",            "03 00 XX XX 02 F0 80 68 00 01 03 EB 70 XX XX XX 16 00"),
-  new Pair("Server CloseConnection",             "03 00 00 09 02 F0 80 21 80"),
-
-//  new Pair("Server TPKT unknown packet",         "03"),
-//  new Pair("Server FastPath update with flags or continuation",  ".*"),
-  // @formatter:on
-
-    };
-
-    public ServerPacketSniffer(String id) {
-        super(id, serverRegexps);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
deleted file mode 100644
index 8fb2fe0..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerPaletteUpdate.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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;
-
-import java.awt.image.IndexColorModel;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.ScreenDescription;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240623.aspx
- */
-public class ServerPaletteUpdate extends BaseElement {
-
-    public static final int UPDATETYPE_PALETTE = 0x0002;
-    protected ScreenDescription screen;
-
-    public ServerPaletteUpdate(String id, ScreenDescription screen) {
-        super(id);
-        this.screen = screen;
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // (2 bytes): A 16-bit, unsigned integer. The update type. This field MUST
-        // be set to UPDATETYPE_PALETTE (0x0002).
-        int updateType = buf.readUnsignedShortLE();
-        if (updateType != UPDATETYPE_PALETTE)
-            throw new RuntimeException("Unexpected update type. Expected type: UPDATETYPE_PALETTE (0x0002), actual value: " + updateType + ", data: " + buf + ".");
-
-        // pad2Octets (2 bytes): A 16-bit, unsigned integer. Padding. Values in this
-        // field MUST be ignored.
-        buf.skipBytes(2);
-
-        // (4 bytes): A 32-bit, unsigned integer. The number of RGB triplets in the
-        // paletteData field. This field MUST be set to 256 (the number of entries
-        // in an 8 bpp palette).
-        int numberColors = (int)buf.readUnsignedIntLE();
-        if (numberColors != 256)
-            throw new RuntimeException("Unexpected value for number of color field in server Palette Update packet. Expected value: 256 colors, actual value: " +
-                numberColors + ", data: " + buf + ".");
-
-        // (variable): An array of palette entries in RGB triplet format packed on
-        // byte boundaries. The number of triplet entries is given by the
-        // numberColors field.
-        ByteBuffer paletteEntries = buf.readBytes(numberColors * 3);
-
-        // In the case of a Palette Update, the client MUST update the global
-        // palette on all drawing surfaces
-        screen.colorMap = new IndexColorModel(8, numberColors, paletteEntries.data, paletteEntries.offset, false);
-
-        /* DEBUG */buf.assertThatBufferIsFullyRead();
-
-        buf.unref();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
deleted file mode 100644
index ad8704d..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerSynchronizePDU.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Link;
-import streamer.OneTimeSwitch;
-
-public class ServerSynchronizePDU extends OneTimeSwitch {
-
-    public ServerSynchronizePDU(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Ignore packet
-        buf.unref();
-        switchOff();
-    }
-
-}
-
-/* @formatter:off */
-/*
-
- * 03 00 00 24 02 F0 80 68 00 01 03 EB 70 16 16 00 17 00 EA 03 EA 03 01 00 08 00 16 00 1F 00 00 00 01 00 86 A4
-
-  Frame: Number = 36, Captured Frame Length = 93, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 36
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 36 (0x24)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Indication, UserID=1002, ChannelID=1003
-   - Type: Send Data Indication
-    - RootIndex: 26
-       Value: (011010..) 0x1a
-   - UserID: 0x3ea
-    - UserID: 0x3ea
-     - ChannelId: 1002
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 1 (0x1)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 22
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 22
-    RDP: RDPBCGR
-- RDPBCGR: SynchronizePDU
-  - SlowPathPacket: SynchronizePDU
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 22 (0x16)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1002 (0x3EA)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
-        ShareID: 66538 (0x103EA)
-        Pad1: 8 (0x8)
-        StreamID: STREAM_UNDEFINED
-        UncompressedLength: 22 (0x16)
-        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsSynchronizePDU: 0x1
-        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
-        TargetUser: 42118 (0xA486)
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
deleted file mode 100644
index 240c624..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ServerTpkt.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ServerTpkt extends BaseElement {
-
-    /**
-     * TPKT protocol version (first byte).
-     */
-    public static final int PROTOCOL_TPKT = 3;
-
-    public ServerTpkt(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // We need at least 4 bytes to get packet length
-        if (!cap(buf, 4, UNLIMITED, link, false))
-            return;
-
-        int version = buf.readUnsignedByte();
-        if (version != PROTOCOL_TPKT)
-            throw new RuntimeException("Unexpected data in TPKT header. Expected TPKT version: 0x03,  actual value: " + buf + ".");
-
-        buf.skipBytes(1); // Reserved byte
-
-        // Length of whole packet, including header
-        int length = buf.readUnsignedShort();
-        if (!cap(buf, length, length, link, false))
-            return;
-
-        int payloadLength = length - buf.cursor;
-
-        // Extract payload
-        ByteBuffer outBuf = buf.slice(buf.cursor, payloadLength, true);
-        buf.unref();
-
-        if (verbose) {
-            outBuf.putMetadata("source", this);
-        }
-
-        pushDataToAllOuts(outBuf);
-    }
-
-}


[20/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
new file mode 100755
index 0000000..c112cd0
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/ObjectID.java
@@ -0,0 +1,67 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class ObjectID extends Tag {
+
+    /**
+     * Raw bytes of encoded OID.
+     */
+    public ByteBuffer value;
+
+    public ObjectID(String name) {
+        super(name);
+        tagType = OBJECT_ID;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new ObjectID(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        value = new ByteBuffer(((ObjectID)tag).value.toByteArray());
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
new file mode 100755
index 0000000..3da9c84
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/OctetString.java
@@ -0,0 +1,80 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class OctetString extends Tag {
+
+    public ByteBuffer value = null;
+
+    public OctetString(String name) {
+        super(name);
+        tagType = OCTET_STRING;
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+
+        if (length > buf.length)
+            throw new RuntimeException("BER octet string is too long: " + length + " bytes. Data: " + buf + ".");
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new OctetString(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        value = ((OctetString)tag).value;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "= " + value;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        if (value != null)
+            return value.length;
+        else
+            return 0;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        if (value != null)
+            buf.writeBytes(value);
+        else
+            return;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
new file mode 100755
index 0000000..6fa23f8
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Sequence.java
@@ -0,0 +1,143 @@
+// 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 common.asn1;
+
+import java.util.Arrays;
+
+import streamer.ByteBuffer;
+
+/**
+ * One or more elements of different types.
+ *
+ * Only prefixed tags are supported.
+ */
+public class Sequence extends Tag {
+
+    public Tag[] tags;
+
+    public Sequence(String name) {
+        super(name);
+        tagType = SEQUENCE;
+        // Sequence and SequenceOf are always encoded as constructed
+        constructed = true;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        long sum = 0;
+
+        for (Tag tag : tags) {
+            long tagLength = tag.calculateFullLength();
+            sum += tagLength;
+        }
+
+        return sum;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        // Write tags
+        for (Tag tag : tags) {
+            tag.writeTag(buf);
+        }
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+        if (length > buf.remainderLength())
+            throw new RuntimeException("BER sequence is too long: " + length + " bytes, while buffer remainder length is " + buf.remainderLength() + ". Data: " + buf
+                    + ".");
+
+        ByteBuffer value = buf.readBytes((int)length);
+        parseContent(value);
+
+        value.unref();
+    }
+
+    protected void parseContent(ByteBuffer buf) {
+        for (int i = 0; buf.remainderLength() > 0 && i < tags.length; i++) {
+            BerType typeAndFlags = readBerType(buf);
+
+            // If current tag does not match data in buffer
+            if (!tags[i].isTypeValid(typeAndFlags)) {
+
+                // If tag is required, then throw exception
+                if (!tags[i].optional) {
+                    throw new RuntimeException("[" + this + "] ERROR: Required tag is missed: " + tags[i] + ". Unexected tag type: " + typeAndFlags + ". Data: " + buf
+                            + ".");
+                } else {
+                    // One or more tags are omitted, so skip them
+                    for (; i < tags.length; i++) {
+                        if (tags[i].isTypeValid(typeAndFlags)) {
+                            break;
+                        }
+                    }
+
+                    if (i >= tags.length || !tags[i].isTypeValid(typeAndFlags)) {
+                        throw new RuntimeException("[" + this + "] ERROR: No more tags to read or skip, but some data still left in buffer. Unexected tag type: "
+                                + typeAndFlags + ". Data: " + buf + ".");
+                    }
+                }
+            }
+
+            tags[i].readTag(buf, typeAndFlags);
+        }
+
+    }
+
+    @Override
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            // Sequences are always encoded as "constructed" in BER.
+            return typeAndFlags.tagClass == UNIVERSAL_CLASS && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == SEQUENCE;
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Sequence(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+
+        if (tags.length != ((Sequence)tag).tags.length)
+            throw new RuntimeException("Incompatible sequences. This: " + this + ", another: " + tag + ".");
+
+        for (int i = 0; i < tags.length; i++) {
+            tags[i].copyFrom(((Sequence)tag).tags[i]);
+        }
+
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "{" + Arrays.toString(tags) + " }";
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return tags != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
new file mode 100755
index 0000000..f288991
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/SequenceOf.java
@@ -0,0 +1,82 @@
+// 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 common.asn1;
+
+import java.util.ArrayList;
+
+import streamer.ByteBuffer;
+
+/**
+ * Zero or more elements of same type (array).
+ */
+public class SequenceOf extends Sequence {
+
+    /**
+     * Type of this array.
+     */
+    public Tag type;
+
+    /* Values are stored in tags[] variable inherited from Sequence. */
+
+    public SequenceOf(String name) {
+        super(name);
+    }
+
+    @Override
+    protected void parseContent(ByteBuffer buf) {
+        ArrayList<Tag> tagList = new ArrayList<Tag>();
+
+        for (int index = 0; buf.remainderLength() > 0; index++) {
+            // End of array is marked with two zero bytes (0x00 0x00)
+            if (buf.peekUnsignedByte(0) == 0x00 && buf.peekUnsignedByte(1) == 0x00) {
+                break;
+            }
+
+            Tag tag = type.deepCopy(index);
+
+            tag.readTag(buf);
+            tagList.add(tag);
+        }
+
+        tags = tagList.toArray(new Tag[tagList.size()]);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new SequenceOf(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        // We can create shallow copy of type, because it will not be modified
+        type = ((SequenceOf)tag).type;
+
+        tags = new Tag[((Sequence)tag).tags.length];
+        for (int i = 0; i < tags.length; i++) {
+            tags[i] = ((Sequence)tag).tags[i].deepCopy("");
+        }
+
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + ": " + type;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
new file mode 100755
index 0000000..80ece43
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Tag.java
@@ -0,0 +1,462 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public abstract class Tag implements Asn1Constants {
+
+    /**
+     * Name of this tag, for debugging purposes.
+     */
+    public String name = "";
+
+    /**
+     * Is this tag required or optional, for explicit tags only.
+     */
+    public boolean optional = false;
+
+    /**
+     * Tag primitive (e.g. implicit boolean), or constructed (e.g. sequence, or
+     * explicit boolean).
+     */
+    public boolean constructed = false;
+
+    /**
+     * Class of tag, when it is explicit.
+     */
+    public int tagClass = UNIVERSAL_CLASS;
+
+    /**
+     * Tag number (e.g. index in sequence), when tag is explicit.
+     */
+    public int tagNumber = -1;
+
+    /**
+     * Tag type (e.g. INDER), when tag is implicit.
+     */
+    public int tagType = -1;
+
+    /**
+     * If tag is explicit, then it is prefixed with tag number, so it can be
+     * optional or used in unordered set.
+     */
+    public boolean explicit = false;
+
+    public Tag(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Write tag value, with or without prefix.
+     */
+    public void writeTag(ByteBuffer buf) {
+
+        if (!isMustBeWritten())
+            return;
+
+        // Write prefix, when necessary
+        if (explicit) {
+
+            // Write tag prefix, always constructed
+            BerType berTagPrefix = new BerType(tagClass, true, tagNumber);
+            writeBerType(buf, berTagPrefix);
+
+            // Write tag prefix length
+            buf.writeBerLength(calculateLength());
+
+            // Write tag value
+            writeTagValue(buf);
+        } else {
+            // If implicit, just write tag value
+            writeTagValue(buf);
+        }
+    }
+
+    /**
+     * Must return true when value of this tag is set or tag is required, so it
+     * can be written, false otherwise.
+     */
+    public boolean isMustBeWritten() {
+        return !optional || isValueSet();
+    }
+
+    /**
+     * Must return true when value of this tag is set or tag is required, so it
+     * can be written, false otherwise.
+     */
+    public abstract boolean isValueSet();
+
+    /**
+     * Calculate full length of tag, including type (or prefix, when explicit).
+     */
+    public long calculateFullLength() {
+        if (!isMustBeWritten())
+            return 0;
+
+        // Length of value, including type
+        long length = calculateLength();
+
+        if (!explicit) {
+            // Length of tag type and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagType) + calculateLengthOfLength(length);
+        } else {
+            // Length of tag prefix and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagNumber) + calculateLengthOfLength(length);
+        }
+
+        return length;
+    }
+
+    /**
+     * Calculate length of tag, including type when explicit, but without length
+     * of prefix (or type, when implicit).
+     */
+    public long calculateLength() {
+        if (!isMustBeWritten())
+            return 0;
+
+        // Length of value
+        long length = calculateLengthOfValuePayload();
+
+        if (explicit) {
+            // Length of tag type and it length
+            length += calculateLengthOfTagTypeOrTagNumber(tagType) + calculateLengthOfLength(length);
+        }
+
+        return length;
+    }
+
+    /**
+     * Calculate length of BER length.
+     */
+    public int calculateLengthOfLength(long length) {
+        if (length < 0)
+            throw new RuntimeException("[" + this + "] ERROR: Length of tag cannot be less than zero: " + length + ".");
+
+        if (length <= 0x7f)
+            return 1;
+        if (length <= 0xff)
+            return 2;
+        if (length <= 0xffFF)
+            return 3;
+        if (length <= 0xffFFff)
+            return 4;
+        if (length <= 0xffFFffFFL)
+            return 5;
+        if (length <= 0xffFFffFFffL)
+            return 6;
+        if (length <= 0xffFFffFFffFFL)
+            return 7;
+        if (length <= 0xffFFffFFffFFffL)
+            return 8;
+
+        return 9;
+    }
+
+    /**
+     * Calculate length of type to tag number. Values less than 31 are encoded
+     * using lower 5 bits of first byte of tag. Values larger than 31 are
+     * indicated by lower 5 bits set to 1 (0x1F, 31), and next bytes are contain
+     * value in network order, where topmost bit of byte (0x80) indicates is value
+     * contains more bytes, i.e. last byte of sequence has this bit set to 0.
+     */
+    public int calculateLengthOfTagTypeOrTagNumber(int tagType) {
+        if (tagType >= EXTENDED_TYPE)
+            throw new RuntimeException("Multibyte tag types are not supported yet.");
+
+        return 1;
+    }
+
+    /**
+     * Calculate length of payload only, without tag prefix, tag type, and
+     * lengths.
+     *
+     * @return
+     */
+    public abstract long calculateLengthOfValuePayload();
+
+    /**
+     * Write tag value only, without prefix.
+     */
+    public void writeTagValue(ByteBuffer buf) {
+
+        // Write type
+        BerType valueType = new BerType(UNIVERSAL_CLASS, constructed, tagType);
+        writeBerType(buf, valueType);
+
+        // Write length
+        long lengthOfPayload = calculateLengthOfValuePayload();
+        buf.writeBerLength(lengthOfPayload);
+
+        // Store cursor to check is calculated length matches length of actual bytes
+        // written
+        int storedCursor = buf.cursor;
+
+        // Write value
+        writeTagValuePayload(buf);
+
+        // Check is calculated length matches length of actual bytes written, to catch errors early
+        int actualLength = buf.cursor - storedCursor;
+        if (actualLength != lengthOfPayload)
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected length of data in buffer. Expected " + lengthOfPayload + " of bytes of payload, but "
+                    + actualLength + " bytes are written instead. Data: " + buf + ".");
+    }
+
+    /**
+     * Write tag value only, without prefix, tag type, and length.
+     */
+    public abstract void writeTagValuePayload(ByteBuffer buf);
+
+    /**
+     * Read required tag, i.e. we are 100% sure that byte buffer will contain this
+     * tag, or exception will be thrown otherwise.
+     *
+     * @param buf
+     *          buffer with tag data
+     */
+    public void readTag(ByteBuffer buf) {
+        BerType typeAndFlags = readBerType(buf);
+
+        // * DEBUG */System.out.println("Tag, read " + typeAndFlags);
+
+        if (!isTypeValid(typeAndFlags))
+            throw new RuntimeException("[" + this + "] Unexpected type: " + typeAndFlags + ".");
+
+        readTag(buf, typeAndFlags);
+    }
+
+    /**
+     * Read tag when it type is already read.
+     */
+    public void readTag(ByteBuffer buf, BerType typeAndFlags) {
+
+        if (explicit) {
+            long length = buf.readBerLength();
+
+            if (length > buf.length)
+                throw new RuntimeException("BER value is too long: " + length + " bytes. Data: " + buf + ".");
+
+            ByteBuffer value = buf.readBytes((int)length);
+
+            readTagValue(value);
+
+            value.unref();
+        } else {
+
+            readTagValue(buf, typeAndFlags);
+        }
+    }
+
+    /**
+     * Read tag value only, i.e. it prefix is already read.
+     */
+    public void readTagValue(ByteBuffer value) {
+        BerType typeAndFlags = readBerType(value);
+
+        // * DEBUG */System.out.println("Tag, read value " + typeAndFlags);
+
+        if (!isTypeValid(typeAndFlags, false))
+            throw new RuntimeException("[" + this + "] Unexpected type: " + typeAndFlags + ".");
+
+        readTagValue(value, typeAndFlags);
+    }
+
+    /**
+     * Check are tag type and flags valid for this tag.
+     */
+    public final boolean isTypeValid(BerType typeAndFlags) {
+        return isTypeValid(typeAndFlags, explicit);
+    }
+
+    /**
+     * Check are tag type and flags valid for this tag with or without tag prefix.
+     *
+     * @param explicit
+     *          if true, then value is wrapped in tag prefix
+     */
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            return typeAndFlags.tagClass == UNIVERSAL_CLASS && !typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagType;
+    }
+
+    @Override
+    public String toString() {
+        return "  \nTag [name="
+                + name
+
+                + ((constructed) ? ", constructed=" + constructed : "")
+
+                + (", tagType=" + tagTypeOrNumberToString(UNIVERSAL_CLASS, tagType))
+
+                + ((explicit) ? ", explicit=" + explicit + ", optional=" + optional + ", tagClass=" + tagClassToString(tagClass) + ", tagNumber="
+                        + tagTypeOrNumberToString(tagClass, tagNumber) : "") + "]";
+    }
+
+    public static final String tagTypeOrNumberToString(int tagClass, int tagTypeOrNumber) {
+        switch (tagClass) {
+        case UNIVERSAL_CLASS:
+            switch (tagTypeOrNumber) {
+            case EOF:
+                return "EOF";
+            case BOOLEAN:
+                return "BOOLEAN";
+            case INTEGER:
+                return "INTEGER";
+            case BIT_STRING:
+                return "BIT_STRING";
+            case OCTET_STRING:
+                return "OCTET_STRING";
+            case NULL:
+                return "NULL";
+            case OBJECT_ID:
+                return "OBJECT_ID";
+            case REAL:
+                return "REAL";
+            case ENUMERATED:
+                return "ENUMERATED";
+            case SEQUENCE:
+                return "SEQUENCE";
+            case SET:
+                return "SET";
+            case NUMERIC_STRING:
+                return "NUMERIC_STRING";
+            case PRINTABLE_STRING:
+                return "PRINTABLE_STRING";
+            case TELETEX_STRING:
+                return "TELETEX_STRING";
+            case VIDEOTEXT_STRING:
+                return "VIDEOTEXT_STRING";
+            case IA5_STRING:
+                return "IA5_STRING";
+            case UTCTIME:
+                return "UTCTIME";
+            case GENERAL_TIME:
+                return "GENERAL_TIME";
+            case GRAPHIC_STRING:
+                return "GRAPHIC_STRING";
+            case VISIBLE_STRING:
+                return "VISIBLE_STRING";
+            case GENERAL_STRING:
+                return "GENERAL_STRING";
+            case EXTENDED_TYPE:
+                return "EXTENDED_TYPE (multibyte)";
+            default:
+                return "UNKNOWN(" + tagTypeOrNumber + ")";
+
+            }
+
+        default:
+            return "[" + tagTypeOrNumber + "]";
+        }
+    }
+
+    public static final String tagClassToString(int tagClass) {
+        switch (tagClass) {
+        case UNIVERSAL_CLASS:
+            return "UNIVERSAL";
+        case CONTEXT_CLASS:
+            return "CONTEXT";
+        case APPLICATION_CLASS:
+            return "APPLICATION";
+        case PRIVATE_CLASS:
+            return "PRIVATE";
+        default:
+            return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Read BER tag type.
+     */
+    public BerType readBerType(ByteBuffer buf) {
+        int typeAndFlags = buf.readUnsignedByte();
+
+        int tagClass = typeAndFlags & CLASS_MASK;
+
+        boolean constructed = (typeAndFlags & CONSTRUCTED) != 0;
+
+        int type = typeAndFlags & TYPE_MASK;
+        if (type == EXTENDED_TYPE)
+            throw new RuntimeException("Extended tag types/numbers (31+) are not supported yet.");
+
+        return new BerType(tagClass, constructed, type);
+    }
+
+    /**
+     * Write BER tag type.
+     */
+    public void writeBerType(ByteBuffer buf, BerType berType) {
+
+        if (berType.typeOrTagNumber >= EXTENDED_TYPE || berType.typeOrTagNumber < 0)
+            throw new RuntimeException("Extended tag types/numbers (31+) are not supported yet: " + berType + ".");
+
+        if ((berType.tagClass & CLASS_MASK) != berType.tagClass)
+            throw new RuntimeException("Value of BER tag class is out of range: " + berType.tagClass + ". Expected values: " + UNIVERSAL_CLASS + ", " + CONTEXT_CLASS
+                    + ", " + APPLICATION_CLASS + ", " + PRIVATE_CLASS + ".");
+
+        int typeAndFlags = berType.tagClass | ((berType.constructed) ? CONSTRUCTED : 0) | berType.typeOrTagNumber;
+
+        buf.writeByte(typeAndFlags);
+    }
+
+    /**
+     * Read tag value only, i.e. it prefix is already read, when value type is
+     * already read.
+     *
+     * @param buf
+     *          buffer with tag data
+     */
+    public abstract void readTagValue(ByteBuffer buf, BerType typeAndFlags);
+
+    /**
+     * Create deep copy of this tag with given suffix appended to name.
+     *
+     * @param suffix
+     *          suffix to add to tag name, or empty string
+     * @return deep copy of this tag
+     */
+    public abstract Tag deepCopy(String suffix);
+
+    /**
+     * Create deep copy of this tag for array or set.
+     *
+     * @param index
+     *          index of element in array or set
+     * @return deep copy of this tag
+     */
+    public Tag deepCopy(int index) {
+        return deepCopy("[" + index + "]");
+    }
+
+    /**
+     * Copy tag values from an other tag, except name.
+     *
+     * @return this
+     */
+    public Tag copyFrom(Tag tag) {
+        constructed = tag.constructed;
+        explicit = tag.explicit;
+        optional = tag.optional;
+        tagClass = tag.tagClass;
+        tagNumber = tag.tagNumber;
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
new file mode 100755
index 0000000..eb24d11
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IncrementalOption.java
@@ -0,0 +1,28 @@
+// 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 common.opt;
+
+public class IncrementalOption extends Option {
+    int value = 0;
+
+    @Override
+    public int parse(int position, String[] args) {
+        value++;
+        return super.parse(position, args);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
new file mode 100755
index 0000000..87e732a
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/IntOption.java
@@ -0,0 +1,41 @@
+// 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 common.opt;
+
+public class IntOption extends Option {
+    public int value = 0;
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = Integer.parseInt(args[position + 1]);
+        return super.parse(position, args) + 1;
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" VALUE\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != 0)
+            help.append(" Default value is \"").append("" + value).append("\".");
+        return help.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
new file mode 100755
index 0000000..a074672
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/NoArgumentForOptionException.java
@@ -0,0 +1,26 @@
+// 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 common.opt;
+
+public class NoArgumentForOptionException extends RuntimeException {
+    public NoArgumentForOptionException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
new file mode 100755
index 0000000..e69d3f3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/Option.java
@@ -0,0 +1,102 @@
+// 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 common.opt;
+
+public class Option {
+
+    public String name = "";
+    public String alias = null;
+    public String aliases[] = null;
+
+    public String description = "";
+    public boolean used = false;
+    public boolean required = false;
+
+    /**
+     * Parse option value, if any.
+     *
+     * @param position
+     *          position of this option in list of arguments
+     * @param args
+     *          command line arguments
+     * @return how many arguments are consumed, at least 1
+     */
+    public int parse(int position, String args[]) {
+        used = true;
+        return 1;
+    }
+
+    @Override
+    public String toString() {
+        return help();
+    }
+
+    /**
+     * Return help string for this option. Example:
+     *
+     * <pre>
+     *   --foo|-f    Foo option.
+     * </pre>
+     */
+    public String help() {
+        return join("|", name, alias, aliases) + "\t" + description + ((required) ? " Required." : "");
+    }
+
+    /**
+     * Return string like "--foo|-f|--another-foo-alias".
+     */
+    protected String join(String delim, String name, String alias, String aliases[]) {
+
+        // Option name is mandatory
+        StringBuilder sb = new StringBuilder(name.length());
+        sb.append(name);
+
+        // Alias is optional
+        if (alias != null && alias.length() > 0) {
+            sb.append(delim).append(alias);
+        }
+
+        // Other aliases are optional too
+        if (aliases != null) {
+            for (String s : aliases) {
+                if (s != null && s.length() > 0) {
+                    sb.append(delim).append(s);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Return description of options in format suitable for help and usage text.
+     *
+     * @param header
+     *          header string to print before list of options
+     * @param options
+     *          list of options to print
+     */
+    public static String toHelp(String header, Option[] options) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(header).append(":\n");
+        for (Option option : options) {
+            sb.append("  ").append(option.help()).append('\n');
+        }
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
new file mode 100755
index 0000000..11c42fe
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionParser.java
@@ -0,0 +1,147 @@
+// 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 common.opt;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Simple parser of GNU-like options.
+ */
+public class OptionParser {
+
+    public static Option helpOption() {
+        return new Option() {
+            {
+                name = "--help";
+                alias = "-h";
+            }
+        };
+    }
+
+    /**
+     * Parse options, capture values and return rest of arguments.
+     *
+     * @param args
+     *          command line arguments to parse
+     * @param startFrom
+     *          number of first argument to start parsing from
+     * @param options
+     *          options to fill with values
+     * @return rest of command line after first non-option or "--" separator
+     */
+    public static String[] parseOptions(String args[], int startFrom, Option options[]) {
+        // Convert array of options into map, where key is option name or alias
+        Map<String, Option> optionMap = new HashMap<String, Option>(options.length);
+        for (Option option : options) {
+            optionMap.put(option.name, option);
+
+            if (option.alias != null)
+                optionMap.put(option.alias, option);
+
+            if (option.aliases != null) {
+                for (String alias : option.aliases)
+                    optionMap.put(alias, option);
+            }
+        }
+
+        // Parse arguments
+        int position = startFrom;
+        while (position < args.length) {
+            // Double dash means end of options
+            String optionName = args[position];
+            if (optionName.equals("--")) {
+                position++;
+                break;
+            }
+
+            Option option = optionMap.get(optionName);
+
+            // If option is not found, then this is argument, unless is starts with
+            // dash
+            if (option == null)
+                if (!optionName.startsWith("-"))
+                    break;
+                else
+                    throw new UnknownOptionException("Option \"" + optionName
+                            + "\" is unknown. If this is not an option, then use \"--\" to separate options and arguments. Known options: " + optionMap.keySet().toString());
+
+            position += option.parse(position, args);
+        }
+
+        // Check is required options are used on command line
+        for (Option option : options) {
+            if (option.required && !option.used)
+                throw new OptionRequiredException("Option \"" + option.name + "\" is required.");
+        }
+
+        // Return rest of arguments, which are left after options
+        return (position < args.length) ? Arrays.copyOfRange(args, position, args.length) : new String[] {};
+    }
+
+    /* Example. */
+    public static void main(String args[]) {
+        if (args.length == 0)
+            args = new String[] {"--help", "--foo", "fooval", "--bar", "123", "-v", "--verbose", "-v", "-a", "a1", "-aa", "a2", "-aaa", "a3", "rest", "of",
+        "arguments"};
+
+        StringOption foo = new StringOption() {
+            {
+                name = "--foo";
+                alias = "-f";
+                value = "fooDefault";
+            }
+        };
+
+        IntOption bar = new IntOption() {
+            {
+                name = "--bar";
+                alias = "-b";
+                value = 123;
+            }
+        };
+
+        IncrementalOption verbose = new IncrementalOption() {
+            {
+                name = "--verbose";
+                alias = "-v";
+            }
+        };
+
+        StringArrayOption array = new StringArrayOption() {
+            {
+                name = "--array";
+                alias = "-a";
+                aliases = new String[] {"-aa", "-aaa"};
+            }
+        };
+
+        String arguments[] = OptionParser.parseOptions(args, 0, new Option[] {helpOption(), foo, bar, verbose, array});
+
+        assertTrue(foo.value.equals("fooval"));
+        assertTrue(bar.value == 123);
+        assertTrue(verbose.value == 3);
+        assertTrue(Arrays.equals(array.value, new String[] {"a1", "a2", "a3"}));
+        assertTrue(Arrays.equals(arguments, new String[] {"rest", "of", "arguments"}));
+    }
+
+    public static void assertTrue(boolean result) {
+        if (!result)
+            throw new AssertionError();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
new file mode 100755
index 0000000..b397627
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/OptionRequiredException.java
@@ -0,0 +1,26 @@
+// 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 common.opt;
+
+public class OptionRequiredException extends RuntimeException {
+    public OptionRequiredException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
new file mode 100755
index 0000000..b2f3c30
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringArrayOption.java
@@ -0,0 +1,38 @@
+// 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 common.opt;
+
+import java.util.Arrays;
+
+public class StringArrayOption extends Option {
+    public String value[] = null;
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        // Append value to end of array of values
+        if (value == null) {
+            value = new String[] {args[position + 1]};
+        } else {
+            value = Arrays.copyOf(value, value.length + 1);
+            value[value.length - 1] = args[position + 1];
+        }
+        return super.parse(position, args) + 1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
new file mode 100755
index 0000000..f59952e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringEnumerationOption.java
@@ -0,0 +1,72 @@
+// 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 common.opt;
+
+public class StringEnumerationOption extends Option {
+    public String value = "";
+    public String choices[] = new String[] {};
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = args[position + 1];
+
+        for (String s : choices) {
+            if (value.equals(s))
+                return super.parse(position, args) + 1;
+        }
+
+        throw new NoArgumentForOptionException("Unexpected argument for option \"" + args[position] + "\": \"" + value + "\". Expected argument: "
+                + join("|", choices) + ".");
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" ").append(join("|", choices)).append("\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != null && value.length() > 0)
+            help.append(" Default value is \"").append(value).append("\".");
+        return help.toString();
+    }
+
+    /**
+     * Join strings in array into one large string.
+     */
+    protected String join(String delim, String values[]) {
+        StringBuilder sb = new StringBuilder();
+        if (values != null) {
+            boolean first = true;
+            for (String s : values) {
+                if (s != null && s.length() > 0) {
+                    if (first)
+                        first = false;
+                    else
+                        sb.append(delim);
+
+                    sb.append(s);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
new file mode 100755
index 0000000..ec9c82c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/StringOption.java
@@ -0,0 +1,41 @@
+// 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 common.opt;
+
+public class StringOption extends Option {
+    public String value = "";
+
+    @Override
+    public int parse(int position, String[] args) {
+        if (position + 1 >= args.length)
+            throw new NoArgumentForOptionException("Cannot find required argument for option \"" + args[position] + "\".");
+
+        value = args[position + 1];
+        return super.parse(position, args) + 1;
+    }
+
+    @Override
+    public String help() {
+        StringBuilder help = new StringBuilder();
+        help.append(join("|", name, alias, aliases)).append(" VALUE\t").append(description);
+        if (required)
+            help.append(" Required.");
+        else if (value != null && value.length() > 0)
+            help.append(" Default value is \"").append(value).append("\".");
+        return help.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
new file mode 100755
index 0000000..58cce73
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/opt/UnknownOptionException.java
@@ -0,0 +1,27 @@
+// 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 common.opt;
+
+public class UnknownOptionException extends RuntimeException {
+
+    public UnknownOptionException(String message) {
+        super(message);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
deleted file mode 100644
index 06449f6..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpKeyboardAdapter.java
+++ /dev/null
@@ -1,350 +0,0 @@
-// 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;
-
-import java.awt.event.KeyEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.KeyOrder;
-
-public class AwtRdpKeyboardAdapter extends BaseElement {
-
-    /**
-     * Absence of this flag indicates a key-down event, while its presence
-     * indicates a key-release event.
-     */
-    public static final int FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01;
-
-    /**
-     * Keystroke message contains an extended scancode. For enhanced 101-key and
-     * 102-key keyboards, extended keys include the right ALT and right CTRL keys
-     * on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE
-     * DOWN and ARROW keys in the clusters to the left of the numeric keypad; and
-     * the Divide ("/") and ENTER keys in the numeric keypad.
-     */
-    public static final int FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02;
-
-    public static final int FASTPATH_INPUT_EVENT_SCANCODE = 0;
-
-    public AwtRdpKeyboardAdapter(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        KeyOrder order = (KeyOrder)buf.getOrder();
-        buf.unref();
-
-        ByteBuffer outBuf = new ByteBuffer(2, true);
-
-        int scanCode = map_en_us(order.event);
-
-        // eventHeader (1 byte): An 8-bit, unsigned integer. The format of this
-        // field is the same as the eventHeader byte field described in section
-        // 2.2.8.1.2.2. The eventCode bitfield (3 bits in size) MUST be set to
-        // FASTPATH_INPUT_EVENT_SCANCODE (0). The eventFlags bitfield (5 bits in
-        // size) contains flags describing the keyboard event.
-        outBuf.writeByte((scanCode >> 8) | (FASTPATH_INPUT_EVENT_SCANCODE << 5) | ((order.pressed) ? 0 : FASTPATH_INPUT_KBDFLAGS_RELEASE));
-
-        // keyCode (1 byte): An 8-bit, unsigned integer. The scancode of the key
-        // which triggered the event.
-        outBuf.writeByte(scanCode);
-
-        // Push buffer to one pad only, so it can be modified without copying of
-        // data
-        pushDataToPad(STDOUT, outBuf);
-    }
-
-    /**
-     * Return key scan code (in lower byte) and extended flags (in second byte).
-     */
-    private int map_en_us(KeyEvent event) {
-        // Also set extended key flag when necessary.
-        // For enhanced 101-key and 102-key keyboards, extended keys include the
-        // right ALT and right CTRL keys on the main section of the keyboard; the
-        // INS, DEL, HOME, END, PAGE UP, PAGE DOWN and ARROW keys in the clusters to
-        // the left of the numeric keypad; and the Divide ("/") and ENTER keys in
-        // the numeric keypad.
-
-        switch (event.getKeyCode()) {
-        // Functional keys
-            case KeyEvent.VK_ESCAPE:
-                return 1;
-            case KeyEvent.VK_F1:
-                return 59;
-            case KeyEvent.VK_F2:
-                return 60;
-            case KeyEvent.VK_F3:
-                return 61;
-            case KeyEvent.VK_F4:
-                return 62;
-            case KeyEvent.VK_F5:
-                return 63;
-            case KeyEvent.VK_F6:
-                return 64;
-            case KeyEvent.VK_F7:
-                return 65;
-            case KeyEvent.VK_F8:
-                return 66;
-            case KeyEvent.VK_F9:
-                return 67;
-            case KeyEvent.VK_F10:
-                return 68;
-            case KeyEvent.VK_F11:
-                return 87;
-            case KeyEvent.VK_F12:
-                return 88;
-
-                // Row #1
-            case KeyEvent.VK_BACK_QUOTE:
-                return 41;
-            case KeyEvent.VK_1:
-                return 2;
-            case KeyEvent.VK_2:
-                return 3;
-            case KeyEvent.VK_3:
-                return 4;
-            case KeyEvent.VK_4:
-                return 5;
-            case KeyEvent.VK_5:
-                return 6;
-            case KeyEvent.VK_6:
-                return 7;
-            case KeyEvent.VK_7:
-                return 8;
-            case KeyEvent.VK_8:
-                return 9;
-            case KeyEvent.VK_9:
-                return 10;
-            case KeyEvent.VK_0:
-                return 11;
-            case KeyEvent.VK_MINUS:
-                return 12;
-            case KeyEvent.VK_EQUALS:
-                return 13;
-            case KeyEvent.VK_BACK_SPACE:
-                return 14;
-
-                // Row #2
-            case KeyEvent.VK_TAB:
-                return 15;
-            case KeyEvent.VK_Q:
-                return 16;
-            case KeyEvent.VK_W:
-                return 17;
-            case KeyEvent.VK_E:
-                return 18;
-            case KeyEvent.VK_R:
-                return 19;
-            case KeyEvent.VK_T:
-                return 20;
-            case KeyEvent.VK_Y:
-                return 21;
-            case KeyEvent.VK_U:
-                return 22;
-            case KeyEvent.VK_I:
-                return 23;
-            case KeyEvent.VK_O:
-                return 24;
-            case KeyEvent.VK_P:
-                return 25;
-            case KeyEvent.VK_OPEN_BRACKET:
-                return 26;
-            case KeyEvent.VK_CLOSE_BRACKET:
-                return 27;
-            case KeyEvent.VK_ENTER:
-                switch (event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_STANDARD:
-                        return 28;
-                    case KeyEvent.KEY_LOCATION_NUMPAD:
-                        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 28;
-                }
-
-                // Row #3
-            case KeyEvent.VK_CAPS_LOCK:
-                return 58;
-            case KeyEvent.VK_A:
-                return 30;
-            case KeyEvent.VK_S:
-                return 31;
-            case KeyEvent.VK_D:
-                return 32;
-            case KeyEvent.VK_F:
-                return 33;
-            case KeyEvent.VK_G:
-                return 34;
-            case KeyEvent.VK_H:
-                return 35;
-            case KeyEvent.VK_J:
-                return 36;
-            case KeyEvent.VK_K:
-                return 37;
-            case KeyEvent.VK_L:
-                return 38;
-            case KeyEvent.VK_SEMICOLON:
-                return 39;
-            case KeyEvent.VK_QUOTE:
-                return 40;
-
-                // Row #4
-            case KeyEvent.VK_SHIFT:
-                switch (event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 42;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 54;
-                }
-            case KeyEvent.VK_BACK_SLASH:
-                return 43;
-            case KeyEvent.VK_Z:
-                return 44;
-            case KeyEvent.VK_X:
-                return 45;
-            case KeyEvent.VK_C:
-                return 46;
-            case KeyEvent.VK_V:
-                return 47;
-            case KeyEvent.VK_B:
-                return 48;
-            case KeyEvent.VK_N:
-                return 49;
-            case KeyEvent.VK_M:
-                return 50;
-            case KeyEvent.VK_COMMA:
-                return 51;
-            case KeyEvent.VK_PERIOD:
-                return 52;
-            case KeyEvent.VK_SLASH:
-                return 53;
-
-                //
-                // Bottom row
-            case KeyEvent.VK_CONTROL:
-                switch (event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 29;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 29;
-                }
-            case KeyEvent.VK_WINDOWS:
-                switch (event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 91;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return 92;
-                }
-            case KeyEvent.VK_ALT:
-                switch (event.getKeyLocation()) {
-                    default:
-                    case KeyEvent.KEY_LOCATION_LEFT:
-                        return 56;
-                    case KeyEvent.KEY_LOCATION_RIGHT:
-                        return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
-                }
-            case KeyEvent.VK_ALT_GRAPH:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 56;
-
-            case KeyEvent.VK_SPACE:
-                return 57;
-
-            case KeyEvent.VK_CONTEXT_MENU:
-                return 93;
-
-                //
-                // Special keys
-            case KeyEvent.VK_PRINTSCREEN:
-                return 55;
-            case KeyEvent.VK_SCROLL_LOCK:
-                return 70;
-            case KeyEvent.VK_PAUSE:
-                return 29;
-
-                // Text navigation keys
-            case KeyEvent.VK_INSERT:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 82;
-            case KeyEvent.VK_HOME:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 71;
-            case KeyEvent.VK_PAGE_UP:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 73;
-            case KeyEvent.VK_DELETE:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 83;
-            case KeyEvent.VK_END:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 79;
-            case KeyEvent.VK_PAGE_DOWN:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 81;
-
-                // Cursor keys
-            case KeyEvent.VK_UP:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 72;
-            case KeyEvent.VK_LEFT:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 75;
-            case KeyEvent.VK_DOWN:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 80;
-            case KeyEvent.VK_RIGHT:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 77;
-
-                // Keypad
-            case KeyEvent.VK_NUM_LOCK:
-                return 69;
-            case KeyEvent.VK_DIVIDE:
-                return (FASTPATH_INPUT_KBDFLAGS_EXTENDED << 8) | 53;
-            case KeyEvent.VK_MULTIPLY:
-                return 55;
-            case KeyEvent.VK_SUBTRACT:
-                return 74;
-            case KeyEvent.VK_ADD:
-                return 78;
-
-            case KeyEvent.VK_NUMPAD7:
-                return 71;
-            case KeyEvent.VK_NUMPAD8:
-                return 72;
-            case KeyEvent.VK_NUMPAD9:
-                return 73;
-            case KeyEvent.VK_NUMPAD4:
-                return 75;
-            case KeyEvent.VK_NUMPAD5:
-                return 76;
-            case KeyEvent.VK_NUMPAD6:
-                return 77;
-            case KeyEvent.VK_NUMPAD1:
-                return 79;
-            case KeyEvent.VK_NUMPAD2:
-                return 80;
-            case KeyEvent.VK_NUMPAD3:
-                return 81;
-            case KeyEvent.VK_NUMPAD0:
-                return 82;
-            case KeyEvent.VK_DECIMAL:
-                return 83;
-
-            default:
-                System.err.println("Key is not mapped: " + event + ".");
-                return 57; // Space
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
deleted file mode 100644
index f533906..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/AwtRdpMouseAdapter.java
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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;
-
-import java.awt.event.InputEvent;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import common.MouseOrder;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240594.aspx
- */
-public class AwtRdpMouseAdapter extends BaseElement {
-    public static final int FASTPATH_INPUT_EVENT_MOUSE = 0x01;
-
-    /**
-     * Event is a mouse wheel rotation. The only valid flags in a wheel rotation
-     * event are PTRFLAGS_WHEEL_NEGATIVE and the WheelRotationMask; all other
-     * pointer flags are ignored.
-     */
-    public static final int PTRFLAGS_WHEEL = 0x0200;
-
-    /**
-     * Wheel rotation value (contained in the WheelRotationMask bit field) is
-     * negative and MUST be sign-extended before injection at the server.
-     */
-    public static final int PTRFLAGS_WHEEL_NEGATIVE = 0x0100;
-
-    /**
-     * Bit field describing the number of rotation units the mouse wheel was
-     * rotated. The value is negative if the PTRFLAGS_WHEEL_NEGATIVE flag is set.
-     */
-    public static final int WHEEL_ROTATION_MASK = 0x01FF;
-
-    /**
-     * Indicates that the mouse position MUST be updated to the location specified
-     * by the xPos and yPos fields.
-     */
-    public static final int PTRFLAGS_MOVE = 0x0800;
-
-    /**
-     * Indicates that a click event has occurred at the position specified by the
-     * xPos and yPos fields. The button flags indicate which button has been
-     * clicked and at least one of these flags MUST be set.
-     */
-    public static final int PTRFLAGS_DOWN = 0x8000;
-
-    /**
-     * Mouse button 1 (left button) was clicked or released. If the PTRFLAGS_DOWN
-     * flag is set, then the button was clicked, otherwise it was released.
-     */
-    public static final int PTRFLAGS_BUTTON1 = 0x1000;
-
-    /**
-     * Mouse button 2 (right button) was clicked or released. If the PTRFLAGS_DOWN
-     * flag is set, then the button was clicked, otherwise it was released.
-     */
-    public static final int PTRFLAGS_BUTTON2 = 0x2000;
-
-    /**
-     * Mouse button 3 (middle button or wheel) was clicked or released. If the
-     * PTRFLAGS_DOWN flag is set, then the button was clicked, otherwise it was
-     * released.
-     */
-    public static final int PTRFLAGS_BUTTON3 = 0x4000;
-
-    public AwtRdpMouseAdapter(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        // Get mouse event
-        MouseOrder order = (MouseOrder)buf.getOrder();
-
-        ByteBuffer outBuf = new ByteBuffer(7, true);
-
-        // eventHeader (1 byte): An 8-bit, unsigned integer. EventCode bitfield (top
-        // 3 bits) MUST be set to FASTPATH_INPUT_EVENT_MOUSE (1). The
-        // eventFlags bitfield (low 5 bits) MUST be zeroed out.
-        outBuf.writeByte(FASTPATH_INPUT_EVENT_MOUSE << 5);
-
-        // pointerFlags (2 bytes): A 16-bit, unsigned integer.
-        outBuf.writeShortLE(getPointerFlags(order));
-
-        // xPos (2 bytes): A 16-bit, unsigned integer. The x-coordinate of the
-        // pointer.
-        outBuf.writeShortLE(order.event.getX());
-
-        // yPos (2 bytes): A 16-bit, unsigned integer. The y-coordinate of the
-        // pointer.
-        outBuf.writeShortLE(order.event.getY());
-
-        // Push buffer to one pad only, so it can be modified without copying of
-        // data
-        pushDataToPad(STDOUT, outBuf);
-    }
-
-    // Remember mouse buttons
-    protected boolean button1, button2, button3;
-
-    protected int getPointerFlags(MouseOrder order) {
-        int flags = 0;
-
-        int modifiers = order.event.getModifiersEx();
-
-        if (order.pressed) {
-            // Mouse pressed
-            flags |= PTRFLAGS_DOWN;
-
-            // Check, which one of buttons is released
-            boolean b1 = ((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && !button1;
-            boolean b2 = ((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && !button2;
-            boolean b3 = ((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && !button3;
-
-            if (b1) {
-                flags |= PTRFLAGS_BUTTON1;
-                button1 = true;
-            }
-
-            if (b2) {
-                flags |= PTRFLAGS_BUTTON3;
-                button2 = true;
-            }
-
-            if (b3) {
-                flags |= PTRFLAGS_BUTTON2;
-                button3 = true;
-            }
-        } else if (order.released) {
-            // Mouse released
-
-            // Check, which one of buttons is released
-            boolean b1 = !((modifiers & InputEvent.BUTTON1_DOWN_MASK) > 0) && button1;
-            boolean b2 = !((modifiers & InputEvent.BUTTON2_DOWN_MASK) > 0) && button2;
-            boolean b3 = !((modifiers & InputEvent.BUTTON3_DOWN_MASK) > 0) && button3;
-
-            if (b1) {
-                flags |= PTRFLAGS_BUTTON1;
-                button1 = false;
-            }
-
-            if (b2) {
-                flags |= PTRFLAGS_BUTTON3;
-                button2 = false;
-            }
-
-            if (b3) {
-                flags |= PTRFLAGS_BUTTON2;
-                button3 = false;
-            }
-        } else {
-            // Mouse moved
-            flags |= PTRFLAGS_MOVE;
-        }
-
-        return flags;
-    }
-
-}


[12/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
new file mode 100755
index 0000000..3208a77
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
@@ -0,0 +1,492 @@
+// 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;
+
+/**
+ * During NTLM authentication, each of the following flags is a possible value
+ * of the NegotiateFlags field of the NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, and
+ * AUTHENTICATE_MESSAGE, unless otherwise noted. These flags define client or
+ * server NTLM capabilities supported by the sender.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc236650.aspx
+ */
+public class NegoFlags {
+
+    /**
+     * 56-bit encryption. If the client sends NTLMSSP_NEGOTIATE_SEAL or
+     * NTLMSSP_NEGOTIATE_SIGN with NTLMSSP_NEGOTIATE_56 to the server in the
+     * NEGOTIATE_MESSAGE, the server MUST return NTLMSSP_NEGOTIATE_56 to the
+     * client in the CHALLENGE_MESSAGE. Otherwise it is ignored. If both
+     * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are requested and supported
+     * by the client and server, NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128
+     * will both be returned to the client. Clients and servers that set
+     * NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_56 if it is supported.
+     * An alternate name for this field is
+     */
+    public static final int NTLMSSP_NEGOTIATE_56 = 0x80000000;
+
+    /**
+     * Explicit key exchange. This capability SHOULD be used because it improves
+     * security for message integrity or confidentiality. See sections 3.2.5.1.2,
+     * 3.2.5.2.1, and 3.2.5.2.2 for details.
+     */
+    public static final int NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000;
+
+    /**
+     * 128-bit session key negotiation. An alternate name for this field is
+     * NTLMSSP_NEGOTIATE_128. If the client sends NTLMSSP_NEGOTIATE_128 to the
+     * server in the NEGOTIATE_MESSAGE, the server MUST return
+     * NTLMSSP_NEGOTIATE_128 to the client in the CHALLENGE_MESSAGE only if the
+     * client sets NTLMSSP_NEGOTIATE_SEAL or NTLMSSP_NEGOTIATE_SIGN. Otherwise it
+     * is ignored. If both NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are
+     * requested and supported by the client and server, NTLMSSP_NEGOTIATE_56 and
+     * NTLMSSP_NEGOTIATE_128 will both be returned to the client. Clients and
+     * servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_128 if
+     * it is supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_128 = 0x20000000;
+
+    /**
+     * Protocol version number. The data corresponding to this flag is provided in
+     * the Version field of the NEGOTIATE_MESSAGE, the CHALLENGE_MESSAGE, and the
+     * AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_NEGOTIATE_VERSION = 0x02000000;
+
+    /**
+     * TargetInfo fields in the CHALLENGE_MESSAGE (section 2.2.1.2) are populated.
+     */
+    public static final int NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000;
+
+    /** LMOWF (section 3.3). */
+    public static final int NTLMSSP_REQUEST_NON_NT_SESSION_KEY = 0x00400000;
+
+    /** An identify level token. */
+    public static final int NTLMSSP_NEGOTIATE_IDENTIFY = 0x00100000;
+
+    /**
+     * NTLM v2 session security. NTLM v2 session security is a misnomer because it
+     * is not NTLM v2. It is NTLM v1 using the extended session security that is
+     * also in NTLM v2. NTLMSSP_NEGOTIATE_LM_KEY and
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY and NTLMSSP_NEGOTIATE_LM_KEY are
+     * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+     * returned to the client. NTLM v2 authentication session key generation MUST
+     * be supported by both the client and the DC in order to be used, and
+     * extended session security signing and sealing requires support from the
+     * client and the server in order to be used.
+     */
+    public static final int NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY = 0x00080000;
+
+    /**
+     * TargetName MUST be a server name. The data corresponding to this flag is
+     * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+     * this bit is set, then NTLMSSP_TARGET_TYPE_DOMAIN MUST NOT be set. This flag
+     * MUST be ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_TARGET_TYPE_SERVER = 0x00020000;
+
+    /**
+     * TargetName MUST be a domain name. The data corresponding to this flag is
+     * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+     * set, then NTLMSSP_TARGET_TYPE_SERVER MUST NOT be set. This flag MUST be
+     * ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+     */
+    public static final int NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000;
+
+    /**
+     * Signature block on all messages. NTLMSSP_NEGOTIATE_ALWAYS_SIGN MUST be set
+     * in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to the
+     * client. NTLMSSP_NEGOTIATE_ALWAYS_SIGN is overridden by
+     * NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL, if they are supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000;
+
+    /**
+     * Workstation field is present. If this flag is not set, the Workstation
+     * field MUST be ignored. If this flag is set, the length field of the
+     * Workstation field specifies whether the workstation name is nonempty or
+     * not.
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000;
+
+    /**
+     * Domain name is provided.
+     *
+     * Sent by the client in the Type 1 message to indicate that the name of the
+     * domain in which the client workstation has membership is included in the
+     * message. This is used by the server to determine whether the client is
+     * eligible for local authentication.
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000;
+
+    /**
+     * Connection SHOULD be anonymous.
+     *
+     * Sent by the client in the Type 3 message to indicate that an anonymous
+     * context has been established. This also affects the response fields (as
+     * detailed in the "Anonymous Response" section).
+     */
+    public static final int NTLMSSP_NEGOTIATE_ANONYMOUS = 0x00000800;
+
+    /**
+     * Usage of the NTLM v1 session security protocol. NTLMSSP_NEGOTIATE_NTLM MUST
+     * be set in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to
+     * the client.
+     */
+    public static final int NTLMSSP_NEGOTIATE_NTLM = 0x00000200;
+
+    /**
+     * LAN Manager (LM) session key computation. NTLMSSP_NEGOTIATE_LM_KEY and
+     * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+     * NTLMSSP_NEGOTIATE_LM_KEY and NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are
+     * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+     * returned to the client. NTLM v2 authentication session key generation MUST
+     * be supported by both the client and the DC in order to be used, and
+     * extended session security signing and sealing requires support from the
+     * client and the server to be used.
+     */
+    public static final int NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080;
+
+    /**
+     * Connectionless authentication. If NTLMSSP_NEGOTIATE_DATAGRAM is set, then
+     * NTLMSSP_NEGOTIATE_KEY_EXCH MUST always be set in the AUTHENTICATE_MESSAGE
+     * to the server and the CHALLENGE_MESSAGE to the client.
+     */
+    public static final int NTLMSSP_NEGOTIATE_DATAGRAM = 0x00000040;
+
+    /**
+     * Session key negotiation for message confidentiality. If the client sends
+     * NTLMSSP_NEGOTIATE_SEAL to the server in the NEGOTIATE_MESSAGE, the server
+     * MUST return NTLMSSP_NEGOTIATE_SEAL to the client in the CHALLENGE_MESSAGE.
+     * Clients and servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD always set
+     * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128, if they are supported.
+     */
+    public static final int NTLMSSP_NEGOTIATE_SEAL = 0x00000020;
+
+    /**
+     * Session key negotiation for message signatures. If the client sends
+     * NTLMSSP_NEGOTIATE_SIGN to the server in the NEGOTIATE_MESSAGE, the server
+     * MUST return NTLMSSP_NEGOTIATE_SIGN to the client in the CHALLENGE_MESSAGE.
+     */
+    public static final int NTLMSSP_NEGOTIATE_SIGN = 0x00000010;
+
+    /**
+     * TargetName field of the CHALLENGE_MESSAGE (section 2.2.1.2) MUST be
+     * supplied.
+     */
+    public static final int NTLMSSP_REQUEST_TARGET = 0x00000004;
+
+    /**
+     * OEM character set encoding.
+     *
+     * @see NTLMSSP_NEGOTIATE_UNICODE
+     */
+    public static final int NTLMSSP_NEGOTIATE_OEM = 0x00000002;
+
+    /**
+     * Unicode character set encoding.
+     *
+     * The NTLMSSP_NEGOTIATE_UNICODE(A) and NTLM_NEGOTIATE_OEM(B) bits are
+     * evaluated together as follows:
+     * <ul>
+     * <li>A==1: The choice of character set encoding MUST be Unicode.
+     *
+     * <li>A==0 and B==1: The choice of character set encoding MUST be OEM.
+     *
+     * <li>A==0 and B==0: The protocol MUST return SEC_E_INVALID_TOKEN.
+     * <ul>
+     * */
+    public static final int NTLMSSP_NEGOTIATE_UNICODE = 0x00000001;
+
+    public int value;
+
+    public NegoFlags(int value) {
+        this.value = value;
+    }
+
+    public NegoFlags() {
+        value = 0;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("NegoFlags [value=0x%04x (%s)]", value, flagsToSting());
+    }
+
+    public String flagsToSting() {
+
+        String str = "";
+
+        if (NEGOTIATE_56())
+            str += "NEGOTIATE_56 ";
+        if (NEGOTIATE_KEY_EXCH())
+            str += "NEGOTIATE_KEY_EXCH ";
+        if (NEGOTIATE_128())
+            str += "NEGOTIATE_128 ";
+        if (NEGOTIATE_VERSION())
+            str += "NEGOTIATE_VERSION ";
+        if (NEGOTIATE_TARGET_INFO())
+            str += "NEGOTIATE_TARGET_INFO ";
+        if (REQUEST_NON_NT_SESSION_KEY())
+            str += "REQUEST_NON_NT_SESSION_KEY ";
+        if (NEGOTIATE_IDENTIFY())
+            str += "NEGOTIATE_IDENTIFY ";
+        if (NEGOTIATE_EXTENDED_SESSION_SECURITY())
+            str += "NEGOTIATE_EXTENDED_SESSION_SECURITY ";
+        if (TARGET_TYPE_SERVER())
+            str += "TARGET_TYPE_SERVER ";
+        if (TARGET_TYPE_DOMAIN())
+            str += "TARGET_TYPE_DOMAIN ";
+        if (NEGOTIATE_ALWAYS_SIGN())
+            str += "NEGOTIATE_ALWAYS_SIGN ";
+        if (NEGOTIATE_OEM_WORKSTATION_SUPPLIED())
+            str += "NEGOTIATE_OEM_WORKSTATION_SUPPLIED ";
+        if (NEGOTIATE_OEM_DOMAIN_SUPPLIED())
+            str += "NEGOTIATE_OEM_DOMAIN_SUPPLIED ";
+        if (NEGOTIATE_ANONYMOUS())
+            str += "NEGOTIATE_ANONYMOUS ";
+        if (NEGOTIATE_NTLM())
+            str += "NEGOTIATE_NTLM ";
+        if (NEGOTIATE_LM_KEY())
+            str += "NEGOTIATE_LM_KEY ";
+        if (NEGOTIATE_DATAGRAM())
+            str += "NEGOTIATE_DATAGRAM ";
+        if (NEGOTIATE_SEAL())
+            str += "NEGOTIATE_SEAL ";
+        if (NEGOTIATE_SIGN())
+            str += "NEGOTIATE_SIGN ";
+        if (REQUEST_TARGET())
+            str += "REQUEST_TARGET ";
+        if (NEGOTIATE_OEM())
+            str += "NEGOTIATE_OEM ";
+        if (NEGOTIATE_UNICODE())
+            str += "NEGOTIATE_UNICODE ";
+
+        return str;
+    }
+
+    public boolean NEGOTIATE_56() {
+        return ((value & NTLMSSP_NEGOTIATE_56) != 0);
+    }
+
+    public boolean NEGOTIATE_KEY_EXCH() {
+        return ((value & NTLMSSP_NEGOTIATE_KEY_EXCH) != 0);
+    }
+
+    public boolean NEGOTIATE_128() {
+        return ((value & NTLMSSP_NEGOTIATE_128) != 0);
+    }
+
+    public boolean NEGOTIATE_VERSION() {
+        return ((value & NTLMSSP_NEGOTIATE_VERSION) != 0);
+    }
+
+    public boolean NEGOTIATE_TARGET_INFO() {
+        return ((value & NTLMSSP_NEGOTIATE_TARGET_INFO) != 0);
+    }
+
+    public boolean REQUEST_NON_NT_SESSION_KEY() {
+        return ((value & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0);
+    }
+
+    public boolean NEGOTIATE_IDENTIFY() {
+        return ((value & NTLMSSP_NEGOTIATE_IDENTIFY) != 0);
+    }
+
+    public boolean NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+        return ((value & NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY) != 0);
+    }
+
+    public boolean TARGET_TYPE_SERVER() {
+        return ((value & NTLMSSP_TARGET_TYPE_SERVER) != 0);
+    }
+
+    public boolean TARGET_TYPE_DOMAIN() {
+        return ((value & NTLMSSP_TARGET_TYPE_DOMAIN) != 0);
+    }
+
+    public boolean NEGOTIATE_ALWAYS_SIGN() {
+        return ((value & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) != 0);
+    }
+
+    public boolean NEGOTIATE_ANONYMOUS() {
+        return ((value & NTLMSSP_NEGOTIATE_ANONYMOUS) != 0);
+    }
+
+    public boolean NEGOTIATE_NTLM() {
+        return ((value & NTLMSSP_NEGOTIATE_NTLM) != 0);
+    }
+
+    public boolean NEGOTIATE_LM_KEY() {
+        return ((value & NTLMSSP_NEGOTIATE_LM_KEY) != 0);
+    }
+
+    public boolean NEGOTIATE_DATAGRAM() {
+        return ((value & NTLMSSP_NEGOTIATE_DATAGRAM) != 0);
+    }
+
+    public boolean NEGOTIATE_SEAL() {
+        return ((value & NTLMSSP_NEGOTIATE_SEAL) != 0);
+    }
+
+    public boolean NEGOTIATE_SIGN() {
+        return ((value & NTLMSSP_NEGOTIATE_SIGN) != 0);
+    }
+
+    public boolean REQUEST_TARGET() {
+        return ((value & NTLMSSP_REQUEST_TARGET) != 0);
+    }
+
+    public boolean NEGOTIATE_OEM() {
+        return ((value & NTLMSSP_NEGOTIATE_OEM) != 0);
+    }
+
+    public boolean NEGOTIATE_UNICODE() {
+        return ((value & NTLMSSP_NEGOTIATE_UNICODE) != 0);
+    }
+
+    public NegoFlags set_NEGOTIATE_56() {
+        value |= NTLMSSP_NEGOTIATE_56;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_KEY_EXCH() {
+        value |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_128() {
+        value |= NTLMSSP_NEGOTIATE_128;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_VERSION() {
+        value |= NTLMSSP_NEGOTIATE_VERSION;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_TARGET_INFO() {
+        value |= NTLMSSP_NEGOTIATE_TARGET_INFO;
+        return this;
+    }
+
+    public NegoFlags set_REQUEST_NON_NT_SESSION_KEY() {
+        value |= NTLMSSP_REQUEST_NON_NT_SESSION_KEY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_IDENTIFY() {
+        value |= NTLMSSP_NEGOTIATE_IDENTIFY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+        value |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
+        return this;
+    }
+
+    public NegoFlags set_TARGET_TYPE_SERVER() {
+        value |= NTLMSSP_TARGET_TYPE_SERVER;
+        return this;
+    }
+
+    public NegoFlags set_TARGET_TYPE_DOMAIN() {
+        value |= NTLMSSP_TARGET_TYPE_DOMAIN;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_ALWAYS_SIGN() {
+        value |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+        value |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+        value |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_ANONYMOUS() {
+        value |= NTLMSSP_NEGOTIATE_ANONYMOUS;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_NTLM() {
+        value |= NTLMSSP_NEGOTIATE_NTLM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_LM_KEY() {
+        value |= NTLMSSP_NEGOTIATE_LM_KEY;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_DATAGRAM() {
+        value |= NTLMSSP_NEGOTIATE_DATAGRAM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_SEAL() {
+        value |= NTLMSSP_NEGOTIATE_SEAL;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_SIGN() {
+        value |= NTLMSSP_NEGOTIATE_SIGN;
+        return this;
+    }
+
+    public NegoFlags set_REQUEST_TARGET() {
+        value |= NTLMSSP_REQUEST_TARGET;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_OEM() {
+        value |= NTLMSSP_NEGOTIATE_OEM;
+        return this;
+    }
+
+    public NegoFlags set_NEGOTIATE_UNICODE() {
+        value |= NTLMSSP_NEGOTIATE_UNICODE;
+        return this;
+    }
+
+    /**
+     * Example.
+     */
+
+    public static void main(String args[]) {
+
+        NegoFlags flags = new NegoFlags(0xe20882b7);
+        System.out.println("Negotiation flags: " + flags);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
new file mode 100755
index 0000000..e75c73c
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmCompute.java
@@ -0,0 +1,24 @@
+// 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;
+
+public class NtlmCompute {
+
+    public void compute_ntlm_v2_hash() {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
new file mode 100755
index 0000000..a823aac
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NtlmConstants.java
@@ -0,0 +1,157 @@
+// 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;
+
+public interface NtlmConstants {
+
+    /**
+     * Attribute type: Indicates that this is the last AV_PAIR in the list. AvLen
+     * MUST be 0. This type of information MUST be present in the AV pair list.
+     */
+    public final static int MSV_AV_EOL = 0x0000;
+
+    /**
+     * Attribute type: The server's NetBIOS computer name. The name MUST be in
+     * Unicode, and is not null-terminated. This type of information MUST be
+     * present in the AV_pair list.
+     */
+    public final static int MSV_AV_NETBIOS_COMPUTER_NAME = 0x0001;
+
+    /**
+     * Attribute type: The server's NetBIOS domain name. The name MUST be in
+     * Unicode, and is not null-terminated. This type of information MUST be
+     * present in the AV_pair list.
+     */
+    public final static int MSV_AV_NETBIOS_DOMAIN_NAME = 0x0002;
+
+    /**
+     * Attribute type: The fully qualified domain name (FQDN (1)) of the computer.
+     * The name MUST be in Unicode, and is not null-terminated.
+     */
+    public final static int MSV_AV_DNS_COMPUTER_NAME = 0x0003;
+
+    /**
+     * Attribute type: The FQDN of the domain. The name MUST be in Unicode, and is
+     * not null-terminated.
+     */
+    public final static int MSV_AV_DNS_DOMAIN_NAME = 0x0004;
+
+    /**
+     * Attribute type: The FQDN of the forest. The name MUST be in Unicode, and is
+     * not null-terminated.
+     */
+    public final static int MSV_AV_DNS_TREE_NAME = 0x0005;
+
+    /**
+     * Attribute type: A 32-bit value indicating server or client configuration.
+     *
+     * <li>0x00000001: indicates to the client that the account authentication is
+     * constrained.
+     *
+     * <li>0x00000002: indicates that the client is providing message integrity in
+     * the MIC field (section 2.2.1.3) in the AUTHENTICATE_MESSAGE.
+     *
+     * <li>0x00000004: indicates that the client is providing a target SPN
+     * generated from an untrusted source.
+     **/
+    public final static int MSV_AV_FLAGS = 0x0006;
+
+    public static final int MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK = 0x00000002;
+
+    /**
+     * Attribute type: A FILETIME structure ([MS-DTYP] section 2.3.3) in
+     * little-endian byte order that contains the server local time.
+     */
+    public final static int MSV_AV_TIMESTAMP = 0x0007;
+
+    /**
+     * Attribute type: A Single_Host_Data (section 2.2.2.2) structure. The Value
+     * field contains a platform-specific blob, as well as a MachineID created at
+     * computer startup to identify the calling machine.<15>
+     */
+    public final static int MSV_AV_SINGLE_HOST = 0x0008;
+
+    /**
+     * Attribute type: The SPN of the target server. The name MUST be in Unicode
+     * and is not null-terminated.<16>
+     */
+    public final static int MSV_AV_TARGET_NAME = 0x0009;
+
+    /**
+     * Attribute type: A channel bindings hash. The Value field contains an MD5
+     * hash ([RFC4121] section 4.1.1.2) of a gss_channel_bindings_struct
+     * ([RFC2744] section 3.11). An all-zero value of the hash is used to indicate
+     * absence of channel bindings.
+     */
+    public final static int MSV_AV_CHANNEL_BINDINGS = 0x000A;
+
+    /**
+     * Signature of NTLMSSP blob.
+     */
+    public static final String NTLMSSP = "NTLMSSP";
+
+    public static final String GSS_RDP_SERVICE_NAME = "TERMSRV";
+
+    /**
+     * NTLM message type: NEGOTIATE.
+     */
+    public static final int NEGOTIATE = 0x00000001;
+
+    /**
+     * NTLM message type: CHALLENGE.
+     */
+    public static final int CHALLENGE = 0x00000002;
+
+    /**
+     * NTLM message type: NTLMSSP_AUTH.
+     */
+    public static final int NTLMSSP_AUTH = 0x00000003;
+
+    public static final String OID_SPNEGO = "1.3.6.1.5.5.2";
+
+    public static final String OID_KERBEROS5 = "1.2.840.113554.1.2.2";
+    public static final String OID_MSKERBEROS5 = "1.2.840.48018.1.2.2";
+
+    public static final String OID_KRB5USERTOUSER = "1.2.840.113554.1.2.2.3";
+
+    public static final String OID_NTLMSSP = "1.3.6.1.4.1.311.2.2.10";
+
+    /**
+     * Magic constant used in calculation of Lan Manager response.
+     */
+    public static final String LM_MAGIC = "KGS!@#$%";
+
+    /**
+     * Magic constant used in generation of client signing key.
+     */
+    public static final String CLIENT_SIGN_MAGIC = "session key to client-to-server signing key magic constant";
+
+    /**
+     * Magic constant used in generation of client sealing key.
+     */
+    public static final String CLIENT_SEAL_MAGIC = "session key to client-to-server sealing key magic constant";
+
+    public static final String SERVER_SIGN_MAGIC = "session key to server-to-client signing key magic constant";
+    public static final String SERVER_SEAL_MAGIC = "session key to server-to-client sealing key magic constant";
+
+    /**
+     * In Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008,
+     * Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows
+     * 8.1, and Windows Server 2012 R2, the maximum lifetime of challenge is 36 hours.
+     */
+    public static final int CHALLENGE_MAX_LIFETIME = 36 * 60 * 60;
+}


[18/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
deleted file mode 100644
index e910c10..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSConnectInitial.java
+++ /dev/null
@@ -1,669 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class ClientMCSConnectInitial extends OneTimeSwitch {
-
-    public ClientMCSConnectInitial(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        int length = 1024; // Large enough
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        /* @formatter:off */
-    buf.writeBytes(new byte[] {
-//        - T125: MCSConnect Initial
-//        - MCSConnectInitial: Identifier=Generic Conference Control (0.0.20.124.0.1), ConnectPDULength=254
-//         - ConnectInitialHeader:
-      (byte)0x7F, (byte)0x65,
-//          - AsnId: Application Constructed Tag (101)
-//           - HighTag:
-//              Class:     (01......) Application (1)
-//              Type:      (..1.....) Constructed
-//              TagNumber: (...11111)
-//              TagValueEnd: 101 (0x65)
-      (byte)0x82, (byte)0x01, (byte)0x6C,
-//          - AsnLen: Length = 364, LengthOfLength = 2
-//             LengthType: LengthOfLength = 2
-//             Length: 364 bytes
-      (byte)0x04, (byte)0x01, (byte)0x01,
-//         - CallingDomainSelector: 0x1
-//          - AsnOctetStringHeader:
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            OctetStream: 0x1
-      (byte)0x04, (byte)0x01, (byte)0x01,
-//         - CalledDomainSelector: 0x1
-//          - AsnOctetStringHeader:
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            OctetStream: 0x1
-      (byte)0x01, (byte)0x01, (byte)0xFF,
-//         - UpwardFlag: True
-//          - AsnBooleanHeader:
-//           - AsnId: Boolean type (Universal 1)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00001) 1
-//           - AsnLen: Length = 1, LengthOfLength = 0
-//              Length: 1 bytes, LengthOfLength = 0
-//            Tf: 255 (0xFF)
-
-//
-//         - TargetParameters: Length = 26, LengthOfLength = 0
-      (byte)0x30, (byte)0x1A,
-//          - DomainParametersHeader: 0x1
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 26, LengthOfLength = 0
-//              Length: 26 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x01, (byte)0x22,
-//          - ChannelIds: 34
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 34 (0x22)
-      (byte)0x02, (byte)0x01, (byte)0x02,
-//          - UserIDs: 2
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - TokenIds: 0
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - NumPriorities: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - MinThroughput: 0
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - Height: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - MCSPDUsize: 65535
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x02,
-//          - protocolVersion: 2
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-
-//
-//         - MinimumParameters: Length = 25, LengthOfLength = 0
-      (byte)0x30, (byte)0x19,
-//          - DomainParametersHeader: 0x1
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 25, LengthOfLength = 0
-//              Length: 25 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - ChannelIds: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - UserIDs: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - TokenIds: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - NumPriorities: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - MinThroughput: 0
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - Height: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20,
-//          - MCSPDUsize: 1056
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 2, LengthOfLength = 0
-//               Length: 2 bytes, LengthOfLength = 0
-//             AsnInt: 1056 (0x420)
-      (byte)0x02, (byte)0x01, (byte)0x02,
-//          - protocolVersion: 2
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-//         - MaximumParameters: Length = 31, LengthOfLength = 0
-//          - DomainParametersHeader: 0x1
-      (byte)0x30, (byte)0x1F,
-//           - AsnId: Sequence and SequenceOf types (Universal 16)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..1.....) Constructed
-//               TagValue: (...10000) 16
-//           - AsnLen: Length = 31, LengthOfLength = 0
-//              Length: 31 bytes, LengthOfLength = 0
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - ChannelIds: 65535
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x02, (byte)0xFC, (byte)0x17,
-//          - UserIDs: 64535
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 2, LengthOfLength = 0
-//               Length: 2 bytes, LengthOfLength = 0
-//             AsnInt: 64535 (0xFC17)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - TokenIds: 65535
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - NumPriorities: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x01, (byte)0x00,
-//          - MinThroughput: 0
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 0 (0x0)
-      (byte)0x02, (byte)0x01, (byte)0x01,
-//          - Height: 1
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 1 (0x1)
-      (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xFF, (byte)0xFF,
-//          - MCSPDUsize: 65535
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 3, LengthOfLength = 0
-//               Length: 3 bytes, LengthOfLength = 0
-//             AsnInt: 65535 (0xFFFF)
-      (byte)0x02, (byte)0x01, (byte)0x02,
-//          - protocolVersion: 2
-//           - AsnIntegerHeader:
-//            - AsnId: Integer type (Universal 2)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00010) 2
-//            - AsnLen: Length = 1, LengthOfLength = 0
-//               Length: 1 bytes, LengthOfLength = 0
-//             AsnInt: 2 (0x2)
-//         - UserData: Identifier=Generic Conference Contro (0.0.20.124.0.1), ConnectPDULength=254
-//          - UserDataHeader:
-      (byte)0x04, (byte)0x82, (byte)0x01, (byte)0x07,
-//           - AsnId: OctetString type (Universal 4)
-//            - LowTag:
-//               Class:    (00......) Universal (0)
-//               Type:     (..0.....) Primitive
-//               TagValue: (...00100) 4
-//           - AsnLen: Length = 263, LengthOfLength = 2
-//              LengthType: LengthOfLength = 2
-//              Length: 263 bytes
-      (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7C, (byte)0x00, (byte)0x01,
-//          - AsnBerObjectIdentifier: Generic Conference Contro (0.0.20.124.0.1)
-//           - AsnObjectIdentifierHeader:
-//            - AsnId: Reserved for use by the encoding rules (Universal 0)
-//             - LowTag:
-//                Class:    (00......) Universal (0)
-//                Type:     (..0.....) Primitive
-//                TagValue: (...00000) 0
-//            - AsnLen: Length = 5, LengthOfLength = 0
-//               Length: 5 bytes, LengthOfLength = 0
-//             First: 0 (0x0)
-//             Final: 20 (0x14)
-//             Final: 124 (0x7C)
-//             Final: 0 (0x0)
-//             Final: 1 (0x1)
-      (byte)0x80, (byte)0xFE,
-//          - ConnectPDULength: 254
-//             Align: No Padding
-//             Length: 254
-      (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10,
-//          - ConnectGCCPDU: conferenceCreateRequest
-//             ExtensionBit: 0 (0x0)
-//           - ChoiceValue: conferenceCreateRequest
-//              Value: (000.....) 0x0
-//           - conferenceCreateRequest:
-//              ExtensionBit: 0 (0x0)
-//              convenerPasswordPresent: 0 (0x0)
-//              passwordPresent: 0 (0x0)
-//              conductorPrivilegesPresent: 0 (0x0)
-//              conductedPrivilegesPresent: 0 (0x0)
-//              nonConductedPrivilegesPresent: 0 (0x0)
-//              conferenceDescriptionPresent: 0 (0x0)
-//              callerIdentifierPresent: 0 (0x0)
-//              userDataPresent: 1 (0x1)
-//            - conferenceName:
-//               ExtensionBit: 0 (0x0)
-//               textPresent: 0 (0x0)
-//             - numeric: 1
-//              - SimpleNumericString: 1
-//               - NumericString: 1
-//                - Align: No Padding
-//                   Padding1: (0.......) 0x0
-//                - Length: 1
-//                   Value: (00000000) 0x0
-//                - Restrictedstr: 1
-//                   FourBits: (0001....) 0x1
-//            - lockedConference: False
-//               Value: False 0.......
-//            - listedConference: False
-//               Value: False 0.......
-//            - conductibleConference: False
-//               Value: False 0.......
-//            - TerminationMethod: automatic
-//               ExtensionBit: 0 (0x0)
-//             - RootIndex: 0
-//                Value: (0.......) 0x0
-//            - userData:
-      (byte)0x00, (byte)0x01,
-//             - Size: 1
-//              - Align: No Padding
-//                 Padding7: (0000000.) 0x0
-//                Length: 1
-//             - UserData: 0x44756361
-      (byte)0xC0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61,
-//                valuePresent: 1 (0x1)
-//              - key: h221NonStandard "Duca"
-//               - ChoiceValue: h221NonStandard
-//                  Value: (1.......) 0x1
-//               - h221NonStandard:
-//                - H221NonStandardIdentifier: length: 4
-//                 - ConstrainedLength: 4
-//                    Value: (00000000) 0x0
-//                 - Align: No Padding
-//                    Padding6: (000000..) 0x0
-//                   Value: Binary Large Object (4 Bytes) "Duca"
-//              - ClientMcsConnectInitialPdu:
-      (byte)0x80, (byte)0xF0,
-//               - RDPGCCUserDataRequestLength: 240
-//                  Align: No Padding
-//                  Length: 240
-//               - TsUd: CS_CORE
-      (byte)0x01, (byte)0xC0, (byte)0xD8, (byte)0x00,
-//                - TsUdHeader: Type = CS_CORE, Length = 216
-//                   Type: CS_CORE
-//                   Length: 216 (0xD8)
-//                - TsUdCsCore:
-      (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
-//                   Version: RDP 5.0, 5.1, 5.2, 6.0, 6.1, and 7.0
-      (byte)0x00, (byte)0x04,
-//                   DesktopWidth: 1024 (0x400)
-      (byte)0x00, (byte)0x03,
-//                   DesktopHeight: 768 (0x300)
-      (byte)0x01, (byte)0xCA,
-//                   ColorDepth: 8 bpp
-      (byte)0x03, (byte)0xAA,
-//                   SASSequence: 0xaa03, SHOULD be set to RNS_UD_SAS_DEL(0xAA03)
-      (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00,
-//                   KeyboardLayout: Language: English, Location: United States
-      (byte)0x28, (byte)0x0A, (byte)0x00, (byte)0x00,
-//                   ClientBuild: 2600 (0xA28)
-      (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6C, (byte)0x00, (byte)0x6F, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   ClientName: apollo3
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   KeyboardType: Undefined value: 0
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   KeyboardSubType: 0 (0x0)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   KeyboardFunctionKey: 0 (0x0)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   ImeFileName:
-      (byte)0x01, (byte)0xCA,
-//                   PostBeta2ColorDepth: 8 bpp
-      (byte)0x01, (byte)0x00,
-//                   ClientProductId: 0x1, SHOULD be set to initialized to 1
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//                   SerialNumber: 0x0, SHOULD be set to 0
-      (byte)0x10, (byte)0x00,
-//                   HighColorDepth: 16-bit 565 RGB
-      (byte)0x07, (byte)0x00,
-//                 - SupportedColorDepth: 7 (0x7)
-//                    Support24BPP: (...............1) Support 24BPP
-//                    Support16BPP: (..............1.) Support 16BPP
-//                    Support15BPP: (.............1..) Support 15BPP
-//                    Support32BPP: (............0...) Not Support 32BPP
-//                    Reserved:     (000000000000....)
-      (byte)0x01, (byte)0x00,
-//                 - EarlyCapabilityFlags: 1 (0x1)
-//                    SupportSetErrorPdu:      (...............1) Indicates that the client supports the Set Error Info PDU
-//                    Want32BppSession:        (..............0.) Client is not requesting 32BPP session
-//                    SupportStatusInfoPdu:    (.............0..) Client not supports the Server Status Info PDU
-//                    StrongAsymmetricKeys:    (............0...) Not support asymmetric keys larger than 512-bits
-//                    Unused:                  (...........0....)
-//                    ValidConnection:         (..........0.....) Not Indicates ConnectionType field contains valid data
-//                    SupportMonitorLayoutPdu: (.........0......) Not Indicates that the client supports the Monitor Layout PDU
-//                    Unused2:                 (000000000.......)
-      (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//      ClientDigProductId:
-(byte)0x00,
-//      connectionType: invalid connection type
-(byte)0x00,
-//      pad1octet: 0 (0x0)
-(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
-//      ServerSelectedProtocols: TLS 1.0
-//
-//  - TsUd: CS_CLUSTER
-//   - TsUdHeader: Type = CS_CLUSTER, Length = 12
-(byte)0x04, (byte)0xC0,
-//      Type: CS_CLUSTER
-(byte)0x0C, (byte)0x00,
-//      Length: 12 (0xC)
-(byte)0x0D, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//   - TsUdCsCluster:
-//    - Flags: 13 (0xD)
-//       RedirectedSupported: (...............................1) Support Redirected
-//       SessionIDFieldValid: (..............................0.) SessionID Field not Valid
-//       SupportedVersion:    (..........................0011..) REDIRECTION_VERSION4
-//       RedirectedSmartcard: (.........................0......) Not Logon with Smartcard
-//       Unused:           (0000000000000000000000000.......)
-//      RedirectedSessionID: 0 (0x0)
-//
-//  - TsUd: CS_SECURITY
-//   - TsUdHeader: Type = CS_SECURITY, Length = 12
-(byte)0x02, (byte)0xC0,
-//      Type: CS_SECURITY
-(byte)0x0C, (byte)0x00,
-//      Length: 12 (0xC)
-//
-//   - TsUdCsSec:
-(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//    - EncryptionMethod:
-//       Support40Bit:  (...............................0) Not Support
-//       Support128Bit: (..............................0.) Not Support 128-bit
-//       Reserved1:     (.............................0..)
-//       Support56Bit:  (............................0...) Not Support 56-bit
-//       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-//       Reserved2:     (000000000000000000000000000.....)
-(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-//    - ExtEncryptionMethod:
-//       Support40Bit:  (...............................0) Not Support
-//       Support128Bit: (..............................0.) Not Support 128-bit
-//       Reserved1:     (.............................0..)
-//       Support56Bit:  (............................0...) Not Support 56-bit
-//       SupportFIPS:   (...........................0....) Not Support FIPS Compliant
-//       Reserved2:     (000000000000000000000000000.....)
-    });
-    /* @formatter:on */
-
-        buf.length = buf.cursor;
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * Example.
-     *
-     * @see http://msdn.microsoft.com/en-us/library/cc240836.aspx
-     */
-    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[] {
-        // TPKT: TPKT version = 3
-        (byte) 0x03,  (byte) 0x00,
-        // TPKT: Packet length: 378 bytes
-        (byte) 0x01,  (byte) 0x78,
-
-        // X.224: Length indicator = 2
-        (byte) 0x02,
-        // X.224: Type: Data TPDU
-        (byte) 0xf0,
-        // X.224: EOT
-        (byte) 0x80,
-
-        // Captured packet
-        (byte)0x7f, (byte)0x65, (byte)0x82, (byte)0x01, (byte)0x6c, (byte)0x04, (byte)0x01, (byte)0x01, (byte)0x04,
-        (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0xff, (byte)0x30, (byte)0x1a, (byte)0x02, (byte)0x01, (byte)0x22, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01, (byte)0x00,
-        (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01,
-        (byte)0x02, (byte)0x30, (byte)0x19, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
-        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x04, (byte)0x20, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x30, (byte)0x1f, (byte)0x02, (byte)0x03,
-        (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x02, (byte)0xfc, (byte)0x17, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02,
-        (byte)0x01, (byte)0x00, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0x04, (byte)0x82, (byte)0x01,
-        (byte)0x07, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x14, (byte)0x7c, (byte)0x00, (byte)0x01, (byte)0x80, (byte)0xfe, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x01,
-        (byte)0xc0, (byte)0x00, (byte)0x44, (byte)0x75, (byte)0x63, (byte)0x61, (byte)0x80, (byte)0xf0, (byte)0x01, (byte)0xc0, (byte)0xd8, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x08, (byte)0x00,
-        (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x03, (byte)0x01, (byte)0xca, (byte)0x03, (byte)0xaa, (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x0a, (byte)0x00, (byte)0x00,
-        (byte)0x61, (byte)0x00, (byte)0x70, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6c, (byte)0x00, (byte)0x6f, (byte)0x00, (byte)0x33, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xca, (byte)0x01, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
-        (byte)0x04, (byte)0xc0, (byte)0x0c, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xc0, (byte)0x0c, (byte)0x00,
-        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-    };
-    /* @formatter:on */
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element todo = new ClientMCSConnectInitial("ClientMCSConnectInitial");
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "ClientMCSConnectInitial", "mainSink");
-        pipeline.link("ClientMCSConnectInitial >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
deleted file mode 100644
index 4cb00aa..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientMCSErectDomainRequest.java
+++ /dev/null
@@ -1,189 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240683.aspx
- */
-public class ClientMCSErectDomainRequest extends OneTimeSwitch {
-
-    public ClientMCSErectDomainRequest(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        int length = 5;
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        buf.writeByte(0x04); // Erect Domain Request
-
-        // Client SHOULD initialize both the subHeight and subinterval fields of the MCS Erect Domain Request PDU to zero.
-
-        buf.writeByte(1); // ErectDomainRequest::subHeight length = 1 byte
-        buf.writeByte(0); // ErectDomainRequest::subHeight
-
-        buf.writeByte(1); // ErectDomainRequest::subInterval length = 1 byte
-        buf.writeByte(0); // ErectDomainRequest::subInterval
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * Example.
-     * @see http://msdn.microsoft.com/en-us/library/cc240837.aspx
-     */
-    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[] {
-
-        0x03, 0x00, 0x00, 0x0c,  //  TPKT Header (length = 12 bytes)
-        0x02, (byte) 0xf0, (byte) 0x80,  //  X.224 Data TPDU
-
-        // PER encoded (ALIGNED variant of BASIC-PER) PDU contents:
-        0x04, 0x01, 0x00, 0x01, 0x00,
-
-        // 0x04:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   | CHOICE: From DomainMCSPDU select erectDomainRequest (1)
-        // 0 -   | of type ErectDomainRequest
-        // 0 -   |
-        // 1 - --/
-        // 0 - padding
-        // 0 - padding
-
-        // 0x01:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subHeight length = 1 byte
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 1 - --/
-
-        // 0x00:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subHeight = 0
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 0 - --/
-
-        // 0x01:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subInterval length = 1 byte
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 1 - --/
-
-        // 0x00:
-        // 0 - --\
-        // 0 -   |
-        // 0 -   |
-        // 0 -   | ErectDomainRequest::subInterval = 0
-        // 0 -   |
-        // 0 -   |
-        // 0 -   |
-        // 0 - --/
-
-
-    };
-    /* @formatter:on */
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element todo = new ClientMCSErectDomainRequest("TODO");
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "TODO", "mainSink");
-        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}
-
-/*
- * 03 00 00 0C 02 F0 80 04 01 00 01 00
-
-  Frame: Number = 14, Captured Frame Length = 69, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 12
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 12 (0xC)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Erect Domain Request, SubHeight = 0, SubInterval = 0
-  - MCSHeader: Type=Erect Domain Request
-   - Type: Erect Domain Request
-    - RootIndex: 1
-       Value: (000001..) 0x1
-  - MCSErectDomainRequest: SubHeight = 0, SubInterval = 0
-   - SubHeight: 0x0
-    - Length: 1
-     - Align: No Padding
-        Padding2: (00......) 0x0
-       Length: 1
-      Value: 0 (0x0)
-   - SubInterval: 0x0
-    - Length: 1
-       Align: No Padding
-       Length: 1
-      Value: 0 (0x0)
-
- */

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
deleted file mode 100644
index 78f5235..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientPacketSniffer.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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;
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class ClientPacketSniffer extends PacketSniffer {
-
-    private static final Pair[] clientRegexps = new Pair[] {
-// @formatter:off
-    new Pair("Client FastPath input",           "04"),
-    new Pair("Client X224ConnectionRequest",    "03 00 XX XX 27 E0"),
-    new Pair("Client ConnectionRequest",        "03 00 XX XX XX E0"),
-    new Pair("Client MCConnectInitial",         "03 00 XX XX 02 F0 80 7F 65"),
-    new Pair("Client ErectDomainRequest",       "03 00 XX XX 02 F0 80 04"),
-    new Pair("Client AttachUserRequest",        "03 00 XX XX 02 F0 80 28"),
-    new Pair("Client ChannelJoinRequest",       "03 00 XX XX 02 F0 80 38"),
-    new Pair("Client Info",                     "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 00 00"),
-    new Pair("Client ConfirmActivePDU",         "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 13 00"),
-    new Pair("Client SynchronizePDU",           "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 1F"),
-    new Pair("Client ControlPDU",               "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 14"),
-    new Pair("Client FontListPDU",              "03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX 00 XX XX XX XX 27"),
-    new Pair("Client BitmapCachePersistentList","03 00 XX XX 02 F0 80 64 00 03 03 EB 70 XX XX XX XX 17 00 EC 03 EA 03 XX XX XX XX XX XX 2b"),
-//    new Pair("Client TPKT Unknown packet",      "03"),
-//    new Pair("Client UNKNOWN PACKET (ERROR)",   ".*"),
-    // @formatter:on
-
-    };
-
-    public ClientPacketSniffer(String id) {
-        super(id, clientRegexps);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
deleted file mode 100644
index 5b370b5..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientSynchronizePDU.java
+++ /dev/null
@@ -1,248 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240489.aspx
- */
-public class ClientSynchronizePDU extends OneTimeSwitch {
-
-    public ClientSynchronizePDU(String id) {
-        super(id);
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        int length = 1024; // Large enough
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        /* @formatter:off */
-    buf.writeBytes(new byte[] {
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16,
-
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00,
-
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01,
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f,
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00,
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-    });
-    /* @formatter:on */
-
-        // Trim buffer to actual length of data written
-        buf.trimAtCursor();
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * Example.
-     *
-     * @see http://msdn.microsoft.com/en-us/library/cc240841.aspx
-     */
-    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[] {
-        // TPKT
-        (byte)0x03, (byte)0x00,
-        // TPKT length: 37 bytes
-        (byte)0x00, (byte)0x25,
-        // X224 Data PDU
-        (byte)0x02, (byte)0xf0, (byte)0x80,
-
-        // MCS send data request
-        (byte)0x64,
-        // Initiator: 1004 (1001+3)
-        (byte)0x00, (byte)0x03,
-        // Channel ID: 1003 (I/O Channel)
-        (byte)0x03, (byte)0xeb,
-        // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10)
-        (byte)0x70,
-        // Data length:  22 bytes (0x16, variable length field)
-        (byte)0x80,  (byte)0x16,
-
-        // RDP: total length: 22 bytes (LE)
-        (byte)0x16, (byte)0x00,
-        // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE)
-        (byte)0x17, (byte)0x00,
-        // PDU source: 1007 (LE)
-        (byte)0xec, (byte)0x03,
-        // Share ID: 0x000103ea (LE)
-        (byte)0xea, (byte)0x03, (byte)0x01,  (byte)0x00,
-        // Padding: 1 byte
-        (byte)0x00,
-        // Stream ID: STREAM_LOW (1)
-        (byte)0x01,
-        // uncompressedLength : 8 bytes (LE)
-        (byte)0x08, (byte)0x00,
-        // pduType2 = PDUTYPE2_SYNCHRONIZE (31)
-        (byte)0x1f,
-        // generalCompressedType: 0
-        (byte)0x00,
-        // generalCompressedLength: 0 (LE?)
-        (byte)0x00, (byte)0x00,
-        //  messageType: SYNCMSGTYPE_SYNC (1) (LE)
-        (byte)0x01, (byte)0x00,
-        // targetUser: 0x03ea
-        (byte)0xea, (byte)0x03,
-
-    };
-    /* @formatter:on */
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element todo = new ClientSynchronizePDU("TODO");
-        Element x224 = new ClientX224DataPdu("x224");
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, todo, x224, tpkt, sink, mainSink);
-        pipeline.link("source", "TODO", "mainSink");
-        pipeline.link("TODO >" + OTOUT, "x224", "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}
-
-/*
- * @formatting:off
-
- * 03 00 00 25 02 F0 80 64 00 03 03 EB 70 80 16 16 00 17 00 EC 03 EA 03 01 00 00 01 08 00 1F 00 00 00 01 00 EA 03
-
-  Frame: Number = 40, Captured Frame Length = 94, MediaType = DecryptedPayloadHeader
-+ DecryptedPayloadHeader: FrameCount = 1, ErrorStatus = SUCCESS
-  TLSSSLData: Transport Layer Security (TLS) Payload Data
-+ TLS: TLS Rec Layer-1 SSL Application Data
-  ISOTS: TPKTCount = 1
-- TPKT: version: 3, Length: 37
-    version: 3 (0x3)
-    Reserved: 0 (0x0)
-    PacketLength: 37 (0x25)
-- X224: Data
-    Length: 2 (0x2)
-    Type: Data
-    EOT: 128 (0x80)
-- T125: Data Packet
-  - MCSHeader: Type=Send Data Request, UserID=1004, ChannelID=1003
-   - Type: Send Data Request
-    - RootIndex: 25
-       Value: (011001..) 0x19
-   - UserID: 0x3ec
-    - UserID: 0x3ec
-     - ChannelId: 1004
-      - Align: No Padding
-         Padding2: (00......) 0x0
-        Value: 3 (0x3)
-   - Channel: 0x3eb
-    - ChannelId: 1003
-       Align: No Padding
-       Value: 1003 (0x3EB)
-   - DataPriority: high
-    - DataPriority: high
-     - RootIndex: 1
-        Value: (01......) 0x1
-   - Segmentation: Begin End
-      Begin: (1.......) Begin
-      End:   (.1......) End
-   - Length: 22
-    - Align: No Padding
-       Padding4: (0000....) 0x0
-      Length: 22
-    RDP: RDPBCGR
-- RDPBCGR: SynchronizePDU
-  - SlowPathPacket: SynchronizePDU
-   - SlowPath: Type = TS_PDUTYPE_DATAPDU
-    - TsShareControlHeader: Type = TS_PDUTYPE_DATAPDU
-       TotalLength: 22 (0x16)
-     - PDUType: 23 (0x17)
-        Type:            (............0111) TS_PDUTYPE_DATAPDU
-        ProtocolVersion: (000000000001....) 1
-       PDUSource: 1004 (0x3EC)
-    - SlowPathIoPacket: 0x0
-     - ShareDataHeader: TS_PDUTYPE2_SYNCHRONIZE
-        ShareID: 66538 (0x103EA)
-        Pad1: 0 (0x0)
-        StreamID: TS_STREAM_LOW
-        UncompressedLength: 8 (0x8)
-        PDUType2: TS_PDUTYPE2_SYNCHRONIZE
-      - CompressedType: Not Compressed
-         MPPC:       (....0000) MPPC 8K
-         Reserved:   (...0....)
-         Compressed: (..0.....) Not Compressed
-         Front:      (.0......) Not At Front
-         Flush:      (0.......) Not Flushed
-        CompressedLength: 0 (0x0)
-     - TsSynchronizePDU: 0x1
-        MessageType: 0x1, MUST be set to SYNCMSGTYPE_SYNC (1)
-        TargetUser: 1002 (0x3EA)
- */
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
deleted file mode 100644
index 036c959..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientTpkt.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ClientTpkt extends BaseElement {
-
-    public ClientTpkt(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        if (buf.length + 4 > 65535)
-            throw new RuntimeException("Packet is too long for TPKT (max length 65535-4): " + buf + ".");
-
-        ByteBuffer data = new ByteBuffer(4);
-        // TPKT version
-        data.writeByte(3);
-        // Reserved
-        data.writeByte(0);
-        // Packet length, including length of the header
-        data.writeShort(buf.length + 4);
-
-        buf.prepend(data);
-        data.unref();
-
-        pushDataToPad(STDOUT, buf);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
deleted file mode 100644
index 66d0fd5..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224ConnectionRequestPDU.java
+++ /dev/null
@@ -1,156 +0,0 @@
-// 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;
-
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.MockSink;
-import streamer.MockSource;
-import streamer.OneTimeSwitch;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-/**
- * @see http://msdn.microsoft.com/en-us/library/cc240470.aspx
- * @see http://msdn.microsoft.com/en-us/library/cc240663.aspx
- */
-public class ClientX224ConnectionRequestPDU extends OneTimeSwitch {
-
-    public static final int X224_TPDU_CONNECTION_REQUEST = 0xe0;
-    public static final int X224_TPDU_CONNECTION_CONFIRM = 0xd0;
-    public static final int X224_TPDU_DISCONNECTION_REQUEST = 0x80;
-    public static final int X224_TPDU_DISCONNECTION_CONFIRM = 0xc0;
-    public static final int X224_TPDU_EXPEDITED_DATA = 0x10;
-    public static final int X224_TPDU_DATA_ACKNOWLEDGE = 0x61;
-    public static final int X224_TPDU_EXPEDITET_ACKNOWLEDGE = 0x40;
-    public static final int X224_TPDU_REJECT = 0x51;
-    public static final int X224_TPDU_ERROR = 0x70;
-    public static final int X224_TPDU_PROTOCOL_IDENTIFIER = 0x01;
-
-    /**
-     * Reconnection cookie.
-     */
-    protected String userName;
-
-    public ClientX224ConnectionRequestPDU(String id, String userName) {
-        super(id);
-        this.userName = userName;
-    }
-
-    @Override
-    protected void handleOneTimeData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        throw new RuntimeException("Unexpected packet: " + buf + ".");
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-
-        // Length of packet without length field
-        int length = 33 + userName.length();
-        ByteBuffer buf = new ByteBuffer(length, true);
-
-        // Type (high nibble) = 0xe = CR TPDU; credit (low nibble) = 0
-        buf.writeByte(X224_TPDU_CONNECTION_REQUEST);
-
-        buf.writeShort(0); // Destination reference = 0
-        buf.writeShort(0); // Source reference = 0
-        buf.writeByte(0); // Class and options = 0
-        buf.writeString("Cookie: mstshash=" + userName + "\r\n", RdpConstants.CHARSET_8); // Cookie
-
-        // RDP_NEG_REQ::type
-        buf.writeByte(RdpConstants.RDP_NEG_REQ_TYPE_NEG_REQ);
-        // RDP_NEG_REQ::flags (0)
-        buf.writeByte(RdpConstants.RDP_NEG_REQ_FLAGS);
-        // RDP_NEG_REQ::length (constant: 8) short int in LE format
-        buf.writeByte(0x08);
-        buf.writeByte(0x00);
-
-        // RDP_NEG_REQ: Requested protocols: PROTOCOL_SSL
-        buf.writeIntLE(RdpConstants.RDP_NEG_REQ_PROTOCOL_SSL);
-
-        // Calculate length of packet and prepend it to buffer
-        ByteBuffer data = new ByteBuffer(5);
-
-        // Write length
-        data.writeVariableIntLE(buf.length);
-
-        // Reset length of buffer to actual length of data written
-        data.length = data.cursor;
-
-        buf.prepend(data);
-        data.unref();
-
-        pushDataToOTOut(buf);
-
-        switchOff();
-    }
-
-    /**
-     * Example.
-     *
-     * @see http://msdn.microsoft.com/en-us/library/cc240842.aspx
-     * @see http://msdn.microsoft.com/en-us/library/cc240500.aspx
-     */
-    public static void main(String args[]) {
-        // System.setProperty("streamer.Link.debug", "true");
-        System.setProperty("streamer.Element.debug", "true");
-        // System.setProperty("streamer.Pipeline.debug", "true");
-
-        String cookie = "eltons";
-
-        byte[] packet = new byte[] {
-
-            0x03, // TPKT Header: version = 3
-            0x00, // TPKT Header: Reserved = 0
-            0x00, // TPKT Header: Packet length - high part
-            0x2c, // TPKT Header: Packet length - low part (total = 44 bytes)
-            0x27, // X.224: Length indicator (39 bytes)
-            (byte)0xe0, // X.224: Type (high nibble) = 0xe = CR TPDU;
-                        // credit (low nibble) = 0
-            0x00, 0x00, // X.224: Destination reference = 0
-            0x00, 0x00, // X.224: Source reference = 0
-            0x00, // X.224: Class and options = 0
-
-            'C', 'o', 'o', 'k', 'i', 'e', ':', ' ', 'm', 's', 't', 's', 'h', 'a', 's', 'h', '=', 'e', 'l', 't', 'o', 'n', 's', // "Cookie: mstshash=eltons"
-            '\r', '\n', // -Cookie terminator sequence
-
-            0x01, // RDP_NEG_REQ::type (TYPE_RDP_NEG_REQ)
-            0x00, // RDP_NEG_REQ::flags (0)
-            0x08, 0x00, // RDP_NEG_REQ::length (8 bytes)
-            0x01, 0x00, 0x00, 0x00 // RDP_NEG_REQ: Requested protocols
-                                   // (PROTOCOL_SSL in little endian format)
-        };
-
-        MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-        Element cr = new ClientX224ConnectionRequestPDU("cr", cookie);
-        Element tpkt = new ClientTpkt("tpkt");
-        Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
-        Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.add(source, cr, tpkt, sink, mainSink);
-        pipeline.link("source", "cr", "mainSink");
-        pipeline.link("cr >" + OTOUT, "tpkt", "sink");
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
deleted file mode 100644
index fc22c43..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ClientX224DataPdu.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-public class ClientX224DataPdu extends BaseElement {
-
-    public static final int X224_TPDU_DATA = 0xF0;
-    public static final int X224_TPDU_LAST_DATA_UNIT = 0x80;
-
-    public ClientX224DataPdu(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (buf == null)
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        ByteBuffer data = new ByteBuffer(3);
-        // X224 header
-        data.writeByte(2); // Header length indicator
-        data.writeByte(X224_TPDU_DATA);
-        data.writeByte(X224_TPDU_LAST_DATA_UNIT);
-
-        buf.prepend(data);
-        data.unref();
-
-        pushDataToPad(STDOUT, buf);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
deleted file mode 100644
index 3a8b4b6..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/HandshakeEnd.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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;
-
-import streamer.BaseElement;
-
-public class HandshakeEnd extends BaseElement {
-
-    public HandshakeEnd(String id) {
-        super(id);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
deleted file mode 100644
index 72e4a6f..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
+++ /dev/null
@@ -1,198 +0,0 @@
-// 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;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Arrays;
-
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-public class MockServer implements Runnable {
-
-    private boolean shutdown = false;
-    private ServerSocket serverSocket;
-    private Packet[] packets;
-    private Throwable exception;
-    private boolean shutdowned;
-
-    /**
-     * Set to true to enable debugging messages.
-     */
-    protected boolean verbose = System.getProperty("rdpclient.MockServer.debug", "false").equals("true");
-
-    public MockServer(Packet packets[]) {
-        this.packets = packets;
-    }
-
-    public void start() throws IOException {
-        serverSocket = new ServerSocket(0);
-
-        shutdown = false;
-        exception = null;
-        shutdowned = false;
-
-        new Thread(this).start();
-    }
-
-    @Override
-    public void run() {
-
-        try {
-            Socket socket = serverSocket.accept();
-
-            InputStream is = socket.getInputStream();
-            OutputStream os = socket.getOutputStream();
-
-            try {
-                for (int i = 0; i < packets.length && !shutdown; i++) {
-
-                    Packet packet = packets[i];
-                    switch (packet.type) {
-                        case CLIENT: {
-                            // Read client data and compare it with mock data
-                            // (unless "ignore" option is set)
-                            byte actualData[] = new byte[packet.data.length];
-                            int actualDataLength = is.read(actualData);
-
-                            if (verbose)
-                                System.out.println("[" + this + "] INFO: Data is read: {" + Arrays.toString(Arrays.copyOf(actualData, actualDataLength)) + "}.");
-
-                            if (!packet.ignore) {
-                                // Compare actual data with expected data
-                                if (actualDataLength != packet.data.length) {
-                                    throw new AssertionError("Actual length of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")" +
-                                        " does not match length of expected client request. Actual length: " + actualDataLength + ", expected legnth: " +
-                                        packet.data.length + ".");
-                                }
-
-                                for (int j = 0; j < packet.data.length; j++) {
-
-                                    if (packet.data[j] != actualData[j]) {
-                                        throw new AssertionError("Actual byte #" + (j + 1) + " of client request for packet #" + (i + 1) + " (\"" + packet.id + "\")" +
-                                            " does not match corresponding byte of expected client request. Actual byte: " + actualData[j] + ", expected byte: " +
-                                            packet.data[j] + ".");
-                                    }
-                                }
-                            }
-                            break;
-                        }
-                        case SERVER: {
-                            // Send mock data to client
-                            os.write(packet.data);
-
-                            if (verbose)
-                                System.out.println("[" + this + "] INFO: Data is written: {" + Arrays.toString(packet.data) + "}.");
-
-                            break;
-                        }
-                        case UPGRADE_TO_SSL: {
-                            // Attach SSL context to socket
-
-                            final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
-                            SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, null, serverSocket.getLocalPort(), true);
-                            sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
-                            sslSocket.setUseClientMode(false);
-                            sslSocket.startHandshake();
-                            is = sslSocket.getInputStream();
-                            os = sslSocket.getOutputStream();
-
-                            break;
-                        }
-                        default:
-                            throw new RuntimeException("Unknown packet type: " + packet.type);
-                    }
-
-                }
-            } finally {
-                try {
-                    is.close();
-                } catch (Throwable e) {
-                }
-                try {
-                    os.close();
-                } catch (Throwable e) {
-                }
-                try {
-                    socket.close();
-                } catch (Throwable e) {
-                }
-                try {
-                    serverSocket.close();
-                } catch (Throwable e) {
-                }
-            }
-        } catch (Throwable e) {
-            System.err.println("Error in mock server: " + e.getMessage());
-            e.printStackTrace(System.err);
-            exception = e;
-        }
-        shutdowned = true;
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Mock server shutdowned.");
-
-    }
-
-    public void shutdown() {
-        shutdown = true;
-    }
-
-    public InetSocketAddress getAddress() {
-        return (InetSocketAddress)serverSocket.getLocalSocketAddress();
-    }
-
-    public Throwable getException() {
-        return exception;
-    }
-
-    public static class Packet {
-        public static enum PacketType {
-            SERVER, CLIENT, UPGRADE_TO_SSL;
-        }
-
-        public String id = "";
-
-        public Packet() {
-        }
-
-        public Packet(String id) {
-            this.id = id;
-        }
-
-        public PacketType type;
-
-        public boolean ignore = false;
-
-        public byte data[];
-    }
-
-    public boolean isShutdowned() {
-        return shutdowned;
-    }
-
-    public void waitUntilShutdowned(long timeToWaitMiliseconds) throws InterruptedException {
-        long deadline = System.currentTimeMillis() + timeToWaitMiliseconds;
-        while (!shutdowned && System.currentTimeMillis() < deadline) {
-            Thread.sleep(10);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
deleted file mode 100644
index 12fa8e3..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/PacketSniffer.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// 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;
-
-import java.util.regex.Pattern;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-
-/**
- * Try to determine packet content by it header fingerprint.
- */
-public class PacketSniffer extends BaseElement {
-
-    protected Pair regexps[] = null;
-
-    public PacketSniffer(String id, Pair[] regexps) {
-        super(id);
-        this.regexps = regexps;
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-
-        matchPacket(buf);
-
-        super.handleData(buf, link);
-    }
-
-    private void matchPacket(ByteBuffer buf) {
-        String header = buf.toPlainHexString(100);
-        for (Pair pair : regexps) {
-            if (pair.regexp.matcher(header).find()) {
-                System.out.println("[" + this + "] INFO: Packet: " + pair.name + ".");
-                return;
-            }
-        }
-
-        System.out.println("[" + this + "] INFO: Unknown packet: " + header + ".");
-    }
-
-    protected static class Pair {
-        String name;
-        Pattern regexp;
-
-        protected Pair(String name, String regexp) {
-            this.name = name;
-            this.regexp = Pattern.compile("^" + replaceShortcuts(regexp), Pattern.CASE_INSENSITIVE);
-        }
-
-        private static String replaceShortcuts(String regexp) {
-            String result = regexp;
-            result = result.replaceAll("XX\\*", "([0-9a-fA-F]{2} )*?");
-            result = result.replaceAll("XX\\?", "([0-9a-fA-F]{2} )?");
-            result = result.replaceAll("XX", "[0-9a-fA-F]{2}");
-            return result;
-        }
-    }
-
-}


[04/21] CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.

Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
old mode 100644
new mode 100755
index d489b18..e78e301
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Element.java
@@ -19,7 +19,7 @@ package streamer;
 import java.util.Set;
 
 /**
- * Element is for processing of data. It has one or more contact pads, which can
+ * Element is basic building block for constructing data processing pipes. It has one or more contact pads, which can
  * be wired with other elements using links.
  */
 public interface Element {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
old mode 100644
new mode 100755
index 9808f62..998274c
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Event.java
@@ -17,7 +17,8 @@
 package streamer;
 
 public enum Event {
-    STREAM_START, STREAM_CLOSE,
+    STREAM_START,
+    STREAM_CLOSE,
 
     /**
      * Upgrade socket to SSL.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
deleted file mode 100644
index e373b19..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 streamer;
-
-public class FakeSink extends BaseElement {
-
-    public FakeSink(String id) {
-        super(id);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
-
-        if (buf == null)
-            return;
-
-        // Use packetNumber variable to count incoming packets
-        packetNumber++;
-
-        buf.unref();
-    }
-
-    @Override
-    public String toString() {
-        return "FakeSink(" + id + ")";
-    }
-
-    @Override
-    public void handleEvent(Event event, Direction direction) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
-
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-
-        Element sink = new FakeSink("sink") {
-            {
-                verbose = true;
-            }
-        };
-
-        byte[] data = new byte[] {1, 2, 3};
-        ByteBuffer buf = new ByteBuffer(data);
-        sink.setLink(STDIN, new SyncLink(), Direction.IN);
-        sink.getLink(STDIN).sendData(buf);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
deleted file mode 100644
index 9056852..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// 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 streamer;
-
-public class FakeSource extends BaseElement {
-
-    /**
-     * Delay for null packets in poll method when blocking is requested, in
-     * milliseconds.
-     */
-    protected long delay = SyncLink.STANDARD_DELAY_FOR_EMPTY_PACKET;
-
-    public FakeSource(String id) {
-        super(id);
-    }
-
-    @Override
-    public void poll(boolean block) {
-        if (numBuffers > 0 && packetNumber >= numBuffers) {
-            // Close stream when limit of packets is reached
-            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-            return;
-        }
-
-        // Prepare new packet
-        ByteBuffer buf = initializeData();
-
-        // Push it to output(s)
-        pushDataToAllOuts(buf);
-
-        // Make slight delay when blocking input was requested (to avoid
-        // consuming of 100% in parent loop)
-        if (block)
-            delay();
-
-    }
-
-    /**
-     * Make slight delay. Should be used when blocking input is requested in pull
-     * mode, but null packed was returned by input.
-     */
-    protected void delay() {
-        try {
-            Thread.sleep(delay);
-        } catch (InterruptedException e) {
-        }
-    }
-
-    /**
-     * Initialize data.
-     */
-    public ByteBuffer initializeData() {
-        ByteBuffer buf = new ByteBuffer(incommingBufLength);
-
-        // Set first byte of package to it sequance number
-        buf.data[buf.offset] = (byte)(packetNumber % 128);
-
-        // Initialize rest of bytes with sequential values, which are
-        // corresponding with their position in byte buffer
-        for (int i = buf.offset + 1; i < buf.length; i++)
-            buf.data[i] = (byte)(i % 128);
-
-        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
-        buf.putMetadata("src", id);
-
-        return buf;
-    }
-
-    @Override
-    public String toString() {
-        return "FakeSource(" + id + ")";
-    }
-
-    public static void main(String args[]) {
-
-        Element fakeSource = new FakeSource("source 3/10/100") {
-            {
-                verbose = true;
-                this.incommingBufLength = 3;
-                this.numBuffers = 10;
-                this.delay = 100;
-            }
-        };
-
-        Element fakeSink = new FakeSink("sink") {
-            {
-                this.verbose = true;
-            }
-        };
-
-        Element fakeSink2 = new FakeSink("sink2") {
-            {
-                this.verbose = true;
-            }
-        };
-
-        Link link = new SyncLink();
-
-        fakeSource.setLink(STDOUT, link, Direction.OUT);
-        fakeSink.setLink(STDIN, link, Direction.IN);
-
-        Link link2 = new SyncLink();
-
-        fakeSource.setLink("out2", link2, Direction.OUT);
-        fakeSink2.setLink(STDIN, link2, Direction.IN);
-
-        link.run();
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
old mode 100644
new mode 100755
index 45155e1..0c8c97d
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/InputStreamSource.java
@@ -20,13 +20,15 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
+import streamer.debug.FakeSink;
+
 /**
  * Source element, which reads data from InputStream.
  */
 public class InputStreamSource extends BaseElement {
 
     protected InputStream is;
-    protected SocketWrapper socketWrapper;
+    protected SocketWrapperImpl socketWrapper;
 
     public InputStreamSource(String id) {
         super(id);
@@ -37,7 +39,7 @@ public class InputStreamSource extends BaseElement {
         this.is = is;
     }
 
-    public InputStreamSource(String id, SocketWrapper socketWrapper) {
+    public InputStreamSource(String id, SocketWrapperImpl socketWrapper) {
         super(id);
         this.socketWrapper = socketWrapper;
     }
@@ -45,27 +47,27 @@ public class InputStreamSource extends BaseElement {
     @Override
     public void handleEvent(Event event, Direction direction) {
         switch (event) {
-            case SOCKET_UPGRADE_TO_SSL:
-                socketWrapper.upgradeToSsl();
-                break;
-            default:
-                super.handleEvent(event, direction);
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
         }
     }
 
     @Override
     public void setLink(String padName, Link link, Direction direction) {
         switch (direction) {
-            case OUT:
-                super.setLink(padName, link, direction);
-
-                if (is == null) {
-                    // Pause links until data stream will be ready
-                    link.pause();
-                }
-                break;
-            case IN:
-                throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        case OUT:
+            super.setLink(padName, link, direction);
+
+            if (is == null) {
+                // Pause links until data stream will be ready
+                link.pause();
+            }
+            break;
+        case IN:
+            throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Link.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
deleted file mode 100644
index 8094c82..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSink.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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 streamer;
-
-import java.util.Arrays;
-
-/**
- * Compare incoming packets with expected packets.
- */
-public class MockSink extends BaseElement {
-
-    protected ByteBuffer bufs[] = null;
-
-    public MockSink(String id) {
-        super(id);
-    }
-
-    public MockSink(String id, ByteBuffer bufs[]) {
-        super(id);
-        this.bufs = bufs;
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Received buf #" + (packetNumber) + " " + buf + ".");
-
-        if (buf == null)
-            return;
-
-        if (packetNumber >= bufs.length)
-            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not expected. Number of expected buffers: " + bufs.length +
-                ", unexpected buffer: " + buf + ".");
-
-        // Compare incoming buffer with expected buffer
-        if (!Arrays.equals(bufs[packetNumber].toByteArray(), buf.toByteArray()))
-            throw new AssertionError("[" + this + "] Incoming buffer #" + packetNumber + " is not equal to expected buffer.\n  Actual bufer: " + buf +
-                ",\n  expected buffer: " + bufs[packetNumber] + ".");
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: buffers are equal.");
-
-        // Use packetNumber variable to count incoming packets
-        packetNumber++;
-
-        buf.unref();
-    }
-
-    @Override
-    protected void onClose() {
-        super.onClose();
-
-        if (packetNumber != bufs.length)
-            throw new AssertionError("[" + this + "] Number of expected buffers: " + bufs.length + ", number of actual buffers: " + packetNumber + ".");
-    }
-
-    @Override
-    public String toString() {
-        return "MockSink(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-
-        Element mockSource = new MockSource("source") {
-            {
-                this.bufs =
-                    new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}), new ByteBuffer(new byte[] {3, 1, 2, 3}),
-                        new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
-                this.verbose = true;
-                this.delay = 100;
-                this.numBuffers = this.bufs.length;
-            }
-        };
-
-        Element mockSink = new MockSink("sink") {
-            {
-                this.bufs =
-                    new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}), new ByteBuffer(new byte[] {3, 1, 2, 3}),
-                        new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
-                this.verbose = true;
-            }
-        };
-
-        Link link = new SyncLink() {
-            {
-                this.verbose = true;
-            }
-        };
-
-        mockSource.setLink(STDOUT, link, Direction.OUT);
-        mockSink.setLink(STDIN, link, Direction.IN);
-
-        link.run();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
deleted file mode 100644
index f758bab..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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 streamer;
-
-public class MockSource extends FakeSource {
-
-    protected ByteBuffer bufs[] = null;
-
-    public MockSource(String id) {
-        super(id);
-    }
-
-    public MockSource(String id, ByteBuffer bufs[]) {
-        super(id);
-        this.bufs = bufs;
-    }
-
-    /**
-     * Initialize data.
-     */
-    @Override
-    public ByteBuffer initializeData() {
-        if (packetNumber >= bufs.length) {
-            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
-            return null;
-        }
-
-        ByteBuffer buf = bufs[packetNumber];
-
-        buf.putMetadata(ByteBuffer.SEQUENCE_NUMBER, packetNumber);
-        return buf;
-    }
-
-    @Override
-    public void handleEvent(Event event, Direction direction) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Event received: " + event + ".");
-
-    }
-
-    @Override
-    public String toString() {
-        return "MockSource(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-
-        Element mockSource = new MockSource("source") {
-            {
-                this.bufs =
-                    new ByteBuffer[] {new ByteBuffer(new byte[] {1, 1, 2, 3, 4, 5}), new ByteBuffer(new byte[] {2, 1, 2, 3, 4}), new ByteBuffer(new byte[] {3, 1, 2, 3}),
-                        new ByteBuffer(new byte[] {4, 1, 2}), new ByteBuffer(new byte[] {5, 1})};
-                this.verbose = true;
-                this.delay = 100;
-                // this.numBuffers = this.bufs.length;
-            }
-        };
-
-        Element fakeSink = new FakeSink("sink") {
-            {
-                this.verbose = true;
-            }
-        };
-
-        Link link = new SyncLink();
-
-        mockSource.setLink(STDOUT, link, Direction.OUT);
-        fakeSink.setLink(STDIN, link, Direction.IN);
-
-        link.run();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
old mode 100644
new mode 100755
index d50995e..9cccb5b
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OneTimeSwitch.java
@@ -87,13 +87,16 @@ public abstract class OneTimeSwitch extends BaseElement {
         // Wake up next peer(s)
         sendEventToAllPads(Event.STREAM_START, Direction.OUT);
 
+        // Disconnect our stdin from this element
         stdin.setSink(null);
         inputPads.remove(STDIN);
 
+        // Replace next peer stdin (our stdout) by our stdin
         Element nextPeer = stdout.getSink();
         nextPeer.replaceLink(stdout, stdin);
         stdout.drop();
 
+        // Drop all other links
         for (Object link : inputPads.values().toArray())
             ((Link)link).drop();
         for (Object link : outputPads.values().toArray())

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Order.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
old mode 100644
new mode 100755
index 7a55ea8..e66899d
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/OutputStreamSink.java
@@ -20,10 +20,12 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import streamer.debug.FakeSource;
+
 public class OutputStreamSink extends BaseElement {
 
     protected OutputStream os;
-    protected SocketWrapper socketWrapper;
+    protected SocketWrapperImpl socketWrapper;
 
     public OutputStreamSink(String id) {
         super(id);
@@ -34,7 +36,7 @@ public class OutputStreamSink extends BaseElement {
         this.os = os;
     }
 
-    public OutputStreamSink(String id, SocketWrapper socketWrapper) {
+    public OutputStreamSink(String id, SocketWrapperImpl socketWrapper) {
         super(id);
         this.socketWrapper = socketWrapper;
     }
@@ -68,26 +70,26 @@ public class OutputStreamSink extends BaseElement {
     @Override
     public void handleEvent(Event event, Direction direction) {
         switch (event) {
-            case SOCKET_UPGRADE_TO_SSL:
-                socketWrapper.upgradeToSsl();
-                break;
-            default:
-                super.handleEvent(event, direction);
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
         }
     }
 
     @Override
     public void setLink(String padName, Link link, Direction direction) {
         switch (direction) {
-            case IN:
-                super.setLink(padName, link, direction);
-
-                if (os == null)
-                    // Pause links until data stream will be ready
-                    link.pause();
-                break;
-            case OUT:
-                throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        case IN:
+            super.setLink(padName, link, direction);
+
+            if (os == null)
+                // Pause links until data stream will be ready
+                link.pause();
+            break;
+        case OUT:
+            throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
         }
     }
 
@@ -126,10 +128,10 @@ public class OutputStreamSink extends BaseElement {
     public static void main(String args[]) {
         Element source = new FakeSource("source") {
             {
-                this.verbose = true;
-                this.numBuffers = 3;
-                this.incommingBufLength = 5;
-                this.delay = 100;
+                verbose = true;
+                numBuffers = 3;
+                incommingBufLength = 5;
+                delay = 100;
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
old mode 100644
new mode 100755
index d2e52dd..0f6089b
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Pipeline.java
@@ -48,6 +48,8 @@ public interface Pipeline extends Element {
      * so when pipeline will be connected with other elements, outside of this
      * pipeline, they will be connected to IN and OUT elements.
      *
+     * Empty names are skipped.
+     *
      * Example:
      *
      * <pre>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
old mode 100644
new mode 100755
index 4e6fc0a..299d0a4
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/PipelineImpl.java
@@ -16,10 +16,15 @@
 // under the License.
 package streamer;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 public class PipelineImpl implements Pipeline {
 
     protected String id;
@@ -51,11 +56,11 @@ public class PipelineImpl implements Pipeline {
     @Override
     public Set<String> getPads(Direction direction) {
         switch (direction) {
-            case IN:
-                return elements.get(IN).getPads(direction);
+        case IN:
+            return elements.get(IN).getPads(direction);
 
-            case OUT:
-                return elements.get(OUT).getPads(direction);
+        case OUT:
+            return elements.get(OUT).getPads(direction);
         }
         return null;
     }
@@ -71,8 +76,8 @@ public class PipelineImpl implements Pipeline {
             int outPadsNumber = element.getPads(Direction.OUT).size();
             int inPadsNumber = element.getPads(Direction.IN).size();
             if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
-                throw new RuntimeException("[ " + this + "] Pads of input element of pipeline are not balanced. Element: " + element + ", output pads: " +
-                    element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+                throw new RuntimeException("[ " + this + "] Pads of input element of pipeline are not balanced. Element: " + element + ", output pads: "
+                        + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
         }
 
         // Check OUT element
@@ -81,8 +86,8 @@ public class PipelineImpl implements Pipeline {
             int outPadsNumber = element.getPads(Direction.OUT).size();
             int inPadsNumber = element.getPads(Direction.IN).size();
             if ((outPadsNumber | inPadsNumber) > 0 && (outPadsNumber == 0 || inPadsNumber == 0))
-                throw new RuntimeException("[ " + this + "] Pads of output element of pipeline are not balanced. Element: " + element + ", output pads: " +
-                    element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
+                throw new RuntimeException("[ " + this + "] Pads of output element of pipeline are not balanced. Element: " + element + ", output pads: "
+                        + element.getPads(Direction.OUT).toString() + ", input pads: " + element.getPads(Direction.IN).toString() + ".");
         }
 
     }
@@ -127,12 +132,12 @@ public class PipelineImpl implements Pipeline {
     @Override
     public void handleEvent(Event event, Direction direction) {
         switch (direction) {
-            case IN:
-                get(IN).handleEvent(event, direction);
-                break;
-            case OUT:
-                get(OUT).handleEvent(event, direction);
-                break;
+        case IN:
+            get(IN).handleEvent(event, direction);
+            break;
+        case OUT:
+            get(OUT).handleEvent(event, direction);
+            break;
         }
     }
 
@@ -142,8 +147,8 @@ public class PipelineImpl implements Pipeline {
             String id = element.getId();
 
             if (this.elements.containsKey(id))
-                throw new RuntimeException("This pipeline already contains element with same ID. New element: " + element + ", existing element: " +
-                    this.elements.get(id) + ".");
+                throw new RuntimeException("This pipeline already contains element with same ID. New element: " + element + ", existing element: "
+                        + this.elements.get(id) + ".");
 
             this.elements.put(id, element);
         }
@@ -152,6 +157,8 @@ public class PipelineImpl implements Pipeline {
     @Override
     public void link(String... elementNames) {
 
+        elementNames = filterOutEmptyStrings(elementNames);
+
         if (elementNames.length < 2)
             throw new RuntimeException("At least two elements are necessary to create link between them.");
 
@@ -180,8 +187,8 @@ public class PipelineImpl implements Pipeline {
             elements[i] = get(elementName);
 
             if (elements[i] == null)
-                throw new RuntimeException("Cannot find element by name in this pipeline. Element name: \"" + elementName + "\" (" + elementNames[i] + "), pipeline: " +
-                    this + ".");
+                throw new RuntimeException("Cannot find element by name in this pipeline. Element name: \"" + elementName + "\" (" + elementNames[i] + "), pipeline: "
+                        + this + ".");
 
             i++;
         }
@@ -204,6 +211,30 @@ public class PipelineImpl implements Pipeline {
         }
     }
 
+    /**
+     * Filter out empty strings from array and return new array with non-empty
+     * elements only. If array contains no empty string, returns same array.
+     */
+    private String[] filterOutEmptyStrings(String[] strings) {
+
+        boolean found = false;
+        for (String string : strings) {
+            if (string == null || string.isEmpty()) {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found)
+            return strings;
+
+        List<String> filteredStrings = new ArrayList<String>(strings.length);
+        for (String string : strings)
+            if (string != null && !string.isEmpty())
+                filteredStrings.add(string);
+        return filteredStrings.toArray(new String[filteredStrings.size()]);
+    }
+
     @Override
     public void addAndLink(Element... elements) {
         add(elements);
@@ -281,20 +312,20 @@ public class PipelineImpl implements Pipeline {
         // Create elements
         pipeline.add(new FakeSource("source") {
             {
-                this.incommingBufLength = 3;
-                this.numBuffers = 10;
-                this.delay = 100;
+                incommingBufLength = 3;
+                numBuffers = 10;
+                delay = 100;
             }
         });
         pipeline.add(new BaseElement("tee"));
         pipeline.add(new FakeSink("sink") {
             {
-                this.verbose = true;
+                verbose = true;
             }
         });
         pipeline.add(new FakeSink("sink2") {
             {
-                this.verbose = true;
+                verbose = true;
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
old mode 100644
new mode 100755
index 23c57e0..910e073
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/Queue.java
@@ -19,6 +19,9 @@ package streamer;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+import streamer.debug.FakeSink;
+import streamer.debug.FakeSource;
+
 /**
  * Message queue for safe transfer of packets between threads.
  */
@@ -30,7 +33,6 @@ public class Queue extends BaseElement {
         super(id);
     }
 
-    @SuppressWarnings("incomplete-switch")
     @Override
     public void poll(boolean block) {
         try {
@@ -67,12 +69,12 @@ public class Queue extends BaseElement {
     @Override
     public void handleEvent(Event event, Direction direction) {
         switch (event) {
-            case LINK_SWITCH_TO_PULL_MODE:
-                // Do not propagate this event, because this element is boundary between
-                // threads
-                break;
-            default:
-                super.handleEvent(event, direction);
+        case LINK_SWITCH_TO_PULL_MODE:
+            // Do not propagate this event, because this element is boundary between
+            // threads
+            break;
+        default:
+            super.handleEvent(event, direction);
         }
     }
 
@@ -104,17 +106,17 @@ public class Queue extends BaseElement {
 
         Element source1 = new FakeSource("source1") {
             {
-                this.delay = 100;
-                this.numBuffers = 10;
-                this.incommingBufLength = 10;
+                delay = 100;
+                numBuffers = 10;
+                incommingBufLength = 10;
             }
         };
 
         Element source2 = new FakeSource("source2") {
             {
-                this.delay = 100;
-                this.numBuffers = 10;
-                this.incommingBufLength = 10;
+                delay = 100;
+                numBuffers = 10;
+                incommingBufLength = 10;
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
old mode 100644
new mode 100755
index dfffd35..22d436e
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapper.java
@@ -16,224 +16,20 @@
 // under the License.
 package streamer;
 
-import static rdpclient.MockServer.Packet.PacketType.CLIENT;
-import static rdpclient.MockServer.Packet.PacketType.SERVER;
-
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.HashMap;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import rdpclient.MockServer;
-import rdpclient.MockServer.Packet;
-import rdpclient.TrustAllX509TrustManager;
-
-public class SocketWrapper extends PipelineImpl {
-
-    protected InputStreamSource source;
-    protected OutputStreamSink sink;
-    protected Socket socket;
-    protected InetSocketAddress address;
-
-    protected SSLSocket sslSocket;
-
-    //protected String SSL_VERSION_TO_USE = "TLSv1.2";
-    /*DEBUG*/protected static final String SSL_VERSION_TO_USE = "TLSv1";
-
-    public SocketWrapper(String id) {
-        super(id);
-    }
-
-    @Override
-    protected HashMap<String, Element> initElementMap(String id) {
-        HashMap<String, Element> map = new HashMap<String, Element>();
-
-        source = new InputStreamSource(id + "." + OUT, this);
-        sink = new OutputStreamSink(id + "." + IN, this);
-
-        // Pass requests to read data to socket input stream
-        map.put(OUT, source);
 
-        // All incoming data, which is sent to this socket wrapper, will be sent
-        // to socket remote
-        map.put(IN, sink);
-
-        return map;
-    }
+public interface SocketWrapper extends Element {
 
     /**
      * Connect this socket wrapper to remote server and start main loop on
-     * IputStreamSource stdout link, to watch for incoming data, and
-     * OutputStreamSink stdin link, to pull for outgoing data.
-     *
-     * @param address
-     * @throws IOException
+     * Source stdout link, to watch for incoming data, and
+     * Sink stdin link, to pull for outgoing data.
      */
-    public void connect(InetSocketAddress address) throws IOException {
-        this.address = address;
-
-        // Connect socket to server
-        socket = SocketFactory.getDefault().createSocket();
-        try {
-            socket.connect(address);
-
-            InputStream is = socket.getInputStream();
-            source.setInputStream(is);
-
-            OutputStream os = socket.getOutputStream();
-            sink.setOutputStream(os);
-
-            // Start polling for data to send to remote sever
-            runMainLoop(IN, STDIN, true, true);
-
-            // Push incoming data from server to handlers
-            runMainLoop(OUT, STDOUT, false, false);
-
-        } finally {
-            socket.close();
-        }
-    }
-
-    @Override
-    public void handleEvent(Event event, Direction direction) {
-        switch (event) {
-            case SOCKET_UPGRADE_TO_SSL:
-                upgradeToSsl();
-                break;
-            default:
-                super.handleEvent(event, direction);
-                break;
-        }
-    }
-
-    public void upgradeToSsl() {
-
-        if (sslSocket != null)
-            // Already upgraded
-            return;
-
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
-
-        try {
-            // Use most secure implementation of SSL available now.
-            // JVM will try to negotiate TLS1.2, then will fallback to TLS1.0, if
-            // TLS1.2 is not supported.
-            SSLContext sslContext = SSLContext.getInstance(SSL_VERSION_TO_USE);
-
-            // Trust all certificates (FIXME: insecure)
-            sslContext.init(null, new TrustManager[] {new TrustAllX509TrustManager()}, null);
-
-            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
-            sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
-            sslSocket.startHandshake();
-
-            InputStream sis = sslSocket.getInputStream();
-            source.setInputStream(sis);
-
-            OutputStream sos = sslSocket.getOutputStream();
-            sink.setOutputStream(sos);
-
-        } catch (Exception e) {
-            throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
-        }
-
-    }
-
-    @Override
-    public void validate() {
-        for (Element element : elements.values())
-            element.validate();
-
-        if (get(IN).getPads(Direction.IN).size() == 0)
-            throw new RuntimeException("[ " + this + "] Input of socket is not connected.");
-
-        if (get(OUT).getPads(Direction.OUT).size() == 0)
-            throw new RuntimeException("[ " + this + "] Output of socket is not connected.");
-
-    }
-
-    public void shutdown() {
-        try {
-            handleEvent(Event.STREAM_CLOSE, Direction.IN);
-        } catch (Exception e) {
-        }
-        try {
-            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
-        } catch (Exception e) {
-        }
-        try {
-            if (sslSocket != null)
-                sslSocket.close();
-        } catch (Exception e) {
-        }
-        try {
-            socket.close();
-        } catch (Exception e) {
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "SocketWrapper(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-        try {
-            System.setProperty("streamer.Link.debug", "true");
-            System.setProperty("streamer.Element.debug", "true");
-            System.setProperty("rdpclient.MockServer.debug", "true");
-
-            Pipeline pipeline = new PipelineImpl("echo client");
-
-            SocketWrapper socketWrapper = new SocketWrapper("socket");
-
-            pipeline.add(socketWrapper);
-            pipeline.add(new BaseElement("echo"));
-
-            pipeline.link("socket", "echo", "socket");
-
-            final byte[] mockData = new byte[] {0x01, 0x02, 0x03};
-            MockServer server = new MockServer(new Packet[] {new Packet("Server hello") {
-                {
-                    type = SERVER;
-                    data = mockData;
-                }
-            }, new Packet("Client hello") {
-                {
-                    type = CLIENT;
-                    data = mockData;
-                }
-            }, new Packet("Server hello") {
-                {
-                    type = SERVER;
-                    data = mockData;
-                }
-            }, new Packet("Client hello") {
-                {
-                    type = CLIENT;
-                    data = mockData;
-                }
-            }});
-            server.start();
-            InetSocketAddress address = server.getAddress();
+    public void connect(InetSocketAddress address) throws IOException;
 
-            socketWrapper.connect(address);
+    public void shutdown();
 
-        } catch (IOException e) {
-            e.printStackTrace(System.err);
-        }
+    void upgradeToSsl();
 
-    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
new file mode 100755
index 0000000..da89a0d
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SocketWrapperImpl.java
@@ -0,0 +1,249 @@
+// 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 streamer;
+
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.HashMap;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
+import streamer.ssl.SSLState;
+import streamer.ssl.TrustAllX509TrustManager;
+
+public class SocketWrapperImpl extends PipelineImpl implements SocketWrapper {
+
+    protected InputStreamSource source;
+    protected OutputStreamSink sink;
+    protected Socket socket;
+    protected InetSocketAddress address;
+
+    protected SSLSocket sslSocket;
+
+    protected String sslVersionToUse = "TLSv1.2";
+
+    protected SSLState sslState;
+
+    public SocketWrapperImpl(String id, SSLState sslState) {
+        super(id);
+        this.sslState = sslState;
+    }
+
+    @Override
+    protected HashMap<String, Element> initElementMap(String id) {
+        HashMap<String, Element> map = new HashMap<String, Element>();
+
+        source = new InputStreamSource(id + "." + OUT, this);
+        sink = new OutputStreamSink(id + "." + IN, this);
+
+        // Pass requests to read data to socket input stream
+        map.put(OUT, source);
+
+        // All incoming data, which is sent to this socket wrapper, will be sent
+        // to socket remote
+        map.put(IN, sink);
+
+        return map;
+    }
+
+    /**
+     * Connect this socket wrapper to remote server and start main loop on
+     * IputStreamSource stdout link, to watch for incoming data, and
+     * OutputStreamSink stdin link, to pull for outgoing data.
+     *
+     * @param address
+     * @throws IOException
+     */
+    @Override
+    public void connect(InetSocketAddress address) throws IOException {
+        this.address = address;
+
+        // Connect socket to server
+        socket = SocketFactory.getDefault().createSocket();
+        try {
+            socket.connect(address);
+
+            InputStream is = socket.getInputStream();
+            source.setInputStream(is);
+
+            OutputStream os = socket.getOutputStream();
+            sink.setOutputStream(os);
+
+            // Start polling for data to send to remote sever
+            runMainLoop(IN, STDIN, true, true);
+
+            // Push incoming data from server to handlers
+            runMainLoop(OUT, STDOUT, false, false);
+
+        } finally {
+            socket.close();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+            break;
+        }
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        if (sslSocket != null)
+            // Already upgraded
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
+
+        try {
+            // Use most secure implementation of SSL available now.
+            // JVM will try to negotiate TLS1.2, then will fallback to TLS1.0, if
+            // TLS1.2 is not supported.
+            SSLContext sslContext = SSLContext.getInstance(sslVersionToUse);
+
+            // Trust all certificates (FIXME: insecure)
+            sslContext.init(null, new TrustManager[] {new TrustAllX509TrustManager(sslState)}, null);
+
+            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+            sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
+
+            sslSocket.startHandshake();
+
+            InputStream sis = sslSocket.getInputStream();
+            source.setInputStream(sis);
+
+            OutputStream sos = sslSocket.getOutputStream();
+            sink.setOutputStream(sos);
+
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
+        }
+
+    }
+
+    @Override
+    public void validate() {
+        for (Element element : elements.values())
+            element.validate();
+
+        if (get(IN).getPads(Direction.IN).size() == 0)
+            throw new RuntimeException("[ " + this + "] Input of socket is not connected.");
+
+        if (get(OUT).getPads(Direction.OUT).size() == 0)
+            throw new RuntimeException("[ " + this + "] Output of socket is not connected.");
+
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        try {
+            if (sslSocket != null)
+                sslSocket.close();
+        } catch (Exception e) {
+        }
+        try {
+            socket.close();
+        } catch (Exception e) {
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SocketWrapper(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        try {
+            System.setProperty("streamer.Link.debug", "true");
+            System.setProperty("streamer.Element.debug", "true");
+            System.setProperty("rdpclient.MockServer.debug", "true");
+
+            Pipeline pipeline = new PipelineImpl("echo client");
+
+            SocketWrapperImpl socketWrapper = new SocketWrapperImpl("socket", null);
+
+            pipeline.add(socketWrapper);
+            pipeline.add(new BaseElement("echo"));
+            pipeline.add(new Queue("queue")); // To decouple input and output
+
+            pipeline.link("socket", "echo", "queue", "socket");
+
+            final byte[] mockData = new byte[] {0x01, 0x02, 0x03};
+            MockServer server = new MockServer(new Packet[] {new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }, new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }});
+            server.start();
+            InetSocketAddress address = server.getAddress();
+
+            /*DEBUG*/System.out.println("Address: " + address);
+            socketWrapper.connect(address);
+
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
old mode 100644
new mode 100755
index 2bd4919..94281d2
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/SyncLink.java
@@ -27,7 +27,7 @@ public class SyncLink implements Link {
      * avoid consuming of 100% of CPU in main loop in cases when link is pauses or
      * source element cannot produce data right now.
      */
-    protected static final long STANDARD_DELAY_FOR_EMPTY_PACKET = 10; // Milliseconds
+    public static final long STANDARD_DELAY_FOR_EMPTY_PACKET = 10; // Milliseconds
 
     /**
      * Delay for null packets in poll method when blocking is requested, in
@@ -46,7 +46,8 @@ public class SyncLink implements Link {
     protected String id = null;
 
     /**
-     * Buffer with data to hold because link is paused, or data is pushed back.
+     * Buffer with data to hold because link is paused, on hold, or data is pushed
+     * back from output element.
      */
     protected ByteBuffer cacheBuffer = null;
 
@@ -62,11 +63,6 @@ public class SyncLink implements Link {
     protected int packetNumber = 0;
 
     /**
-     * Set to true to hold all data in link until it will be set to false again.
-     */
-    protected boolean paused = false;
-
-    /**
      * Element to pull data from, when in pull mode.
      */
     protected Element source = null;
@@ -87,12 +83,24 @@ public class SyncLink implements Link {
      * Indicates that event STREAM_START is passed over this link, so main loop
      * can be started to pull data from source element.
      */
-    protected boolean start;
+    protected boolean started = false;
+
+    /**
+     * Set to true to hold all data in link until it will be set to false again.
+     */
+    protected boolean paused = false;
+
+    /**
+     * Used by pull() method to hold all data in this link to avoid recursion when
+     * source element is asked to push new data to it outputs.
+     */
+    protected boolean hold = false;
 
     /**
-     * Operate in pull mode.
+     * Operate in pull mode instead of default push mode. In pull mode, link will
+     * ask it source element for new data.
      */
-    protected boolean pullMode;
+    protected boolean pullMode = false;
 
     public SyncLink() {
     }
@@ -139,7 +147,7 @@ public class SyncLink implements Link {
      */
     @Override
     public void sendData(ByteBuffer buf) {
-        if (!paused && pullMode)
+        if (!hold && pullMode)
             throw new RuntimeException("[" + this + "] ERROR: link is not in push mode.");
 
         if (verbose)
@@ -162,7 +170,7 @@ public class SyncLink implements Link {
         // When data pushed back and length of data is less than length of full
         // packet, then feed data to sink element immediately
         while (cacheBuffer != null) {
-            if (paused) {
+            if (paused || hold) {
                 if (verbose)
                     System.out.println("[" + this + "] INFO: Transfer is paused. Data in cache buffer: " + cacheBuffer + ".");
 
@@ -172,8 +180,8 @@ public class SyncLink implements Link {
 
             if (expectedPacketSize > 0 && cacheBuffer.length < expectedPacketSize) {
                 if (verbose)
-                    System.out.println("[" + this + "] INFO: Transfer is suspended because available data is less than expected packet size. Expected packet size: " +
-                        expectedPacketSize + ", data in cache buffer: " + cacheBuffer + ".");
+                    System.out.println("[" + this + "] INFO: Transfer is suspended because available data is less than expected packet size. Expected packet size: "
+                            + expectedPacketSize + ", data in cache buffer: " + cacheBuffer + ".");
 
                 // Wait until rest of packet will be read
                 return;
@@ -203,43 +211,46 @@ public class SyncLink implements Link {
 
         // Shutdown main loop (if any) when STREAM_CLOSE event is received.
         switch (event) {
-            case STREAM_START: {
-                if (!start)
-                    start = true;
-                else
-                    // Event already sent trough this link
-                    return;
-                break;
-            }
-            case STREAM_CLOSE: {
-                if (!shutdown)
-                    shutdown = true;
-                else
-                    // Event already sent trough this link
-                    return;
-                break;
-            }
-            case LINK_SWITCH_TO_PULL_MODE: {
-                setPullMode();
-                break;
-            }
+        case STREAM_START: {
+            if (!started)
+                started = true;
+            else
+                // Event already sent trough this link
+                return;
+            break;
+        }
+        case STREAM_CLOSE: {
+            if (!shutdown)
+                shutdown = true;
+            else
+                // Event already sent trough this link
+                return;
+            break;
+        }
+        case LINK_SWITCH_TO_PULL_MODE: {
+            setPullMode();
+            break;
+        }
 
         }
 
         switch (direction) {
-            case IN:
-                source.handleEvent(event, direction);
-                break;
-            case OUT:
-                sink.handleEvent(event, direction);
-                break;
+        case IN:
+            source.handleEvent(event, direction);
+            break;
+        case OUT:
+            sink.handleEvent(event, direction);
+            break;
         }
     }
 
     @Override
     public ByteBuffer pull(boolean block) {
         if (!pullMode)
-            throw new RuntimeException("This link is not in pull mode.");
+            throw new RuntimeException("[" + this + "] ERROR: This link is not in pull mode.");
+
+        if (hold)
+            throw new RuntimeException("[" + this + "] ERROR: This link is already on hold, waiting for data to be pulled in. Circular reference?");
 
         if (paused) {
             if (verbose)
@@ -269,9 +280,12 @@ public class SyncLink implements Link {
 
         // Pause this link, so incoming data will not be sent to sink
         // immediately, then ask source element for more data
-        pause();
-        source.poll(block);
-        resume();
+        try {
+            hold = true;
+            source.poll(block);
+        } finally {
+            hold = false;
+        }
 
         // Can return something only when data was stored in buffer
         if (cacheBuffer != null && (expectedPacketSize == 0 || (expectedPacketSize > 0 && cacheBuffer.length >= expectedPacketSize))) {
@@ -289,10 +303,11 @@ public class SyncLink implements Link {
     @Override
     public Element setSink(Element sink) {
         if (sink != null && this.sink != null)
-            throw new RuntimeException("This link sink element is already set. Link: " + this + ", new sink: " + sink + ", existing sink: " + this.sink + ".");
+            throw new RuntimeException("[" + this + "] ERROR: This link sink element is already set. Link: " + this + ", new sink: " + sink + ", existing sink: "
+                    + this.sink + ".");
 
         if (sink == null && cacheBuffer != null)
-            throw new RuntimeException("Cannot drop link: cache is not empty. Link: " + this + ", cache: " + cacheBuffer);
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link: cache is not empty. Link: " + this + ", cache: " + cacheBuffer);
 
         this.sink = sink;
 
@@ -302,7 +317,8 @@ public class SyncLink implements Link {
     @Override
     public Element setSource(Element source) {
         if (this.source != null && source != null)
-            throw new RuntimeException("This link source element is already set. Link: " + this + ", new source: " + source + ", existing source: " + this.source + ".");
+            throw new RuntimeException("[" + this + "] ERROR: This link source element is already set. Link: " + this + ", new source: " + source
+                    + ", existing source: " + this.source + ".");
 
         this.source = source;
         return source;
@@ -321,7 +337,7 @@ public class SyncLink implements Link {
     @Override
     public void pause() {
         if (paused)
-            throw new RuntimeException("Link is already paused.");
+            throw new RuntimeException("[" + this + "] ERROR: Link is already paused.");
 
         paused = true;
 
@@ -343,7 +359,7 @@ public class SyncLink implements Link {
     @Override
     public void run() {
         // Wait until even STREAM_START will arrive
-        while (!start) {
+        while (!started) {
             delay();
         }
 
@@ -374,8 +390,7 @@ public class SyncLink implements Link {
         try {
             Thread.sleep(delay);
         } catch (InterruptedException e) {
-            e.printStackTrace(System.err);
-            throw new RuntimeException("Interrupted in main loop.", e);
+            throw new RuntimeException("[" + this + "] ERROR: Interrupted in main loop.", e);
         }
     }
 
@@ -384,16 +399,16 @@ public class SyncLink implements Link {
         if (verbose)
             System.out.println("[" + this + "] INFO: Switching to PULL mode.");
 
-        this.pullMode = true;
+        pullMode = true;
     }
 
     @Override
     public void drop() {
         if (pullMode)
-            throw new RuntimeException("Cannot drop link in pull mode.");
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link in pull mode.");
 
         if (cacheBuffer != null)
-            throw new RuntimeException("Cannot drop link when cache conatains data: " + cacheBuffer + ".");
+            throw new RuntimeException("[" + this + "] ERROR: Cannot drop link when cache conatains data: " + cacheBuffer + ".");
 
         source.dropLink(this);
         sink.dropLink(this);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
new file mode 100755
index 0000000..edfe8db
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSink.java
@@ -0,0 +1,129 @@
+// 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 streamer.apr;
+
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.DataSource;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+
+public class AprSocketSink extends BaseElement {
+
+    protected AprSocketWrapperImpl socketWrapper;
+    protected Long socket;
+
+    public AprSocketSink(String id) {
+        super(id);
+    }
+
+    public AprSocketSink(String id, AprSocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
+    }
+
+    public void setSocket(long socket) {
+        this.socket = socket;
+
+        // Resume links
+        resumeLinks();
+    }
+
+    /**
+     * Send incoming data to stream.
+     */
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (buf == null)
+            return;
+
+        if (socketWrapper.shutdown)
+            return;
+
+        try {
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Writing data to stream: " + buf + ".");
+
+            // FIXME: If pull is destroyed or socket is closed, segfault will happen here
+            Socket.send(socket, buf.data, buf.offset, buf.length);
+        } catch (Exception e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        case LINK_SWITCH_TO_PULL_MODE:
+            throw new RuntimeException("[" + this + "] ERROR: Unexpected event: sink recived LINK_SWITCH_TO_PULL_MODE event.");
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
+
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case IN:
+            super.setLink(padName, link, direction);
+
+            if (socket == null)
+                // Pause links until data stream will be ready
+                link.pause();
+            break;
+        case OUT:
+            throw new RuntimeException("Cannot assign link to output pad in sink element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
+    }
+
+    private void resumeLinks() {
+        for (DataSource source : inputPads.values())
+            ((Link)source).resume();
+    }
+
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
+
+    private void closeStream() {
+        if (socketWrapper.shutdown)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        socketWrapper.shutdown();
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketSink(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
new file mode 100755
index 0000000..0298349
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketSource.java
@@ -0,0 +1,171 @@
+// 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 streamer.apr;
+
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.DataSink;
+import streamer.Direction;
+import streamer.Event;
+import streamer.Link;
+
+/**
+ * Source element, which reads data from InputStream.
+ */
+public class AprSocketSource extends BaseElement {
+
+    protected AprSocketWrapperImpl socketWrapper;
+    protected Long socket;
+
+    public AprSocketSource(String id) {
+        super(id);
+    }
+
+    public AprSocketSource(String id, AprSocketWrapperImpl socketWrapper) {
+        super(id);
+        this.socketWrapper = socketWrapper;
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            socketWrapper.upgradeToSsl();
+            break;
+        case LINK_SWITCH_TO_PULL_MODE:
+            // Do nothing - this is the source
+            break;
+        default:
+            super.handleEvent(event, direction);
+        }
+    }
+
+    @Override
+    public void setLink(String padName, Link link, Direction direction) {
+        switch (direction) {
+        case OUT:
+            super.setLink(padName, link, direction);
+
+            if (socket == null) {
+                // Pause links until data stream will be ready
+                link.pause();
+            }
+            break;
+        case IN:
+            throw new RuntimeException("Cannot assign link to input pad in source element. Element: " + this + ", pad: " + padName + ", link: " + link + ".");
+        }
+    }
+
+    public void setSocket(long socket) {
+        this.socket = socket;
+
+        // Resume links
+        resumeLinks();
+    }
+
+    private void resumeLinks() {
+        for (DataSink sink : outputPads.values())
+            ((Link)sink).resume();
+    }
+
+    /**
+     * Read data from input stream.
+     */
+    @Override
+    public void poll(boolean block) {
+        if (socketWrapper.shutdown) {
+            socketWrapper.destroyPull();
+            return;
+        }
+
+        try {
+            // Create buffer of recommended size and with default offset
+            ByteBuffer buf = new ByteBuffer(incommingBufLength);
+
+            if (verbose)
+                System.out.println("[" + this + "] INFO: Reading data from stream.");
+
+            // FIXME: If pull is destroyed or socket is closed, segfault will happen here
+            int actualLength = (block) ? // Blocking read
+                    Socket.recv(socket, buf.data, buf.offset, buf.data.length - buf.offset)
+                    : // Non-blocking read
+                        Socket.recvt(socket, buf.data, buf.offset, buf.data.length - buf.offset, 1);
+
+                    if (socketWrapper.shutdown) {
+                        socketWrapper.destroyPull();
+                        return;
+                    }
+
+                    if (actualLength < 0) {
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: End of stream.");
+
+                        buf.unref();
+                        closeStream();
+                        sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+                        return;
+                    }
+
+                    if (actualLength == 0) {
+                        if (verbose)
+                            System.out.println("[" + this + "] INFO: Empty buffer is read from stream.");
+
+                        buf.unref();
+                        return;
+                    }
+
+                    buf.length = actualLength;
+
+                    if (verbose)
+                        System.out.println("[" + this + "] INFO: Data read from stream: " + buf + ".");
+
+                    pushDataToAllOuts(buf);
+
+        } catch (Exception e) {
+            System.err.println("[" + this + "] ERROR: " + e.getMessage());
+            closeStream();
+        }
+    }
+
+    @Override
+    protected void onClose() {
+        closeStream();
+    }
+
+    private void closeStream() {
+
+        if (socketWrapper.shutdown)
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Closing stream.");
+
+        try {
+            sendEventToAllPads(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        socketWrapper.shutdown();
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketSource(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
new file mode 100755
index 0000000..2ee426b
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/apr/AprSocketWrapperImpl.java
@@ -0,0 +1,281 @@
+// 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 streamer.apr;
+
+import static streamer.debug.MockServer.Packet.PacketType.CLIENT;
+import static streamer.debug.MockServer.Packet.PacketType.SERVER;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import org.apache.tomcat.jni.Address;
+import org.apache.tomcat.jni.Error;
+import org.apache.tomcat.jni.Library;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.SSL;
+import org.apache.tomcat.jni.SSLContext;
+import org.apache.tomcat.jni.SSLSocket;
+import org.apache.tomcat.jni.Socket;
+
+import streamer.BaseElement;
+import streamer.Direction;
+import streamer.Element;
+import streamer.Event;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.Queue;
+import streamer.SocketWrapper;
+import streamer.debug.MockServer;
+import streamer.debug.MockServer.Packet;
+import streamer.ssl.SSLState;
+import sun.security.x509.X509CertImpl;
+
+public class AprSocketWrapperImpl extends PipelineImpl implements SocketWrapper {
+
+    static {
+        try {
+            Library.initialize(null);
+            SSL.initialize(null);
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot load Tomcat Native Library (Apache Portable Runtime).", e);
+        }
+    }
+
+    private final SSLState sslState;
+
+    final long pool = Pool.create(0);
+    long inetAddress;
+    long socket;
+    private AprSocketSource source;
+    private AprSocketSink sink;
+
+    boolean shutdown = false;
+
+    private final boolean shutdowned = false;
+
+    public AprSocketWrapperImpl(String id, SSLState sslState) {
+        super(id);
+        this.sslState = sslState;
+    }
+
+    @Override
+    protected HashMap<String, Element> initElementMap(String id) {
+        HashMap<String, Element> map = new HashMap<String, Element>();
+
+        source = new AprSocketSource(id + "." + OUT, this);
+        sink = new AprSocketSink(id + "." + IN, this);
+
+        // Pass requests to read data to socket input stream
+        map.put(OUT, source);
+
+        // All incoming data, which is sent to this socket wrapper, will be sent
+        // to socket remote
+        map.put(IN, sink);
+
+        return map;
+    }
+
+    /**
+     * Connect this socket wrapper to remote server and start main loop on
+     * AprSocketSource stdout link, to watch for incoming data, and
+     * AprSocketSink stdin link, to pull for outgoing data.
+     */
+    @Override
+    public void connect(InetSocketAddress address) throws IOException {
+        try {
+            inetAddress = Address.info(address.getHostName(), Socket.APR_UNSPEC, address.getPort(), 0, pool);
+            socket = Socket.create(Address.getInfo(inetAddress).family, Socket.SOCK_STREAM, Socket.APR_PROTO_TCP, pool);
+        } catch (Exception e) {
+            throw new IOException("[" + this + "] ERROR: Cannot create socket for \"" + address + "\".", e);
+        }
+
+        int ret = Socket.connect(socket, inetAddress);
+        if (ret != 0)
+            throw new IOException("[" + this + "] ERROR: Cannot connect to remote host \"" + address + "\": " + Error.strerror(ret));
+
+        source.setSocket(socket);
+        sink.setSocket(socket);
+
+        // Start polling for data to send to remote sever
+        runMainLoop(IN, STDIN, true, true);
+
+        // Push incoming data from server to handlers
+        runMainLoop(OUT, STDOUT, false, false);
+
+    }
+
+    @Override
+    public void handleEvent(Event event, Direction direction) {
+        switch (event) {
+        case SOCKET_UPGRADE_TO_SSL:
+            upgradeToSsl();
+            break;
+        default:
+            super.handleEvent(event, direction);
+            break;
+        }
+    }
+
+    @Override
+    public void validate() {
+
+        if (getPads(Direction.IN).size() == 0)
+            throw new RuntimeException("[ " + this + "] BUG: Input of socket is not connected.");
+
+        if (getPads(Direction.OUT).size() == 0)
+            throw new RuntimeException("[ " + this + "] BUG: Output of socket is not connected.");
+
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        try {
+            long sslContext;
+            try {
+                sslContext = SSLContext.make(pool, SSL.SSL_PROTOCOL_TLSV1, SSL.SSL_MODE_CLIENT);
+            } catch (Exception e) {
+                throw new RuntimeException("Cannot create SSL context using Tomcat native library.", e);
+            }
+
+            SSLContext.setOptions(sslContext, SSL.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS | SSL.SSL_OP_TLS_BLOCK_PADDING_BUG | SSL.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+                    | SSL.SSL_OP_MSIE_SSLV2_RSA_PADDING);
+            // FIXME: verify certificate by default
+            SSLContext.setVerify(sslContext, SSL.SSL_CVERIFY_NONE, 0);
+            int ret;
+            try {
+                ret = SSLSocket.attach(sslContext, socket);
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot attach SSL context to socket: ", e);
+            }
+            if (ret != 0)
+                throw new RuntimeException("[" + this + "] ERROR: Cannot attach SSL context to socket(" + ret + "): " + SSL.getLastError());
+
+            try {
+                ret = SSLSocket.handshake(socket);
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot make SSL handshake with server: ", e);
+            }
+            if (ret != 0 && ret != 20014) // 20014: bad certificate signature FIXME: show prompt for self signed certificate
+                throw new RuntimeException("[" + this + "] ERROR: Cannot make SSL handshake with server(" + ret + "): " + SSL.getLastError());
+
+            try {
+                byte[] key = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT);
+                //*DEBUG*/System.out.println("DEBUG: Server cert:\n"+new ByteBuffer(key).dump());
+                sslState.serverCertificateSubjectPublicKeyInfo = new X509CertImpl(key).getPublicKey().getEncoded();
+            } catch (Exception e) {
+                throw new RuntimeException("[" + this + "] ERROR: Cannot get server public key: ", e);
+            }
+
+        } catch (RuntimeException e) {
+            shutdown();
+            throw e;
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        if (shutdown)
+            return;
+
+        shutdown = true;
+
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+    }
+
+    void destroyPull() {
+        if (shutdowned)
+            return;
+
+        // Causes segfault in AprSocketSource.poll() method, so this function must be called from it
+        try {
+            Socket.close(socket);
+            // or
+            // Socket.shutdown(socket, Socket.APR_SHUTDOWN_READWRITE);
+            Pool.destroy(pool);
+        } catch (Exception e) {
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return "AprSocketWrapper(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+
+        try {
+            System.setProperty("streamer.Link.debug", "true");
+            System.setProperty("streamer.Element.debug", "true");
+            System.setProperty("rdpclient.MockServer.debug", "true");
+
+            Pipeline pipeline = new PipelineImpl("echo client");
+
+            AprSocketWrapperImpl socketWrapper = new AprSocketWrapperImpl("socket", null);
+
+            pipeline.add(socketWrapper);
+            pipeline.add(new BaseElement("echo"));
+            pipeline.add(new Queue("queue")); // To decouple input and output
+
+            pipeline.link("socket", "echo", "queue", "socket");
+
+            final byte[] mockData = new byte[] {0x01, 0x02, 0x03};
+            MockServer server = new MockServer(new Packet[] {new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }, new Packet("Server hello") {
+                {
+                    type = SERVER;
+                    data = mockData;
+                }
+            }, new Packet("Client hello") {
+                {
+                    type = CLIENT;
+                    data = mockData;
+                }
+            }});
+            server.start();
+            InetSocketAddress address = server.getAddress();
+
+            socketWrapper.connect(address);
+
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
new file mode 100755
index 0000000..67e2dbd
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/bco/BcoSocketWrapperImpl.java
@@ -0,0 +1,119 @@
+// 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 streamer.bco;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.security.Security;
+
+import org.bouncycastle.asn1.x509.X509CertificateStructure;
+import org.bouncycastle.crypto.tls.CertificateVerifyer;
+import org.bouncycastle.crypto.tls.TlsProtocolHandler;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import streamer.Direction;
+import streamer.Event;
+import streamer.SocketWrapperImpl;
+import streamer.ssl.SSLState;
+
+@SuppressWarnings("deprecation")
+public class BcoSocketWrapperImpl extends SocketWrapperImpl {
+
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    private TlsProtocolHandler bcoSslSocket;
+
+    public BcoSocketWrapperImpl(String id, SSLState sslState) {
+        super(id, sslState);
+    }
+
+    @Override
+    public void upgradeToSsl() {
+
+        if (sslSocket != null)
+            // Already upgraded
+            return;
+
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Upgrading socket to SSL.");
+
+        try {
+
+            SecureRandom secureRandom = new SecureRandom();
+            bcoSslSocket = new TlsProtocolHandler(socket.getInputStream(), socket.getOutputStream(), secureRandom);
+
+            CertificateVerifyer client = new CertificateVerifyer() {
+
+                @Override
+                public boolean isValid(X509CertificateStructure[] chain) {
+
+                    try {
+                        if (sslState != null) {
+                            sslState.serverCertificateSubjectPublicKeyInfo = chain[0].getSubjectPublicKeyInfo().getEncoded();
+                        }
+                    } catch (IOException e) {
+                        throw new RuntimeException("Cannot get server public key.", e);
+                    }
+
+                    return true;
+                }
+            };
+            bcoSslSocket.connect(client);
+
+            InputStream sis = bcoSslSocket.getInputStream();
+            source.setInputStream(sis);
+
+            OutputStream sos = bcoSslSocket.getOutputStream();
+            sink.setOutputStream(sos);
+
+        } catch (Exception e) {
+            throw new RuntimeException("Cannot upgrade socket to SSL: " + e.getMessage(), e);
+        }
+
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.IN);
+        } catch (Exception e) {
+        }
+        try {
+            handleEvent(Event.STREAM_CLOSE, Direction.OUT);
+        } catch (Exception e) {
+        }
+        try {
+            if (bcoSslSocket != null)
+                bcoSslSocket.close();
+        } catch (Exception e) {
+        }
+        try {
+            socket.close();
+        } catch (Exception e) {
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "BcoSocketWrapper(" + id + ")";
+    }
+
+}


[21/21] git commit: updated refs/heads/master to 48c4710

Posted by de...@apache.org.
CLOUDSTACK-5344: Updated to allow rdp console to access hyper-v vm virtual framebuffer.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/48c47101
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/48c47101
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/48c47101

Branch: refs/heads/master
Commit: 48c47101aa9996c68851de878cb2229cf70dcf2b
Parents: 97ede25
Author: Donal Lafferty <dl...@gmail.com>
Authored: Wed Nov 27 14:38:51 2013 +0000
Committer: Devdeep Singh <de...@gmail.com>
Committed: Thu Jan 2 13:06:10 2014 +0530

----------------------------------------------------------------------
 .../console-proxy-rdp/rdpconsole/README.txt     |   54 +-
 services/console-proxy-rdp/rdpconsole/pom.xml   |    9 +-
 .../console-proxy-rdp/rdpconsole/rdp-config.bat |    2 +-
 .../src/main/java/common/AwtBellAdapter.java    |   77 --
 .../src/main/java/common/AwtCanvasAdapter.java  |  166 ---
 .../main/java/common/AwtClipboardAdapter.java   |   56 -
 .../src/main/java/common/AwtKeyEventSource.java |    0
 .../main/java/common/AwtMouseEventSource.java   |    0
 .../src/main/java/common/BitmapOrder.java       |    3 +-
 .../src/main/java/common/BitmapRectangle.java   |    6 +-
 .../main/java/common/BufferedImageCanvas.java   |    2 +-
 .../common/BufferedImageCopyRectAdapter.java    |   32 +-
 .../java/common/BufferedImagePixelsAdapter.java |   46 +-
 .../rdpconsole/src/main/java/common/Client.java |  283 ++++-
 .../src/main/java/common/CopyRectOrder.java     |    0
 .../src/main/java/common/KeyOrder.java          |    0
 .../src/main/java/common/MouseOrder.java        |    0
 .../src/main/java/common/OrderType.java         |    0
 .../src/main/java/common/ScreenDescription.java |   56 +-
 .../main/java/common/SizeChangeListener.java    |    0
 .../java/common/adapter/AwtBellAdapter.java     |   77 ++
 .../java/common/adapter/AwtCanvasAdapter.java   |  171 +++
 .../common/adapter/AwtClipboardAdapter.java     |   57 +
 .../src/main/java/common/asn1/Any.java          |   78 ++
 .../main/java/common/asn1/Asn1Constants.java    |   83 ++
 .../src/main/java/common/asn1/Asn1Integer.java  |  116 ++
 .../src/main/java/common/asn1/BerType.java      |   40 +
 .../src/main/java/common/asn1/BitString.java    |   67 ++
 .../src/main/java/common/asn1/ObjectID.java     |   67 ++
 .../src/main/java/common/asn1/OctetString.java  |   80 ++
 .../src/main/java/common/asn1/Sequence.java     |  143 +++
 .../src/main/java/common/asn1/SequenceOf.java   |   82 ++
 .../src/main/java/common/asn1/Tag.java          |  462 +++++++
 .../main/java/common/opt/IncrementalOption.java |   28 +
 .../src/main/java/common/opt/IntOption.java     |   41 +
 .../opt/NoArgumentForOptionException.java       |   26 +
 .../src/main/java/common/opt/Option.java        |  102 ++
 .../src/main/java/common/opt/OptionParser.java  |  147 +++
 .../common/opt/OptionRequiredException.java     |   26 +
 .../main/java/common/opt/StringArrayOption.java |   38 +
 .../common/opt/StringEnumerationOption.java     |   72 ++
 .../src/main/java/common/opt/StringOption.java  |   41 +
 .../java/common/opt/UnknownOptionException.java |   27 +
 .../java/rdpclient/AwtRdpKeyboardAdapter.java   |  350 ------
 .../main/java/rdpclient/AwtRdpMouseAdapter.java |  179 ---
 .../java/rdpclient/ClientConfirmActivePDU.java  | 1129 -----------------
 .../main/java/rdpclient/ClientFastPathPDU.java  |   55 -
 .../src/main/java/rdpclient/ClientInfoPDU.java  |  455 -------
 .../rdpclient/ClientMCSAttachUserRequest.java   |  103 --
 ...lJoinRequestServerMCSChannelConfirmPDUs.java |  222 ----
 .../java/rdpclient/ClientMCSConnectInitial.java |  669 -----------
 .../rdpclient/ClientMCSErectDomainRequest.java  |  189 ---
 .../java/rdpclient/ClientPacketSniffer.java     |   49 -
 .../java/rdpclient/ClientSynchronizePDU.java    |  248 ----
 .../src/main/java/rdpclient/ClientTpkt.java     |   54 -
 .../ClientX224ConnectionRequestPDU.java         |  156 ---
 .../main/java/rdpclient/ClientX224DataPdu.java  |   52 -
 .../src/main/java/rdpclient/HandshakeEnd.java   |   27 -
 .../src/main/java/rdpclient/MockServer.java     |  198 ---
 .../src/main/java/rdpclient/PacketSniffer.java  |   75 --
 .../java/rdpclient/RLEBitmapDecompression.java  |  985 ---------------
 .../src/main/java/rdpclient/RdpClient.java      |  297 ++++-
 .../src/main/java/rdpclient/RdpConstants.java   |   70 --
 .../src/main/java/rdpclient/RdpState.java       |   33 -
 .../main/java/rdpclient/ServerBitmapUpdate.java |  200 ----
 .../java/rdpclient/ServerChannel1003Router.java |  533 ---------
 .../rdpclient/ServerControlPDUCooperate.java    |  117 --
 .../ServerControlPDUGrantedControl.java         |  114 --
 .../java/rdpclient/ServerDemandActivePDU.java   |  660 ----------
 .../src/main/java/rdpclient/ServerFastPath.java |  258 ----
 .../ServerLicenseErrorPDUValidClient.java       |  121 --
 .../ServerMCSAttachUserConfirmPDU.java          |  134 ---
 .../ServerMCSChannelJoinConfirmPDU.java         |   89 --
 .../rdpclient/ServerMCSConnectResponse.java     |  283 -----
 .../src/main/java/rdpclient/ServerMCSPDU.java   |  149 ---
 .../java/rdpclient/ServerPacketSniffer.java     |   50 -
 .../java/rdpclient/ServerPaletteUpdate.java     |   77 --
 .../java/rdpclient/ServerSynchronizePDU.java    |  115 --
 .../src/main/java/rdpclient/ServerTpkt.java     |   70 --
 .../ServerX224ConnectionConfirmPDU.java         |  237 ----
 .../main/java/rdpclient/ServerX224DataPdu.java  |   64 -
 .../rdpclient/TrustAllX509TrustManager.java     |   40 -
 .../main/java/rdpclient/UpgradeSocketToSSL.java |   44 -
 .../adapter/AwtRdpKeyboardAdapter.java          |  350 ++++++
 .../rdpclient/adapter/AwtRdpMouseAdapter.java   |  179 +++
 .../rdpclient/clip/ClipboardDataFormat.java     |  143 +++
 .../java/rdpclient/clip/ClipboardState.java     |   70 ++
 .../clip/ServerClipRdrChannelRouter.java        |  193 +++
 .../clip/ServerClipboardCapabilitiesPDU.java    |  180 +++
 .../clip/ServerFormatDataResponsePDU.java       |   97 ++
 .../rdpclient/clip/ServerFormatListPDU.java     |  237 ++++
 .../rdpclient/clip/ServerMonitorReadyPDU.java   |   85 ++
 .../rdpclient/debug/ClientPacketSniffer.java    |   51 +
 .../java/rdpclient/debug/PacketSniffer.java     |   75 ++
 .../rdpclient/debug/ServerPacketSniffer.java    |   49 +
 .../hyperv/ClientPreConnectionBlob.java         |  121 ++
 .../ntlmssp/ClientNtlmsspNegotiate.java         |  177 +++
 .../ntlmssp/ClientNtlmsspPubKeyAuth.java        |  680 +++++++++++
 .../ntlmssp/ClientNtlmsspUserCredentials.java   |  128 ++
 .../java/rdpclient/ntlmssp/CryptoAlgos.java     |  361 ++++++
 .../main/java/rdpclient/ntlmssp/NegoFlags.java  |  492 ++++++++
 .../java/rdpclient/ntlmssp/NtlmCompute.java     |   24 +
 .../java/rdpclient/ntlmssp/NtlmConstants.java   |  157 +++
 .../main/java/rdpclient/ntlmssp/NtlmState.java  |  887 ++++++++++++++
 .../main/java/rdpclient/ntlmssp/SecBuffer.java  |   21 +
 .../ntlmssp/ServerNtlmsspChallenge.java         |  293 +++++
 .../ntlmssp/ServerNtlmsspPubKeyPlus1.java       |  125 ++
 .../ntlmssp/asn1/AlgorithmIdentifier.java       |   40 +
 .../java/rdpclient/ntlmssp/asn1/NegoData.java   |   64 +
 .../java/rdpclient/ntlmssp/asn1/NegoItem.java   |   73 ++
 .../ntlmssp/asn1/SubjectPublicKeyInfo.java      |   35 +
 .../rdpclient/ntlmssp/asn1/TSCredentials.java   |   62 +
 .../rdpclient/ntlmssp/asn1/TSCspDataDetail.java |   98 ++
 .../rdpclient/ntlmssp/asn1/TSPasswordCreds.java |   76 ++
 .../java/rdpclient/ntlmssp/asn1/TSRequest.java  |  201 ++++
 .../ntlmssp/asn1/TSSmartCardCreds.java          |   90 ++
 .../java/rdpclient/ntlmssp/package-info.java    |   71 ++
 .../rdpclient/rdp/ClientConfirmActivePDU.java   | 1131 ++++++++++++++++++
 .../java/rdpclient/rdp/ClientFastPathPDU.java   |   55 +
 .../main/java/rdpclient/rdp/ClientInfoPDU.java  |  456 +++++++
 .../rdp/ClientMCSAttachUserRequest.java         |  103 ++
 ...lJoinRequestServerMCSChannelConfirmPDUs.java |  223 ++++
 .../rdpclient/rdp/ClientMCSConnectInitial.java  |  696 +++++++++++
 .../rdp/ClientMCSErectDomainRequest.java        |  189 +++
 .../rdpclient/rdp/ClientSynchronizePDU.java     |  248 ++++
 .../src/main/java/rdpclient/rdp/ClientTpkt.java |   54 +
 .../rdp/ClientX224ConnectionRequestPDU.java     |  162 +++
 .../java/rdpclient/rdp/ClientX224DataPDU.java   |   52 +
 .../rdpclient/rdp/RLEBitmapDecompression.java   | 1014 ++++++++++++++++
 .../main/java/rdpclient/rdp/RdpConstants.java   |   91 ++
 .../src/main/java/rdpclient/rdp/RdpState.java   |   33 +
 .../java/rdpclient/rdp/ServerBitmapUpdate.java  |  199 +++
 .../rdp/ServerControlPDUCooperate.java          |  117 ++
 .../rdp/ServerControlPDUGrantedControl.java     |  114 ++
 .../rdpclient/rdp/ServerDemandActivePDU.java    |  660 ++++++++++
 .../main/java/rdpclient/rdp/ServerFastPath.java |  315 +++++
 .../rdpclient/rdp/ServerIOChannelRouter.java    |  534 +++++++++
 .../rdp/ServerLicenseErrorPDUValidClient.java   |  121 ++
 .../rdp/ServerMCSAttachUserConfirmPDU.java      |  116 ++
 .../rdp/ServerMCSChannelJoinConfirmPDU.java     |   89 ++
 .../rdpclient/rdp/ServerMCSConnectResponse.java |  283 +++++
 .../main/java/rdpclient/rdp/ServerMCSPDU.java   |  149 +++
 .../java/rdpclient/rdp/ServerPaletteUpdate.java |   77 ++
 .../rdpclient/rdp/ServerSynchronizePDU.java     |  115 ++
 .../src/main/java/rdpclient/rdp/ServerTpkt.java |   70 ++
 .../rdp/ServerX224ConnectionConfirmPDU.java     |  234 ++++
 .../java/rdpclient/rdp/ServerX224DataPdu.java   |   64 +
 .../main/java/streamer/AssertingByteBuffer.java |  107 --
 .../src/main/java/streamer/BaseElement.java     |   98 +-
 .../src/main/java/streamer/BufferPool.java      |    0
 .../src/main/java/streamer/ByteBuffer.java      |  466 ++++++--
 .../src/main/java/streamer/DataSink.java        |    0
 .../src/main/java/streamer/DataSource.java      |    0
 .../src/main/java/streamer/Direction.java       |    0
 .../src/main/java/streamer/Element.java         |    2 +-
 .../src/main/java/streamer/Event.java           |    3 +-
 .../src/main/java/streamer/FakeSink.java        |   69 --
 .../src/main/java/streamer/FakeSource.java      |  125 --
 .../main/java/streamer/InputStreamSource.java   |   36 +-
 .../rdpconsole/src/main/java/streamer/Link.java |    0
 .../src/main/java/streamer/MockSink.java        |  113 --
 .../src/main/java/streamer/MockSource.java      |   89 --
 .../src/main/java/streamer/OneTimeSwitch.java   |    3 +
 .../src/main/java/streamer/Order.java           |    0
 .../main/java/streamer/OutputStreamSink.java    |   42 +-
 .../src/main/java/streamer/Pipeline.java        |    2 +
 .../src/main/java/streamer/PipelineImpl.java    |   77 +-
 .../src/main/java/streamer/Queue.java           |   28 +-
 .../src/main/java/streamer/SocketWrapper.java   |  216 +---
 .../main/java/streamer/SocketWrapperImpl.java   |  249 ++++
 .../src/main/java/streamer/SyncLink.java        |  123 +-
 .../main/java/streamer/apr/AprSocketSink.java   |  129 ++
 .../main/java/streamer/apr/AprSocketSource.java |  171 +++
 .../java/streamer/apr/AprSocketWrapperImpl.java |  281 +++++
 .../java/streamer/bco/BcoSocketWrapperImpl.java |  119 ++
 .../streamer/debug/AssertingByteBuffer.java     |  109 ++
 .../src/main/java/streamer/debug/Dumper.java    |   28 +
 .../src/main/java/streamer/debug/FakeSink.java  |   77 ++
 .../main/java/streamer/debug/FakeSource.java    |  138 +++
 .../main/java/streamer/debug/MockServer.java    |  203 ++++
 .../src/main/java/streamer/debug/MockSink.java  |  154 +++
 .../main/java/streamer/debug/MockSource.java    |   95 ++
 .../src/main/java/streamer/ssl/SSLState.java    |   26 +
 .../streamer/ssl/TrustAllX509TrustManager.java  |   52 +
 .../java/streamer/ssl/UpgradeSocketToSSL.java   |   44 +
 .../vncclient/AwtKeyboardEventToVncAdapter.java |  368 ------
 .../vncclient/AwtMouseEventToVncAdapter.java    |   71 --
 .../main/java/vncclient/EncodingsMessage.java   |   63 -
 .../vncclient/FrameBufferUpdateRequest.java     |  126 --
 .../vncclient/RGB888LE32PixelFormatRequest.java |   89 --
 .../src/main/java/vncclient/RfbConstants.java   |   85 --
 .../java/vncclient/Vnc33Authentication.java     |  292 -----
 .../src/main/java/vncclient/Vnc33Hello.java     |  116 --
 .../src/main/java/vncclient/VncClient.java      |   58 +-
 .../src/main/java/vncclient/VncInitializer.java |  245 ----
 .../main/java/vncclient/VncMessageHandler.java  |  420 -------
 .../adapter/AwtVncKeyboardAdapter.java          |  369 ++++++
 .../vncclient/adapter/AwtVncMouseAdapter.java   |   71 ++
 .../java/vncclient/vnc/EncodingsMessage.java    |   63 +
 .../vncclient/vnc/FrameBufferUpdateRequest.java |  126 ++
 .../vnc/RGB888LE32PixelFormatRequest.java       |   89 ++
 .../main/java/vncclient/vnc/RfbConstants.java   |   85 ++
 .../java/vncclient/vnc/Vnc33Authentication.java |  292 +++++
 .../src/main/java/vncclient/vnc/Vnc33Hello.java |  116 ++
 .../main/java/vncclient/vnc/VncInitializer.java |  245 ++++
 .../java/vncclient/vnc/VncMessageHandler.java   |  420 +++++++
 .../src/main/resources/jaas_ntlm_config.txt     |   21 +
 .../rdpconsole/src/test/doc/README.txt          |    2 +
 .../rdpconsole/src/test/doc/dev-rdp-config.bat  |   13 +
 .../src/test/doc/freerdp-debug-log.txt          |  772 ++++++++++++
 .../rdpconsole/src/test/doc/rdp.pfx             |  Bin 0 -> 2572 bytes
 .../src/test/java/rdpclient/MockServerTest.java |    9 +-
 212 files changed, 21655 insertions(+), 12007 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/README.txt
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/README.txt b/services/console-proxy-rdp/rdpconsole/README.txt
old mode 100644
new mode 100755
index 15029d4..546746c
--- a/services/console-proxy-rdp/rdpconsole/README.txt
+++ b/services/console-proxy-rdp/rdpconsole/README.txt
@@ -14,28 +14,38 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-This project contains code for basic VNC and RDP clients.
-
-VNC client can be invoked using following command:
-
-  mvn exec:java -Dexec.mainClass="common.Client" -Dexec.args="vnc 192.168.0.101 5901 password"
-
-where
-  * vnc - name of protcol;
-  * 192.168.0.101 - IP of VNC server;
-  * 5901 - port of VNC server screen (5900+display number);
-  * password - VNC server password.
-
-
-RDP client can be invoked using following command:
-
-  mvn exec:java -Dexec.mainClass="common.Client" -Dexec.args="rdp 192.168.0.101 3389 Administrator"
-
-where
-  * rdp - name of protcol;
-  * 192.168.0.101 - IP of RDP server;
-  * 3389 - port of RDP server;
-  * Administrator - user name for loging dialog.
+This project contains code for basic VNC, RDP, and HyperV (RDP) clients.
+
+Usage: 
+  java common.Client vnc|rdp|hyperv OPTIONS
+
+Common options:
+  --help|-h	Show this help text.
+  --debug-link|-DL	Print debugging messages when packets are trasnferred via links.
+  --debug-element|-DE	Print debugging messages when packets are received or sended by elements.
+  --debug-pipeline|-DP	Print debugging messages in pipelines.
+  --host|-n|--host-name VALUE	Name or IP address of host to connect to. Required.
+  --width|-W VALUE	Width of canvas. Default value is "1024".
+  --height|-H VALUE	Height of canvas. Default value is "768".
+
+VNC options:
+  --port|-p VALUE	Port of VNC display server to connect to. Calculate as 5900 + display number, e.g. 5900 for display #0, 5901 for display #1, and so on. Default value is "5901".
+  --password|-P VALUE	Password to use. Required.
+
+RDP options:
+  --ssl-implementation|-j jre|apr|bco	Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation. Default value is "apr".
+  --port|-p VALUE	Port of RDP server to connect to. Default value is "3389".
+  --domain|-D VALUE	NTLM domain to login into. Default value is "Workgroup".
+  --user|-U VALUE	User name to use. Default value is "Administrator".
+  --password|-P VALUE	Password to use. If omitted, then login screen will be shown.
+
+HyperV options:
+  --ssl-implementation|-j jre|apr|bco	Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation. Default value is "apr".
+  --port|-p VALUE	Port of HyperV server to connect to. Default value is "2179".
+  --instance|-i VALUE	HyperV instance ID to use. Required.
+  --domain|-D VALUE	NTLM domain to login into. Default value is "Workgroup".
+  --user|-U VALUE	User name to use. Default value is "Administrator".
+  --password|-P VALUE	Password to use. Required.
 
 
 Limitations of VNC client:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml
old mode 100644
new mode 100755
index d25329a..5737a85
--- a/services/console-proxy-rdp/rdpconsole/pom.xml
+++ b/services/console-proxy-rdp/rdpconsole/pom.xml
@@ -61,11 +61,18 @@
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
+    <!-- Apache Portable Runtime implementation of SSL protocol, which is compatible with broken MS RDP SSL suport.
+    NOTE: tomcat-native package with /usr/lib/libtcnative-1.so library is necessary for APR to work. -->
     <dependency>
       <groupId>org.apache.tomcat.embed</groupId>
       <artifactId>tomcat-embed-core</artifactId>
       <version>7.0.30</version>
-      <scope>test</scope>
+    </dependency>
+    <!-- Another implementation of SSL protocol. Does not work with broken MS RDP SSL too. -->
+    <dependency>
+      <groupId>org.bouncycastle</groupId>
+      <artifactId>bcprov-jdk16</artifactId>
+      <version>1.46</version>
     </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/rdp-config.bat
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/rdp-config.bat b/services/console-proxy-rdp/rdpconsole/rdp-config.bat
old mode 100644
new mode 100755
index e951014..f19b00d
--- a/services/console-proxy-rdp/rdpconsole/rdp-config.bat
+++ b/services/console-proxy-rdp/rdpconsole/rdp-config.bat
@@ -16,7 +16,7 @@ rem specific language governing permissions and limitations
 rem under the License.
 
 rem 
-rem Configure and start RDP service.
+rem Configure and start RDP service. Run this script on RDP server.
 rem 
  
 rem Turn off firewall

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
deleted file mode 100644
index 5970abb..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtBellAdapter.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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 common;
-
-import java.awt.Toolkit;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.FakeSource;
-import streamer.Link;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class AwtBellAdapter extends BaseElement {
-
-    public AwtBellAdapter(String id) {
-        super(id);
-        declarePads();
-    }
-
-    private void declarePads() {
-        inputPads.put(STDIN, null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        if (buf == null)
-            return;
-
-        Toolkit.getDefaultToolkit().beep();
-    }
-
-    @Override
-    public String toString() {
-        return "Bell(" + id + ")";
-    }
-
-    /**
-     * Example.
-     */
-    public static void main(String args[]) {
-        System.setProperty("streamer.Element.debug", "true");
-
-        Element source = new FakeSource("source") {
-            {
-                this.incommingBufLength = 0;
-                this.delay = 1000;
-                this.numBuffers = 3;
-            }
-        };
-
-        Element sink = new AwtBellAdapter("sink");
-
-        Pipeline pipeline = new PipelineImpl("test");
-        pipeline.addAndLink(source, sink);
-        pipeline.runMainLoop("source", STDOUT, false, false);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
deleted file mode 100644
index 8adee49..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtCanvasAdapter.java
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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 common;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.WritableRaster;
-
-import rdpclient.ServerBitmapUpdate;
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Element;
-import streamer.Link;
-import streamer.Order;
-import streamer.Pipeline;
-import streamer.PipelineImpl;
-
-public class AwtCanvasAdapter extends BaseElement {
-
-    protected ScreenDescription screen;
-
-    public AwtCanvasAdapter(String id, BufferedImageCanvas canvas, ScreenDescription screen) {
-        super(id);
-        this.canvas = canvas;
-        this.screen = screen;
-    }
-
-    protected BufferedImageCanvas canvas;
-
-    @Override
-    public String toString() {
-        return "AwtRdpAdapter(" + id + ")";
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        Order order = buf.getOrder();
-        switch ((OrderType)order.type) {
-
-            case BITMAP_UPDATE:
-                handleBitmap((BitmapOrder)order, buf);
-                break;
-
-            case COPY_RECT:
-                handleCopyRect((CopyRectOrder)order, buf);
-                break;
-
-            default:
-                throw new RuntimeException("Order is not implemented: " + buf + ".");
-                // break;
-        }
-
-        buf.unref();
-    }
-
-    private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) {
-        // TODO Auto-generated method stub
-        // Copy image
-        canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY);
-
-        // Request update of repainted area
-        canvas.repaint(order.x, order.y, order.width, order.height);
-
-    }
-
-    private void handleBitmap(BitmapOrder order, ByteBuffer buf) {
-        // Draw rectangle on offline buffer
-        BufferedImage image = canvas.getOfflineImage();
-        Graphics2D g = (Graphics2D)image.getGraphics();
-
-        for (BitmapRectangle rectangle : order.rectangles) {
-            // *DEBUG*/System.out.println("["+this+"] DEBUG: Rectangle: " +
-            // rectangle.toString());
-
-            int x = rectangle.x;
-            int y = rectangle.y;
-            int width = rectangle.width;
-            int height = rectangle.height;
-            int bufferWidth = rectangle.bufferWidth;
-            int bufferHeight = rectangle.bufferHeight;
-
-            BufferedImage rectImage;
-            switch (rectangle.colorDepth) {
-                case 8: {
-                    rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_BYTE_INDEXED, screen.colorMap);
-                    WritableRaster raster = rectImage.getRaster();
-                    raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toByteArray());
-                    break;
-                }
-                case 15: {
-                    rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_555_RGB);
-                    WritableRaster raster = rectImage.getRaster();
-                    raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
-                    break;
-                }
-                case 16: {
-                    rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_565_RGB);
-                    WritableRaster raster = rectImage.getRaster();
-                    raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
-                    break;
-                }
-                case 24:
-                case 32: {
-                    rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_INT_RGB);
-                    WritableRaster raster = rectImage.getRaster();
-                    raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toIntLEArray());
-                    break;
-                }
-                default:
-                    throw new RuntimeException("Unsupported color depth: " + rectangle.colorDepth + ".");
-            }
-
-            g.setClip(x, y, width, height);
-            g.drawImage(rectImage, x, y, null);
-
-            // Request update of repainted area
-            canvas.repaint(x, y, width, height);
-        }
-
-    }
-
-    /**
-     * 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");
-        ByteBuffer packet =
-            new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x04, 0x0a,
-                0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
-
-        Pipeline pipeline = new PipelineImpl("test");
-
-        Element bitmap = new ServerBitmapUpdate("bitmap");
-
-        BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
-        Element adapter = new AwtCanvasAdapter("test", canvas, null) {
-            {
-                verbose = true;
-            }
-        };
-        pipeline.addAndLink(bitmap, adapter);
-
-        bitmap.handleData(packet, null);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
deleted file mode 100644
index 75dc1b9..0000000
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtClipboardAdapter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 common;
-
-import java.awt.Toolkit;
-import java.awt.datatransfer.StringSelection;
-
-import streamer.BaseElement;
-import streamer.ByteBuffer;
-import streamer.Link;
-import vncclient.VncMessageHandler;
-
-public class AwtClipboardAdapter extends BaseElement {
-
-    public AwtClipboardAdapter(String id) {
-        super(id);
-        declarePads();
-    }
-
-    private void declarePads() {
-        inputPads.put(STDIN, null);
-    }
-
-    @Override
-    public void handleData(ByteBuffer buf, Link link) {
-        if (verbose)
-            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
-
-        if (buf == null)
-            return;
-
-        String content = (String)buf.getMetadata(VncMessageHandler.CLIPBOARD_CONTENT);
-        StringSelection contents = new StringSelection(content);
-        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
-    }
-
-    @Override
-    public String toString() {
-        return "Clipboard(" + id + ")";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtKeyEventSource.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/AwtMouseEventSource.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
old mode 100644
new mode 100755
index 3a25c8f..8d64331
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapOrder.java
@@ -40,7 +40,8 @@ public class BitmapOrder extends Order {
     @Override
     public String toString() {
         final int maxLen = 10;
-        return String.format("BitmapUpdateOrder [rectangles=%s]", rectangles != null ? Arrays.asList(rectangles).subList(0, Math.min(rectangles.length, maxLen)) : null);
+        return String.format("BitmapUpdateOrder [rectangles=%s]", rectangles != null ? Arrays.asList(rectangles).subList(0, Math.min(rectangles.length, maxLen))
+                : null);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
old mode 100644
new mode 100755
index 08dcbf6..1685114
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BitmapRectangle.java
@@ -65,8 +65,10 @@ public class BitmapRectangle {
 
     @Override
     public String toString() {
-        return String.format("BitmapUpdateRectangle [x=%s, y=%s, width=%s, height=%s, bitsPerPixel=%s, bitmapDataStream=%s]", x, y, width, height, colorDepth,
-            bitmapDataStream);
+        return String
+                .format(
+                        "BitmapUpdateRectangle [x=%s, y=%s, width=%s, height=%s, bitsPerPixel=%s, bitmapDataStream=%s]",
+                        x, y, width, height, colorDepth, bitmapDataStream);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
old mode 100644
new mode 100755
index 2418de3..43abb27
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java
@@ -49,7 +49,7 @@ public class BufferedImageCanvas extends Canvas {
     }
 
     public void setCanvasSize(int width, int height) {
-        this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         graphics = offlineImage.createGraphics();
 
         setSize(offlineImage.getWidth(), offlineImage.getHeight());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
old mode 100644
new mode 100755
index 28bf640..804cab7
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCopyRectAdapter.java
@@ -81,23 +81,23 @@ public class BufferedImageCopyRectAdapter extends BaseElement {
         Element renderer = new BufferedImageCopyRectAdapter("renderer", canvas);
 
         int[] pixelsBeforeCopy = new int[] {
-            // 0
-            1, 2, 3, 4,
-            // 1
-            5, 6, 7, 8,
-            // 2
-            9, 10, 11, 12,
-            // 3
-            13, 14, 15, 16};
+                // 0
+                1, 2, 3, 4,
+                // 1
+                5, 6, 7, 8,
+                // 2
+                9, 10, 11, 12,
+                // 3
+                13, 14, 15, 16};
         int[] pixelsAfterCopy = new int[] {
-            // 0
-            11, 12, 3, 4,
-            // 1
-            15, 16, 7, 8,
-            // 2
-            9, 10, 11, 12,
-            // 3
-            13, 14, 15, 16};
+                // 0
+                11, 12, 3, 4,
+                // 1
+                15, 16, 7, 8,
+                // 2
+                9, 10, 11, 12,
+                // 3
+                13, 14, 15, 16};
 
         // Initalize image
         int[] data = ((DataBufferInt)canvas.getOfflineImage().getRaster().getDataBuffer()).getData();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
old mode 100644
new mode 100755
index e93df3e..396bdd4
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImagePixelsAdapter.java
@@ -82,32 +82,32 @@ public class BufferedImagePixelsAdapter extends BaseElement {
 
         switch (dataBuf.getDataType()) {
 
-            case DataBuffer.TYPE_INT: {
+        case DataBuffer.TYPE_INT: {
 
-                // Convert array of bytes to array of int's
-                int[] intArray = buf.toIntLEArray();
+            // Convert array of bytes to array of int's
+            int[] intArray = buf.toIntLEArray();
 
-                // We chose RGB888 model, so Raster will use DataBufferInt type
-                DataBufferInt dataBuffer = (DataBufferInt)dataBuf;
+            // We chose RGB888 model, so Raster will use DataBufferInt type
+            DataBufferInt dataBuffer = (DataBufferInt)dataBuf;
 
-                int imageWidth = image.getWidth();
-                int imageHeight = image.getHeight();
+            int imageWidth = image.getWidth();
+            int imageHeight = image.getHeight();
 
-                // Paint rectangle directly on buffer, line by line
-                int[] imageBuffer = dataBuffer.getData();
+            // Paint rectangle directly on buffer, line by line
+            int[] imageBuffer = dataBuffer.getData();
 
-                for (int srcLine = 0, dstLine = y; srcLine < rectHeight && dstLine < imageHeight; srcLine++, dstLine++) {
-                    try {
-                        System.arraycopy(intArray, srcLine * rectWidth, imageBuffer, x + dstLine * imageWidth, rectWidth);
-                    } catch (IndexOutOfBoundsException e) {
-                    }
+            for (int srcLine = 0, dstLine = y; srcLine < rectHeight && dstLine < imageHeight; srcLine++, dstLine++) {
+                try {
+                    System.arraycopy(intArray, srcLine * rectWidth, imageBuffer, x + dstLine * imageWidth, rectWidth);
+                } catch (IndexOutOfBoundsException e) {
                 }
-                break;
             }
+            break;
+        }
 
-            default:
-                throw new RuntimeException("Unsupported data buffer in buffered image: expected data buffer of type int (DataBufferInt). Actual data buffer type: " +
-                    dataBuf.getClass().getSimpleName());
+        default:
+            throw new RuntimeException("Unsupported data buffer in buffered image: expected data buffer of type int (DataBufferInt). Actual data buffer type: "
+                    + dataBuf.getClass().getSimpleName());
         }
 
         // Request update of repainted area
@@ -123,13 +123,11 @@ public class BufferedImagePixelsAdapter extends BaseElement {
 
         Element renderer = new BufferedImagePixelsAdapter("renderer", canvas);
 
-        byte[] pixels =
-            new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
-                12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+        byte[] pixels = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5,
+                6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
 
-        int[] pixelsLE =
-            new int[] {0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d,
-                0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d};
+        int[] pixelsLE = new int[] {0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605,
+                0x0c0b0a09, 0x100f0e0d, 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d};
 
         ByteBuffer buf = new ByteBuffer(pixels);
         buf.putMetadata(TARGET_X, 0);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
old mode 100644
new mode 100755
index b6dc4a2..688693b
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/Client.java
@@ -22,46 +22,216 @@ import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowListener;
 import java.net.InetSocketAddress;
+import java.util.Arrays;
 
 import rdpclient.RdpClient;
 import streamer.Element;
 import streamer.Pipeline;
 import streamer.PipelineImpl;
 import streamer.SocketWrapper;
+import streamer.SocketWrapperImpl;
+import streamer.apr.AprSocketWrapperImpl;
+import streamer.bco.BcoSocketWrapperImpl;
+import streamer.ssl.SSLState;
 import vncclient.VncClient;
+import common.opt.IntOption;
+import common.opt.Option;
+import common.opt.OptionParser;
+import common.opt.StringEnumerationOption;
+import common.opt.StringOption;
 
 public class Client {
 
+    enum Protocol {
+        NONE, VNC, RDP, HYPERV
+    }
+
+    // Common options
+    private Option help = new Option() {
+        {
+            name = "--help";
+            alias = "-h";
+            description = "Show this help text.";
+        }
+    };
+    private Option debugLink = new Option() {
+        {
+            name = "--debug-link";
+            alias = "-DL";
+            description = "Print debugging messages when packets are trasnferred via links.";
+        }
+    };
+    private Option debugElement = new Option() {
+        {
+            name = "--debug-element";
+            alias = "-DE";
+            description = "Print debugging messages when packets are received or sended by elements.";
+        }
+    };
+    private Option debugPipeline = new Option() {
+        {
+            name = "--debug-pipeline";
+            alias = "-DP";
+            description = "Print debugging messages in pipelines.";
+        }
+    };
+
+    private StringOption hostName = new StringOption() {
+        {
+            name = "--host";
+            alias = "-n";
+            aliases = new String[] {"--host-name"};
+            required = true;
+            description = "Name or IP address of host to connect to.";
+        }
+    };
+    private IntOption canvasWidth = new IntOption() {
+        {
+            name = "--width";
+            alias = "-W";
+            value = 1024;
+            description = "Width of canvas.";
+        }
+    };
+
+    private IntOption canvasHeight = new IntOption() {
+        {
+            name = "--height";
+            alias = "-H";
+            value = 768;
+            description = "Height of canvas.";
+        }
+    };
+
+    // Protocol specific options
+
+    private IntOption vncPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 5901;
+            description = "Port of VNC display server to connect to. Calculate as 5900 + display number, e.g. 5900 for display #0, 5901 for display #1, and so on.";
+        }
+    };
+
+    private IntOption rdpPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 3389;
+            description = "Port of RDP server to connect to.";
+        }
+    };
+
+    private IntOption hyperVPort = new IntOption() {
+        {
+            name = "--port";
+            alias = "-p";
+            value = 2179;
+            description = "Port of HyperV server to connect to.";
+        }
+    };
+
+    private StringOption password = new StringOption() {
+        {
+            name = "--password";
+            alias = "-P";
+            required = true;
+            description = "Password to use.";
+        }
+    };
+
+    private StringOption rdpPassword = new StringOption() {
+        {
+            name = "--password";
+            alias = "-P";
+            required = false;
+            description = "Password to use. If omitted, then login screen will be shown.";
+        }
+    };
+
+    private StringOption userName = new StringOption() {
+        {
+            name = "--user";
+            alias = "-U";
+            value = "Administrator";
+            description = "User name to use.";
+        }
+    };
+
+    private StringOption domain = new StringOption() {
+        {
+            name = "--domain";
+            alias = "-D";
+            value = "Workgroup";
+            description = "NTLM domain to login into.";
+        }
+    };
+
+    private StringOption hyperVInstanceId = new StringOption() {
+        {
+            name = "--instance";
+            alias = "-i";
+            required = true;
+            description = "HyperV instance ID to use.";
+        }
+    };
+    private StringEnumerationOption sslImplementation = new StringEnumerationOption() {
+        {
+            name = "--ssl-implementation";
+            alias = "-j";
+            value = "apr";
+            choices = new String[] {"jre", "apr", "bco"};
+            description = "Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation.";
+        }
+    };
+
+    private final Option[] commonOptions = new Option[] {help, debugLink, debugElement, debugPipeline, hostName, canvasWidth, canvasHeight};
+    private final Option[] vncOptions = new Option[] {vncPort, password};
+    private final Option[] rdpOptions = new Option[] {sslImplementation, rdpPort, domain, userName, rdpPassword};
+    private final Option[] hyperVOptions = new Option[] {sslImplementation, hyperVPort, hyperVInstanceId, domain, userName, password};
+
     private static Frame frame;
     private static SocketWrapper socket;
     private static ScrollPane scroller;
     private static ScreenDescription screen;
     private static BufferedImageCanvas canvas;
 
-    public static void main(String args[]) {
-        // System.setProperty("streamer.Link.debug", "true");
-        // System.setProperty("streamer.Element.debug", "true");
-        // System.setProperty("streamer.Pipeline.debug", "true");
+    private void help() {
+        System.out.println("Usage: \n  java common.Client vnc|rdp|hyperv OPTIONS\n");
+        System.out.println(Option.toHelp("Common options", commonOptions));
+        System.out.println(Option.toHelp("VNC options", vncOptions));
+        System.out.println(Option.toHelp("RDP options", rdpOptions));
+        System.out.println(Option.toHelp("HyperV options", hyperVOptions));
+    }
+
+    public void runClient(String[] args) {
 
         try {
-            if (args.length < 4) {
-                System.out.println("Usage: \n  java common.Client vnc IP PORT PASSWORD\n  java common.Client rdp IP PORT username\n");
-                System.exit(0);
-            }
 
-            String connectionType = args[0];
-            String hostname = args[1];
-            int port = Integer.parseInt(args[2]);
-            String userNameOrPassword = args[3];
+            Protocol protocol = parseOptions(args);
+            if (protocol == Protocol.NONE)
+                return;
 
-            // Create address from arguments
-            InetSocketAddress address = new InetSocketAddress(hostname, port);
+            System.setProperty("streamer.Link.debug", "" + debugLink.used);
+            System.setProperty("streamer.Element.debug", "" + debugElement.used);
+            System.setProperty("streamer.Pipeline.debug", "" + debugPipeline.used);
+
+            SSLState sslState = new SSLState();
 
             // Create socket wrapper
-            socket = new SocketWrapper("socket");
+            if ("jre".equals(sslImplementation.value)) {
+                socket = new SocketWrapperImpl("socket", sslState);
+            } else if ("apr".equals(sslImplementation.value)) {
+                socket = new AprSocketWrapperImpl("socket", sslState);
+            } else if ("bco".equals(sslImplementation.value)) {
+                socket = new BcoSocketWrapperImpl("socket", sslState);
+            } else {
+                throw new RuntimeException("Unexpected option value: \"" + sslImplementation.value + "\". " + sslImplementation.help());
+            }
 
             screen = new ScreenDescription();
-            canvas = new BufferedImageCanvas(1024, 768);
+            canvas = new BufferedImageCanvas(canvasWidth.value, canvasHeight.value);
             screen.addSizeChangeListener(new SizeChangeListener() {
                 @Override
                 public void sizeChanged(int width, int height) {
@@ -74,13 +244,24 @@ public class Client {
             });
 
             // Assemble pipeline
+            InetSocketAddress address;
             Element main;
-            if ("vnc".equals(connectionType)) {
-                main = new VncClient("client", userNameOrPassword, screen, canvas);
-            } else if ("rdp".equals(connectionType)) {
-                main = new RdpClient("client", userNameOrPassword, screen, canvas);
-            } else {
-                throw new RuntimeException("Unknown connection type. Expected value: \"vnc\" or \"rdp\", actual value: \"" + connectionType + "\".");
+            switch (protocol) {
+            case VNC:
+                address = new InetSocketAddress(hostName.value, vncPort.value);
+                main = new VncClient("client", password.value, screen, canvas);
+                break;
+            case RDP:
+                address = new InetSocketAddress(hostName.value, rdpPort.value);
+                main = new RdpClient("client", hostName.value, domain.value, userName.value, rdpPassword.value, null, screen, canvas, sslState);
+                break;
+            case HYPERV:
+                address = new InetSocketAddress(hostName.value, hyperVPort.value);
+                main = new RdpClient("client", hostName.value, domain.value, userName.value, password.value, hyperVInstanceId.value, screen, canvas, sslState);
+                break;
+            default:
+                address = null;
+                main = null;
             }
 
             Pipeline pipeline = new PipelineImpl("Client");
@@ -89,7 +270,7 @@ public class Client {
 
             pipeline.validate();
 
-            frame = createVncClientMainWindow(canvas, "VNC", new WindowAdapter() {
+            frame = createVncClientMainWindow(canvas, protocol.toString() + " " + hostName.value, new WindowAdapter() {
                 @Override
                 public void windowClosing(WindowEvent evt) {
                     shutdown();
@@ -108,6 +289,41 @@ public class Client {
         }
     }
 
+    private Protocol parseOptions(String[] args) {
+        String protocolName = (args.length > 0) ? args[0] : "";
+        Protocol protocol = Protocol.NONE;
+
+        Option[] options;
+        if (protocolName.equals("vnc")) {
+            protocol = Protocol.VNC;
+            options = join(commonOptions, vncOptions);
+        } else if (protocolName.equals("rdp")) {
+            protocol = Protocol.RDP;
+            options = join(commonOptions, rdpOptions);
+        } else if (protocolName.equals("hyperv")) {
+            protocol = Protocol.HYPERV;
+            options = join(commonOptions, hyperVOptions);
+        } else {
+            help();
+            return Protocol.NONE;
+        }
+
+        // Parse all options for given protocol
+        String[] arguments = OptionParser.parseOptions(args, 1, options);
+
+        if (arguments.length > 0) {
+            System.err.println("[Client] ERROR: Arguments are not allowed here. Check command syntax. Extra arguments: \"" + Arrays.toString(arguments) + "\".");
+            help();
+            return Protocol.NONE;
+        }
+
+        if (help.used) {
+            help();
+            return Protocol.NONE;
+        }
+        return protocol;
+    }
+
     protected static void shutdown() {
         if (frame != null) {
             frame.setVisible(false);
@@ -135,4 +351,25 @@ public class Client {
         return frame;
     }
 
+    /**
+     * Join two arrays with options and return new array.
+     */
+    private Option[] join(Option[] a1, Option[] a2) {
+        // Extend first array
+        Option[] result = Arrays.copyOf(a1, a1.length + a2.length);
+
+        // Append second array to first
+        for (int i = 0, p = a1.length; i < a2.length; i++, p++)
+            result[p] = a2[i];
+
+        return result;
+    }
+
+    public static void main(String args[]) {
+        // *DEBUG*/System.setProperty("javax.net.debug", "ssl");
+        // * DEBUG */System.setProperty("javax.net.debug", "ssl:record:packet");
+
+        new Client().runClient(args);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/CopyRectOrder.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/KeyOrder.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/MouseOrder.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/OrderType.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
old mode 100644
new mode 100755
index a9155e8..1c33a63
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/ScreenDescription.java
@@ -56,12 +56,12 @@ public class ScreenDescription {
      * Store information about server pixel format.
      */
     public void setPixelFormat(int bitsPerPixel, int depth, boolean bigEndianFlag, boolean trueColorFlag, int redMax, int greenMax, int blueMax, int redShift,
-        int greenShift, int blueShift) {
+            int greenShift, int blueShift) {
 
-        this.bytesPerPixel = (bitsPerPixel + 7) / 8;
+        bytesPerPixel = (bitsPerPixel + 7) / 8;
 
         this.bitsPerPixel = bitsPerPixel;
-        this.colorDepth = depth;
+        colorDepth = depth;
         this.bigEndianFlag = bigEndianFlag;
         this.trueColorFlag = trueColorFlag;
 
@@ -79,23 +79,23 @@ public class ScreenDescription {
     public void setPixelFormatRGBTrueColor(int bitsPerPixel) {
 
         switch (bitsPerPixel) {
-            case 8:
-                setPixelFormat(8, 8, false, false, -1, -1, -1, -1, -1, -1);
-                break;
-            case 15:
-                setPixelFormat(16, 15, false, true, 31, 31, 31, 0, 5, 10);
-                break;
-            case 16:
-                setPixelFormat(16, 16, false, true, 31, 63, 31, 0, 5, 11);
-                break;
-            case 24:
-                setPixelFormat(24, 24, false, true, 255, 255, 255, 0, 8, 16);
-                break;
-            case 32:
-                setPixelFormat(32, 24, false, true, 255, 255, 255, 0, 8, 16);
-                break;
-            default:
-                throw new RuntimeException("Unknown color depth.");
+        case 8:
+            setPixelFormat(8, 8, false, false, -1, -1, -1, -1, -1, -1);
+            break;
+        case 15:
+            setPixelFormat(16, 15, false, true, 31, 31, 31, 0, 5, 10);
+            break;
+        case 16:
+            setPixelFormat(16, 16, false, true, 31, 63, 31, 0, 5, 11);
+            break;
+        case 24:
+            setPixelFormat(24, 24, false, true, 255, 255, 255, 0, 8, 16);
+            break;
+        case 32:
+            setPixelFormat(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+            break;
+        default:
+            throw new RuntimeException("Unknown color depth.");
         }
 
     }
@@ -107,8 +107,8 @@ public class ScreenDescription {
         if (height <= 0 || width <= 0)
             throw new RuntimeException("Incorrect framebuffer size: " + width + "x" + height + ".");
 
-        this.framebufferWidth = width;
-        this.framebufferHeight = height;
+        framebufferWidth = width;
+        framebufferHeight = height;
 
         callSizeChangeListeners(width, height);
     }
@@ -145,16 +145,16 @@ public class ScreenDescription {
     }
 
     public boolean isRGB888_32_LE() {
-        return (colorDepth == 24 && bitsPerPixel == 32 && redShift == 0 && greenShift == 8 && blueShift == 16 && redMax == 255 && greenMax == 255 && blueMax == 255 &&
-            !bigEndianFlag && trueColorFlag);
+        return (colorDepth == 24 && bitsPerPixel == 32 && redShift == 0 && greenShift == 8 && blueShift == 16 && redMax == 255 && greenMax == 255 && blueMax == 255
+                && !bigEndianFlag && trueColorFlag);
     }
 
     @Override
     public String toString() {
-        return "ScreenDescription [framebufferWidth=" + framebufferWidth + ", framebufferHeight=" + framebufferHeight + ", desktopName=" + desktopName +
-            ", bytesPerPixel=" + bytesPerPixel + ", depth=" + colorDepth + ", bitsPerPixel=" + bitsPerPixel + ", redShift=" + redShift + ", greenShift=" + greenShift +
-            ", blueShift=" + blueShift + ", redMax=" + redMax + ", greenMax=" + greenMax + ", blueMax=" + blueMax + ", bigEndianFlag=" + bigEndianFlag +
-            ", trueColorFlag=" + trueColorFlag + "]";
+        return "ScreenDescription [framebufferWidth=" + framebufferWidth + ", framebufferHeight=" + framebufferHeight + ", desktopName=" + desktopName
+                + ", bytesPerPixel=" + bytesPerPixel + ", depth=" + colorDepth + ", bitsPerPixel=" + bitsPerPixel + ", redShift=" + redShift + ", greenShift=" + greenShift
+                + ", blueShift=" + blueShift + ", redMax=" + redMax + ", greenMax=" + greenMax + ", blueMax=" + blueMax + ", bigEndianFlag=" + bigEndianFlag
+                + ", trueColorFlag=" + trueColorFlag + "]";
     }
 
     public void addSizeChangeListener(SizeChangeListener sizeChangeListener) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/SizeChangeListener.java
old mode 100644
new mode 100755

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
new file mode 100755
index 0000000..c25b07f
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtBellAdapter.java
@@ -0,0 +1,77 @@
+// 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 common.adapter;
+
+import java.awt.Toolkit;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.FakeSource;
+
+public class AwtBellAdapter extends BaseElement {
+
+    public AwtBellAdapter(String id) {
+        super(id);
+        declarePads();
+    }
+
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        Toolkit.getDefaultToolkit().beep();
+    }
+
+    @Override
+    public String toString() {
+        return "Bell(" + id + ")";
+    }
+
+    /**
+     * Example.
+     */
+    public static void main(String args[]) {
+        System.setProperty("streamer.Element.debug", "true");
+
+        Element source = new FakeSource("source") {
+            {
+                incommingBufLength = 0;
+                delay = 1000;
+                numBuffers = 3;
+            }
+        };
+
+        Element sink = new AwtBellAdapter("sink");
+
+        Pipeline pipeline = new PipelineImpl("test");
+        pipeline.addAndLink(source, sink);
+        pipeline.runMainLoop("source", STDOUT, false, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
new file mode 100755
index 0000000..55ca8fd
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java
@@ -0,0 +1,171 @@
+// 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 common.adapter;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+
+import rdpclient.rdp.ServerBitmapUpdate;
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.Order;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import common.BitmapOrder;
+import common.BitmapRectangle;
+import common.BufferedImageCanvas;
+import common.CopyRectOrder;
+import common.OrderType;
+import common.ScreenDescription;
+
+public class AwtCanvasAdapter extends BaseElement {
+
+    protected ScreenDescription screen;
+
+    public AwtCanvasAdapter(String id, BufferedImageCanvas canvas, ScreenDescription screen) {
+        super(id);
+        this.canvas = canvas;
+        this.screen = screen;
+    }
+
+    protected BufferedImageCanvas canvas;
+
+    @Override
+    public String toString() {
+        return "AwtRdpAdapter(" + id + ")";
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        Order order = buf.getOrder();
+        switch ((OrderType)order.type) {
+
+        case BITMAP_UPDATE:
+            handleBitmap((BitmapOrder)order, buf);
+            break;
+
+        case COPY_RECT:
+            handleCopyRect((CopyRectOrder)order, buf);
+            break;
+
+        default:
+            throw new RuntimeException("Order is not implemented: " + buf + ".");
+            // break;
+        }
+
+        buf.unref();
+    }
+
+    private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) {
+        // TODO Auto-generated method stub
+        // Copy image
+        canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY);
+
+        // Request update of repainted area
+        canvas.repaint(order.x, order.y, order.width, order.height);
+
+    }
+
+    private void handleBitmap(BitmapOrder order, ByteBuffer buf) {
+        // Draw rectangle on offline buffer
+        BufferedImage image = canvas.getOfflineImage();
+        Graphics2D g = (Graphics2D)image.getGraphics();
+
+        for (BitmapRectangle rectangle : order.rectangles) {
+            // *DEBUG*/System.out.println("["+this+"] DEBUG: Rectangle: " +
+            // rectangle.toString());
+
+            int x = rectangle.x;
+            int y = rectangle.y;
+            int width = rectangle.width;
+            int height = rectangle.height;
+            int bufferWidth = rectangle.bufferWidth;
+            int bufferHeight = rectangle.bufferHeight;
+
+            BufferedImage rectImage;
+            switch (rectangle.colorDepth) {
+            case 8: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_BYTE_INDEXED, screen.colorMap);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toByteArray());
+                break;
+            }
+            case 15: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_555_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
+                break;
+            }
+            case 16: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_565_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
+                break;
+            }
+            case 24:
+            case 32: {
+                rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_INT_RGB);
+                WritableRaster raster = rectImage.getRaster();
+                raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toIntLEArray());
+                break;
+            }
+            default:
+                throw new RuntimeException("Unsupported color depth: " + rectangle.colorDepth + ".");
+            }
+
+            g.setClip(x, y, width, height);
+            g.drawImage(rectImage, x, y, null);
+
+            // Request update of repainted area
+            canvas.repaint(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * 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");
+        ByteBuffer packet = new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
+                0x01, 0x04, 0x0a, 0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+
+        Pipeline pipeline = new PipelineImpl("test");
+
+        Element bitmap = new ServerBitmapUpdate("bitmap");
+
+        BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
+        Element adapter = new AwtCanvasAdapter("test", canvas, null) {
+            {
+                verbose = true;
+            }
+        };
+        pipeline.addAndLink(bitmap, adapter);
+
+        bitmap.handleData(packet, null);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
new file mode 100755
index 0000000..cc7f330
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtClipboardAdapter.java
@@ -0,0 +1,57 @@
+// 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 common.adapter;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+
+import streamer.BaseElement;
+import streamer.ByteBuffer;
+import streamer.Link;
+
+public class AwtClipboardAdapter extends BaseElement {
+
+    public static final String CLIPBOARD_CONTENT = "content";
+
+    public AwtClipboardAdapter(String id) {
+        super(id);
+        declarePads();
+    }
+
+    private void declarePads() {
+        inputPads.put(STDIN, null);
+    }
+
+    @Override
+    public void handleData(ByteBuffer buf, Link link) {
+        if (verbose)
+            System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
+
+        if (buf == null)
+            return;
+
+        String content = (String)buf.getMetadata(CLIPBOARD_CONTENT);
+        StringSelection contents = new StringSelection(content);
+        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null);
+    }
+
+    @Override
+    public String toString() {
+        return "ClipboardAdapter(" + id + ")";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
new file mode 100755
index 0000000..2ef7c69
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Any.java
@@ -0,0 +1,78 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+/**
+ * Any type. Don't forget to set type.
+ */
+public class Any extends Tag {
+
+    /**
+     * Raw bytes of any value.
+     */
+    public ByteBuffer value;
+
+    public Any(String name) {
+        super(name);
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Any(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        tagType = tag.tagType;
+        value = new ByteBuffer(((Any)tag).value.toByteArray());
+        return this;
+    }
+
+    @Override
+    public boolean isTypeValid(BerType typeAndFlags, boolean explicit) {
+        if (explicit)
+            return typeAndFlags.tagClass == tagClass && typeAndFlags.constructed && typeAndFlags.typeOrTagNumber == tagNumber;
+        else
+            return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
new file mode 100755
index 0000000..6dacd60
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Constants.java
@@ -0,0 +1,83 @@
+// 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 common.asn1;
+
+public interface Asn1Constants {
+
+    /**
+     * Universal class type.
+     */
+    public static final int UNIVERSAL_CLASS = 0x00;
+
+    /**
+     * Application class type.
+     */
+    public static final int APPLICATION_CLASS = 0x40;
+
+    public static final int CONTEXT_CLASS = 0x80;
+
+    public static final int PRIVATE_CLASS = 0xC0;
+
+    /**
+     * Constructed type.
+     */
+    public static final int CONSTRUCTED = 0x20;
+
+    /**
+     * Mask to extract class.
+     */
+    public static final int CLASS_MASK = 0xC0;
+
+    /**
+     * Mask to extract type.
+     */
+    public static final int TYPE_MASK = 0x1F;
+
+    public static final int EOF = 0x00;
+    public static final int BOOLEAN = 0x01;
+    /**
+     * Integer primitive.
+     */
+    public static final int INTEGER = 0x02;
+    public static final int BIT_STRING = 0x03;
+    /**
+     * Octet string primitive.
+     */
+    public static final int OCTET_STRING = 0x04;
+    public static final int NULL = 0x05;
+    public static final int OBJECT_ID = 0x06;
+    public static final int REAL = 0x09;
+    public static final int ENUMERATED = 0x0A;
+    /**
+     * Sequence primitive.
+     */
+    public static final int SEQUENCE = 0x10;
+    public static final int SET = 0x11;
+    public static final int NUMERIC_STRING = 0x12;
+    public static final int PRINTABLE_STRING = 0x13;
+    public static final int TELETEX_STRING = 0x14;
+    public static final int VIDEOTEXT_STRING = 0x15;
+    public static final int IA5_STRING = 0x16;
+    public static final int UTCTIME = 0x17;
+    public static final int GENERAL_TIME = 0x18;
+    public static final int GRAPHIC_STRING = 0x19;
+    public static final int VISIBLE_STRING = 0x1A;
+    public static final int GENERAL_STRING = 0x1B;
+
+    public static final int EXTENDED_TYPE = 0x1F;
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
new file mode 100755
index 0000000..678e04e
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/Asn1Integer.java
@@ -0,0 +1,116 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+/**
+ * Variable length integer.
+ */
+public class Asn1Integer extends Tag {
+
+    public Long value = null;
+
+    public Asn1Integer(String name) {
+        super(name);
+        tagType = INTEGER;
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        // Type is already read by parent parser
+
+        long length = buf.readBerLength();
+        if (length > 8)
+            throw new RuntimeException("[" + this + "] ERROR: Integer value is too long: " + length + " bytes. Cannot handle integers more than 8 bytes long. Data: "
+                    + buf + ".");
+
+        value = buf.readSignedVarInt((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new Asn1Integer(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        value = ((Asn1Integer)tag).value;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "= " + value;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        if (value <= 0xff)
+            return 1;
+        if (value <= 0xffFF)
+            return 2;
+        if (value <= 0xffFFff)
+            return 3;
+        if (value <= 0xffFFffFFL)
+            return 4;
+        if (value <= 0xffFFffFFffL)
+            return 5;
+        if (value <= 0xffFFffFFffFFL)
+            return 6;
+        if (value <= 0xffFFffFFffFFffL)
+            return 7;
+
+        return 8;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        long value = this.value.longValue();
+
+        if (value < 0xff) {
+            buf.writeByte((int)value);
+        } else if (value <= 0xffFF) {
+            buf.writeShort((int)value);
+        } else if (value <= 0xffFFff) {
+            buf.writeByte((int)(value >> 16));
+            buf.writeShort((int)value);
+        } else if (value <= 0xffFFffFFL) {
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffL) {
+            buf.writeByte((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffFFL) {
+            buf.writeShort((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else if (value <= 0xffFFffFFffFFffL) {
+            buf.writeByte((int)(value >> (32 + 16)));
+            buf.writeShort((int)(value >> 32));
+            buf.writeInt((int)value);
+        } else {
+            buf.writeInt((int)(value >> 32));
+            buf.writeInt((int)value);
+        }
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.java
new file mode 100755
index 0000000..8e53f24
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BerType.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 common.asn1;
+
+public class BerType {
+
+    public int tagClass;
+    public boolean constructed;
+    public int typeOrTagNumber;
+
+    public BerType() {
+    }
+
+    public BerType(int tagClass, boolean constructed, int typeOrTagNumber) {
+        this.tagClass = tagClass;
+        this.constructed = constructed;
+        this.typeOrTagNumber = typeOrTagNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "BerType [tagClass=" + Tag.tagClassToString(tagClass) + ", constructed=" + constructed + ", type or tag number="
+                + Tag.tagTypeOrNumberToString(tagClass, typeOrTagNumber) + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/48c47101/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
new file mode 100755
index 0000000..3323c72
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/asn1/BitString.java
@@ -0,0 +1,67 @@
+// 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 common.asn1;
+
+import streamer.ByteBuffer;
+
+public class BitString extends Tag {
+
+    /**
+     * Bit string value.
+     */
+    public ByteBuffer value;
+
+    public BitString(String name) {
+        super(name);
+        tagType = BIT_STRING;
+    }
+
+    @Override
+    public boolean isValueSet() {
+        return value != null;
+    }
+
+    @Override
+    public long calculateLengthOfValuePayload() {
+        return value.length;
+    }
+
+    @Override
+    public void writeTagValuePayload(ByteBuffer buf) {
+        buf.writeBytes(value);
+    }
+
+    @Override
+    public void readTagValue(ByteBuffer buf, BerType typeAndFlags) {
+        long length = buf.readBerLength();
+
+        value = buf.readBytes((int)length);
+    }
+
+    @Override
+    public Tag deepCopy(String suffix) {
+        return new BitString(name + suffix).copyFrom(this);
+    }
+
+    @Override
+    public Tag copyFrom(Tag tag) {
+        super.copyFrom(tag);
+        value = new ByteBuffer(((BitString)tag).value.toByteArray());
+        return this;
+    }
+
+}