(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();
+ }
+
}
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
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
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
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 d489b182393..e78e3012856
--- 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 {
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 9808f62b684..998274cf1d0
--- 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.
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 45155e185fb..0c8c97df690
--- 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);
+ 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 + ".");
+ 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 + ".");
}
}
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
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 8094c82b7b3..00000000000
--- 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();
- }
-
-}
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 d50995eae72..9cccb5bf2c2
--- 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())
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
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 7a55ea81bea..e66899df8fc
--- 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);
+ 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 + ".");
+ 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;
}
};
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 d2e52ddbb27..0f6089bcf23
--- 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:
*
*
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 4e6fc0a44ca..299d0a466f7
--- 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 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 filteredStrings = new ArrayList(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;
}
});
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 23c57e0add8..910e073a058
--- 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;
}
};
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 dfffd35944d..22d436e5c67
--- 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 initElementMap(String id) {
- HashMap map = new HashMap();
-
- 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;
+ public void connect(InetSocketAddress address) throws IOException;
- // Connect socket to server
- socket = SocketFactory.getDefault().createSocket();
- try {
- socket.connect(address);
+ public void shutdown();
- InputStream is = socket.getInputStream();
- source.setInputStream(is);
+ void upgradeToSsl();
- 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();
-
- socketWrapper.connect(address);
-
- } catch (IOException e) {
- e.printStackTrace(System.err);
- }
-
- }
}
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 00000000000..da89a0d0417
--- /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 initElementMap(String id) {
+ HashMap map = new HashMap();
+
+ 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);
+ }
+
+ }
+}
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 2bd4919e5f4..94281d21c9d
--- 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;
@@ -61,11 +62,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.
*/
@@ -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;
/**
- * Operate in pull mode.
+ * Set to true to hold all data in link until it will be set to false again.
*/
- protected boolean pullMode;
+ 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 instead of default push mode. In pull mode, link will
+ * ask it source element for new data.
+ */
+ 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);
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 00000000000..edfe8dbc752
--- /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 + ")";
+ }
+
+}
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 00000000000..02983492e8d
--- /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 + ")";
+ }
+
+}
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 00000000000..2ee426b89c3
--- /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 initElementMap(String id) {
+ HashMap map = new HashMap();
+
+ 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);
+ }
+
+ }
+
+}
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 00000000000..67e2dbd019e
--- /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 + ")";
+ }
+
+}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
old mode 100644
new mode 100755
similarity index 98%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
index fe9cc50ad60..15449c315ba
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/AssertingByteBuffer.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/AssertingByteBuffer.java
@@ -14,10 +14,12 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package streamer;
+package streamer.debug;
import java.nio.charset.Charset;
+import streamer.ByteBuffer;
+
/**
* Assert that writes to this buffer are matching expected data.
*/
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 00000000000..c884cfbdfa7
--- /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);
+
+}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
old mode 100644
new mode 100755
similarity index 90%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
index e373b19a10c..93154886503
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSink.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSink.java
@@ -14,7 +14,15 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package streamer;
+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 {
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
old mode 100644
new mode 100755
similarity index 86%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
index 9056852855b..7f0c554cab0
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/FakeSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/FakeSource.java
@@ -14,7 +14,15 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package streamer;
+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 {
@@ -40,7 +48,8 @@ public class FakeSource extends BaseElement {
ByteBuffer buf = initializeData();
// Push it to output(s)
- pushDataToAllOuts(buf);
+ if (buf != null)
+ pushDataToAllOuts(buf);
// Make slight delay when blocking input was requested (to avoid
// consuming of 100% in parent loop)
@@ -85,26 +94,29 @@ public class FakeSource extends BaseElement {
return "FakeSource(" + id + ")";
}
+ /**
+ * Example.
+ */
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;
+ incommingBufLength = 3;
+ numBuffers = 10;
+ delay = 100;
}
};
Element fakeSink = new FakeSink("sink") {
{
- this.verbose = true;
+ verbose = true;
}
};
Element fakeSink2 = new FakeSink("sink2") {
{
- this.verbose = true;
+ verbose = true;
}
};
@@ -118,6 +130,7 @@ public class FakeSource extends BaseElement {
fakeSource.setLink("out2", link2, Direction.OUT);
fakeSink2.setLink(STDIN, link2, Direction.IN);
+ link.sendEvent(Event.STREAM_START, Direction.IN);
link.run();
}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
old mode 100644
new mode 100755
similarity index 57%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
index 72e4a6f182c..348a006c1aa
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/MockServer.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockServer.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package rdpclient;
+package streamer.debug;
import java.io.IOException;
import java.io.InputStream;
@@ -51,7 +51,9 @@ public class MockServer implements Runnable {
exception = null;
shutdowned = false;
- new Thread(this).start();
+ Thread thread = new Thread(this);
+ thread.setDaemon(true);
+ thread.start();
}
@Override
@@ -60,6 +62,9 @@ public class MockServer implements Runnable {
try {
Socket socket = serverSocket.accept();
+ if (verbose)
+ System.out.println("[" + this + "] INFO: Clien connected: " + socket.getRemoteSocketAddress() + ".");
+
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
@@ -68,58 +73,58 @@ public class MockServer implements Runnable {
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);
+ 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 (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 + ".");
- }
+ 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++) {
+ 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] + ".");
- }
+ 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);
+ 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) + "}.");
+ if (verbose)
+ System.out.println("[" + this + "] INFO: Data is written: {" + Arrays.toString(packet.data) + "}.");
- break;
- }
- case UPGRADE_TO_SSL: {
- // Attach SSL context to socket
+ 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();
+ 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);
+ break;
+ }
+ default:
+ throw new RuntimeException("Unknown packet type: " + packet.type);
}
}
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 00000000000..fe038a96454
--- /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 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();
+ }
+
+}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
old mode 100644
new mode 100755
similarity index 80%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
index f758bab6aff..a77f1d4a84b
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/MockSource.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/debug/MockSource.java
@@ -14,7 +14,14 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package streamer;
+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 {
@@ -64,18 +71,17 @@ public class MockSource extends FakeSource {
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;
+ 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") {
{
- this.verbose = true;
+ verbose = true;
}
};
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 00000000000..f4050887329
--- /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;
+
+}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
old mode 100644
new mode 100755
similarity index 77%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
index 088094a38e6..4d9eac27d6a
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/TrustAllX509TrustManager.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/TrustAllX509TrustManager.java
@@ -14,21 +14,33 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package rdpclient;
+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
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
old mode 100644
new mode 100755
similarity index 98%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
index 72677081859..9d7c7087492
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/UpgradeSocketToSSL.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/streamer/ssl/UpgradeSocketToSSL.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package rdpclient;
+package streamer.ssl;
import streamer.ByteBuffer;
import streamer.Direction;
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 a804e262e59..00000000000
--- 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
- }
- }
-
-}
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 c035b52fc4e..1c76656e0d9
--- 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");
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 00000000000..6b50e35eafd
--- /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
+ }
+ }
+
+}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
old mode 100644
new mode 100755
similarity index 85%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
index 8af0195c22e..59216d3f2ce
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/AwtMouseEventToVncAdapter.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/adapter/AwtVncMouseAdapter.java
@@ -14,18 +14,19 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+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 AwtMouseEventToVncAdapter extends BaseElement {
+public class AwtVncMouseAdapter extends BaseElement {
- public AwtMouseEventToVncAdapter(String id) {
+ public AwtVncMouseAdapter(String id) {
super(id);
}
@@ -62,9 +63,8 @@ public class AwtMouseEventToVncAdapter extends BaseElement {
* @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);
+ 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;
}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
old mode 100644
new mode 100755
similarity index 98%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
index 81540d66412..5dfa83101b1
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/EncodingsMessage.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/EncodingsMessage.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
import streamer.BaseElement;
import streamer.ByteBuffer;
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
old mode 100644
new mode 100755
similarity index 89%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
index 0081827bd01..ee94c60cadc
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/FrameBufferUpdateRequest.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/FrameBufferUpdateRequest.java
@@ -14,16 +14,16 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
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 streamer.debug.MockSink;
+import streamer.debug.MockSource;
import common.ScreenDescription;
public class FrameBufferUpdateRequest extends BaseElement {
@@ -95,18 +95,18 @@ public class FrameBufferUpdateRequest extends BaseElement {
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}));
+ // 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);
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
old mode 100644
new mode 100755
similarity index 96%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
index 32de903d706..2350f1483f4
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RGB888LE32PixelFormatRequest.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RGB888LE32PixelFormatRequest.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
import streamer.BaseElement;
import streamer.ByteBuffer;
@@ -80,8 +80,8 @@ public class RGB888LE32PixelFormatRequest extends BaseElement {
outBuf.writeByte(0);
outBuf.writeByte(0);
- screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax, blueMax,
- redShift, greenShift, blueShift);
+ screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag != RfbConstants.LITTLE_ENDIAN, trueColourFlag == RfbConstants.TRUE_COLOR, redMax, greenMax,
+ blueMax, redShift, greenShift, blueShift);
pushDataToAllOuts(outBuf);
}
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
old mode 100644
new mode 100755
similarity index 99%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
index 7359cd30099..a3895d401ff
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/RfbConstants.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/RfbConstants.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
import java.nio.charset.Charset;
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
old mode 100644
new mode 100755
similarity index 76%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
index de1036c62f8..6fdb3b1f69e
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Authentication.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Authentication.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
import java.security.spec.KeySpec;
@@ -25,13 +25,13 @@ 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;
+import streamer.debug.FakeSink;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
public class Vnc33Authentication extends OneTimeSwitch {
@@ -64,13 +64,13 @@ public class Vnc33Authentication extends OneTimeSwitch {
System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
switch (stage) {
- case 0: // Read security with optional challenge and response
- stage0(buf, link);
+ case 0: // Read security with optional challenge and response
+ stage0(buf, link);
- break;
- case 1: // Read authentication response
- stage1(buf, link);
- break;
+ break;
+ case 1: // Read authentication response
+ stage1(buf, link);
+ break;
}
}
@@ -91,30 +91,30 @@ public class Vnc33Authentication extends OneTimeSwitch {
int authType = buf.readSignedInt();
switch (authType) {
- case RfbConstants.CONNECTION_FAILED: {
- // Server forbids to connect. Read reason and throw exception
+ 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);
+ 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);
- }
+ 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.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;
- }
+ 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 + ".");
+ default:
+ throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + ".");
}
}
@@ -226,21 +226,21 @@ public class Vnc33Authentication extends OneTimeSwitch {
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_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_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.");
+ 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);
+ default:
+ throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult);
}
switchOff();
@@ -265,10 +265,10 @@ public class Vnc33Authentication extends OneTimeSwitch {
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});
+ // 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});
}
};
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
old mode 100644
new mode 100755
similarity index 99%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
index 63d0caa3627..812c6a83644
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/Vnc33Hello.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/Vnc33Hello.java
@@ -14,7 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
old mode 100644
new mode 100755
similarity index 77%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
index 25631c2a10d..0b96c7303e4
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncInitializer.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncInitializer.java
@@ -14,16 +14,16 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
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 streamer.debug.MockSink;
+import streamer.debug.MockSource;
import common.ScreenDescription;
public class VncInitializer extends OneTimeSwitch {
@@ -113,13 +113,13 @@ public class VncInitializer extends OneTimeSwitch {
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 + ".");
+ 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.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
@@ -167,45 +167,45 @@ public class VncInitializer extends OneTimeSwitch {
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',
+ // 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
+ 1, 2, 3
- },
- // Tail packet
- new byte[] {4, 5, 6});
+ },
+ // Tail packet
+ new byte[] {4, 5, 6});
}
};
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
old mode 100644
new mode 100755
similarity index 74%
rename from services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
rename to services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
index 6421fb220d5..5914cb30f7a
--- a/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/VncMessageHandler.java
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/vncclient/vnc/VncMessageHandler.java
@@ -14,20 +14,21 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package vncclient;
+package vncclient.vnc;
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 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;
@@ -39,7 +40,6 @@ public class VncMessageHandler extends BaseElement {
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";
@@ -88,33 +88,33 @@ public class VncMessageHandler extends BaseElement {
// Invoke packet handler by packet type.
switch (messageType) {
- case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: {
- // Handle frame buffer update
- if (!handleFBU(buf, link))
- return;
+ 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();
+ // Frame buffer update is received and fully processed, send request for
+ // another frame buffer update to server.
+ sendFBUR();
- break;
- }
+ break;
+ }
- case RfbConstants.SERVER_BELL: {
- if (!handleBell(buf, link))
- return;
- break;
- }
+ case RfbConstants.SERVER_BELL: {
+ if (!handleBell(buf, link))
+ return;
+ break;
+ }
- case RfbConstants.SERVER_CUT_TEXT: {
- if (!handleClipboard(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 + ".");
+ default:
+ // TODO: allow to extend functionality
+ throw new RuntimeException("Unknown server packet type: " + messageType + ".");
}
// Cut tail, if any
@@ -144,7 +144,7 @@ public class VncMessageHandler extends BaseElement {
// Send content in metadata
ByteBuffer outBuf = new ByteBuffer(0);
- outBuf.putMetadata(CLIPBOARD_CONTENT, content);
+ outBuf.putMetadata(AwtClipboardAdapter.CLIPBOARD_CONTENT, content);
pushDataToPad(SERVER_CLIPBOARD_ADAPTER_PAD, outBuf);
@@ -186,8 +186,8 @@ public class VncMessageHandler extends BaseElement {
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 + ".");
+ 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++) {
@@ -209,27 +209,27 @@ public class VncMessageHandler extends BaseElement {
// Process rectangle
switch (encodingType) {
- case RfbConstants.ENCODING_RAW: {
- if (!handleRawRectangle(buf, link, x, y, width, height))
- return false;
- break;
- }
+ 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_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;
- }
+ 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 + ".");
+ default:
+ // TODO: allow to extend functionality
+ throw new RuntimeException("Unsupported ecnoding: " + encodingType + ".");
}
// Update information about processed rectangles to avoid handling of same
@@ -270,8 +270,8 @@ public class VncMessageHandler extends BaseElement {
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 + ".");
+ 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));
@@ -288,8 +288,8 @@ public class VncMessageHandler extends BaseElement {
return false;
if (verbose)
- System.out.println("[" + this + "] INFO: Raw rect. X: " + x + ", y: " + y + ", width: " + width + ", height: " + height + ", data length: " + rectDataLength +
- ".");
+ 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;
@@ -337,8 +337,7 @@ public class VncMessageHandler extends BaseElement {
Element source = new MockSource("source") {
{
// Split messages at random boundaries to check "pushback" logic
- bufs =
- ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
+ bufs = ByteBuffer.convertByteArraysToByteBuffers(new byte[] {
// Message type: server bell
RfbConstants.SERVER_BELL,
@@ -349,7 +348,7 @@ public class VncMessageHandler extends BaseElement {
// Length (test)
0, 0, 0, 4,
- }, new byte[] {
+ }, new byte[] {
// Clipboard text
't', 'e', 's', 't',
@@ -362,35 +361,35 @@ public class VncMessageHandler extends BaseElement {
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),},
+ // 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@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,});
+ // 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;
+ bytesPerPixel = 1;
}
};
@@ -401,7 +400,8 @@ public class VncMessageHandler extends BaseElement {
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 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");
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 00000000000..41376095acf
--- /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;
+};
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 dd4168373b1..704f5f52f16
--- 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.
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 14a7bbd0f0a..4e19157e5d5
--- 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.
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 00000000000..d3101d698ed
--- /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.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.<..
+
+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.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
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 00000000000..311ca43b71a
Binary files /dev/null and b/services/console-proxy-rdp/rdpconsole/src/test/doc/rdp.pfx differ
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 283beac3456..a40cdb8ed79
--- 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 {