From 853efa586af10e5ee021369a7b8f4d725091531d Mon Sep 17 00:00:00 2001 From: Gary Spencer Date: Thu, 2 Sep 2010 14:40:53 +0000 Subject: [PATCH] FTP over SSL/TLS configuration additions. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22185 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../default/file-servers-context.xml | 21 ++++ .../default/file-servers.properties | 11 +- .../AbstractServerConfigurationBean.java | 2 +- .../filesys/config/FTPConfigBean.java | 107 ++++++++++++++++++ .../config/ServerConfigurationBean.java | 79 ++++++++++++- 5 files changed, 216 insertions(+), 4 deletions(-) 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()); } - } /**