Skip to content

Commit

Permalink
Fixed error with anonymous authentication (Fixes #779) (#781)
Browse files Browse the repository at this point in the history
* Fixed error with anonymous authentication (Fixes #779)

* Add license headers
  • Loading branch information
hierynomus authored Aug 7, 2023
1 parent 6e8059f commit 4633709
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 19 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ testing {
}

sources {
java {
srcDirs = ['src/it/java']
}
groovy {
srcDirs = ['src/it/groovy']
}
Expand Down
66 changes: 66 additions & 0 deletions src/it/java/com/hierynomus/smbj/AnonymousIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (C)2016 - SMBJ Contributors
*
* Licensed 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 com.hierynomus.smbj;

import org.junit.jupiter.api.Test;

import com.hierynomus.mssmb2.SMB2Dialect;
import com.hierynomus.security.bc.BCSecurityProvider;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.session.SMB2GuestSigningRequiredException;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.Share;

import static org.junit.jupiter.api.Assertions.*;
import static com.hierynomus.smbj.testing.TestingUtils.*;

public class AnonymousIntegrationTest {

private SmbConfig base = SmbConfig.builder().withDialects(SMB2Dialect.SMB_3_1_1).withEncryptData(true).withSigningRequired(false).withMultiProtocolNegotiate(true).withDfsEnabled(true).withSecurityProvider(new BCSecurityProvider()).build();

@Test
public void shouldAuthenticateAnonymous() throws Exception {
withConnectedClient(base, (connection) -> {
try (Session session = connection.authenticate(AuthenticationContext.anonymous())) {
assertNotNull(session.getSessionId());
}
});
}

@Test
public void shouldFailConnectingAnonymousWhenSigningRequired() throws Exception {
SmbConfig config = SmbConfig.builder(base).withSigningRequired(true).build();
assertThrows(SMB2GuestSigningRequiredException.class, () -> withConnectedClient(config, (connection) -> {
try (Session session = connection.authenticate(AuthenticationContext.anonymous())) {
fail("Should not be able to connect");
}
}));
}

@Test
public void shouldConnectToPublicShare() throws Exception {
withConnectedClient(base, (connection) -> {
try (Session session = connection.authenticate(AuthenticationContext.anonymous())) {
try (Share share = session.connectShare("public")) {
assertInstanceOf(DiskShare.class, share);
assertTrue(share.isConnected());
assertNotNull(share.getTreeConnect().getTreeId());
}
}
});
}
}
36 changes: 36 additions & 0 deletions src/it/java/com/hierynomus/smbj/testing/TestingUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C)2016 - SMBJ Contributors
*
* Licensed 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 com.hierynomus.smbj.testing;

import java.util.function.Consumer;

import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.connection.Connection;

public class TestingUtils {
public static void withConnectedClient(SmbConfig config, ConsumerWithError<Connection> f) throws Exception {
try (SMBClient client = new SMBClient(config)) {
try (Connection connection = client.connect("127.0.0.1")) {
f.accept(connection);
}
}
}

public interface ConsumerWithError<T> {
void accept(T val) throws Exception;
}
}
11 changes: 10 additions & 1 deletion src/main/java/com/hierynomus/ntlm/NtlmConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public static Builder builder(Random r) {
return new Builder(r);
}

public static Builder builder(NtlmConfig baseConfig) {
return new Builder(baseConfig);
}

private NtlmConfig() {
}

Expand Down Expand Up @@ -74,13 +78,18 @@ public static class 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.windowsVersion = new WindowsVersion(ProductMajorVersion.WINDOWS_MAJOR_VERSION_6,
ProductMinorVersion.WINDOWS_MINOR_VERSION_1, 7600, NtlmRevisionCurrent.NTLMSSP_REVISION_W2K3);
config.integrity = true;
config.omitVersion = false;
config.machineID = new byte[32];
r.nextBytes(config.machineID);
}

public Builder(NtlmConfig baseConfig) {
config = new NtlmConfig(baseConfig);
}

public Builder withWindowsVersion(WindowsVersion windowsVersion) {
config.windowsVersion = windowsVersion;
return this;
Expand Down
41 changes: 25 additions & 16 deletions src/main/java/com/hierynomus/smbj/SmbConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,30 @@ public static SmbConfig createDefaultConfig() {
}

public static Builder builder() {
Builder b = new Builder()
.withClientGuid(UUID.randomUUID())
.withSecurityProvider(getDefaultSecurityProvider())
.withSocketFactory(new ProxySocketFactory())
.withSigningRequired(false)
.withDfsEnabled(false)
.withMultiProtocolNegotiate(false)
.withBufferSize(DEFAULT_BUFFER_SIZE)
.withTransportLayerFactory(DEFAULT_TRANSPORT_LAYER_FACTORY)
.withSoTimeout(DEFAULT_SO_TIMEOUT, DEFAULT_SO_TIMEOUT_UNIT)
.withDialects(SMB_3_1_1, SMB_3_0_2, SMB_3_0, SMB_2_1, SMB_2_0_2)
// order is important. The authenticators listed first will be selected
.withAuthenticators(getDefaultAuthenticators())
.withTimeout(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT)
.withClientGSSContextConfig(GSSContextConfig.createDefaultConfig())
.withEncryptData(false);
Builder b = new Builder()
.withClientGuid(UUID.randomUUID())
.withSecurityProvider(getDefaultSecurityProvider())
.withSocketFactory(new ProxySocketFactory())
.withSigningRequired(false)
.withDfsEnabled(false)
.withMultiProtocolNegotiate(false)
.withBufferSize(DEFAULT_BUFFER_SIZE)
.withTransportLayerFactory(DEFAULT_TRANSPORT_LAYER_FACTORY)
.withSoTimeout(DEFAULT_SO_TIMEOUT, DEFAULT_SO_TIMEOUT_UNIT)
.withDialects(SMB_3_1_1, SMB_3_0_2, SMB_3_0, SMB_2_1, SMB_2_0_2)
// order is important. The authenticators listed first will be selected
.withAuthenticators(getDefaultAuthenticators())
.withTimeout(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT)
.withClientGSSContextConfig(GSSContextConfig.createDefaultConfig())
.withEncryptData(false);

return b;
}

public static Builder builder(SmbConfig baseConfig) {
return new Builder(baseConfig);
}

private static SecurityProvider getDefaultSecurityProvider() {
return new BCSecurityProvider();
}
Expand Down Expand Up @@ -284,6 +288,11 @@ public static class Builder {
ntlmConfigBuilder = NtlmConfig.builder(config.random);
}

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

public Builder withRandomProvider(Random random) {
if (random == null) {
throw new IllegalArgumentException("Random provider may not be null");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public SMBSessionBuilder(Connection connection, SmbConfig config, SessionFactory
public Session establish(AuthenticationContext authContext) {
try {
Authenticator authenticator = getAuthenticator(authContext);
if (authenticator instanceof NtlmAuthenticator && config.getNtlmConfig().isIntegrityEnabled()) {
if (authenticator instanceof NtlmAuthenticator && config.getNtlmConfig().isIntegrityEnabled() && !(authContext.isAnonymous() && !(authContext.isGuest()))) {
authenticator = new NtlmSealer((NtlmAuthenticator) authenticator);
}

Expand Down Expand Up @@ -163,7 +163,9 @@ private Session setupSession(BuilderContext ctx) throws IOException {

SessionContext context = session.getSessionContext();
processAuthenticationToken(ctx, response.getSecurityBuffer());
context.setSessionKey(new SecretKeySpec(ctx.sessionKey, HMAC_SHA256_ALGORITHM));
if (!ctx.authContext.isAnonymous() && !ctx.authContext.isGuest()) {
context.setSessionKey(new SecretKeySpec(ctx.sessionKey, HMAC_SHA256_ALGORITHM));
}
if (dialect == SMB2Dialect.SMB_3_1_1) {
updatePreauthIntegrityValue(ctx, context, ctx.request);
}
Expand Down

0 comments on commit 4633709

Please sign in to comment.