diff --git a/config/alfresco/subsystems/fileServers/default/file-servers-context.xml b/config/alfresco/subsystems/fileServers/default/file-servers-context.xml
index f344bce6de..c8bdf85dd7 100644
--- a/config/alfresco/subsystems/fileServers/default/file-servers-context.xml
+++ b/config/alfresco/subsystems/fileServers/default/file-servers-context.xml
@@ -221,6 +221,27 @@
${ftp.dataPortTo}
+
+
+
+ ${ftp.keyStore}
+
+
+
+ ${ftp.trustStore}
+
+
+
+ ${ftp.passphrase}
+
+
+
+ ${ftp.requireSecureSession}
+
+
+
+ ${ftp.sslEngineDebug}
+
diff --git a/config/alfresco/subsystems/fileServers/default/file-servers.properties b/config/alfresco/subsystems/fileServers/default/file-servers.properties
index 5b7216c03a..907dad5be7 100644
--- a/config/alfresco/subsystems/fileServers/default/file-servers.properties
+++ b/config/alfresco/subsystems/fileServers/default/file-servers.properties
@@ -3,7 +3,7 @@ filesystem.acl.global.defaultAccessLevel=
### CIFS Server Configuration ###
cifs.enabled=true
-cifs.serverName=${localname}A
+cifs.serverName=${localname}
cifs.domain=
cifs.broadcast=255.255.255.255
# An empty value indicates bind to all available network adapters
@@ -46,9 +46,16 @@ ftp.ipv6.enabled=false
ftp.dataPortFrom=0
ftp.dataPortTo=0
+# FTPS support (enabled when the keystore, truststore and passphrase are set)
+ftp.keyStore=
+ftp.trustStore=
+ftp.passphrase=
+ftp.requireSecureSession=true
+ftp.sslEngineDebug=false
+
# FTP session debug flags (also enable org.alfresco.fileserver=debug logging level)
# Comma delimeted list of levels :-
-# STATE, RXDATA, TXDATA, DUMPDATA, SEARCH, INFO, FILE, FILEIO, ERROR, PKTTYPE, TIMING, DATAPORT, DIRECTORY
+# STATE, RXDATA, TXDATA, DUMPDATA, SEARCH, INFO, FILE, FILEIO, ERROR, PKTTYPE, TIMING, DATAPORT, DIRECTORY, SSL
ftp.sessionDebug=
### NFS Server Configuration ###
diff --git a/source/java/org/alfresco/filesys/AbstractServerConfigurationBean.java b/source/java/org/alfresco/filesys/AbstractServerConfigurationBean.java
index 0981878d17..7ddf803303 100644
--- a/source/java/org/alfresco/filesys/AbstractServerConfigurationBean.java
+++ b/source/java/org/alfresco/filesys/AbstractServerConfigurationBean.java
@@ -91,7 +91,7 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
// FTP server debug type strings
protected static final String m_ftpDebugStr[] = { "STATE", "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE", "FILEIO", "ERROR", "PKTTYPE",
- "TIMING", "DATAPORT", "DIRECTORY" };
+ "TIMING", "DATAPORT", "DIRECTORY", "SSL" };
// Default FTP server port
diff --git a/source/java/org/alfresco/filesys/config/FTPConfigBean.java b/source/java/org/alfresco/filesys/config/FTPConfigBean.java
index dd94df7084..f09ff9f0c3 100644
--- a/source/java/org/alfresco/filesys/config/FTPConfigBean.java
+++ b/source/java/org/alfresco/filesys/config/FTPConfigBean.java
@@ -64,6 +64,23 @@ public class FTPConfigBean
private int dataPortFrom;
private int dataPortTo;
+ // FTPS configuration
+ //
+ // Path to the keystore/truststore files
+
+ private String m_keyStorePath;
+ private String m_trustStorePath;
+
+ private String m_passphrase;
+
+ // Only allow FTPS/encrypted session logons
+
+ private boolean m_requireSecureSess;
+
+ // SSL engine debug enable
+
+ private boolean m_sslDebug;
+
/**
* Checks if is server enabled.
*
@@ -309,4 +326,94 @@ public class FTPConfigBean
public void setDataPortTo(int toPort) {
dataPortTo = toPort;
}
+
+ /**
+ * Return the key store path
+ *
+ * @return String
+ */
+ public final String getKeyStorePath() {
+ return m_keyStorePath;
+ }
+
+ /**
+ * Return the trust store path
+ *
+ * @return String
+ */
+ public final String getTrustStorePath() {
+ return m_trustStorePath;
+ }
+
+ /**
+ * Return the passphrase for the key store/trust store
+ *
+ * @return String
+ */
+ public final String getPassphrase() {
+ return m_passphrase;
+ }
+
+ /**
+ * Determine if only secure sessions will be allowed to logon
+ *
+ * @return boolean
+ */
+ public final boolean hasRequireSecureSession() {
+ return m_requireSecureSess;
+ }
+
+ /**
+ * Set/clear the require secure sessions flag
+ *
+ * @param reqSec boolean
+ */
+ public final void setRequireSecureSession( boolean reqSec) {
+ m_requireSecureSess = reqSec;
+ }
+
+ /**
+ * Set the key store path
+ *
+ * @param path String
+ */
+ public final void setKeyStorePath( String path) {
+ m_keyStorePath = path;
+ }
+
+ /**
+ * Set the trust store path
+ *
+ * @param path String
+ */
+ public final void setTrustStorePath( String path) {
+ m_trustStorePath = path;
+ }
+
+ /**
+ * Set the passphrase
+ *
+ * @param phrase String
+ */
+ public final void setPassphrase( String phrase) {
+ m_passphrase = phrase;
+ }
+
+ /**
+ * Check if SSLEngine debug output should be enabled
+ *
+ * @return boolean
+ */
+ public final boolean hasSslEngineDebug() {
+ return m_sslDebug;
+ }
+
+ /**
+ * Enable SSLEngine class debug output
+ *
+ * @param sslDebug boolean
+ */
+ public final void setSslEngineDebug( boolean sslDebug) {
+ m_sslDebug = sslDebug;
+ }
}
diff --git a/source/java/org/alfresco/filesys/config/ServerConfigurationBean.java b/source/java/org/alfresco/filesys/config/ServerConfigurationBean.java
index 50cf50e2c0..9064902c74 100644
--- a/source/java/org/alfresco/filesys/config/ServerConfigurationBean.java
+++ b/source/java/org/alfresco/filesys/config/ServerConfigurationBean.java
@@ -18,6 +18,7 @@
*/
package org.alfresco.filesys.config;
+import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -1331,12 +1332,88 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean
logger.info("FTP server data ports restricted to range " + rangeFrom + ":" + rangeTo);
}
}
+
+ // FTPS parameter parsing
+ //
+ // Check if a key store path has been specified
+
+ if ( ftpConfigBean.getKeyStorePath() != null && ftpConfigBean.getKeyStorePath().length() > 0) {
+
+ // Get the path to the key store, check that the file exists
+
+ String keyStorePath = ftpConfigBean.getKeyStorePath();
+ File keyStoreFile = new File( keyStorePath);
+
+ if ( keyStoreFile.exists() == false)
+ throw new InvalidConfigurationException("FTPS key store file does not exist, " + keyStorePath);
+ else if ( keyStoreFile.isDirectory())
+ throw new InvalidConfigurationException("FTPS key store path is a directory, " + keyStorePath);
+
+ // Set the key store path
+
+ ftpConfig.setKeyStorePath( keyStorePath);
+ }
+
+ // Check if the trust store path has been specified
+
+ if ( ftpConfigBean.getTrustStorePath() != null && ftpConfigBean.getTrustStorePath().length() > 0) {
+
+ // Get the path to the trust store, check that the file exists
+
+ String trustStorePath = ftpConfigBean.getTrustStorePath();
+ File trustStoreFile = new File( trustStorePath);
+
+ if ( trustStoreFile.exists() == false)
+ throw new InvalidConfigurationException("FTPS trust store file does not exist, " + trustStorePath);
+ else if ( trustStoreFile.isDirectory())
+ throw new InvalidConfigurationException("FTPS trust store path is a directory, " + trustStorePath);
+
+ // Set the trust store path
+
+ ftpConfig.setTrustStorePath( trustStorePath);
+ }
+
+ // Check if the store passphrase has been specified
+
+ if ( ftpConfigBean.getPassphrase() != null && ftpConfigBean.getPassphrase().length() > 0) {
+
+ // Set the store passphrase
+
+ ftpConfig.setPassphrase( ftpConfigBean.getPassphrase());
+ }
+
+ // Check if only secure sessions should be allowed to logon
+
+ if ( ftpConfigBean.hasRequireSecureSession()) {
+
+ // Only allow secure sessions to logon to the FTP server
+
+ ftpConfig.setRequireSecureSession( true);
+ }
+
+ // Check that all the required FTPS parameters have been set
+
+ if ( ftpConfig.getKeyStorePath() != null || ftpConfig.getTrustStorePath() != null || ftpConfig.getPassphrase() != null) {
+
+ // Make sure all parameters are set
+
+ if ( ftpConfig.getKeyStorePath() == null || ftpConfig.getTrustStorePath() == null || ftpConfig.getPassphrase() == null)
+ throw new InvalidConfigurationException("FTPS configuration requires keyStore, trustStore and storePassphrase to be set");
+ }
+
+ // Check if SSLEngine debug output should be enabled
+
+ if ( ftpConfigBean.hasSslEngineDebug()) {
+
+ // Enable SSLEngine debug output
+
+ System.setProperty("javax.net.debug", "ssl,handshake");
+ }
}
catch (InvalidConfigurationException ex)
{
throw new AlfrescoRuntimeException(ex.getMessage());
}
-
}
/**