Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split off from 0.10.0 without the reworked authentication fixes #762

Merged
merged 60 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
383dfa3
Ignore VSCode
hierynomus May 8, 2023
d0a14c7
Add NtStatus.STATUS_UNSUCCESSFUL
hierynomus May 19, 2021
a3efd24
Add NtStatus.STATUS_INSUFF_SERVER_RESOURCES (#611)
hierynomus May 19, 2021
a2d117b
Add NtStatus.STATUS_IO_REPARSE_TAG_NOT_HANDLED (#514)
hierynomus May 20, 2021
682c3e1
Update gradle build
hierynomus May 20, 2021
8983a5e
Update release plugin
hierynomus May 20, 2021
3054836
Release version: 0.11.0
hierynomus May 20, 2021
05297d7
Fix signing task dependency
hierynomus May 20, 2021
46d573e
Release version: 0.11.1
hierynomus May 20, 2021
5fb29d8
Use BCSecurityProvider by default for SMB3 compatibility (Fixes #638)
hierynomus May 28, 2021
4056519
Ensure DFS Path Referral times out after transactTimeout (Fixes #578)
hierynomus May 31, 2021
67ce970
Only add DFSPathResolver if both client and server support DFS (#640)
hierynomus May 31, 2021
f9d67c6
Upgrade Bouncy Castle to 1.68 to fix vulnerability report (#641)
hierynomus May 31, 2021
c2cdb8e
address issue #604 - stop closing the dfs share connection immediatel…
nddipiazza May 31, 2021
1ec546a
Add support for unregistering server from serverlist (Fixes #644) (#647)
hierynomus Jun 28, 2021
d687ded
Reducing logging for smb3 (#650)
ndimitry Jul 2, 2021
9ce0979
Consolidate SMBv1 error messages
hierynomus Aug 30, 2021
514436b
Upgrade BouncyCastle to 1.69
hierynomus Aug 30, 2021
2ddcaa3
Release version: 0.11.2
hierynomus Aug 30, 2021
0af7845
Ensure artifact is signed
hierynomus Aug 30, 2021
eb0a36b
Release version: 0.11.3
hierynomus Aug 30, 2021
f6d8d6d
Fix #665: Allow JCE KDF to work (#666)
pboyd04 Aug 31, 2021
cdb59ba
Use correct maxPayloadSize for encrypted packets (Fixes #668) (#683)
hierynomus Jan 19, 2022
5878ded
Read fileId as long (#693)
hannosgit Jan 31, 2022
93a45e7
File the issue that nested folder creation throw NAME EXIST error. (#…
Jan 31, 2022
1a22847
Updated build status badges (#684)
exceptionfactory Feb 4, 2022
a9a39ce
Use AceSize field when reading ACEs (#696)
cpacejo Feb 10, 2022
e79f98f
Ensure that enough bytes are cached from InputStream to get a correct…
kardashov Feb 11, 2022
7988c16
Add GH workflow for publishing
hierynomus Feb 22, 2022
cc1ea0a
Update dependencies and build file
hierynomus Feb 22, 2022
cbac919
Rename test class to *Spec
hierynomus Feb 22, 2022
421e0e9
Release version: 0.11.5
hierynomus Feb 22, 2022
e516cad
Use the hostname part of the TargetHint for DFS step 9 (fixes \#419) …
hierynomus Jun 28, 2022
537d692
Slightly reduce the locking in Connection.send and DirectTcpTransport…
hierynomus Sep 14, 2022
b667395
Fixed indentation
hierynomus Sep 14, 2022
498c095
Converting bytes written to long (Fixes #740)
hierynomus Mar 15, 2023
9e2c8df
Upgrading gradle to 8.0.2
hierynomus Mar 15, 2023
a65f5f2
Add Implementation manifest attributes (Fixes #743)
hierynomus Mar 16, 2023
07c92dc
Revert accidental comment of integration docker tasks
hierynomus Mar 16, 2023
2e3f845
Do not send SMB2EncryptionCapabilities NegotiationContext is !isEncry…
hierynomus Mar 17, 2023
7592f19
Add preliminary changelog for new release
hierynomus Mar 17, 2023
0b926eb
Ensure we call flip() on Buffer to avoid Java8 problems (Fixes #705)
hierynomus Mar 19, 2023
350c73e
Ensure path is set for rmdir to prevent accidents (Fixes #756)
hierynomus Mar 28, 2023
01d720e
Add support for reading / writing NIO ByteBuffers (#759)
laeubi Apr 28, 2023
6bf720c
Fix some sonatype warnings
hierynomus May 1, 2023
16049ea
resolve conflict with master
hierynomus May 9, 2023
1aabefe
Ignore non-semver tags for release workflow
hierynomus May 10, 2023
470b322
Small warning cleanup
hierynomus May 10, 2023
b3529fb
Setup ConnectionContext and AuthenticationContext for NTLM improvements
hierynomus May 11, 2023
5f1b9de
Refactor TargetInfo/AvPairs
hierynomus May 11, 2023
c930ce2
Added null check and rename field
hierynomus May 11, 2023
f67045e
Refactor NtlmFunctions
hierynomus May 12, 2023
7794355
Change hierarchy of Ntlm messages
hierynomus May 12, 2023
5c37afa
Next step of NTLM refactor
hierynomus May 12, 2023
de452fa
NtlmNegotiate sends Domain/Workstation/Version fields
hierynomus May 16, 2023
72fbbe5
Filter negotiateflags and use clientTargetInfo
hierynomus May 22, 2023
900621d
Rework keys in NtlmAuthenticator
hierynomus May 24, 2023
e648ab6
Change to structure of NtlmAuthenticate
hierynomus Jun 26, 2023
7d89551
Added last changes
hierynomus Jun 29, 2023
e17a275
Merge branch 'master' into working-auth
hierynomus Jul 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions WORKING_AUTH_TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Missing commit: 10001efcf7b5beee6994fb0e4a3680a6503f6eab
Extract TargetInfo to separate class and correct offsets for NtlmNegotiate (#630)

* Extract TargetInfo to separate class and correct offsets for NtlmNegotiate

* Add Target SPN AvId if NTLMSSP_REQUEST_TARGET set

* Use clientTargetInfo to calculate NTLM clientChallenge
------
Missing commit: 3e454de9a29db2ef0896af60573378ea7ba4fa4b
Fix ClassCastException (fixes \#712)
------
32 changes: 27 additions & 5 deletions src/main/java/com/hierynomus/ntlm/NtlmConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.hierynomus.ntlm;

import java.security.SecureRandom;
import java.util.Random;

import com.hierynomus.ntlm.messages.WindowsVersion;
import com.hierynomus.ntlm.messages.WindowsVersion.NtlmRevisionCurrent;
import com.hierynomus.ntlm.messages.WindowsVersion.ProductMajorVersion;
Expand All @@ -25,13 +28,14 @@ public class NtlmConfig {
private String workstationName;
private boolean integrity;
private boolean omitVersion;
private byte[] machineID;

public static NtlmConfig defaultConfig() {
return builder().build();
return builder(new SecureRandom()).build();
}

public static Builder builder() {
return new Builder();
public static Builder builder(Random r) {
return new Builder(r);
}

private NtlmConfig() {
Expand All @@ -42,6 +46,7 @@ private NtlmConfig(NtlmConfig other) {
this.workstationName = other.workstationName;
this.integrity = other.integrity;
this.omitVersion = other.omitVersion;
this.machineID = other.machineID;
}

public WindowsVersion getWindowsVersion() {
Expand All @@ -60,14 +65,20 @@ public boolean isOmitVersion() {
return omitVersion;
}

public byte[] getMachineID() {
return machineID;
}

public static class Builder {
private NtlmConfig config;

public Builder() {
public Builder(Random r) {
config = new NtlmConfig();
config.windowsVersion = new WindowsVersion(ProductMajorVersion.WINDOWS_MAJOR_VERSION_6, ProductMinorVersion.WINDOWS_MINOR_VERSION_1, 7600, NtlmRevisionCurrent.NTLMSSP_REVISION_W2K3);
config.integrity = false; // TODO temporarily disabled until we can figure out why it fails (probably mechListMIC in NegTokenTarg)
config.integrity = false;
config.omitVersion = false;
config.machineID = new byte[32];
r.nextBytes(config.machineID);
}

public Builder withWindowsVersion(WindowsVersion windowsVersion) {
Expand All @@ -90,6 +101,17 @@ public Builder withOmitVersion(boolean omitVersion) {
return this;
}

public Builder withMachineID(byte[] machineID) {
if (machineID == null) {
throw new IllegalArgumentException("MachineID must not be null");
}
if (machineID.length != 32) {
throw new IllegalArgumentException("MachineID must be 32 bytes");
}
config.machineID = machineID;
return this;
}

public NtlmConfig build() {
return new NtlmConfig(config);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class AvPairChannelBindings extends AvPair<byte[]> {
super(AvId.MsvAvChannelBindings);
}

public AvPairChannelBindings(byte[] value) {
super(AvId.MsvAvChannelBindings, value);
}

@Override
public void write(Buffer<?> buffer) {
buffer.putUInt16((int) this.avId.getValue()); // AvId (2 bytes)
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/hierynomus/ntlm/av/AvPairSingleHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public class AvPairSingleHost extends AvPair<byte[]> {
super(AvId.MsvAvSingleHost);
}

public AvPairSingleHost(byte[] value, byte[] machineID) {
super(AvId.MsvAvSingleHost, value);
this.machineID = machineID;
}

public AvPairSingleHost read(Buffer<?> buffer) throws BufferException {
buffer.readUInt16(); // AvLen (2 bytes)
buffer.readUInt32(); // Size (4 bytes)
Expand Down
84 changes: 37 additions & 47 deletions src/main/java/com/hierynomus/ntlm/messages/NtlmAuthenticate.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.hierynomus.protocol.commons.EnumWithValue;
import com.hierynomus.protocol.commons.buffer.Buffer;
import com.hierynomus.protocol.commons.buffer.Endian;
import com.hierynomus.protocol.commons.buffer.Buffer.PlainBuffer;

import static com.hierynomus.ntlm.messages.Utils.*;

Expand All @@ -45,7 +46,7 @@ public NtlmAuthenticate(
byte[] lmResponse, byte[] ntResponse,
String userName, String domainName, String workstation,
byte[] encryptedRandomSessionKey, Set<NtlmNegotiateFlag> negotiateFlags,
WindowsVersion version, boolean isIntegrityEnabled, boolean isOmitVersion) {
WindowsVersion version) {
super(negotiateFlags, version);
this.lmResponse = ensureNotNull(lmResponse);
this.ntResponse = ensureNotNull(ntResponse);
Expand All @@ -54,70 +55,58 @@ public NtlmAuthenticate(
this.workstation = ensureNotNull(workstation);
this.encryptedRandomSessionKey = ensureNotNull(encryptedRandomSessionKey);
this.negotiateFlags = negotiateFlags;
this.integrityEnabled = isIntegrityEnabled;
this.omitVersion = isOmitVersion;
}

@Override
public void write(Buffer.PlainBuffer buffer) {
private int getBaseMessageSize() {
int baseMessageSize = 64;
if (integrityEnabled) {
baseMessageSize += 16;
}

if (!omitVersion) {
if (negotiateFlags.contains(NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_VERSION) || mic != null) {
baseMessageSize += 8;
}

writeNtlmAuthenticate(buffer, baseMessageSize);

// MIC (16 bytes)
if (mic != null) {
buffer.putRawBytes(mic);
} else if (integrityEnabled) {
buffer.putUInt64(0L);
buffer.putUInt64(0L);
} else {
// Skipping MIC, not enabled.
baseMessageSize += 16;
}

// Payload
buffer.putRawBytes(lmResponse);
buffer.putRawBytes(ntResponse);
buffer.putRawBytes(domainName);
buffer.putRawBytes(userName);
buffer.putRawBytes(workstation);
buffer.putRawBytes(encryptedRandomSessionKey);
return baseMessageSize;
}

public void setMic(byte[] mic) {
this.mic = mic;
}
@Override
public void write(PlainBuffer buffer) {

public void writeNtlmAuthenticate(Buffer.PlainBuffer buffer, int baseMessageSize) {
buffer.putString("NTLMSSP\0", Charsets.UTF_8); // Signature (8 bytes)
buffer.putUInt32(0x03); // MessageType (4 bytes)

int offset = baseMessageSize; // for the offset
int offset = getBaseMessageSize(); // for the offset
offset = writeOffsettedByteArrayFields(buffer, lmResponse, offset); // LmChallengeResponseFields (8 bytes)
offset = writeOffsettedByteArrayFields(buffer, ntResponse, offset); // NtChallengeResponseFields (8 bytes)
offset = writeOffsettedByteArrayFields(buffer, domainName, offset); // DomainNameFields (8 bytes)
offset = writeOffsettedByteArrayFields(buffer, userName, offset); // UserNameFields (8 bytes)
offset = writeOffsettedByteArrayFields(buffer, workstation, offset); // WorkstationFields (8 bytes)
if (negotiateFlags.contains(NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_KEY_EXCH)) { // TODO probably unnecessary check
offset = writeOffsettedByteArrayFields(buffer, encryptedRandomSessionKey, offset);
} else {
offset = writeOffsettedByteArrayFields(buffer, EMPTY, offset);
}
offset = writeOffsettedByteArrayFields(buffer, encryptedRandomSessionKey, offset); // EncryptedRandomSessionKeyFields (8 bytes)

buffer.putUInt32(EnumWithValue.EnumUtils.toLong(negotiateFlags)); // NegotiateFlags (4 bytes)

// If `omitVersion`, we skip rendering the Version, as some servers don't like it.
if (negotiateFlags.contains(NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_VERSION)) {
buffer.putRawBytes(getVersion()); // Version (8 bytes)
} else if (!omitVersion) {
buffer.putUInt64(0L);
} else if (mic != null) {
buffer.putUInt64(0L); // If the MIC is present, the Version field MUST be present.
}

if (mic != null) {
buffer.putRawBytes(mic, 0, 16); // MIC (16 bytes)
}

// Payload
buffer.putRawBytes(lmResponse);
buffer.putRawBytes(ntResponse);
buffer.putRawBytes(domainName);
buffer.putRawBytes(userName);
buffer.putRawBytes(workstation);
buffer.putRawBytes(encryptedRandomSessionKey);
}

public void setMic(byte[] mic) {
this.mic = mic;
}

/**
Expand All @@ -136,16 +125,17 @@ public byte[] getVersion() {
return plainBuffer.getCompactData();
}


@Override
public String toString() {
return "NtlmAuthenticate{\n" +
" mic=" + (mic != null ? ByteArrayUtils.printHex(mic) : "[]") + ",\n" +
" lmResponse=" + ByteArrayUtils.printHex(lmResponse) + ",\n" +
" ntResponse=" + ByteArrayUtils.printHex(ntResponse) + ",\n" +
" domainName='" + NtlmFunctions.unicode(domainName) + "',\n" +
" userName='" + NtlmFunctions.unicode(userName) + "',\n" +
" workstation='" + NtlmFunctions.unicode(workstation) + "',\n" +
" encryptedRandomSessionKey=[<secret>],\n" +
'}';
" mic=" + (mic != null ? ByteArrayUtils.printHex(mic) : "[]") + ",\n" +
" lmResponse=" + ByteArrayUtils.printHex(lmResponse) + ",\n" +
" ntResponse=" + ByteArrayUtils.printHex(ntResponse) + ",\n" +
" domainName='" + NtlmFunctions.unicode(domainName) + "',\n" +
" userName='" + NtlmFunctions.unicode(userName) + "',\n" +
" workstation='" + NtlmFunctions.unicode(workstation) + "',\n" +
" encryptedRandomSessionKey=[<secret>],\n" +
'}';
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/hierynomus/smbj/SmbConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ public static SmbConfig createDefaultConfig() {
public static Builder builder() {
Builder b = new Builder()
.withClientGuid(UUID.randomUUID())
.withRandomProvider(new SecureRandom())
.withSecurityProvider(getDefaultSecurityProvider())
.withSocketFactory(new ProxySocketFactory())
.withSigningRequired(false)
Expand Down Expand Up @@ -141,6 +140,7 @@ private static List<Factory.Named<Authenticator>> getDefaultAuthenticators() {

private SmbConfig() {
dialects = EnumSet.noneOf(SMB2Dialect.class);
random = new SecureRandom();
authenticators = new ArrayList<>();
}

Expand Down Expand Up @@ -281,7 +281,7 @@ public static class Builder {

Builder() {
config = new SmbConfig();
ntlmConfigBuilder = NtlmConfig.builder();
ntlmConfigBuilder = NtlmConfig.builder(config.random);
}

public Builder withRandomProvider(Random random) {
Expand Down
Loading