GH-208: Allow setting of SMB min/max versions
Fixes https://github.com/spring-projects/spring-integration-extensions/issues/208 * Updated to be able to use min/max SMB version property settings * cleanup of formatting of file * Updated based on review comments * Updated readme for new functionality * Some polishing of readme and follow current naming conventions * Updated, missed naming convention on Javadoc * Updated per review comments
This commit is contained in:
committed by
Artem Bilan
parent
e91cb382e7
commit
d4f42cb6b8
@@ -3,7 +3,7 @@ Spring Integration SMB Support
|
||||
|
||||
## Introduction
|
||||
|
||||
This module add Spring Integration support for [Server Message Block][] (SMB).
|
||||
This module adds Spring Integration support for [Server Message Block][] (SMB).
|
||||
|
||||
[Server Message Block]: https://en.wikipedia.org/wiki/Server_Message_Block
|
||||
|
||||
@@ -23,9 +23,13 @@ Put the following block into pom.xml if using Maven:
|
||||
|
||||
## Changes
|
||||
|
||||
##### Version 1.1
|
||||
* Updated to use the latest version of the [JCIFS](https://github.com/codelibs/jcifs) library
|
||||
* SMB2 (2.02 protocol level) support, some SMB3 support
|
||||
|
||||
##### Version 1.2
|
||||
* Ability to set the SMB min/max versions in the `SmbSessionFactory` via configuration in the JCIFS library
|
||||
|
||||
## Overview
|
||||
|
||||
The Java CIFS Client Library has been chosen as a Java implementation for the CIFS/SMB networking protocol.
|
||||
@@ -46,15 +50,37 @@ For XML configuration the `<int-smb:inbound-channel-adapter>` component is provi
|
||||
There is no (yet) some SMB specific requirements for files transferring to SMB, so for XML `<int-smb:outbound-channel-adapter>` component we simply reuse an existing `FileTransferringMessageHandler`.
|
||||
In case of Java configuration that `FileTransferringMessageHandler` should be supplied with the `SmbSessionFactory` (or `SmbRemoteFileTemplate`).
|
||||
|
||||
@ServiceActivator(inputChannel = "storeToSmb")
|
||||
@Bean
|
||||
public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) {
|
||||
FileTransferringMessageHandler<SmbFile> handler =
|
||||
new FileTransferringMessageHandler<>(smbSessionFactory);
|
||||
handler.setRemoteDirectoryExpression(
|
||||
new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(m ->
|
||||
m.getHeaders().get(FileHeaders.FILENAME, String.class) + ".test");
|
||||
handler.setAutoCreateDirectory(true);
|
||||
return handler;
|
||||
}
|
||||
````java
|
||||
@ServiceActivator(inputChannel = "storeToSmb")
|
||||
@Bean
|
||||
public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) {
|
||||
FileTransferringMessageHandler<SmbFile> handler =
|
||||
new FileTransferringMessageHandler<>(smbSessionFactory);
|
||||
handler.setRemoteDirectoryExpression(
|
||||
new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(m ->
|
||||
m.getHeaders().get(FileHeaders.FILENAME, String.class) + ".test");
|
||||
handler.setAutoCreateDirectory(true);
|
||||
return handler;
|
||||
}
|
||||
````
|
||||
|
||||
### Setting SMB Protocol Min/Max Versions
|
||||
|
||||
Example: To set a minimum version of SMB 2.1 and a maximum version of SMB 3.1.1
|
||||
|
||||
````java
|
||||
@Bean
|
||||
public SmbSessionFactory smbSessionFactory() {
|
||||
SmbSessionFactory smbSession = new SmbSessionFactory();
|
||||
smbSession.setHost("myHost");
|
||||
smbSession.setPort(445);
|
||||
smbSession.setDomain("myDomain");
|
||||
smbSession.setUsername("myUser");
|
||||
smbSession.setPassword("myPassword");
|
||||
smbSession.setShareAndDir("myShareAndDir");
|
||||
smbSession.setSmbMinVersion(DialectVersion.SMB210);
|
||||
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
|
||||
return smbSession;
|
||||
}
|
||||
````
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2018 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,8 @@ import java.net.URISyntaxException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import jcifs.DialectVersion;
|
||||
|
||||
/**
|
||||
* Data holder class for a SMB share configuration.
|
||||
*
|
||||
@@ -31,8 +33,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Markus Spann
|
||||
* @author Prafull Kumar Soni
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 1.0
|
||||
* @author Gregory Bragg
|
||||
*/
|
||||
public class SmbConfig {
|
||||
|
||||
@@ -52,6 +53,18 @@ public class SmbConfig {
|
||||
|
||||
private boolean useTempFile = false;
|
||||
|
||||
/**
|
||||
* Defaults to and follows the jCIFS library default of 'SMB1'
|
||||
* @since 1.2
|
||||
*/
|
||||
private DialectVersion smbMinVersion = DialectVersion.SMB1;
|
||||
|
||||
/**
|
||||
* Defaults to and follows the jCIFS library default of 'SMB210'
|
||||
* @since 1.2
|
||||
*/
|
||||
private DialectVersion smbMaxVersion = DialectVersion.SMB210;
|
||||
|
||||
public SmbConfig() {
|
||||
}
|
||||
|
||||
@@ -134,6 +147,46 @@ public class SmbConfig {
|
||||
return this.useTempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the desired minimum SMB version value for what the Windows server will allow
|
||||
* during protocol transport negotiation.
|
||||
* @return one of SMB1, SMB202, SMB210, SMB300, SMB302 or SMB311
|
||||
* @since 1.2
|
||||
*/
|
||||
public DialectVersion getSmbMinVersion() {
|
||||
return this.smbMinVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired minimum SMB version value for what the Windows server will allow
|
||||
* during protocol transport negotiation.
|
||||
* @param _smbMinVersion one of SMB1, SMB202, SMB210, SMB300, SMB302 or SMB311
|
||||
* @since 1.2
|
||||
*/
|
||||
public void setSmbMinVersion(DialectVersion _smbMinVersion) {
|
||||
this.smbMinVersion = _smbMinVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the desired maximum SMB version value for what the Windows server will allow
|
||||
* during protocol transport negotiation.
|
||||
* @return one of SMB1, SMB202, SMB210, SMB300, SMB302 or SMB311
|
||||
* @since 1.2
|
||||
*/
|
||||
public DialectVersion getSmbMaxVersion() {
|
||||
return this.smbMaxVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired maximum SMB version value for what the Windows server will allow
|
||||
* during protocol transport negotiation.
|
||||
* @param _smbMaxVersion one of SMB1, SMB202, SMB210, SMB300, SMB302 or SMB311
|
||||
* @since 1.2
|
||||
*/
|
||||
public void setSmbMaxVersion(DialectVersion _smbMaxVersion) {
|
||||
this.smbMaxVersion = _smbMaxVersion;
|
||||
}
|
||||
|
||||
String getDomainUserPass(boolean _includePassword) {
|
||||
String domainUserPass;
|
||||
if (StringUtils.hasText(this.domain)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.smb.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -29,7 +30,7 @@ import jcifs.smb.SmbFile;
|
||||
* The SMB session factory.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 1.0
|
||||
* @author Gregory Bragg
|
||||
*/
|
||||
public class SmbSessionFactory extends SmbConfig implements SessionFactory<SmbFile> {
|
||||
|
||||
@@ -39,6 +40,7 @@ public class SmbSessionFactory extends SmbConfig implements SessionFactory<SmbFi
|
||||
logger.debug("New " + getClass().getName() + " created.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SmbSession getSession() {
|
||||
try {
|
||||
return createSession();
|
||||
@@ -49,7 +51,11 @@ public class SmbSessionFactory extends SmbConfig implements SessionFactory<SmbFi
|
||||
}
|
||||
|
||||
protected SmbSession createSession() throws IOException {
|
||||
SmbShare smbShare = new SmbShare(this);
|
||||
Properties props = new Properties();
|
||||
props.setProperty("jcifs.smb.client.minVersion", this.getSmbMinVersion().name());
|
||||
props.setProperty("jcifs.smb.client.maxVersion", this.getSmbMaxVersion().name());
|
||||
|
||||
SmbShare smbShare = new SmbShare(this, props);
|
||||
smbShare.setReplaceFile(isReplaceFile());
|
||||
smbShare.setUseTempFile(isUseTempFile());
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.integration.smb.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -26,6 +27,8 @@ import org.springframework.core.NestedIOException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import jcifs.config.PropertyConfiguration;
|
||||
import jcifs.context.BaseContext;
|
||||
import jcifs.context.SingletonContext;
|
||||
import jcifs.smb.NtlmPasswordAuthenticator;
|
||||
import jcifs.smb.SmbException;
|
||||
@@ -55,12 +58,36 @@ public class SmbShare extends SmbFile {
|
||||
super(StringUtils.cleanPath(url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the jCIFS library with default properties.
|
||||
* @param _smbConfig the SMB share configuration
|
||||
* @throws IOException if an invalid SMB URL was constructed by jCIFS
|
||||
* @since 1.1
|
||||
*/
|
||||
public SmbShare(SmbConfig _smbConfig) throws IOException {
|
||||
super(StringUtils.cleanPath(_smbConfig.validate().getUrl()),
|
||||
SingletonContext.getInstance().withCredentials(new NtlmPasswordAuthenticator(
|
||||
SingletonContext.getInstance().withCredentials(
|
||||
new NtlmPasswordAuthenticator(
|
||||
_smbConfig.getDomain(), _smbConfig.getUsername(), _smbConfig.getPassword())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the jCIFS library with custom properties such as
|
||||
* 'jcifs.smb.client.minVersion' and 'jcifs.smb.client.maxVersion'
|
||||
* for setting the minimum/maximum SMB supported versions.
|
||||
* @param _smbConfig the SMB share configuration
|
||||
* @param _props the custom property set for jCIFS to initialize
|
||||
* @throws IOException if an invalid property was set or an invalid SMB URL was constructed by jCIFS
|
||||
* @since 1.2
|
||||
*/
|
||||
public SmbShare(SmbConfig _smbConfig, Properties _props) throws IOException {
|
||||
super(StringUtils.cleanPath(_smbConfig.validate().getUrl()),
|
||||
new BaseContext(
|
||||
new PropertyConfiguration(_props)).withCredentials(
|
||||
new NtlmPasswordAuthenticator(
|
||||
_smbConfig.getDomain(), _smbConfig.getUsername(), _smbConfig.getPassword())));
|
||||
}
|
||||
|
||||
public void init() throws NestedIOException {
|
||||
boolean canRead = false;
|
||||
try {
|
||||
|
||||
@@ -19,9 +19,11 @@ package org.springframework.integration.smb.session;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import jcifs.DialectVersion;
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
/**
|
||||
@@ -134,4 +136,69 @@ public class SmbSessionTests {
|
||||
smbSession.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSmbFileObjectWithSmb3Versions1() throws IOException {
|
||||
Properties props = new Properties();
|
||||
SmbConfig config = new SmbConfig();
|
||||
|
||||
config.setHost("myshare");
|
||||
config.setPort(445);
|
||||
config.setShareAndDir("shared/");
|
||||
config.setSmbMinVersion(DialectVersion.SMB300);
|
||||
config.setSmbMaxVersion(DialectVersion.SMB311);
|
||||
|
||||
props.setProperty("jcifs.smb.client.minVersion", config.getSmbMinVersion().name());
|
||||
props.setProperty("jcifs.smb.client.maxVersion", config.getSmbMaxVersion().name());
|
||||
|
||||
SmbShare smbShare = new SmbShare(config, props);
|
||||
SmbSession smbSession = new SmbSession(smbShare);
|
||||
|
||||
SmbFile smbFile = smbSession.createSmbFileObject("smb://myshare\\blubba");
|
||||
assertEquals("smb://myshare/blubba", smbFile.getPath());
|
||||
smbSession.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSmbFileObjectWithSmb3Versions2() throws IOException {
|
||||
Properties props = new Properties();
|
||||
SmbConfig config = new SmbConfig();
|
||||
|
||||
config.setHost("myshare");
|
||||
config.setPort(445);
|
||||
config.setShareAndDir("shared/");
|
||||
config.setSmbMinVersion(DialectVersion.SMB302);
|
||||
config.setSmbMaxVersion(DialectVersion.SMB311);
|
||||
|
||||
props.setProperty("jcifs.smb.client.minVersion", config.getSmbMinVersion().name());
|
||||
props.setProperty("jcifs.smb.client.maxVersion", config.getSmbMaxVersion().name());
|
||||
|
||||
SmbShare smbShare = new SmbShare(config, props);
|
||||
SmbSession smbSession = new SmbSession(smbShare);
|
||||
|
||||
SmbFile smbFile = smbSession.createSmbFileObject("smb://myshare\\blubba");
|
||||
assertEquals("smb://myshare/blubba", smbFile.getPath());
|
||||
smbSession.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSmbFileObjectWithSmb3Versions3() throws IOException {
|
||||
Properties props = new Properties();
|
||||
SmbConfig config = new SmbConfig();
|
||||
|
||||
config.setHost("myshare");
|
||||
config.setPort(445);
|
||||
config.setShareAndDir("shared/");
|
||||
config.setSmbMinVersion(DialectVersion.SMB311);
|
||||
config.setSmbMaxVersion(DialectVersion.SMB311);
|
||||
|
||||
props.setProperty("jcifs.smb.client.minVersion", config.getSmbMinVersion().name());
|
||||
props.setProperty("jcifs.smb.client.maxVersion", config.getSmbMaxVersion().name());
|
||||
|
||||
SmbShare smbShare = new SmbShare(config, props);
|
||||
SmbSession smbSession = new SmbSession(smbShare);
|
||||
|
||||
SmbFile smbFile = smbSession.createSmbFileObject("smb://myshare\\blubba");
|
||||
assertEquals("smb://myshare/blubba", smbFile.getPath());
|
||||
smbSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user