Skip to content

Commit

Permalink
Development -> Master (#162)
Browse files Browse the repository at this point in the history
* Integration tests (#161)
* Bumping smbj to 0.11.1
* Adding Bouncy Castle dep
* Bump jdk target to 1.8 to align with smbj
* Add integration tests for SRVSVC
  • Loading branch information
asmith-r7 authored Aug 25, 2021
1 parent 0109dde commit 8cc3ca2
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
key: ${{ runner.os }}-java${{ matrix.java }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-java${{ matrix.java }}-m2
- name: Run Tests
run: mvn test -Dgpg.skip -Dmaven.javadoc.skip=true -B -V -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
run: mvn verify -Dgpg.skip -Dmaven.javadoc.skip=true -B -V -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Add to your pom.xml:
<dependency>
<groupId>com.rapid7.client</groupId>
<artifactId>dcerpc</artifactId>
<version>0.10.0</version>
<version>0.11.0</version>
</dependency>
```

Expand Down Expand Up @@ -83,7 +83,8 @@ try (final Connection smbConnection = smbClient.connect("aaa.bbb.ccc.ddd")) {

final RPCTransport transport = SMBTransportFactories.SRVSVC.getTransport(session);
final ServerService serverService = new ServerService(transport);
final List<NetShareInfo0> shares = serverService.getShares();
// Get shares at information level 0
final List<NetShareInfo0> shares = serverService.getShares0();
for (final NetShareInfo0 share : shares) {
System.out.println(share);
}
Expand Down
114 changes: 103 additions & 11 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@
<thirdparty.commons-lang3.version>3.4</thirdparty.commons-lang3.version>
<thirdparty.guava.version>18.0</thirdparty.guava.version>
<thirdparty.hamcrest.version>1.3</thirdparty.hamcrest.version>
<thirdparty.junit.version>4.13.1</thirdparty.junit.version>
<thirdparty.junit.version>5.7.2</thirdparty.junit.version>
<thirdparty.mockito.version>1.10.19</thirdparty.mockito.version>
<thirdparty.smbj.version>0.10.0</thirdparty.smbj.version>
<thirdparty.smbj.version>0.11.1</thirdparty.smbj.version>
<thirdparty.testng.version>6.11</thirdparty.testng.version>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
<thirdparty.bouncycastle.version>1.60</thirdparty.bouncycastle.version>
<thirdparty.testcontainers.version>1.16.0</thirdparty.testcontainers.version>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

Expand All @@ -79,6 +81,11 @@
<artifactId>smbj</artifactId>
<version>${thirdparty.smbj.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${thirdparty.bouncycastle.version}</version>
</dependency>

<!-- Test dependencies. -->
<!-- 3rdparty dependencies. -->
Expand All @@ -88,12 +95,6 @@
<version>${thirdparty.hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${thirdparty.junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand All @@ -106,6 +107,49 @@
<version>${thirdparty.testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${thirdparty.testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${thirdparty.testcontainers.version}</version>
<scope>test</scope>
</dependency>
<!-- Needed for test containers logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${thirdparty.junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${thirdparty.junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${thirdparty.junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${thirdparty.junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -122,8 +166,56 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<version>2.22.2</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<testSourceDirectory>src/integration-test/java</testSourceDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/integration-test/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-test-resource</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/integration-test/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
92 changes: 92 additions & 0 deletions src/integration-test/java/IntegrationTestsIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import com.rapid7.client.dcerpc.msrrp.RegistryService;
import com.rapid7.client.dcerpc.mssrvs.ServerService;
import com.rapid7.client.dcerpc.transport.RPCTransport;
import com.rapid7.client.dcerpc.transport.SMBTransportFactories;
import com.hierynomus.mssmb2.SMB2Dialect;
import com.hierynomus.security.bc.BCSecurityProvider;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import static org.junit.jupiter.api.Assertions.assertEquals;

@Testcontainers
class IntegrationTestsIT
{
private static final Path DOCKER_BUILD_CONTEXT = Paths.get("src", "integration-test", "resources", "docker-image");

@Container
private static final GenericContainer<?> sambaContainer = new GenericContainer(
new ImageFromDockerfile()
.withFileFromPath(".", DOCKER_BUILD_CONTEXT))
.withExposedPorts(445);

@ParameterizedTest
@MethodSource("testWinRegDoesKeyExistForEachSupportedSMBVersionArgs")
@DisplayName("Test registry service key exists function for different SMB protocols")
void testWinRegDoesKeyExistForEachSupportedSMBVersion(String keyPath, boolean shouldExist, SMB2Dialect dialect)
throws IOException
{
final SmbConfig smbConfig = SmbConfig.builder().withSecurityProvider(new BCSecurityProvider()).withDialects(dialect).build();
final SMBClient smbClient = new SMBClient(smbConfig);
try (final Connection smbConnection = smbClient.connect("localhost", sambaContainer.getMappedPort(445))) {
final AuthenticationContext smbAuthenticationContext = new AuthenticationContext("smbj", "smbj".toCharArray(), "");
final Session session = smbConnection.authenticate(smbAuthenticationContext);

final RPCTransport transport = SMBTransportFactories.WINREG.getTransport(session);
final RegistryService registryService = new RegistryService(transport);

assertEquals(dialect, smbConnection.getNegotiatedProtocol().getDialect());
assertEquals(shouldExist, registryService.doesKeyExist("HKLM", keyPath));
}
}

@ParameterizedTest
@EnumSource(value = SMB2Dialect.class, names = {"SMB_2_0_2", "SMB_2_1", "SMB_3_0", "SMB_3_0_2", "SMB_3_1_1"})
@DisplayName("Test service service enumerates shares for different SMB protocols")
void testSRVSVCReturnsSharesForEachSupportedSMBVersion(SMB2Dialect dialect)
throws IOException
{
final SmbConfig smbConfig = SmbConfig.builder().withSecurityProvider(new BCSecurityProvider()).withDialects(dialect).build();
final SMBClient smbClient = new SMBClient(smbConfig);
try (final Connection smbConnection = smbClient.connect("localhost", sambaContainer.getMappedPort(445))) {
final AuthenticationContext smbAuthenticationContext = new AuthenticationContext("smbj", "smbj".toCharArray(), "");
final Session session = smbConnection.authenticate(smbAuthenticationContext);

final RPCTransport transport = SMBTransportFactories.SRVSVC.getTransport(session);
final ServerService serverService = new ServerService(transport);

assertEquals(dialect, smbConnection.getNegotiatedProtocol().getDialect());
assertEquals(5, serverService.getShares0().size());
}
}

static Stream<Arguments> testWinRegDoesKeyExistForEachSupportedSMBVersionArgs() {
return Stream.of(
Arguments.of("Software", true, SMB2Dialect.SMB_3_1_1),
Arguments.of("not_exist", false, SMB2Dialect.SMB_3_1_1),
Arguments.of("Software", true, SMB2Dialect.SMB_3_0_2),
Arguments.of("not_exist", false, SMB2Dialect.SMB_3_0_2),
Arguments.of("Software", true, SMB2Dialect.SMB_3_0),
Arguments.of("not_exist", false, SMB2Dialect.SMB_3_0),
Arguments.of("Software", true, SMB2Dialect.SMB_2_1),
Arguments.of("not_exist", false, SMB2Dialect.SMB_2_1),
Arguments.of("Software", true, SMB2Dialect.SMB_2_0_2),
Arguments.of("not_exist", false, SMB2Dialect.SMB_2_0_2)
);
}
}
23 changes: 23 additions & 0 deletions src/integration-test/resources/docker-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM alpine:3.7

RUN apk update && apk add --no-cache tini samba samba-common-tools supervisor bash

ENV SMB_USER smbj
ENV SMB_PASSWORD smbj

COPY smb.conf /etc/samba/smb.conf
COPY supervisord.conf /etc/supervisord.conf
COPY entrypoint.sh /entrypoint.sh
ADD public /opt/samba/share

RUN mkdir -p /opt/samba/readonly /opt/samba/user /opt/samba/dfs && \
chmod 777 /opt/samba/readonly /opt/samba/user /opt/samba/dfs && \
adduser -s /bin/false "$SMB_USER" -D $SMB_PASSWORD && \
(echo "$SMB_PASSWORD"; echo "$SMB_PASSWORD" ) | pdbedit -a -u "$SMB_USER" && \
chmod ugo+x /entrypoint.sh

EXPOSE 137/udp 138/udp 139 445

ENTRYPOINT ["/sbin/tini", "/entrypoint.sh"]
CMD ["supervisord"]

26 changes: 26 additions & 0 deletions src/integration-test/resources/docker-image/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
set -e

: "${SMB_USER:=smbuser}"
: "${SMB_PASSWORD:=smbpassword}"
#
#for netdev in /sys/class/net/*; do
# netdev=${netdev##*/}
# if [[ "$netdev" != "lo" ]]; then
# break
# fi
#done
#subnet=$(ip addr show "$netdev" | sed -n 's/.*inet \([0-9\.]*\/[0-9]*\) .*/\1/p')
#ip_address=${subnet%%/*}

ip_address="127.0.0.1"

# Create DFS links
# - /public -> public share
# - /user -> user share
# - /firstfail-public -> first listed server fails, second -> public share
ln -s "msdfs:${ip_address}\\public" /opt/samba/dfs/public
ln -s "msdfs:${ip_address}\\user" /opt/samba/dfs/user
ln -s "msdfs:192.0.2.1\\notthere,${ip_address}\\public" /opt/samba/dfs/firstfail-public

exec "$@"
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hi there!
61 changes: 61 additions & 0 deletions src/integration-test/resources/docker-image/smb.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[global]
security = user

load printers = no
printcap name = /dev/null
printing = bsd

unix charset = UTF-8
dos charset = CP932

workgroup = WORKGROUP

server string = %h server (Samba, Ubuntu)
dns proxy = no
interfaces = 192.168.2.0/24 eth0
bind interfaces only = yes
log file = /var/log/samba/log.%m
max log size = 1000
syslog = 0
panic action = /usr/share/samba/panic-action %d
server role = standalone server
passdb backend = tdbsam
obey pam restrictions = yes
unix password sync = yes
passwd program = /usr/bin/passwd %u
passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
pam password change = yes
map to guest = Bad User
usershare allow guests = yes
host msdfs = yes

[public]
path = /opt/samba/share
writable = yes
printable = no
public = yes
guest only = yes
create mode = 0777
directory mode = 0777

[readonly]
path = /opt/samba/readonly
writable = no
printable = no
public = no

[user]
path = /opt/samba/user
writable = yes
printable = no
public = no
create mode = 0777
directory mode = 0777

[dfs]
path = /opt/samba/dfs
writable = no
printable = no
public = yes
guest ok = yes
msdfs root = yes
14 changes: 14 additions & 0 deletions src/integration-test/resources/docker-image/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[supervisord]
nodaemon=true
/* user=root */
loglevel=info

[program:smbd]
/* command=/usr/sbin/smbd -i --daemon --foreground --log-stdout */
command=/usr/sbin/smbd --daemon --foreground --log-stdout
redirect_stderr=true

[program:nmbd]
/* command=/usr/sbin/nmbd -i --daemon --foreground --log-stdout */
command=/usr/sbin/nmbd --daemon --foreground --log-stdout
redirect_stderr=true
Loading

0 comments on commit 8cc3ca2

Please sign in to comment.