You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2013/12/23 10:13:08 UTC
[14/22] CLOUDSTACK-5344: Update to allow rdp console to access
hyper-v vm virtual framebuffer.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
new file mode 100755
index 0000000..639ca50
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/hyperv/ClientPreConnectionBlob.java
@@ -0,0 +1,121 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.hyperv;
+
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * For HyperV server, client must send VM ID before any other packet.
+ */
+public class ClientPreConnectionBlob extends OneTimeSwitch {
+
+ protected String data;
+
+ public ClientPreConnectionBlob(String id, String data) {
+ super(id);
+ this.data = data;
+ }
+
+ @Override
+ protected void handleOneTimeData(ByteBuffer buf, Link link) {
+ if (buf == null)
+ return;
+
+ throw new RuntimeException("This element only sends data. This method must not be called. Unexpected packet: " + buf + ".");
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ sendPreConnectionBlobData(data);
+ }
+
+ protected void sendPreConnectionBlobData(String data) {
+ // Length of packet
+ ByteBuffer buf = new ByteBuffer(1024, true);
+
+ // Header
+ buf.writeBytes(new byte[] {(byte)0x5e, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,});
+
+ // Length of string in wide characters + two wide \0 (LE)
+ buf.writeShortLE(data.length() + 2);
+
+ // Wide string + two wide '\0' characters
+ buf.writeString(data + "\0\0", RdpConstants.CHARSET_16);
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+
+ pushDataToOTOut(buf);
+
+ switchOff();
+ }
+
+ /**
+ * Example.
+ */
+ public static void main(String[] args) {
+ // System.setProperty("streamer.Link.debug", "true");
+ System.setProperty("streamer.Element.debug", "true");
+ // System.setProperty("streamer.Pipeline.debug", "true");
+
+ /* @formatter:off */
+ byte[] packet = new byte[] {
+ // Header
+ (byte) 0x5e, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+ // Length of string in wide characters + two wide \0 (LE)
+ (byte) 0x26, (byte) 0x00,
+
+ // Wide string
+ (byte) 0x33, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x46,
+ (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+ (byte) 0x30, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x34, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x38,
+ (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x42, (byte) 0x00, (byte) 0x37, (byte) 0x00, (byte) 0x39, (byte) 0x00,
+ (byte) 0x36, (byte) 0x00, (byte) 0x2d, (byte) 0x00, (byte) 0x39, (byte) 0x00, (byte) 0x31, (byte) 0x00, (byte) 0x43, (byte) 0x00, (byte) 0x36,
+ (byte) 0x00, (byte) 0x30, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x36, (byte) 0x00, (byte) 0x36, (byte) 0x00,
+ (byte) 0x35, (byte) 0x00, (byte) 0x33, (byte) 0x00, (byte) 0x41, (byte) 0x00,
+
+ // Two wide \0
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ };
+ /* @formatter:on */
+
+ MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+ Element pcb = new ClientPreConnectionBlob("pcb", "39418F90-6D03-468E-B796-91C60DD6653A");
+ Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+ Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+ Pipeline pipeline = new PipelineImpl("test");
+ pipeline.add(source, pcb, sink, mainSink);
+ pipeline.link("source", "pcb", "mainSink");
+ pipeline.link("pcb >" + OTOUT, "sink");
+ pipeline.runMainLoop("source", STDOUT, false, false);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
new file mode 100755
index 0000000..d32c8ca
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspNegotiate.java
@@ -0,0 +1,178 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import common.asn1.Tag;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236641.aspx
+ */
+public class ClientNtlmsspNegotiate extends OneTimeSwitch {
+
+ /**
+ * The set of client configuration flags (section 2.2.2.5) that specify the
+ * full set of capabilities of the client.
+ */
+ public NegoFlags clientConfigFlags = new NegoFlags().set_NEGOTIATE_56().set_NEGOTIATE_KEY_EXCH().set_NEGOTIATE_128().set_NEGOTIATE_VERSION()
+ .set_NEGOTIATE_EXTENDED_SESSION_SECURITY().set_NEGOTIATE_ALWAYS_SIGN().set_NEGOTIATE_NTLM().set_NEGOTIATE_LM_KEY().set_NEGOTIATE_SEAL()
+ .set_NEGOTIATE_SIGN().set_REQUEST_TARGET().set_NEGOTIATE_OEM().set_NEGOTIATE_UNICODE();
+
+ protected NtlmState ntlmState;
+
+ public ClientNtlmsspNegotiate(String id, NtlmState state) {
+ super(id);
+ this.ntlmState = state;
+ }
+
+ @Override
+ protected void handleOneTimeData(ByteBuffer buf, Link link) {
+ if (buf == null)
+ return;
+
+ throw new RuntimeException("Unexpected packet: " + buf + ".");
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ ByteBuffer negoToken = generateNegotiateMessage();
+ ntlmState.negotiateMessage = negoToken.toByteArray(); // Store message for MIC calculation in AUTH message
+
+ // Length of packet
+ ByteBuffer buf = new ByteBuffer(1024, true);
+
+ TSRequest tsRequest = new TSRequest("TSRequest");
+ tsRequest.version.value = 2L;
+ NegoItem negoItem = new NegoItem("NegoItem");
+ negoItem.negoToken.value = negoToken;
+ tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+ tsRequest.writeTag(buf);
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+
+ pushDataToOTOut(buf);
+
+ switchOff();
+ }
+
+ private ByteBuffer generateNegotiateMessage() {
+ ByteBuffer buf = new ByteBuffer(1024);
+
+ // Signature
+ buf.writeString("NTLMSSP", RdpConstants.CHARSET_8);
+ buf.writeByte(0);
+
+ // Message type
+ buf.writeIntLE(NtlmConstants.NEGOTIATE);
+
+ buf.writeIntLE(clientConfigFlags.value); // Flags
+
+ // If the NTLMSSP_NEGOTIATE_VERSION flag is set by the client application,
+ // the Version field MUST be set to the current version (section 2.2.2.10),
+ // the DomainName field MUST be set to a zero-length string, and the
+ // Workstation field MUST be set to a zero-length string.
+
+ // Domain: ""
+ buf.writeShortLE(0); // Length
+ buf.writeShortLE(0); // Allocated space
+ buf.writeIntLE(0); // Offset
+
+ // Workstation: ""
+ buf.writeShortLE(0); // Length
+ buf.writeShortLE(0); // Allocated space
+ buf.writeIntLE(0); // Offset
+
+ // OS Version: 6.1 (Build 7601); NTLM Current Revision 15
+ buf.writeBytes(new byte[] {(byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f});
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+
+ return buf;
+ }
+
+ /**
+ * Example.
+ */
+ public static void main(String args[]) {
+ // System.setProperty("streamer.Link.debug", "true");
+ System.setProperty("streamer.Element.debug", "true");
+ // System.setProperty("streamer.Pipeline.debug", "true");
+
+ /* @formatter:off */
+ byte[] packet = new byte[] {
+ // CredSSP BER header:
+
+ (byte)0x30, // Sequence
+ (byte)0x37, // Length, 55 bytes
+
+ (byte)0xa0, (byte)0x03, // TAG: [0] (constructed) LEN: 3 byte
+ (byte)0x02, (byte)0x01, (byte)0x02, // Version: (int, 1 byte, 0x02)
+
+ // Sequence of sequence
+ (byte)0xa1, (byte)0x30, // TAG: [1] (constructed) LEN: 48 bytes
+ (byte)0x30, (byte)0x2e, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 46 bytes
+ (byte)0x30, (byte)0x2c, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 44 bytes
+ (byte)0xa0, (byte)0x2a, // TAG: [0] (constructed) LEN: 42 bytes
+
+
+ (byte)0x04, (byte)0x28, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 40 bytes
+
+ // NTLM negotiate request
+
+ (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, // "NTLMSSP\0"
+
+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, // Message type: NEGOTIATE (0x1, LE)
+
+ (byte)0xb7, (byte)0x82, (byte)0x08, (byte)0xe2, // Flags: 0xe20882b7 (LE)
+
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Domain (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Workstation (security buffer, 8bit, 8 bytes): length: 0x0000 (LE), allocated space: 0x0000 (LE), offset: 0x00000000 (LE)
+ (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f, // OS Version: 6.1 (Build 7601); NTLM Current Revision 15, 8 bytes
+
+ };
+ /* @formatter:on */
+
+ NtlmState state = new NtlmState();
+
+ MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+ Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", state);
+ Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet));
+ Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+ Pipeline pipeline = new PipelineImpl("test");
+ pipeline.add(source, ntlmssp_negotiate, sink, mainSink);
+ pipeline.link("source", "ntlmssp_negotiate", "mainSink");
+ pipeline.link("ntlmssp_negotiate >" + OTOUT, "sink");
+ pipeline.runMainLoop("source", STDOUT, false, false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
new file mode 100755
index 0000000..3d9e0c5
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspPubKeyAuth.java
@@ -0,0 +1,681 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import java.nio.charset.Charset;
+
+import rdpclient.ntlmssp.asn1.NegoItem;
+import rdpclient.ntlmssp.asn1.SubjectPublicKeyInfo;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+import streamer.Pipeline;
+import streamer.PipelineImpl;
+import streamer.debug.Dumper;
+import streamer.debug.MockSink;
+import streamer.debug.MockSource;
+import streamer.ssl.SSLState;
+
+import common.asn1.Tag;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236643.aspx
+ */
+public class ClientNtlmsspPubKeyAuth extends OneTimeSwitch implements NtlmConstants, Dumper {
+
+ /**
+ * Offset of first byte of allocated block after NTLMSSP header and block
+ * descriptors.
+ */
+ private static final int BLOCKS_OFFSET = 88;
+
+ protected NtlmState ntlmState;
+ protected SSLState sslState;
+
+ protected String targetDomain;
+ protected String user;
+ protected String password;
+ protected String workstation;
+ protected String serverHostName;
+
+ public ClientNtlmsspPubKeyAuth(String id, NtlmState ntlmState, SSLState sslState, String serverHostName, String targetDomain, String workstation,
+ String user, String password) {
+ super(id);
+ this.ntlmState = ntlmState;
+ this.sslState = sslState;
+ this.serverHostName = serverHostName;
+ this.targetDomain = targetDomain;
+ this.workstation = workstation;
+ this.user = user;
+ this.password = password;
+ }
+
+ @Override
+ protected void handleOneTimeData(ByteBuffer buf, Link link) {
+ if (buf == null)
+ return;
+
+ throw new RuntimeException("Unexpected packet: " + buf + ".");
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ /*
+ * @see
+ * http://blogs.msdn.com/b/openspecification/archive/2010/04/20/ntlm-keys
+ * -and-sundry-stuff.aspx
+ */
+ ntlmState.domain = this.targetDomain;
+ ntlmState.user = this.user;
+ ntlmState.password = this.password;
+ ntlmState.workstation = this.workstation;
+ ntlmState.generateServicePrincipalName(serverHostName);
+ ntlmState.ntlm_construct_authenticate_target_info();
+ ntlmState.ntlm_generate_timestamp();
+ ntlmState.ntlm_generate_client_challenge();
+ ntlmState.ntlm_compute_lm_v2_response();
+ ntlmState.ntlm_compute_ntlm_v2_response();
+ ntlmState.ntlm_generate_key_exchange_key();
+ ntlmState.ntlm_generate_random_session_key();
+ ntlmState.ntlm_generate_exported_session_key();
+ ntlmState.ntlm_encrypt_random_session_key();
+ ntlmState.ntlm_init_rc4_seal_states();
+
+ ByteBuffer authenticateMessage = generateAuthenticateMessage(ntlmState);
+ ByteBuffer messageSignatureAndEncryptedServerPublicKey = generateMessageSignatureAndEncryptedServerPublicKey(ntlmState);
+
+ // Length of packet
+ ByteBuffer buf = new ByteBuffer(4096, true);
+
+ TSRequest tsRequest = new TSRequest("TSRequest");
+ tsRequest.version.value = 2L;
+ NegoItem negoItem = new NegoItem("NegoItem");
+ negoItem.negoToken.value = authenticateMessage;
+
+ tsRequest.negoTokens.tags = new Tag[] {negoItem};
+
+ tsRequest.pubKeyAuth.value = messageSignatureAndEncryptedServerPublicKey;
+
+ tsRequest.writeTag(buf);
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+
+ pushDataToOTOut(buf);
+
+ switchOff();
+ }
+
+ private byte[] getServerPublicKey() {
+ // SSL certificate public key with algorithm
+ ByteBuffer subjectPublicKeyInfo = new ByteBuffer(sslState.serverCertificateSubjectPublicKeyInfo);
+
+ // Parse subjectPublicKeyInfo
+ SubjectPublicKeyInfo parser = new SubjectPublicKeyInfo("SubjectPublicKeyInfo");
+ parser.readTag(subjectPublicKeyInfo);
+
+ // Copy subjectPublicKey subfield to separate byte buffer
+ ByteBuffer subjectPublicKey = new ByteBuffer(subjectPublicKeyInfo.length);
+ parser.subjectPublicKey.writeTag(subjectPublicKey);
+
+ subjectPublicKeyInfo.unref();
+ subjectPublicKey.trimAtCursor();
+
+ // Skip tag:
+ // 03 82 01 0f (tag) 00 (padding byte)
+ subjectPublicKey.trimHeader(5);// FIXME: parse it properly
+ // * DEBUG */System.out.println("DEBUG: subjectPublicKey:\n" +
+ // subjectPublicKey.dump());
+
+ ntlmState.subjectPublicKey = subjectPublicKey.toByteArray();
+
+ return ntlmState.subjectPublicKey;
+ }
+
+ /**
+ * The client encrypts the public key it received from the server (contained
+ * in the X.509 certificate) in the TLS handshake from step 1, by using the
+ * confidentiality support of SPNEGO.
+ *
+ * The public key that is encrypted is the ASN.1-encoded SubjectPublicKey
+ * sub-field of SubjectPublicKeyInfo from the X.509 certificate, as specified
+ * in [RFC3280] section 4.1. The encrypted key is encapsulated in the
+ * pubKeyAuth field of the TSRequest structure and is sent over the TLS
+ * channel to the server.
+ */
+ private ByteBuffer generateMessageSignatureAndEncryptedServerPublicKey(NtlmState ntlmState) {
+ return new ByteBuffer(ntlmState.ntlm_EncryptMessage(getServerPublicKey()));
+ }
+
+ public static ByteBuffer generateAuthenticateMessage(NtlmState ntlmState) {
+
+ // Allocate memory for blocks from given fixed offset
+ int blocksCursor = BLOCKS_OFFSET;
+
+ ByteBuffer buf = new ByteBuffer(4096);
+
+ // Signature: "NTLMSSP\0"
+ buf.writeString(NTLMSSP, RdpConstants.CHARSET_8);
+ buf.writeByte(0);
+
+ // NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+ buf.writeIntLE(NtlmConstants.NTLMSSP_AUTH);
+
+ // Although the protocol allows authentication to succeed if the client
+ // provides either LmChallengeResponse or NtChallengeResponse, Windows
+ // implementations provide both.
+
+ // LM V2 response
+ blocksCursor = writeBlock(buf, ntlmState.lmChallengeResponse, blocksCursor);
+
+ // NT v2 response
+ blocksCursor = writeBlock(buf, ntlmState.ntChallengeResponse, blocksCursor);
+
+ // DomainName
+ blocksCursor = writeStringBlock(buf, ntlmState.domain, blocksCursor, RdpConstants.CHARSET_16);
+
+ // UserName
+ blocksCursor = writeStringBlock(buf, ntlmState.user, blocksCursor, RdpConstants.CHARSET_16);
+
+ // Workstation
+ blocksCursor = writeStringBlock(buf, ntlmState.workstation, blocksCursor, RdpConstants.CHARSET_16);
+
+ // EncryptedRandomSessionKey, 16 bytes
+ blocksCursor = writeBlock(buf, ntlmState.encryptedRandomSessionKey, blocksCursor);
+
+ // NegotiateFlags (4 bytes): In connection-oriented mode, a NEGOTIATE
+ // structure that contains the set of bit flags (section 2.2.2.5) negotiated
+ // in the previous messages.
+ buf.writeIntLE(/*ntlmState.negotiatedFlags.value*/0xe288b235); // FIXME: remove hardcoded value
+
+ buf.writeBytes(generateVersion());
+
+ // If the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an
+ // MsvAvTimestamp present, the client SHOULD provide a MIC(Message Integrity
+ // Check)
+
+ int savedCursorForMIC = buf.cursor; // Save cursor position to write MIC
+ // later
+ buf.writeBytes(new byte[16]); // Write 16 zeroes
+
+ if (BLOCKS_OFFSET != buf.cursor)
+ throw new RuntimeException("BUG: Actual offset of first byte of allocated blocks is not equal hardcoded offset. Hardcoded offset: " + BLOCKS_OFFSET
+ + ", actual offset: " + buf.cursor + ". Update hardcoded offset to match actual offset.");
+
+ buf.cursor = blocksCursor;
+ buf.trimAtCursor();
+
+ ntlmState.authenticateMessage = buf.toByteArray();
+
+ // Calculate and write MIC to reserved position
+ ntlmState.ntlm_compute_message_integrity_check();
+ buf.cursor = savedCursorForMIC;
+ buf.writeBytes(ntlmState.messageIntegrityCheck);
+ buf.rewindCursor();
+
+ return buf;
+ }
+
+ /**
+ * Write string as security buffer, using given charset, without trailing '\0'
+ * character.
+ */
+ private static int writeStringBlock(ByteBuffer buf, String string, int blocksCursor, Charset charset) {
+ return writeBlock(buf, string.getBytes(charset), blocksCursor);
+ }
+
+ /**
+ * Write block to blocks buffer and block descriptor to main buffer.
+ */
+ private static int writeBlock(ByteBuffer buf, byte[] block, int blocksCursor) {
+
+ // Write block descriptor
+
+ // Length
+ buf.writeShortLE(block.length);
+ // Allocated
+ buf.writeShortLE(block.length);
+ // Offset
+ buf.writeIntLE(blocksCursor);
+
+ // Write block to position pointed by blocksCursor instead of buf.cursor
+ int savedCursor = buf.cursor;
+ buf.cursor = blocksCursor;
+ buf.writeBytes(block);
+ blocksCursor = buf.cursor;
+ buf.cursor = savedCursor;
+
+ return blocksCursor;
+ }
+
+ /**
+ * Version (8 bytes): A VERSION structure (section 2.2.2.10) that is present
+ * only when the NTLMSSP_NEGOTIATE_VERSION flag is set in the NegotiateFlags
+ * field. This structure is used for debugging purposes only. In normal
+ * protocol messages, it is ignored and does not affect the NTLM message
+ * processing.
+ */
+ private static byte[] generateVersion() {
+ // Version (6.1, Build 7601), NTLM current revision: 15
+ return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+ }
+
+ /**
+ * Example.
+ */
+ public static void main(String args[]) {
+ System.setProperty("streamer.Element.debug", "true");
+
+ /* @formatter:off */
+ //
+ // Client NEGOTIATE
+ //
+ byte[] clientNegotiatePacket = new byte[] {
+ (byte)0x30, (byte)0x37, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x30, (byte)0x30, (byte)0x2e, (byte)0x30, (byte)0x2c, (byte)0xa0, (byte)0x2a, (byte)0x04,
+ (byte)0x28, (byte)0x4e, (byte)0x54, (byte)0x4c, (byte)0x4d, (byte)0x53, (byte)0x53, (byte)0x50, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xb7, (byte)0x82, (byte)0x08,
+ (byte)0xe2, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x06, (byte)0x01, (byte)0xb1, (byte)0x1d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0f,
+ };
+
+//
+// Server CHALLENGE
+//
+ byte[] serverChallengePacket = new byte[] {
+ 0x30, (byte) 0x82, 0x01, 0x02, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 258 bytes
+
+ (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+ 0x02, 0x01, 0x03, // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes, Version: 0x3
+ (byte) 0xa1, (byte) 0x81, (byte) 0xfa, // TAG: [1] (constructed) LEN: 250 bytes
+ 0x30, (byte) 0x81, (byte) 0xf7, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 247 bytes
+ 0x30, (byte) 0x81, (byte) 0xf4, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 244 bytes
+ (byte) 0xa0, (byte) 0x81, (byte) 0xf1, // TAG: [0] (constructed) LEN: 241 bytes
+ 0x04, (byte) 0x81, (byte) 0xee, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 238 bytes
+
+ 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+ 0x02, 0x00, 0x00, 0x00, // MessageType (CHALLENGE)
+
+ 0x1e, 0x00, 0x1e, 0x00, 0x38, 0x00, 0x00, 0x00, // TargetName (length: 30, allocated space: 30, offset: 56)
+ 0x35, (byte) 0x82, (byte) 0x8a, (byte) 0xe2, // NegotiateFlags: NEGOTIATE_56 NEGOTIATE_KEY_EXCH NEGOTIATE_128 NEGOTIATE_VERSION NEGOTIATE_TARGET_INFO NEGOTIATE_EXTENDED_SESSION_SECURITY TARGET_TYPE_SERVER NEGOTIATE_ALWAYS_SIGN NEGOTIATE_NTLM NEGOTIATE_SEAL NEGOTIATE_SIGN REQUEST_TARGET NEGOTIATE_UNICODE
+
+ (byte)0xc1, (byte)0x4a, (byte)0xc8, (byte)0x98, (byte)0x2f, (byte)0xd1, (byte)0x93, (byte)0xd4, // ServerChallenge
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
+ (byte) 0x98, 0x00, (byte) 0x98, 0x00, 0x56, 0x00, 0x00, 0x00, // TargetInfo (length: 152, allocated space: 152, offset: 86)
+ 0x06, 0x03, (byte) 0xd7, 0x24, 0x00, 0x00, 0x00, 0x0f, // Version (6.3, build 9431) , NTLM current revision: 15
+
+
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // Target name value: "WIN-LO419B2LSR0"
+
+ // Target Info value:
+
+ // Attribute list
+
+ 0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+ 0x01, 0x00, // Item Type: NetBIOS computer name (0x0001, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+ 0x04, 0x00, // Item Type: DNS domain name (0x0004, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+ 0x03, 0x00, // Item Type: DNS computer name (0x0003, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0"
+
+ 0x07, 0x00, // Item Type: Timestamp (0x0007, LE)
+ 0x08, 0x00, // Item Length: 8 (LE)
+ (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+
+ // Attribute: End of list
+ 0x00, 0x00,
+ 0x00, 0x00,
+
+ };
+
+//
+// Client NTLMSSP_AUTH
+//
+ byte[] clientAuthPacket = new byte[] {
+ 0x30, (byte) 0x82, 0x03, 0x13, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 787 bytes
+
+ //
+ // TSRequest.version
+ //
+ (byte) 0xa0, 0x03, // TAG: [0] (constructed) LEN: 3 bytes
+ 0x02, 0x01, 0x02, // TAG: [UNIVERSAL 2] (primitive) "INTEGER" LEN: 1 bytes
+
+ //
+ // TSRequest.negoData
+ //
+ (byte) 0xa1, (byte) 0x82, 0x01, (byte) 0xe4, // TAG: [1] (constructed) LEN: 484 bytes
+ 0x30, (byte) 0x82, 0x01, (byte) 0xe0, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 480 bytes
+ 0x30, (byte) 0x82, 0x01, (byte) 0xdc, // TAG: [UNIVERSAL 16] (constructed) "SEQUENCE" LEN: 476 bytes
+
+ //
+ // NegoItem.negoToken
+ //
+ (byte) 0xa0, (byte) 0x82, 0x01, (byte) 0xd8, // TAG: [0] (constructed) LEN: 472 bytes
+ 0x04, (byte) 0x82, 0x01, (byte) 0xd4, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 468 bytes
+
+ // NTLMSSP
+
+ 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, // "NTLMSSP\0"
+
+ 0x03, 0x00, 0x00, 0x00, // NTLM Message Type: NTLMSSP_AUTH (0x00000003)
+ 0x18, 0x00, 0x18, 0x00, (byte) 0x92, 0x00, 0x00, 0x00, // LmChallengeResponse (length 24, allocated: 24, offset 146)
+ 0x1a, 0x01, 0x1a, 0x01, (byte) 0xaa, 0x00, 0x00, 0x00, // NtChallengeResponse (length 282, allocated: 282, offset 170)
+ 0x12, 0x00, 0x12, 0x00, 0x58, 0x00, 0x00, 0x00, // DomainName (length 18, allocated: 88, offset 88)
+ 0x1a, 0x00, 0x1a, 0x00, 0x6a, 0x00, 0x00, 0x00, // UserName (length 26, allocated:26, offset 106)
+ 0x0e, 0x00, 0x0e, 0x00, (byte) 0x84, 0x00, 0x00, 0x00, // Workstation (length 14, offset 132)
+ 0x10, 0x00, 0x10, 0x00, (byte) 0xc4, 0x01, 0x00, 0x00, // EncryptedRandomSessionKey (length 16, offset 452)
+ 0x35, (byte) 0xb2, (byte) 0x88, (byte) 0xe2, // NegotiateFlags
+ 0x06, 0x01, (byte) 0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f, // Version (6.1, Build 7601), NTLM current revision: 15
+
+ (byte)0x8c, (byte)0x69, (byte)0x53, (byte)0x1c, (byte)0xbb, (byte)0x6f, (byte)0xfb, (byte)0x9a, (byte)0x5d, (byte)0x2c, (byte)0x63, (byte)0xf2, (byte)0xc9, (byte)0x51, (byte)0xc5, (byte)0x11, // Message integrity check
+
+ 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x67, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x70, 0x00, // Domain name value: "Workgroup"
+
+ 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, // User name value: "Administrator"
+
+ 0x61, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x33, 0x00, // Workstation host name value: "apollo3"
+
+ // Lan manager challenge response value
+ // Response: HMAC_MD(ResponseKeyLM, concatenate(ServerChallenge, ClientChallenge), where ResponseKeyLM=ntlmv2Hash(target, user, password)
+ (byte)0x17, (byte)0x9b, (byte)0x7d, (byte)0x7b, (byte)0x2f, (byte)0x79, (byte)0x9f, (byte)0x19, (byte)0xa0, (byte)0x4b, (byte)0x00, (byte)0xed, (byte)0x2b, (byte)0x39, (byte)0xbb, (byte)0x23,
+ // Client challenge (fixed for debugging)
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+
+ //
+ // NTLM challenge response value:
+ //
+
+ (byte)0x49, (byte)0xea, (byte)0x27, (byte)0x4f, (byte)0xcc, (byte)0x05, (byte)0x8b, (byte)0x79, (byte)0x20, (byte)0x0b, (byte)0x08, (byte)0x42, (byte)0xa9, (byte)0xc8, (byte)0x0e, (byte)0xc7, // HMAC
+
+ 0x01, 0x01, 0x00, 0x00, // Header: 0x00000101 (LE)
+ 0x00, 0x00, 0x00, 0x00, // Reserved: 0x00000000
+ (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Time: Oct 10, 2013 23:36:20.056937300 EEST
+ (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08, // Client challenge (fixed)
+ 0x00, 0x00, 0x00, 0x00, // Reserved
+
+ // Target Info value:
+
+ // Attribute list
+
+ 0x02, 0x00, // Item Type: NetBIOS domain name (0x0002, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0 "
+
+ 0x01, 0x00, // Item Type: NetBIOS computer name (0x0001, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0 "
+
+ 0x04, 0x00, // Item Type: DNS domain name (0x0004, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0 "
+
+ 0x03, 0x00, // Item Type: DNS computer name (0x0003, LE)
+ 0x1e, 0x00, // Item Length: 30 (LE)
+ 0x57, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x34, 0x00, 0x31, 0x00, 0x39, 0x00, 0x42, 0x00, 0x32, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x52, 0x00, 0x30, 0x00, // "WIN-LO419B2LSR0 "
+
+ 0x07, 0x00, // Item Type: Timestamp (0x0007, LE)
+ 0x08, 0x00, // Item Length: 8 (LE)
+ (byte)0x1d, (byte)0xea, (byte)0x6b, (byte)0x60, (byte)0xf8, (byte)0xc5, (byte)0xce, (byte)0x01, // Timestamp: Oct 10, 2013 23:36:20.056937300 EEST
+
+ 0x06, 0x00, // Item Type: Flags (0x0006, LE)
+ 0x04, 0x00, // Item Length: 4 (LE)
+ 0x02, 0x00, 0x00, 0x00, // Flags: 0x00000002
+
+ 0x0a, 0x00, // Item Type: Channel Bindings (0x000a, LE)
+ 0x10, 0x00, // Item Length: 16 (LE)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Channel Bindings: 00000000000000000000000000000000
+
+ 0x09, 0x00, // Item Type: Target Name (0x0009, LE)
+ 0x2a, 0x00, // Item Length: 42 (LE)
+ 0x54, 0x00, 0x45, 0x00, 0x52, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x52, 0x00, 0x56, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x30, 0x00, 0x31, 0x00, // Target Name: "TERMSRV/192.168.0.101" (UTF-16)
+
+ // Attribute: End of list
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ // Attribute: End of list
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ // Attribute: End of list
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+ // Attribute: End of list
+ 0x00, 0x00, //
+ 0x00, 0x00, //
+
+ // Session Key
+ // RC4 key (Server KeyExchangeKey or SessionBaseKey):
+ // 6e bd e3 da 83 c2 fd f1 38 a2 78 be 8c e6 75 d6
+ //
+ // RC4 data (Client nonce):
+ // 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
+ //
+ // RC4 encrypted:
+ // 2c 24 da 10 17 cf 40 69 35 49 6f 58 e1 29 9e 79
+ (byte)0x2c, (byte)0x24, (byte)0xda, (byte)0x10, (byte)0x17, (byte)0xcf, (byte)0x40, (byte)0x69, (byte)0x35, (byte)0x49, (byte)0x6f, (byte)0x58, (byte)0xe1, (byte)0x29, (byte)0x9e, (byte)0x79,
+
+ //
+ // TSRequest.publicKey
+ //
+ (byte) 0xa3, (byte) 0x82, 0x01, 0x22, // TAG: [3] (constructed) LEN: 290 bytes
+ 0x04, (byte) 0x82, 0x01, 0x1e, // TAG: [UNIVERSAL 4] (primitive) "OCTET STRING" LEN: 286 bytes
+
+ // NTLMSSP_MESSAGE_SIGNATURE, @see http://msdn.microsoft.com/en-us/library/cc422952.aspx
+
+ // Version: 0x00000001
+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // Checksum (8 bytes): An 8-byte array that contains the checksum for the message.
+ (byte)0x72, (byte)0x76, (byte)0x1e, (byte)0x57, (byte)0x49, (byte)0xb5, (byte)0x0f, (byte)0xad,
+
+ // seqNum of the message: 0
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // Encrypted public key
+ (byte)0x15, (byte)0xf7, (byte)0xf2, (byte)0x54, (byte)0xda, (byte)0xa9, (byte)0xe5, (byte)0xad, (byte)0x85, (byte)0x04, (byte)0x67, (byte)0x4d, (byte)0x0b, (byte)0xcb, (byte)0xf9, (byte)0xb1,
+ (byte)0xf8, (byte)0x02, (byte)0x8a, (byte)0x77, (byte)0xc2, (byte)0x63, (byte)0xab, (byte)0xd5, (byte)0x74, (byte)0x23, (byte)0x9f, (byte)0x9d, (byte)0x5d, (byte)0x1f, (byte)0xd3, (byte)0xb3,
+ (byte)0xa0, (byte)0xac, (byte)0x16, (byte)0x8a, (byte)0x4b, (byte)0x08, (byte)0xf5, (byte)0x47, (byte)0x70, (byte)0x58, (byte)0x10, (byte)0xb4, (byte)0xe7, (byte)0x87, (byte)0xb3, (byte)0x4b,
+ (byte)0xc9, (byte)0xa2, (byte)0xd5, (byte)0xd1, (byte)0xca, (byte)0x0f, (byte)0xd4, (byte)0xe3, (byte)0x8d, (byte)0x76, (byte)0x5a, (byte)0x60, (byte)0x28, (byte)0xf8, (byte)0x06, (byte)0x5d,
+ (byte)0xe4, (byte)0x7e, (byte)0x21, (byte)0xc8, (byte)0xbb, (byte)0xac, (byte)0xe5, (byte)0x79, (byte)0x85, (byte)0x30, (byte)0x9b, (byte)0x88, (byte)0x13, (byte)0x2f, (byte)0x8f, (byte)0xfc,
+ (byte)0x04, (byte)0x52, (byte)0xfe, (byte)0x87, (byte)0x94, (byte)0xcf, (byte)0xcb, (byte)0x49, (byte)0x4a, (byte)0xda, (byte)0x6f, (byte)0xdd, (byte)0xee, (byte)0x57, (byte)0xa5, (byte)0xe4,
+ (byte)0x4d, (byte)0x0e, (byte)0x5c, (byte)0x3d, (byte)0x0b, (byte)0x63, (byte)0x1f, (byte)0xf6, (byte)0x3d, (byte)0x1b, (byte)0xae, (byte)0x5a, (byte)0xf6, (byte)0x42, (byte)0x2a, (byte)0x46,
+ (byte)0xfa, (byte)0x42, (byte)0x71, (byte)0x67, (byte)0x46, (byte)0x02, (byte)0x71, (byte)0xea, (byte)0x51, (byte)0x98, (byte)0xf7, (byte)0xd4, (byte)0x43, (byte)0xbf, (byte)0x8e, (byte)0xe8,
+ (byte)0x3c, (byte)0xc8, (byte)0xfa, (byte)0x79, (byte)0x9d, (byte)0x8c, (byte)0xfc, (byte)0xc2, (byte)0x42, (byte)0xc9, (byte)0xbb, (byte)0xd0, (byte)0xab, (byte)0x81, (byte)0xc4, (byte)0x53,
+ (byte)0xfd, (byte)0x41, (byte)0xda, (byte)0xab, (byte)0x0f, (byte)0x25, (byte)0x79, (byte)0x5f, (byte)0xbd, (byte)0xa3, (byte)0x8c, (byte)0xd3, (byte)0xf5, (byte)0x1b, (byte)0xab, (byte)0x20,
+ (byte)0xd1, (byte)0xf4, (byte)0xd8, (byte)0x81, (byte)0x9c, (byte)0x18, (byte)0x4a, (byte)0xa4, (byte)0x77, (byte)0xee, (byte)0xe1, (byte)0x51, (byte)0xee, (byte)0x2a, (byte)0xc1, (byte)0x94,
+ (byte)0x37, (byte)0xc5, (byte)0x06, (byte)0x7a, (byte)0x3f, (byte)0x0f, (byte)0x25, (byte)0x5b, (byte)0x4e, (byte)0x6a, (byte)0xdc, (byte)0x0b, (byte)0x62, (byte)0x6f, (byte)0x12, (byte)0x83,
+ (byte)0x03, (byte)0xae, (byte)0x4e, (byte)0xce, (byte)0x2b, (byte)0x6e, (byte)0xd4, (byte)0xd5, (byte)0x23, (byte)0x27, (byte)0xf6, (byte)0xa6, (byte)0x38, (byte)0x67, (byte)0xec, (byte)0x95,
+ (byte)0x82, (byte)0xc6, (byte)0xba, (byte)0xd4, (byte)0xf6, (byte)0xe6, (byte)0x22, (byte)0x7d, (byte)0xb9, (byte)0xe4, (byte)0x81, (byte)0x97, (byte)0x24, (byte)0xff, (byte)0x40, (byte)0xb2,
+ (byte)0x42, (byte)0x3c, (byte)0x11, (byte)0x24, (byte)0xd0, (byte)0x3a, (byte)0x96, (byte)0xd9, (byte)0xc1, (byte)0x13, (byte)0xd6, (byte)0x62, (byte)0x45, (byte)0x21, (byte)0x60, (byte)0x5b,
+ (byte)0x7b, (byte)0x2b, (byte)0x62, (byte)0x44, (byte)0xf7, (byte)0x40, (byte)0x93, (byte)0x29, (byte)0x5b, (byte)0x44, (byte)0xb7, (byte)0xda, (byte)0x9c, (byte)0xa6, (byte)0xa9, (byte)0x3b,
+ (byte)0xe1, (byte)0x3b, (byte)0x9d, (byte)0x31, (byte)0xf2, (byte)0x21, (byte)0x53, (byte)0x0f, (byte)0xb3, (byte)0x70, (byte)0x55, (byte)0x84, (byte)0x2c, (byte)0xb4,
+ };
+
+ SSLState sslState = new SSLState();
+
+ sslState.serverCertificateSubjectPublicKeyInfo = new byte[] {
+ 0x30, (byte) 0x82, 0x01, 0x22, // Sequence, length: 290 bytes
+ 0x30, 0x0d, // Sequence, length: 13 bytes {
+ 0x06, 0x09, // Object ID, length: 9 bytes
+ 0x2a, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xf7, 0x0d, 0x01, 0x01, 0x01,
+ 0x05, 0x00, // NULL, length: 0 bytes
+
+ (byte)0x03, (byte)0x82, (byte)0x01, (byte)0x0f, // Bit string, length: 271 bytes
+
+ (byte)0x00, // Pading
+ (byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a, // Sequence
+ (byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01, // Integer, length: 257 bytes
+
+ (byte)0x00, (byte)0xa8, (byte)0x56,
+ (byte)0x65, (byte)0xd3, (byte)0xce, (byte)0x8a, (byte)0x54, (byte)0x4d, (byte)0x9d, (byte)0xb0,
+ (byte)0x84, (byte)0x31, (byte)0x19, (byte)0x71, (byte)0x7f, (byte)0xdd, (byte)0x42, (byte)0xfb,
+ (byte)0x2a, (byte)0x7a, (byte)0x72, (byte)0x13, (byte)0xa1, (byte)0xb9, (byte)0x72, (byte)0xbb,
+ (byte)0xd3, (byte)0x08, (byte)0xad, (byte)0x7d, (byte)0x6c, (byte)0x15, (byte)0x65, (byte)0x03,
+ (byte)0xd1, (byte)0xc4, (byte)0x54, (byte)0xc5, (byte)0x33, (byte)0x6b, (byte)0x7d, (byte)0x69,
+ (byte)0x89, (byte)0x5e, (byte)0xfe, (byte)0xe0, (byte)0x01, (byte)0xc0, (byte)0x7e, (byte)0x9b,
+ (byte)0xcb, (byte)0x5d, (byte)0x65, (byte)0x36, (byte)0xcd, (byte)0x77, (byte)0x5d, (byte)0xf3,
+ (byte)0x7a, (byte)0x5b, (byte)0x29, (byte)0x44, (byte)0x72, (byte)0xd5, (byte)0x38, (byte)0xe2,
+ (byte)0xcf, (byte)0xb1, (byte)0xc7, (byte)0x78, (byte)0x9b, (byte)0x58, (byte)0xb9, (byte)0x17,
+ (byte)0x7c, (byte)0xb7, (byte)0xd6, (byte)0xc7, (byte)0xc7, (byte)0xbf, (byte)0x90, (byte)0x4e,
+ (byte)0x7c, (byte)0x39, (byte)0x93, (byte)0xcb, (byte)0x2e, (byte)0xe0, (byte)0xc2, (byte)0x33,
+ (byte)0x2d, (byte)0xa5, (byte)0x7e, (byte)0xe0, (byte)0x7b, (byte)0xb6, (byte)0xf9, (byte)0x91,
+ (byte)0x32, (byte)0xb7, (byte)0xd4, (byte)0x85, (byte)0xb7, (byte)0x35, (byte)0x2d, (byte)0x2b,
+ (byte)0x00, (byte)0x6d, (byte)0xf8, (byte)0xea, (byte)0x8c, (byte)0x97, (byte)0x5f, (byte)0x51,
+ (byte)0x1d, (byte)0x68, (byte)0x04, (byte)0x3c, (byte)0x79, (byte)0x14, (byte)0x71, (byte)0xa7,
+ (byte)0xc7, (byte)0xd7, (byte)0x70, (byte)0x7a, (byte)0xe0, (byte)0xba, (byte)0x12, (byte)0x69,
+ (byte)0xc8, (byte)0xd3, (byte)0xd9, (byte)0x4e, (byte)0xab, (byte)0x51, (byte)0x47, (byte)0xa3,
+ (byte)0xec, (byte)0x99, (byte)0xd4, (byte)0x88, (byte)0xca, (byte)0xda, (byte)0xc2, (byte)0x7f,
+ (byte)0x79, (byte)0x4b, (byte)0x66, (byte)0xed, (byte)0x87, (byte)0xbe, (byte)0xc2, (byte)0x5f,
+ (byte)0xea, (byte)0xcf, (byte)0xe1, (byte)0xb5, (byte)0xf0, (byte)0x3d, (byte)0x9b, (byte)0xf2,
+ (byte)0x19, (byte)0xc3, (byte)0xe0, (byte)0xe1, (byte)0x7a, (byte)0x45, (byte)0x71, (byte)0x12,
+ (byte)0x3d, (byte)0x72, (byte)0x1d, (byte)0x6f, (byte)0x2b, (byte)0x1c, (byte)0x46, (byte)0x68,
+ (byte)0xc0, (byte)0x8f, (byte)0x4f, (byte)0xce, (byte)0x3a, (byte)0xc5, (byte)0xcd, (byte)0x22,
+ (byte)0x65, (byte)0x2d, (byte)0x43, (byte)0xb0, (byte)0x5c, (byte)0xdd, (byte)0x89, (byte)0xae,
+ (byte)0xbe, (byte)0x70, (byte)0x59, (byte)0x5e, (byte)0x0c, (byte)0xbd, (byte)0xf5, (byte)0x46,
+ (byte)0x82, (byte)0x1e, (byte)0xe4, (byte)0x86, (byte)0x95, (byte)0x7b, (byte)0x60, (byte)0xae,
+ (byte)0x45, (byte)0x50, (byte)0xc2, (byte)0x54, (byte)0x08, (byte)0x49, (byte)0x9a, (byte)0x9e,
+ (byte)0xfb, (byte)0xb2, (byte)0xb6, (byte)0x78, (byte)0xe5, (byte)0x2f, (byte)0x9c, (byte)0x5a,
+ (byte)0xd0, (byte)0x8a, (byte)0x03, (byte)0x77, (byte)0x68, (byte)0x30, (byte)0x93, (byte)0x78,
+ (byte)0x6d, (byte)0x90, (byte)0x6d, (byte)0x50, (byte)0xfa, (byte)0xa7, (byte)0x65, (byte)0xfe,
+ (byte)0x59, (byte)0x33, (byte)0x27, (byte)0x4e, (byte)0x4b, (byte)0xf8, (byte)0x38, (byte)0x44,
+ (byte)0x3a, (byte)0x12, (byte)0xf4, (byte)0x07, (byte)0xa0, (byte)0x8d, (byte)0x02, (byte)0x03,
+ (byte)0x01, (byte)0x00, (byte)0x01,
+ };
+ /* @formatter:on */
+
+ NtlmState ntlmState = new NtlmState();
+ MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(serverChallengePacket, new byte[] {1, 2, 3}));
+ Element ntlmssp_negotiate = new ClientNtlmsspNegotiate("ntlmssp_negotiate", ntlmState);
+ Element ntlmssp_challenge = new ServerNtlmsspChallenge("ntlmssp_challenge", ntlmState);
+ Element ntlmssp_auth = new ClientNtlmsspPubKeyAuth("ntlmssp_auth", ntlmState, sslState, "192.168.0.101", "workgroup", "apollo3", "Administrator",
+ "R2Preview!");
+ Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(clientNegotiatePacket, clientAuthPacket), (Dumper)ntlmssp_auth);
+ Element mainSink = new MockSink("mainSink", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {1, 2, 3}));
+
+ Pipeline pipeline = new PipelineImpl("test");
+ pipeline.add(source, ntlmssp_negotiate, ntlmssp_challenge, ntlmssp_auth, sink, mainSink);
+ pipeline.link("source", "ntlmssp_negotiate", "ntlmssp_challenge", "ntlmssp_auth", "mainSink");
+ pipeline.link("ntlmssp_negotiate >" + OTOUT, "ntlmssp_negotiate< sink");
+ pipeline.link("ntlmssp_challenge >" + OTOUT, "ntlmssp_challenge< sink");
+ pipeline.link("ntlmssp_auth >" + OTOUT, "ntlmssp_auth< sink");
+ pipeline.runMainLoop("source", STDOUT, false, false);
+
+ }
+
+ @Override
+ public void dump(ByteBuffer buf) {
+ buf.rewindCursor();
+ TSRequest request = new TSRequest("TSRequest");
+ request.readTag(buf);
+ System.out.println("TSRequest version: " + request.version.value);
+ System.out.println("TSRequest pubKey: " + request.pubKeyAuth.value.toPlainHexString());
+
+ ByteBuffer negoToken = ((NegoItem)request.negoTokens.tags[0]).negoToken.value;
+ System.out.println("TSRequest negotoken: " + negoToken.toPlainHexString());
+ dumpNegoToken(negoToken);
+
+ negoToken.unref();
+ }
+
+ private void dumpNegoToken(ByteBuffer buf) {
+ String signature = buf.readVariableString(RdpConstants.CHARSET_8);
+ if (!signature.equals(NTLMSSP))
+ throw new RuntimeException("Unexpected NTLM message singature: \"" + signature + "\". Expected signature: \"" + NTLMSSP + "\". Data: " + buf + ".");
+
+ // MessageType (CHALLENGE)
+ int messageType = buf.readSignedIntLE();
+ if (messageType != NtlmConstants.NTLMSSP_AUTH)
+ throw new RuntimeException("Unexpected NTLM message type: " + messageType + ". Expected type: CHALLENGE (" + NtlmConstants.CHALLENGE + "). Data: " + buf
+ + ".");
+
+ System.out.println("lmChallengeResponseFields: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+ ByteBuffer ntChallengeResponseBuf = ServerNtlmsspChallenge.readBlockByDescription(buf);
+ System.out.println("NtChallengeResponse: " + ntChallengeResponseBuf.toPlainHexString());
+ System.out.println("DomainName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+ System.out.println("UserName: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+ System.out.println("Workstation: " + ServerNtlmsspChallenge.readStringByDescription(buf));
+ System.out.println("EncryptedRandomSessionKey: " + ServerNtlmsspChallenge.readBlockByDescription(buf).toPlainHexString());
+ System.out.println("NegotiateFlags: " + new NegoFlags(buf.readSignedIntLE()));
+ System.out.println("Version: " + buf.readBytes(8).toPlainHexString());
+
+ dumpNtChallengeResponse(ntChallengeResponseBuf);
+ }
+
+ private void dumpNtChallengeResponse(ByteBuffer buf) {
+ System.out.println("HMAC: " + buf.readBytes(16).toPlainHexString());
+ System.out.format("Header: 0x%08x\n", buf.readUnsignedIntLE());
+ System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+ System.out.println("Time: " + buf.readBytes(8).toPlainHexString());
+ System.out.println("Client challenge: " + buf.readBytes(8).toPlainHexString());
+ System.out.format("Reserved: 0x%08x\n", buf.readUnsignedIntLE());
+
+ // Parse attribute list
+
+ while (buf.remainderLength() > 0) {
+ int type = buf.readUnsignedShortLE();
+ int length = buf.readUnsignedShortLE();
+
+ if (type == MSV_AV_EOL)
+ // End of list
+ break;
+
+ ByteBuffer data = buf.readBytes(length);
+ switch (type) {
+ case MSV_AV_NETBIOS_DOMAIN_NAME:
+ System.out.println("AV Netbios Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+ break;
+ case MSV_AV_NETBIOS_COMPUTER_NAME:
+ System.out.println("AV Netbios Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+ break;
+ case MSV_AV_DNS_DOMAIN_NAME:
+ System.out.println("AV DNS Domain name: " + data.readString(length, RdpConstants.CHARSET_16));
+ break;
+ case MSV_AV_DNS_COMPUTER_NAME:
+ System.out.println("AV DNS Computer name: " + data.readString(length, RdpConstants.CHARSET_16));
+ break;
+ case MSV_AV_CHANNEL_BINDINGS:
+ System.out.println("AV Channel Bindings: " + data.readBytes(length).toPlainHexString());
+ break;
+ case MSV_AV_TIMESTAMP:
+ System.out.println("AV Timestamp: " + data.readBytes(length).toPlainHexString());
+ break;
+ case MSV_AV_FLAGS:
+ System.out.println("AV Flags: " + data.readBytes(length).toPlainHexString());
+ break;
+ case MSV_AV_TARGET_NAME:
+ System.out.println("AV Target Name: " + data.readString(length, RdpConstants.CHARSET_16));
+ break;
+ default:
+ System.out.println("Unknown NTLM target info attribute: " + type + ". Data: " + data + ".");
+ }
+ data.unref();
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
new file mode 100755
index 0000000..50584c3
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/ClientNtlmsspUserCredentials.java
@@ -0,0 +1,128 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import rdpclient.ntlmssp.asn1.TSCredentials;
+import rdpclient.ntlmssp.asn1.TSPasswordCreds;
+import rdpclient.ntlmssp.asn1.TSRequest;
+import rdpclient.rdp.RdpConstants;
+import streamer.ByteBuffer;
+import streamer.Element;
+import streamer.Link;
+import streamer.OneTimeSwitch;
+
+public class ClientNtlmsspUserCredentials extends OneTimeSwitch implements Element {
+
+ protected NtlmState ntlmState;
+
+ public ClientNtlmsspUserCredentials(String id, NtlmState ntlmState) {
+ super(id);
+ this.ntlmState = ntlmState;
+ }
+
+ @Override
+ protected void handleOneTimeData(ByteBuffer buf, Link link) {
+ if (buf == null)
+ return;
+
+ throw new RuntimeException("Unexpected packet: " + buf + ".");
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ ByteBuffer buf = new ByteBuffer(4096, true);
+
+ TSRequest tsRequest = new TSRequest("TSRequest");
+ tsRequest.version.value = 2L;
+
+ ByteBuffer tsCredentialsBuf = generateTSCredentials();
+ tsRequest.authInfo.value = encryptTSCredentials(tsCredentialsBuf);
+ tsCredentialsBuf.unref();
+
+ tsRequest.writeTag(buf);
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+
+ pushDataToOTOut(buf);
+
+ switchOff();
+ }
+
+ private ByteBuffer encryptTSCredentials(ByteBuffer buf2) {
+ return new ByteBuffer(ntlmState.ntlm_EncryptMessage(buf2.toByteArray()));
+ }
+
+ private ByteBuffer generateTSCredentials() {
+ ByteBuffer buf = new ByteBuffer(4096);
+
+ TSCredentials tsCredentials = new TSCredentials("authInfo");
+ // 1 means that credentials field contains a TSPasswordCreds structure
+ tsCredentials.credType.value = 1L;
+
+ ByteBuffer tsPasswordCredsBuf = new ByteBuffer(4096, true);
+ TSPasswordCreds tsPasswordCreds = new TSPasswordCreds("credentials");
+ tsPasswordCreds.domainName.value = new ByteBuffer(ntlmState.domain.getBytes(RdpConstants.CHARSET_16));
+ tsPasswordCreds.userName.value = new ByteBuffer(ntlmState.user.getBytes(RdpConstants.CHARSET_16));
+ tsPasswordCreds.password.value = new ByteBuffer(ntlmState.password.getBytes(RdpConstants.CHARSET_16));
+ tsPasswordCreds.writeTag(tsPasswordCredsBuf);
+ tsPasswordCredsBuf.trimAtCursor();
+ //* DEBUG */System.out.println("TSPasswordCreds:\n" + tsPasswordCredsBuf.dump());
+
+ tsCredentials.credentials.value = tsPasswordCredsBuf;
+
+ tsCredentials.writeTag(buf);
+ tsPasswordCredsBuf.unref();
+
+ // Trim buffer to actual length of data written
+ buf.trimAtCursor();
+ //* DEBUG */System.out.println("TSCredentials:\n" + buf.dump());
+
+ return buf;
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+
+ /* @formatter:off */
+ // TSCredentials
+// 30 57 // Sequence
+// a0 03 // TAG 0
+// 02 01 01 // Integer: 1 : credentials contains a TSPasswordCreds structure
+// a1 50 // TAG 1
+// 04 4e // OCTETSTRING
+ // TSPasswordCreds
+// 30 4c // SEQUENCE
+// a0 14 // TAG 0
+// 04 12 // OCTETSTRING
+// 77 00 6f 00 72 00 6b 00 67 00 72 00 6f 00 75 00 70 00 // "workgroup"
+// a1 1c // TAG 1
+// 04 1a // OCTETSTRING
+// 41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 00 // "Administrator"
+// a2 16 // TAG 2
+// 04 14 //
+// 52 00 32 00 50 00 72 00 65 00 76 00 69 00 65 00 77 00 21 00 // "R2Preview!"
+ /* @formatter:on */
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
new file mode 100755
index 0000000..817dbd9
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/CryptoAlgos.java
@@ -0,0 +1,361 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+import java.lang.reflect.Method;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import rdpclient.rdp.RdpConstants;
+
+/**
+ * @see http://msdn.microsoft.com/en-us/library/cc236717.aspx
+ */
+public class CryptoAlgos implements NtlmConstants {
+
+ /**
+ * Indicates the left-to-right concatenation of the string parameters, from
+ * the first string to the Nnth. Any numbers are converted to strings and all
+ * numeric conversions to strings retain all digits, even nonsignificant ones.
+ * The result is a string. For example, ConcatenationOf(0x00122, "XYZ",
+ * "Client") results in the string "00122XYZClient."
+ */
+ public static String concatenationOf(String... args) {
+ StringBuffer sb = new StringBuffer();
+ for (String arg : args) {
+ sb.append(arg);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Concatenate byte arrays.
+ */
+ public static byte[] concatenationOf(byte[]... arrays) {
+ int length = 0;
+ for (byte[] array : arrays) {
+ length += array.length;
+ }
+
+ byte[] result = new byte[length];
+ int destPos = 0;
+ for (byte[] array : arrays) {
+ System.arraycopy(array, 0, result, destPos, array.length);
+ destPos += array.length;
+ }
+
+ return result;
+ }
+
+ /** Indicates a 32-bit CRC calculated over M. */
+ public static byte[] CRC32(byte[] M) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the encryption of an 8-byte data item D with the 7-byte key K
+ * using the Data Encryption Standard (DES) algorithm in Electronic Codebook
+ * (ECB) mode. The result is 8 bytes in length ([FIPS46-2]).
+ */
+ public static byte[] DES(byte[] K, byte[] D) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the encryption of an 8-byte data item D with the 16-byte key K
+ * using the Data Encryption Standard Long (DESL) algorithm. The result is 24
+ * bytes in length. DESL(K, D) is computed as follows.
+ *
+ * <pre>
+ * ConcatenationOf( DES(K[0..6], D),
+ * DES(K[7..13], D), DES(
+ * ConcatenationOf(K[14..15], Z(5)), D));
+ * </pre>
+ *
+ * Note K[] implies a key represented as a character array.
+ */
+ public static byte[] DESL(byte[] K, byte[] D) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * An auxiliary function that returns an operating system version-specific
+ * value (section 2.2.2.8).
+ */
+ public static byte[] getVersion() {
+ // Version (6.1, Build 7601), NTLM current revision: 15
+ return new byte[] {0x06, 0x01, (byte)0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+ }
+
+ /**
+ * Retrieve the user's LM response key from the server database (directory or
+ * local database).
+ */
+ public static byte[] LMGETKEY(byte[] U, byte[] D) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /** Retrieve the user's NT response key from the server database. */
+ public static byte[] NTGETKEY(byte[] U, byte[] D) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the encryption of data item M with the key K using the HMAC
+ * algorithm ([RFC2104]).
+ */
+ public static byte[] HMAC(byte[] K, byte[] M) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the computation of a 16-byte HMAC-keyed MD5 message digest of the
+ * byte string M using the key K.
+ */
+ public static byte[] HMAC_MD5(byte[] K, byte[] M) {
+ try {
+ String algorithm = "HMacMD5";
+ Mac hashMac = Mac.getInstance(algorithm);
+
+ Key secretKey = new SecretKeySpec(K, 0, K.length, algorithm);
+ hashMac.init(secretKey);
+ return hashMac.doFinal(M);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot calculate HMAC-MD5.", e);
+ }
+ }
+
+ /**
+ * Produces a key exchange key from the session base key K, LM response and
+ * server challenge SC as defined in the sections KXKEY, SIGNKEY, and SEALKEY.
+ */
+ public static byte[] KXKEY(byte[] sessionBaseKey/*K, byte[] LM, byte[] SC*/) {
+ // Key eXchange Key is server challenge
+ /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */
+ return Arrays.copyOf(sessionBaseKey, sessionBaseKey.length);
+ }
+
+ /**
+ * Computes a one-way function of the user's password to use as the response
+ * key. NTLM v1 and NTLM v2 define separate LMOWF() functions in the NTLM v1
+ * authentication and NTLM v2 authentication sections, respectively.
+ */
+ public static byte[] LMOWF() {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the computation of an MD4 message digest of the null-terminated
+ * byte string M ([RFC1320]).
+ */
+ public static byte[] MD4(byte[] M) {
+ try {
+ return sun.security.provider.MD4.getInstance().digest(M);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot calculate MD5.", e);
+ }
+ }
+
+ /**
+ * Indicates the computation of an MD5 message digest of the null-terminated
+ * byte string M ([RFC1321]).
+ */
+ public static byte[] MD5(byte[] M) {
+ try {
+ return MessageDigest.getInstance("MD5").digest(M);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot calculate MD5.", e);
+ }
+ }
+
+ /**
+ * Indicates the computation of an MD5 message digest of a binary blob
+ * ([RFC4121] section 4.1.1.2).
+ */
+ public static byte[] MD5_HASH(byte[] M) {
+ try {
+ return MessageDigest.getInstance("MD5").digest(M);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot calculate MD5.", e);
+ }
+ }
+
+ /** A zero-length string. */
+ public static final String NIL = "";
+
+ /**
+ * Indicates the computation of an N-byte cryptographic-strength random
+ * number.
+ *
+ * Note The NTLM Authentication Protocol does not define the statistical
+ * properties of the random number generator. It is left to the discretion of
+ * the implementation to define the strength requirements of the NONCE(N)
+ * operation.
+ */
+ public static byte[] NONCE(int N) {
+ // Generate random nonce for LMv2 and NTv2 responses
+ byte[] nonce = new byte[N];
+ SecureRandom random = new SecureRandom();
+ random.nextBytes(nonce);
+
+ // Fixed nonce for debugging purposes
+ //* DEBUG */for (int i = 0; i < N; i++) nonce[i] = (byte) (i + 1);
+
+ return nonce;
+ }
+
+ /**
+ * Computes a one-way function of the user's password to use as the response
+ * key. NTLM v1 and NTLM v2 define separate NTOWF() functions in the NTLM v1
+ * authentication and NTLM v2 authentication sections, respectively.
+ */
+ public static byte[] NTOWF() {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * The RC4 Encryption Algorithm. To obtain this stream cipher that is licensed
+ * by RSA Data Security, Inc., contact this company.
+ *
+ * Indicates the encryption of data item D with the current session or message
+ * key state, using the RC4 algorithm. H is the handle to a key state
+ * structure initialized by RC4INIT.
+ */
+ public static byte[] RC4(Cipher H, byte[] D) {
+ return H.update(D);
+ }
+
+ /**
+ * Indicates the encryption of data item D with the key K using the RC4
+ * algorithm.
+ *
+ * Note The key sizes for RC4 encryption in NTLM are defined in sections
+ * KXKEY, SIGNKEY, and SEALKEY, where they are created.
+ */
+ public static byte[] RC4K(byte[] K, byte[] D) {
+ try {
+ Cipher cipher = Cipher.getInstance("RC4");
+ Key key = new SecretKeySpec(K, "RC4");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ return cipher.doFinal(D);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Initialization of the RC4 key and handle to a key state structure for the
+ * session.
+ */
+ public static Cipher RC4Init(byte[] K) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Produces an encryption key from the session key as defined in sections
+ * KXKEY, SIGNKEY, and SEALKEY.
+ */
+ public static byte[] SEALKEY(byte[] F, byte[] K, byte[] string1) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Produces a signing key from the session key as defined in sections KXKEY,
+ * SIGNKEY, and SEALKEY.
+ */
+ public static byte[] SIGNKEY(int flag, byte[] K, byte[] string1) {
+ throw new RuntimeException("FATAL: Not implemented.");
+ }
+
+ /**
+ * Indicates the retrieval of the current time as a 64-bit value, represented
+ * as the number of 100-nanosecond ticks elapsed since midnight of January
+ * 1st, 1601 (UTC).
+ */
+ public static byte[] Currenttime() {
+ // (current time + milliseconds from 1.01.1601 to 1.01.1970) *
+ // 100-nanosecond ticks
+ long time = (System.currentTimeMillis() + 11644473600000L) * 10000;
+
+ // Convert 64bit value to byte array.
+ byte[] result = new byte[8];
+ for (int i = 0; i < 8; i++, time >>>= 8) {
+ result[i] = (byte)time;
+ }
+
+ return result;
+ }
+
+ /**
+ * Indicates the 2-byte little-endian byte order encoding of the Unicode
+ * UTF-16 representation of string. The Byte Order Mark (BOM) is not sent over
+ * the wire.
+ */
+ public static byte[] UNICODE(String string) {
+ return string.getBytes(RdpConstants.CHARSET_16);
+ }
+
+ /** Indicates the uppercase representation of string. */
+ public static String UpperCase(String string) {
+ return string.toUpperCase();
+ }
+
+ /**
+ * Indicates the creation of a byte array of length N. Each byte in the array
+ * is initialized to the value zero.
+ */
+ public static byte[] Z(int N) {
+ return new byte[N];
+ }
+
+ public static Cipher initRC4(byte[] key) {
+ try {
+ Cipher cipher = Cipher.getInstance("RC4");
+ cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "RC4"));
+ return cipher;
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot initialize RC4 sealing handle with client sealing key.", e);
+ }
+ }
+
+ /**
+ * Helper method for embedded test cases.
+ */
+ public static void callAll(Object obj) {
+ Method[] methods = obj.getClass().getDeclaredMethods();
+ for (Method m : methods) {
+ if (m.getName().startsWith("test")) {
+ try {
+ m.invoke(obj, (Object[])null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) {
+ callAll(new CryptoAlgos());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4f3611f9/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
----------------------------------------------------------------------
diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
new file mode 100755
index 0000000..c35dbec
--- /dev/null
+++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/ntlmssp/NegoFlags.java
@@ -0,0 +1,492 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package rdpclient.ntlmssp;
+
+/**
+ * During NTLM authentication, each of the following flags is a possible value
+ * of the NegotiateFlags field of the NEGOTIATE_MESSAGE, CHALLENGE_MESSAGE, and
+ * AUTHENTICATE_MESSAGE, unless otherwise noted. These flags define client or
+ * server NTLM capabilities supported by the sender.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/cc236650.aspx
+ */
+public class NegoFlags {
+
+ /**
+ * 56-bit encryption. If the client sends NTLMSSP_NEGOTIATE_SEAL or
+ * NTLMSSP_NEGOTIATE_SIGN with NTLMSSP_NEGOTIATE_56 to the server in the
+ * NEGOTIATE_MESSAGE, the server MUST return NTLMSSP_NEGOTIATE_56 to the
+ * client in the CHALLENGE_MESSAGE. Otherwise it is ignored. If both
+ * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are requested and supported
+ * by the client and server, NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128
+ * will both be returned to the client. Clients and servers that set
+ * NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_56 if it is supported.
+ * An alternate name for this field is
+ */
+ public static final int NTLMSSP_NEGOTIATE_56 = 0x80000000;
+
+ /**
+ * Explicit key exchange. This capability SHOULD be used because it improves
+ * security for message integrity or confidentiality. See sections 3.2.5.1.2,
+ * 3.2.5.2.1, and 3.2.5.2.2 for details.
+ */
+ public static final int NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000;
+
+ /**
+ * 128-bit session key negotiation. An alternate name for this field is
+ * NTLMSSP_NEGOTIATE_128. If the client sends NTLMSSP_NEGOTIATE_128 to the
+ * server in the NEGOTIATE_MESSAGE, the server MUST return
+ * NTLMSSP_NEGOTIATE_128 to the client in the CHALLENGE_MESSAGE only if the
+ * client sets NTLMSSP_NEGOTIATE_SEAL or NTLMSSP_NEGOTIATE_SIGN. Otherwise it
+ * is ignored. If both NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128 are
+ * requested and supported by the client and server, NTLMSSP_NEGOTIATE_56 and
+ * NTLMSSP_NEGOTIATE_128 will both be returned to the client. Clients and
+ * servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD set NTLMSSP_NEGOTIATE_128 if
+ * it is supported.
+ */
+ public static final int NTLMSSP_NEGOTIATE_128 = 0x20000000;
+
+ /**
+ * Protocol version number. The data corresponding to this flag is provided in
+ * the Version field of the NEGOTIATE_MESSAGE, the CHALLENGE_MESSAGE, and the
+ * AUTHENTICATE_MESSAGE.
+ */
+ public static final int NTLMSSP_NEGOTIATE_VERSION = 0x02000000;
+
+ /**
+ * TargetInfo fields in the CHALLENGE_MESSAGE (section 2.2.1.2) are populated.
+ */
+ public static final int NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000;
+
+ /** LMOWF (section 3.3). */
+ public static final int NTLMSSP_REQUEST_NON_NT_SESSION_KEY = 0x00400000;
+
+ /** An identify level token. */
+ public static final int NTLMSSP_NEGOTIATE_IDENTIFY = 0x00100000;
+
+ /**
+ * NTLM v2 session security. NTLM v2 session security is a misnomer because it
+ * is not NTLM v2. It is NTLM v1 using the extended session security that is
+ * also in NTLM v2. NTLMSSP_NEGOTIATE_LM_KEY and
+ * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+ * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY and NTLMSSP_NEGOTIATE_LM_KEY are
+ * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+ * returned to the client. NTLM v2 authentication session key generation MUST
+ * be supported by both the client and the DC in order to be used, and
+ * extended session security signing and sealing requires support from the
+ * client and the server in order to be used.
+ */
+ public static final int NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY = 0x00080000;
+
+ /**
+ * TargetName MUST be a server name. The data corresponding to this flag is
+ * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+ * this bit is set, then NTLMSSP_TARGET_TYPE_DOMAIN MUST NOT be set. This flag
+ * MUST be ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+ */
+ public static final int NTLMSSP_TARGET_TYPE_SERVER = 0x00020000;
+
+ /**
+ * TargetName MUST be a domain name. The data corresponding to this flag is
+ * provided by the server in the TargetName field of the CHALLENGE_MESSAGE. If
+ * set, then NTLMSSP_TARGET_TYPE_SERVER MUST NOT be set. This flag MUST be
+ * ignored in the NEGOTIATE_MESSAGE and the AUTHENTICATE_MESSAGE.
+ */
+ public static final int NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000;
+
+ /**
+ * Signature block on all messages. NTLMSSP_NEGOTIATE_ALWAYS_SIGN MUST be set
+ * in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to the
+ * client. NTLMSSP_NEGOTIATE_ALWAYS_SIGN is overridden by
+ * NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL, if they are supported.
+ */
+ public static final int NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000;
+
+ /**
+ * Workstation field is present. If this flag is not set, the Workstation
+ * field MUST be ignored. If this flag is set, the length field of the
+ * Workstation field specifies whether the workstation name is nonempty or
+ * not.
+ */
+ public static final int NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000;
+
+ /**
+ * Domain name is provided.
+ *
+ * Sent by the client in the Type 1 message to indicate that the name of the
+ * domain in which the client workstation has membership is included in the
+ * message. This is used by the server to determine whether the client is
+ * eligible for local authentication.
+ */
+ public static final int NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000;
+
+ /**
+ * Connection SHOULD be anonymous.
+ *
+ * Sent by the client in the Type 3 message to indicate that an anonymous
+ * context has been established. This also affects the response fields (as
+ * detailed in the "Anonymous Response" section).
+ */
+ public static final int NTLMSSP_NEGOTIATE_ANONYMOUS = 0x00000800;
+
+ /**
+ * Usage of the NTLM v1 session security protocol. NTLMSSP_NEGOTIATE_NTLM MUST
+ * be set in the NEGOTIATE_MESSAGE to the server and the CHALLENGE_MESSAGE to
+ * the client.
+ */
+ public static final int NTLMSSP_NEGOTIATE_NTLM = 0x00000200;
+
+ /**
+ * LAN Manager (LM) session key computation. NTLMSSP_NEGOTIATE_LM_KEY and
+ * NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are mutually exclusive. If both
+ * NTLMSSP_NEGOTIATE_LM_KEY and NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are
+ * requested, NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY alone MUST be
+ * returned to the client. NTLM v2 authentication session key generation MUST
+ * be supported by both the client and the DC in order to be used, and
+ * extended session security signing and sealing requires support from the
+ * client and the server to be used.
+ */
+ public static final int NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080;
+
+ /**
+ * Connectionless authentication. If NTLMSSP_NEGOTIATE_DATAGRAM is set, then
+ * NTLMSSP_NEGOTIATE_KEY_EXCH MUST always be set in the AUTHENTICATE_MESSAGE
+ * to the server and the CHALLENGE_MESSAGE to the client.
+ */
+ public static final int NTLMSSP_NEGOTIATE_DATAGRAM = 0x00000040;
+
+ /**
+ * Session key negotiation for message confidentiality. If the client sends
+ * NTLMSSP_NEGOTIATE_SEAL to the server in the NEGOTIATE_MESSAGE, the server
+ * MUST return NTLMSSP_NEGOTIATE_SEAL to the client in the CHALLENGE_MESSAGE.
+ * Clients and servers that set NTLMSSP_NEGOTIATE_SEAL SHOULD always set
+ * NTLMSSP_NEGOTIATE_56 and NTLMSSP_NEGOTIATE_128, if they are supported.
+ */
+ public static final int NTLMSSP_NEGOTIATE_SEAL = 0x00000020;
+
+ /**
+ * Session key negotiation for message signatures. If the client sends
+ * NTLMSSP_NEGOTIATE_SIGN to the server in the NEGOTIATE_MESSAGE, the server
+ * MUST return NTLMSSP_NEGOTIATE_SIGN to the client in the CHALLENGE_MESSAGE.
+ */
+ public static final int NTLMSSP_NEGOTIATE_SIGN = 0x00000010;
+
+ /**
+ * TargetName field of the CHALLENGE_MESSAGE (section 2.2.1.2) MUST be
+ * supplied.
+ */
+ public static final int NTLMSSP_REQUEST_TARGET = 0x00000004;
+
+ /**
+ * OEM character set encoding.
+ *
+ * @see NTLMSSP_NEGOTIATE_UNICODE
+ */
+ public static final int NTLMSSP_NEGOTIATE_OEM = 0x00000002;
+
+ /**
+ * Unicode character set encoding.
+ *
+ * The NTLMSSP_NEGOTIATE_UNICODE(A) and NTLM_NEGOTIATE_OEM(B) bits are
+ * evaluated together as follows:
+ * <ul>
+ * <li>A==1: The choice of character set encoding MUST be Unicode.
+ *
+ * <li>A==0 and B==1: The choice of character set encoding MUST be OEM.
+ *
+ * <li>A==0 and B==0: The protocol MUST return SEC_E_INVALID_TOKEN.
+ * <ul>
+ * */
+ public static final int NTLMSSP_NEGOTIATE_UNICODE = 0x00000001;
+
+ public int value;
+
+ public NegoFlags(int value) {
+ this.value = value;
+ }
+
+ public NegoFlags() {
+ this.value = 0;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("NegoFlags [value=0x%04x (%s)]", value, flagsToSting());
+ }
+
+ public String flagsToSting() {
+
+ String str = "";
+
+ if (NEGOTIATE_56())
+ str += "NEGOTIATE_56 ";
+ if (NEGOTIATE_KEY_EXCH())
+ str += "NEGOTIATE_KEY_EXCH ";
+ if (NEGOTIATE_128())
+ str += "NEGOTIATE_128 ";
+ if (NEGOTIATE_VERSION())
+ str += "NEGOTIATE_VERSION ";
+ if (NEGOTIATE_TARGET_INFO())
+ str += "NEGOTIATE_TARGET_INFO ";
+ if (REQUEST_NON_NT_SESSION_KEY())
+ str += "REQUEST_NON_NT_SESSION_KEY ";
+ if (NEGOTIATE_IDENTIFY())
+ str += "NEGOTIATE_IDENTIFY ";
+ if (NEGOTIATE_EXTENDED_SESSION_SECURITY())
+ str += "NEGOTIATE_EXTENDED_SESSION_SECURITY ";
+ if (TARGET_TYPE_SERVER())
+ str += "TARGET_TYPE_SERVER ";
+ if (TARGET_TYPE_DOMAIN())
+ str += "TARGET_TYPE_DOMAIN ";
+ if (NEGOTIATE_ALWAYS_SIGN())
+ str += "NEGOTIATE_ALWAYS_SIGN ";
+ if (NEGOTIATE_OEM_WORKSTATION_SUPPLIED())
+ str += "NEGOTIATE_OEM_WORKSTATION_SUPPLIED ";
+ if (NEGOTIATE_OEM_DOMAIN_SUPPLIED())
+ str += "NEGOTIATE_OEM_DOMAIN_SUPPLIED ";
+ if (NEGOTIATE_ANONYMOUS())
+ str += "NEGOTIATE_ANONYMOUS ";
+ if (NEGOTIATE_NTLM())
+ str += "NEGOTIATE_NTLM ";
+ if (NEGOTIATE_LM_KEY())
+ str += "NEGOTIATE_LM_KEY ";
+ if (NEGOTIATE_DATAGRAM())
+ str += "NEGOTIATE_DATAGRAM ";
+ if (NEGOTIATE_SEAL())
+ str += "NEGOTIATE_SEAL ";
+ if (NEGOTIATE_SIGN())
+ str += "NEGOTIATE_SIGN ";
+ if (REQUEST_TARGET())
+ str += "REQUEST_TARGET ";
+ if (NEGOTIATE_OEM())
+ str += "NEGOTIATE_OEM ";
+ if (NEGOTIATE_UNICODE())
+ str += "NEGOTIATE_UNICODE ";
+
+ return str;
+ }
+
+ public boolean NEGOTIATE_56() {
+ return ((value & NTLMSSP_NEGOTIATE_56) != 0);
+ }
+
+ public boolean NEGOTIATE_KEY_EXCH() {
+ return ((value & NTLMSSP_NEGOTIATE_KEY_EXCH) != 0);
+ }
+
+ public boolean NEGOTIATE_128() {
+ return ((value & NTLMSSP_NEGOTIATE_128) != 0);
+ }
+
+ public boolean NEGOTIATE_VERSION() {
+ return ((value & NTLMSSP_NEGOTIATE_VERSION) != 0);
+ }
+
+ public boolean NEGOTIATE_TARGET_INFO() {
+ return ((value & NTLMSSP_NEGOTIATE_TARGET_INFO) != 0);
+ }
+
+ public boolean REQUEST_NON_NT_SESSION_KEY() {
+ return ((value & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0);
+ }
+
+ public boolean NEGOTIATE_IDENTIFY() {
+ return ((value & NTLMSSP_NEGOTIATE_IDENTIFY) != 0);
+ }
+
+ public boolean NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+ return ((value & NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY) != 0);
+ }
+
+ public boolean TARGET_TYPE_SERVER() {
+ return ((value & NTLMSSP_TARGET_TYPE_SERVER) != 0);
+ }
+
+ public boolean TARGET_TYPE_DOMAIN() {
+ return ((value & NTLMSSP_TARGET_TYPE_DOMAIN) != 0);
+ }
+
+ public boolean NEGOTIATE_ALWAYS_SIGN() {
+ return ((value & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) != 0);
+ }
+
+ public boolean NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+ return ((value & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) != 0);
+ }
+
+ public boolean NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+ return ((value & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) != 0);
+ }
+
+ public boolean NEGOTIATE_ANONYMOUS() {
+ return ((value & NTLMSSP_NEGOTIATE_ANONYMOUS) != 0);
+ }
+
+ public boolean NEGOTIATE_NTLM() {
+ return ((value & NTLMSSP_NEGOTIATE_NTLM) != 0);
+ }
+
+ public boolean NEGOTIATE_LM_KEY() {
+ return ((value & NTLMSSP_NEGOTIATE_LM_KEY) != 0);
+ }
+
+ public boolean NEGOTIATE_DATAGRAM() {
+ return ((value & NTLMSSP_NEGOTIATE_DATAGRAM) != 0);
+ }
+
+ public boolean NEGOTIATE_SEAL() {
+ return ((value & NTLMSSP_NEGOTIATE_SEAL) != 0);
+ }
+
+ public boolean NEGOTIATE_SIGN() {
+ return ((value & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ }
+
+ public boolean REQUEST_TARGET() {
+ return ((value & NTLMSSP_REQUEST_TARGET) != 0);
+ }
+
+ public boolean NEGOTIATE_OEM() {
+ return ((value & NTLMSSP_NEGOTIATE_OEM) != 0);
+ }
+
+ public boolean NEGOTIATE_UNICODE() {
+ return ((value & NTLMSSP_NEGOTIATE_UNICODE) != 0);
+ }
+
+ public NegoFlags set_NEGOTIATE_56() {
+ value |= NTLMSSP_NEGOTIATE_56;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_KEY_EXCH() {
+ value |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_128() {
+ value |= NTLMSSP_NEGOTIATE_128;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_VERSION() {
+ value |= NTLMSSP_NEGOTIATE_VERSION;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_TARGET_INFO() {
+ value |= NTLMSSP_NEGOTIATE_TARGET_INFO;
+ return this;
+ }
+
+ public NegoFlags set_REQUEST_NON_NT_SESSION_KEY() {
+ value |= NTLMSSP_REQUEST_NON_NT_SESSION_KEY;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_IDENTIFY() {
+ value |= NTLMSSP_NEGOTIATE_IDENTIFY;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_EXTENDED_SESSION_SECURITY() {
+ value |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
+ return this;
+ }
+
+ public NegoFlags set_TARGET_TYPE_SERVER() {
+ value |= NTLMSSP_TARGET_TYPE_SERVER;
+ return this;
+ }
+
+ public NegoFlags set_TARGET_TYPE_DOMAIN() {
+ value |= NTLMSSP_TARGET_TYPE_DOMAIN;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_ALWAYS_SIGN() {
+ value |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_OEM_WORKSTATION_SUPPLIED() {
+ value |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_OEM_DOMAIN_SUPPLIED() {
+ value |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_ANONYMOUS() {
+ value |= NTLMSSP_NEGOTIATE_ANONYMOUS;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_NTLM() {
+ value |= NTLMSSP_NEGOTIATE_NTLM;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_LM_KEY() {
+ value |= NTLMSSP_NEGOTIATE_LM_KEY;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_DATAGRAM() {
+ value |= NTLMSSP_NEGOTIATE_DATAGRAM;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_SEAL() {
+ value |= NTLMSSP_NEGOTIATE_SEAL;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_SIGN() {
+ value |= NTLMSSP_NEGOTIATE_SIGN;
+ return this;
+ }
+
+ public NegoFlags set_REQUEST_TARGET() {
+ value |= NTLMSSP_REQUEST_TARGET;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_OEM() {
+ value |= NTLMSSP_NEGOTIATE_OEM;
+ return this;
+ }
+
+ public NegoFlags set_NEGOTIATE_UNICODE() {
+ value |= NTLMSSP_NEGOTIATE_UNICODE;
+ return this;
+ }
+
+ /**
+ * Example.
+ */
+
+ public static void main(String args[]) {
+
+ NegoFlags flags = new NegoFlags(0xe20882b7);
+ System.out.println("Negotiation flags: " + flags);
+
+ }
+
+}