Skip to content

Commit

Permalink
WIP marshalling/unmarshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
M. Noerder-Tuitje committed Jan 8, 2024
1 parent 74dd4d3 commit 97ec9ee
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 3 deletions.
99 changes: 97 additions & 2 deletions src/main/java/com/hierynomus/ntlm/messages/NtlmChallenge.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import java.io.IOException;
import java.util.EnumSet;

import static com.hierynomus.ntlm.messages.NtlmNegotiateFlag.NTLMSSP_REQUEST_TARGET;
import static com.hierynomus.ntlm.messages.NtlmNegotiateFlag.*;

/**
* [MS-NLMP].pdf 2.2.1.2 CHALLENGE_MESSAGE
Expand Down Expand Up @@ -66,6 +66,41 @@ public NtlmChallenge(NtlmNegotiate type1, byte[] challenge, String target) {
"coo" : target);
}


static void writeULong ( byte[] dest, int offset, int ulong ) {
dest[ offset ] = (byte) ( ulong & 0xff );
dest[ offset + 1 ] = (byte) ( ulong >> 8 & 0xff );
dest[ offset + 2 ] = (byte) ( ulong >> 16 & 0xff );
dest[ offset + 3 ] = (byte) ( ulong >> 24 & 0xff );
}


static void writeUShort ( byte[] dest, int offset, int ushort ) {
dest[ offset ] = (byte) ( ushort & 0xff );
dest[ offset + 1 ] = (byte) ( ushort >> 8 & 0xff );
}


static int writeSecurityBuffer ( byte[] dest, int offset, byte[] src ) {
int length = ( src != null ) ? src.length : 0;
if ( length == 0 ) {
return offset + 4;
}
writeUShort(dest, offset, length);
writeUShort(dest, offset + 2, length);
return offset + 4;
}


static int writeSecurityBufferContent ( byte[] dest, int pos, int off, byte[] src ) {
writeULong(dest, off, pos);
if ( src != null && src.length > 0 ) {
System.arraycopy(src, 0, dest, pos, src.length);
return src.length;
}
return 0;
}

@Override
public void read(Buffer.PlainBuffer buffer) throws Buffer.BufferException {
buffer.readString(Charsets.UTF_8, 8); // Signature (8 bytes) (NTLMSSP\0)
Expand All @@ -80,6 +115,66 @@ public void read(Buffer.PlainBuffer buffer) throws Buffer.BufferException {
readTargetInfo(buffer);
}

@Override
public void write(Buffer.PlainBuffer buffer) {
try {
int flags = getFlags(this.negotiateFlags);
String targetName = this.targetName;

// Header
buffer.putRawBytes("NTLMSP\0".getBytes(Charsets.UTF_8));

// MessageType
buffer.putUInt32(NTLMSSP_TYPE2);

// TargetNameFields
if (negotiateFlags.contains(NTLMSSP_REQUEST_TARGET)){
byte[] targetBytes = new byte[0];
targetBytes = (flags & NTLMSSP_NEGOTIATE_UNICODE.getValue()) != 0 ? targetName.getBytes(UNI_ENCODING)
: targetName.toUpperCase().getBytes(OEM_ENCODING);
targetNameLen = targetBytes.length;
targetNameBufferOffset= 64;
buffer.putUInt16(targetNameLen);
buffer.putUInt16(targetNameLen);
buffer.putUInt32(targetNameBufferOffset);

} else {
buffer.putUInt16(0);
buffer.putUInt16(0);
buffer.putUInt32(0);
}

// Flags
buffer.putUInt32(flags);

// ServerChallenge
buffer.putRawBytes(serverChallenge);


// TargetInfoFields
if (negotiateFlags.contains(NTLMSSP_NEGOTIATE_TARGET_INFO) && this.targetInfo != null) {
this.targetInfo.writeTo(buffer);
flags |= NTLMSSP_NEGOTIATE_TARGET_INFO.getValue();
}

// Version
buffer.putUInt32(0);
buffer.putUInt32(0);

// TargetName
if (negotiateFlags.contains(NTLMSSP_REQUEST_TARGET)){
byte[] targetBytes = new byte[0];
targetBytes = (flags & NTLMSSP_NEGOTIATE_UNICODE.getValue()) != 0 ? targetName.getBytes(UNI_ENCODING)
: targetName.toUpperCase().getBytes(OEM_ENCODING);
buffer.putRawBytes(targetBytes);
}


} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void readTargetInfo(Buffer.PlainBuffer buffer) throws Buffer.BufferException {
if (targetInfoLen > 0) {
// Move to where buffer begins
Expand Down Expand Up @@ -113,7 +208,7 @@ private void readTargetNameFields(Buffer.PlainBuffer buffer) throws Buffer.Buffe
}

private void readTargetInfoFields(Buffer.PlainBuffer buffer) throws Buffer.BufferException {
if (negotiateFlags.contains(NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_TARGET_INFO)) {
if (negotiateFlags.contains(NTLMSSP_NEGOTIATE_TARGET_INFO)) {
targetInfoLen = buffer.readUInt16(); // TargetInfoLen (2 bytes)
buffer.skip(2); // TargetInfoMaxLen (2 bytes)
targetInfoBufferOffset = buffer.readUInt32AsInt(); // TargetInfoBufferOffset (2 bytes)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/hierynomus/ntlm/messages/NtlmPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class NtlmPacket implements Packet<Buffer.PlainBuffer> {
protected static final int NTLMSSP_TYPE1 = 0x1;
protected static final int NTLMSSP_TYPE2 = 0x2;
protected static final int NTLMSSP_TYPE3 = 0x3;
protected EnumSet<NtlmNegotiateFlag> negotiateFlags;
protected EnumSet<NtlmNegotiateFlag> negotiateFlags = EnumSet.of(NTLMSSP_NEGOTIATE_NTLM);

protected static final String OEM_ENCODING = "cp850";
protected static final String UNI_ENCODING = "UTF-16LE";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hierynomus.ntlm.messages;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
* @author M. Noerder-Tuitje (CROWDCODE)
*/
class NtlmAuthenticateTest {


@Test
void write() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ class NtlmChallengeSpec extends Specification implements SampleMessages {
m.targetInfo == null
}

def "Should correctly write a challenge String"(){
given:
String authorization ="TlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw==";
String challenge = "76C8CQ+RNTfEBpWLdNxNHQ=="
when:
def m = new NtlmNegotiate(Base64.decoder.decode(authorization));
def n = new NtlmChallenge(m,Base64.decoder.decode(challenge),null);
then:
m != null
n != null
}

def "Should correctly decode NTLMv2 NtlmChallenge message"() {
given:
def m = new NtlmChallenge()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,13 @@ class NtlmNegotiateFlagSpec extends Specification {
0xa0880205L | NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_UNICODE

}

def "Should correctly write a challenge String"(){
given:
String authorization ="TlRMTVNTUAABAAAAAYIIogAAAAAoAAAAAAAAACgAAAAFASgKAAAADw==";
when:
def m = new NtlmNegotiate(Base64.decoder.decode(authorization));
then:
m != null
}
}

0 comments on commit 97ec9ee

Please sign in to comment.