This is an automated email from the ASF dual-hosted git repository.
elecharny pushed a commit to branch 1.2.X
in repository https://gitbox.apache.org/repos/asf/mina-ftpserver.git
The following commit(s) were added to refs/heads/1.2.X by this push:
new 5ab035a5 o Minor code refactoring o Fixed javadoc warnings o Renamed
some variables for clarity o Slight code improvement o Added a toString method
to the Default%essageResource class o Bumped up a couple of dependencies
5ab035a5 is described below
commit 5ab035a590a45b605872d3cfc6c11bc917eb9684
Author: emmanuel lecharny <[email protected]>
AuthorDate: Sat Jan 11 00:14:18 2025 +0100
o Minor code refactoring
o Fixed javadoc warnings
o Renamed some variables for clarity
o Slight code improvement
o Added a toString method to the Default%essageResource class
o Bumped up a couple of dependencies
---
.../ftpserver/command/CommandFactoryFactory.java | 4 +-
.../org/apache/ftpserver/command/impl/PASS.java | 89 +++++++++-------------
.../nativefs/impl/NativeFileSystemView.java | 22 +++---
.../apache/ftpserver/impl/DefaultFtpHandler.java | 88 ++++++++++++---------
.../apache/ftpserver/impl/DefaultFtpRequest.java | 23 +++---
.../ftpserver/impl/DefaultFtpStatistics.java | 83 +++++++++++---------
.../ftpserver/listener/nio/FtpHandlerAdapter.java | 21 +++++
.../ftpserver/listener/nio/FtpLoggingFilter.java | 20 ++---
.../ftpserver/listener/nio/FtpResponseEncoder.java | 3 +-
.../message/impl/DefaultMessageResource.java | 67 ++++++++++++++++
.../usermanager/PropertiesUserManagerFactory.java | 7 +-
.../org/apache/ftpserver/util/EncryptUtils.java | 4 +-
pom.xml | 4 +-
13 files changed, 262 insertions(+), 173 deletions(-)
diff --git
a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
index 540de8c1..5e7af9d8 100644
--- a/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/command/CommandFactoryFactory.java
@@ -81,7 +81,6 @@ import org.apache.ftpserver.command.impl.USER;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class CommandFactoryFactory {
-
private static final HashMap<String, Command> DEFAULT_COMMAND_MAP = new
HashMap<>();
static {
@@ -116,6 +115,7 @@ public class CommandFactoryFactory {
DEFAULT_COMMAND_MAP.put("MDTM", new MDTM()); //
rfc3659, 3
// "MFCT, draft-somers-ftp-mfxx, 4
// "MFF, draft-somers-ftp-mfxx, 5
+ // "MIC, rfc2228, 3?
DEFAULT_COMMAND_MAP.put("MFMT", new MFMT()); //
draft-somers-ftp-mfxx, 3
DEFAULT_COMMAND_MAP.put("MKD", new MKD()); //
rfc959, 4.1.3
DEFAULT_COMMAND_MAP.put("MLSD", new MLSD()); //
rfc3659, 7
@@ -166,6 +166,7 @@ public class CommandFactoryFactory {
/**
* Create an {@link CommandFactory} based on the configuration on the
factory.
+ *
* @return The {@link CommandFactory}
*/
public CommandFactory createCommandFactory() {
@@ -210,6 +211,7 @@ public class CommandFactoryFactory {
/**
* Add or override a command.
+ *
* @param commandName The command name, e.g. STOR
* @param command The command
*/
diff --git a/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
b/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
index a2ca32fd..c8395a8b 100644
--- a/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
+++ b/core/src/main/java/org/apache/ftpserver/command/impl/PASS.java
@@ -53,7 +53,6 @@ import org.slf4j.LoggerFactory;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class PASS extends AbstractCommand {
-
private final Logger LOG = LoggerFactory.getLogger(PASS.class);
/**
@@ -64,46 +63,41 @@ public class PASS extends AbstractCommand {
public void execute(final FtpIoSession session,
final FtpServerContext context, final FtpRequest request)
throws IOException, FtpException {
-
boolean success = false;
+ ServerFtpStatistics stat = (ServerFtpStatistics) context
.getFtpStatistics();
- ServerFtpStatistics stat = (ServerFtpStatistics) context
- .getFtpStatistics();
try {
-
// reset state variables
session.resetState();
// argument check
String password = request.getArgument();
-
// check user name
String userName = session.getUserArgument();
- if (userName == null && session.getUser() == null) {
+ if ((userName == null) && (session.getUser() == null)) {
session.write(LocalizedFtpReply.translate(session, request,
context,
- FtpReply.REPLY_503_BAD_SEQUENCE_OF_COMMANDS, "PASS",
- null));
+ FtpReply.REPLY_503_BAD_SEQUENCE_OF_COMMANDS, "PASS",
null));
+
return;
}
// already logged-in
if (session.isLoggedIn()) {
session.write(LocalizedFtpReply.translate(session, request,
context,
- FtpReply.REPLY_202_COMMAND_NOT_IMPLEMENTED, "PASS",
- null));
+ FtpReply.REPLY_202_COMMAND_NOT_IMPLEMENTED, "PASS",
null));
+
return;
}
// anonymous login limit check
+ boolean anonymous = UserManager.ANONYMOUS.equals(userName);
- boolean anonymous = userName != null
- && userName.equals("anonymous");
if (anonymous) {
int currAnonLogin = stat.getCurrentAnonymousLoginNumber();
- int maxAnonLogin = context.getConnectionConfig()
- .getMaxAnonymousLogins();
+ int maxAnonLogin =
context.getConnectionConfig().getMaxAnonymousLogins();
+
if (maxAnonLogin == 0) {
LOG.debug("Currently {} anonymous users logged in,
unlimited allowed", currAnonLogin);
} else {
@@ -112,14 +106,10 @@ public class PASS extends AbstractCommand {
if (currAnonLogin >= maxAnonLogin) {
LOG.debug("Too many anonymous users logged in, user will
be disconnected");
- session
- .write(LocalizedFtpReply
- .translate(
- session,
- request,
- context,
+ session.write(LocalizedFtpReply.translate(session,
request, context,
FtpReply.REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION,
"PASS.anonymous", null));
+
return;
}
}
@@ -127,43 +117,42 @@ public class PASS extends AbstractCommand {
// login limit check
int currLogin = stat.getCurrentLoginNumber();
int maxLogin = context.getConnectionConfig().getMaxLogins();
+
if (maxLogin == 0) {
LOG.debug("Currently {} users logged in, unlimited allowed",
currLogin);
} else {
LOG.debug("Currently {} out of {} users logged in", currLogin,
maxLogin);
}
+
if (maxLogin != 0 && currLogin >= maxLogin) {
LOG.debug("Too many users logged in, user will be
disconnected");
- session
- .write(LocalizedFtpReply
- .translate(
- session,
- request,
- context,
+ session.write(LocalizedFtpReply.translate(
+ session, request, context,
FtpReply.REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION,
"PASS.login", null));
+
return;
}
// authenticate user
UserManager userManager = context.getUserManager();
User authenticatedUser = null;
+
try {
UserMetadata userMetadata = new UserMetadata();
if (session.getRemoteAddress() instanceof InetSocketAddress) {
- userMetadata.setInetAddress(((InetSocketAddress) session
- .getRemoteAddress()).getAddress());
+ userMetadata.setInetAddress(((InetSocketAddress)
session.getRemoteAddress()).getAddress());
}
- userMetadata.setCertificateChain(session
- .getClientCertificates());
+
+
userMetadata.setCertificateChain(session.getClientCertificates());
Authentication auth;
+
if (anonymous) {
auth = new AnonymousAuthentication(userMetadata);
} else {
- auth = new UsernamePasswordAuthentication(userName,
- password, userMetadata);
+ auth = new UsernamePasswordAuthentication(userName,
password, userMetadata);
}
authenticatedUser = userManager.authenticate(auth);
@@ -182,14 +171,9 @@ public class PASS extends AbstractCommand {
if (authenticatedUser != null) {
if (!authenticatedUser.getEnabled()) {
- session
- .write(LocalizedFtpReply
- .translate(
- session,
- request,
- context,
- FtpReply.REPLY_530_NOT_LOGGED_IN,
- "PASS", null));
+ session.write(LocalizedFtpReply.translate(
+ session, request, context,
FtpReply.REPLY_530_NOT_LOGGED_IN, "PASS", null));
+
return;
}
@@ -207,8 +191,7 @@ public class PASS extends AbstractCommand {
session.setUserArgument(oldUserArgument);
session.setMaxIdleTime(oldMaxIdleTime);
- delayAfterLoginFailure(context.getConnectionConfig()
- .getLoginFailureDelay());
+
delayAfterLoginFailure(context.getConnectionConfig().getLoginFailureDelay());
LOG.warn("Login failure - " + userName);
session.write(LocalizedFtpReply.translate(session, request,
context,
@@ -218,10 +201,9 @@ public class PASS extends AbstractCommand {
session.increaseFailedLogins();
// kick the user if the max number of failed logins is reached
- int maxAllowedLoginFailues = context.getConnectionConfig()
- .getMaxLoginFailures();
- if (maxAllowedLoginFailues != 0
- && session.getFailedLogins() >=
maxAllowedLoginFailues) {
+ int maxAllowedLoginFailues =
context.getConnectionConfig().getMaxLoginFailures();
+
+ if ((maxAllowedLoginFailues != 0) &&
(session.getFailedLogins() >= maxAllowedLoginFailues)) {
LOG.warn("User exceeded the number of allowed failed
logins, session will be closed");
session.close(false).awaitUninterruptibly(10000);
@@ -232,22 +214,20 @@ public class PASS extends AbstractCommand {
// update different objects
FileSystemFactory fmanager = context.getFileSystemManager();
- FileSystemView fsview = fmanager
- .createFileSystemView(authenticatedUser);
+ FileSystemView fsview =
fmanager.createFileSystemView(authenticatedUser);
session.setLogin(fsview);
stat.setLogin(session);
// everything is fine - send login ok message
session.write(LocalizedFtpReply.translate(session, request,
context,
- FtpReply.REPLY_230_USER_LOGGED_IN, "PASS", userName));
+ FtpReply.REPLY_230_USER_LOGGED_IN, "PASS", userName));
+
if (anonymous) {
- LOG.info("Anonymous login success - " + password);
+ LOG.info("Anonymous login success");
} else {
- LOG.info("Login success - " + userName);
+ LOG.info("Login success - {}", userName);
}
-
} finally {
-
// if login failed - reset user
if (!success) {
session.reinitialize();
@@ -256,7 +236,6 @@ public class PASS extends AbstractCommand {
}
private void delayAfterLoginFailure(final int loginFailureDelay) {
-
if (loginFailureDelay > 0) {
LOG.debug("Waiting for {} milliseconds due to login failure",
loginFailureDelay);
diff --git
a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
index 227046e3..d14b96a6 100644
---
a/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
+++
b/core/src/main/java/org/apache/ftpserver/filesystem/nativefs/impl/NativeFileSystemView.java
@@ -39,9 +39,7 @@ import org.slf4j.LoggerFactory;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class NativeFileSystemView implements FileSystemView {
-
- private final Logger LOG = LoggerFactory
- .getLogger(NativeFileSystemView.class);
+ private final Logger LOG =
LoggerFactory.getLogger(NativeFileSystemView.class);
// the root directory will always end with '/'.
@@ -69,15 +67,15 @@ public class NativeFileSystemView implements FileSystemView
{
*
* @param user The current user
* @param caseInsensitive If the OS FS is case sensitive or not
+ * @throws FtpException Actually, never thrown... To be removed!
*/
- public NativeFileSystemView(User user, boolean caseInsensitive)
- throws FtpException {
+ public NativeFileSystemView(User user, boolean caseInsensitive) throws
FtpException {
if (user == null) {
throw new IllegalArgumentException("user can not be null");
}
+
if (user.getHomeDirectory() == null) {
- throw new IllegalArgumentException(
- "User home directory can not be null");
+ throw new IllegalArgumentException("User home directory can not be
null");
}
this.caseInsensitive = caseInsensitive;
@@ -90,7 +88,6 @@ public class NativeFileSystemView implements FileSystemView {
LOG.debug("Native filesystem view created for user \"{}\" with root
\"{}\"", user.getName(), rootDir);
this.rootDir = rootDir;
-
this.user = user;
currDir = "/";
@@ -111,13 +108,14 @@ public class NativeFileSystemView implements
FileSystemView {
*/
public FtpFile getWorkingDirectory() {
FtpFile fileObj = null;
+
if (currDir.equals("/")) {
fileObj = new NativeFtpFile("/", new File(rootDir), user);
} else {
File file = new File(rootDir, currDir.substring(1));
fileObj = new NativeFtpFile(currDir, file, user);
-
}
+
return fileObj;
}
@@ -125,14 +123,13 @@ public class NativeFileSystemView implements
FileSystemView {
* {@inheritDoc}
*/
public FtpFile getFile(String file) {
-
// get actual file object
- String physicalName = getPhysicalName(rootDir,
- currDir, file, caseInsensitive);
+ String physicalName = getPhysicalName(rootDir, currDir, file,
caseInsensitive);
File fileObj = new File(physicalName);
// strip the root directory and return
String userFileName = physicalName.substring(rootDir.length() - 1);
+
return new NativeFtpFile(userFileName, fileObj, user);
}
@@ -304,6 +301,7 @@ public class NativeFileSystemView implements FileSystemView
{
private String normalizeSeparateChar(final String pathName) {
String normalizedPathName = pathName.replace(File.separatorChar, '/');
normalizedPathName = normalizedPathName.replace('\\', '/');
+
return normalizedPathName;
}
diff --git
a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
index 0f25973a..3afe06bd 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
@@ -44,7 +44,6 @@ import org.slf4j.LoggerFactory;
*
*/
public class DefaultFtpHandler implements FtpHandler {
-
private final Logger LOG =
LoggerFactory.getLogger(DefaultFtpHandler.class);
private static final String[] NON_AUTHENTICATED_COMMANDS = new String[] {
@@ -59,27 +58,34 @@ public class DefaultFtpHandler implements FtpHandler {
this.listener = listener;
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionCreated(final FtpIoSession session) throws Exception {
session.setListener(listener);
- ServerFtpStatistics stats = ((ServerFtpStatistics) context
- .getFtpStatistics());
+ ServerFtpStatistics stats = ((ServerFtpStatistics)
context.getFtpStatistics());
if (stats != null) {
stats.setOpenConnection(session);
}
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionOpened(final FtpIoSession session) throws Exception {
FtpletContainer ftplets = context.getFtpletContainer();
FtpletResult ftpletRet;
+
try {
ftpletRet = ftplets.onConnect(session.getFtpletSession());
} catch (Exception e) {
LOG.debug("Ftplet threw exception", e);
ftpletRet = FtpletResult.DISCONNECT;
}
+
if (ftpletRet == FtpletResult.DISCONNECT) {
LOG.debug("Ftplet returned DISCONNECT, session will be closed");
session.close(false).awaitUninterruptibly(10000);
@@ -91,8 +97,12 @@ public class DefaultFtpHandler implements FtpHandler {
}
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionClosed(final FtpIoSession session) throws Exception {
LOG.debug("Closing session");
+
try {
context.getFtpletContainer().onDisconnect(
session.getFtpletSession());
@@ -104,6 +114,7 @@ public class DefaultFtpHandler implements FtpHandler {
// make sure we close the data connection if it happens to be open
try {
ServerDataConnectionFactory dc = session.getDataConnection();
+
if (dc != null) {
dc.closeDataConnection();
}
@@ -113,6 +124,7 @@ public class DefaultFtpHandler implements FtpHandler {
}
FileSystemView fs = session.getFileSystemView();
+
if (fs != null) {
try {
fs.dispose();
@@ -131,12 +143,14 @@ public class DefaultFtpHandler implements FtpHandler {
} else {
LOG.warn("Statistics not available in session, can not decrease
login and connection count");
}
+
LOG.debug("Session closed");
}
- public void exceptionCaught(final FtpIoSession session,
- final Throwable cause) throws Exception {
-
+ /**
+ * {@inheritDoc}
+ */
+ public void exceptionCaught(final FtpIoSession session, final Throwable
cause) throws Exception {
if (cause instanceof ProtocolDecoderException &&
cause.getCause() instanceof MalformedInputException) {
// client probably sent something which is not UTF-8 and we failed
to
@@ -147,33 +161,30 @@ public class DefaultFtpHandler implements FtpHandler {
session.write(new
DefaultFtpReply(FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS,
"Invalid character in command"));
} else if (cause instanceof WriteToClosedSessionException) {
- WriteToClosedSessionException writeToClosedSessionException =
- (WriteToClosedSessionException) cause;
- LOG.warn(
- "Client closed connection before all replies could
be sent, last reply was {}",
- writeToClosedSessionException.getRequest());
+ WriteToClosedSessionException writeToClosedSessionException =
(WriteToClosedSessionException) cause;
+ LOG.warn("Client closed connection before all replies could be
sent, last reply was {}",
+ writeToClosedSessionException.getRequest());
session.close(false).awaitUninterruptibly(10000);
} else {
LOG.error("Exception caught, closing session", cause);
session.close(false).awaitUninterruptibly(10000);
}
-
-
}
private boolean isCommandOkWithoutAuthentication(String command) {
- boolean okay = false;
for (String allowed : NON_AUTHENTICATED_COMMANDS) {
if (allowed.equals(command)) {
- okay = true;
- break;
+ return true;
}
}
- return okay;
+
+ return false;
}
- public void messageReceived(final FtpIoSession session,
- final FtpRequest request) throws Exception {
+ /**
+ * {@inheritDoc}
+ */
+ public void messageReceived(final FtpIoSession session, final FtpRequest
request) throws Exception {
try {
session.updateLastAccessTime();
@@ -182,30 +193,30 @@ public class DefaultFtpHandler implements FtpHandler {
Command command = commandFactory.getCommand(commandName);
// make sure the user is authenticated before he issues commands
- if (!session.isLoggedIn()
- && !isCommandOkWithoutAuthentication(commandName)) {
+ if (!session.isLoggedIn() &&
!isCommandOkWithoutAuthentication(commandName)) {
session.write(LocalizedFtpReply.translate(session, request,
- context, FtpReply.REPLY_530_NOT_LOGGED_IN,
- "permission", null));
+ context, FtpReply.REPLY_530_NOT_LOGGED_IN,
"permission", null));
+
return;
}
FtpletContainer ftplets = context.getFtpletContainer();
FtpletResult ftpletRet;
+
try {
- ftpletRet = ftplets.beforeCommand(session.getFtpletSession(),
- request);
+ ftpletRet = ftplets.beforeCommand(session.getFtpletSession(),
request);
} catch (Exception e) {
LOG.debug("Ftplet container threw exception", e);
ftpletRet = FtpletResult.DISCONNECT;
}
+
if (ftpletRet == FtpletResult.DISCONNECT) {
LOG.debug("Ftplet returned DISCONNECT, session will be
closed");
session.close(false).awaitUninterruptibly(10000);
+
return;
} else if (ftpletRet != FtpletResult.SKIP) {
-
if (command != null) {
synchronized (session) {
command.execute(session, context, request);
@@ -219,28 +230,28 @@ public class DefaultFtpHandler implements FtpHandler {
try {
ftpletRet = ftplets.afterCommand(
- session.getFtpletSession(), request, session
- .getLastReply());
+ session.getFtpletSession(), request,
session.getLastReply());
} catch (Exception e) {
LOG.debug("Ftplet container threw exception", e);
ftpletRet = FtpletResult.DISCONNECT;
}
+
if (ftpletRet == FtpletResult.DISCONNECT) {
LOG.debug("Ftplet returned DISCONNECT, session will be
closed");
session.close(false).awaitUninterruptibly(10000);
+
return;
}
}
-
} catch (Exception ex) {
// send error reply
- try {
+ //try {
session.write(LocalizedFtpReply.translate(session, request,
context, FtpReply.REPLY_550_REQUESTED_ACTION_NOT_TAKEN,
null, null));
- } catch (Exception ex1) {
- }
+ // } catch (Exception ex1) {
+ //}
if (ex instanceof java.io.IOException) {
throw (IOException) ex;
@@ -251,15 +262,18 @@ public class DefaultFtpHandler implements FtpHandler {
}
- public void sessionIdle(final FtpIoSession session, final IdleStatus
status)
- throws Exception {
+ /**
+ * {@inheritDoc}
+ */
+ public void sessionIdle(final FtpIoSession session, final IdleStatus
status) throws Exception {
LOG.info("Session idle, closing");
session.close(false).awaitUninterruptibly(10000);
}
- public void messageSent(final FtpIoSession session, final FtpReply reply)
- throws Exception {
+ /**
+ * {@inheritDoc}
+ */
+ public void messageSent(final FtpIoSession session, final FtpReply reply)
throws Exception {
// do nothing
-
}
}
diff --git
a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
index 5c4d2efd..89e1dbc2 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpRequest.java
@@ -54,23 +54,25 @@ public class DefaultFtpRequest implements FtpRequest {
//going to be accurate and need to look for an alternative solution.
receivedTime = System.currentTimeMillis();
line = requestLine.trim();
- int spInd = line.indexOf(' ');
- command = parseCmd(line, spInd);
- argument = parseArg(line, spInd);
+ int spaceIndex = line.indexOf(' ');
+ command = parseCmd(line, spaceIndex);
+ argument = parseArg(line, spaceIndex);
}
/**
* Parse the ftp command line.
*/
- private String parseCmd(final String lineToParse, int spInd) {
+ private String parseCmd(final String lineToParse, int spaceIndex) {
String cmd = null;
- if (spInd != -1) {
- cmd = line.substring(0, spInd).toUpperCase();
+ if (spaceIndex != -1) {
+ cmd = line.substring(0, spaceIndex);
} else {
- cmd = line.toUpperCase();
+ cmd = line;
}
+ cmd = cmd.toUpperCase();
+
if ((cmd.length() > 0) && (cmd.charAt(0) == 'X')) {
cmd = cmd.substring(1);
}
@@ -78,10 +80,11 @@ public class DefaultFtpRequest implements FtpRequest {
return cmd;
}
- private String parseArg(final String lineToParse, int spInd) {
+ private String parseArg(final String lineToParse, int spaceIndex) {
String arg = null;
- if (spInd != -1) {
- arg = line.substring(spInd + 1);
+
+ if (spaceIndex != -1) {
+ arg = line.substring(spaceIndex + 1);
if (arg.isEmpty()) {
arg = null;
diff --git
a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
index 095c0ec5..98a73739 100644
--- a/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
+++ b/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpStatistics.java
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicLong;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;
+import org.apache.ftpserver.ftplet.UserManager;
/**
* <strong>Internal class, do not use directly.</strong>
@@ -41,7 +42,6 @@ import org.apache.ftpserver.ftplet.User;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class DefaultFtpStatistics implements ServerFtpStatistics {
-
private StatisticsObserver observer = null;
private FileObserver fileObserver = null;
@@ -87,10 +87,12 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
public AtomicInteger loginsFromInetAddress(InetAddress address) {
AtomicInteger logins = perAddress.get(address);
+
if (logins == null) {
logins = new AtomicInteger(0);
perAddress.put(address, logins);
}
+
return logins;
}
@@ -234,6 +236,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
public synchronized int getCurrentUserLoginNumber(final User user) {
UserLogins userLogins = userLoginTable.get(user.getName());
+
if (userLogins == null) {// not found the login user's statistics info
return 0;
} else {
@@ -248,9 +251,9 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
* @param ipAddress the ip address of the remote user
* @return The login number
*/
- public synchronized int getCurrentUserLoginNumber(final User user,
- final InetAddress ipAddress) {
+ public synchronized int getCurrentUserLoginNumber(final User user, final
InetAddress ipAddress) {
UserLogins userLogins = userLoginTable.get(user.getName());
+
if (userLogins == null) {// not found the login user's statistics info
return 0;
} else {
@@ -263,8 +266,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- public synchronized void setUpload(final FtpIoSession session,
- final FtpFile file, final long size) {
+ public synchronized void setUpload(final FtpIoSession session, final
FtpFile file, final long size) {
uploadCount.incrementAndGet();
bytesUpload.addAndGet(size);
notifyUpload(session, file, size);
@@ -273,8 +275,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- public synchronized void setDownload(final FtpIoSession session,
- final FtpFile file, final long size) {
+ public synchronized void setDownload(final FtpIoSession session, final
FtpFile file, final long size) {
downloadCount.incrementAndGet();
bytesDownload.addAndGet(size);
notifyDownload(session, file, size);
@@ -283,8 +284,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- public synchronized void setDelete(final FtpIoSession session,
- final FtpFile file) {
+ public synchronized void setDelete(final FtpIoSession session, final
FtpFile file) {
deleteCount.incrementAndGet();
notifyDelete(session, file);
}
@@ -292,8 +292,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- public synchronized void setMkdir(final FtpIoSession session,
- final FtpFile file) {
+ public synchronized void setMkdir(final FtpIoSession session, final
FtpFile file) {
mkdirCount.incrementAndGet();
notifyMkdir(session, file);
}
@@ -301,8 +300,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- public synchronized void setRmdir(final FtpIoSession session,
- final FtpFile file) {
+ public synchronized void setRmdir(final FtpIoSession session, final
FtpFile file) {
rmdirCount.incrementAndGet();
notifyRmdir(session, file);
}
@@ -323,6 +321,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
if (currConnections.get() > 0) {
currConnections.decrementAndGet();
}
+
notifyCloseConnection(session);
}
@@ -333,7 +332,8 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
currLogins.incrementAndGet();
totalLogins.incrementAndGet();
User user = session.getUser();
- if ("anonymous".equals(user.getName())) {
+
+ if (UserManager.ANONYMOUS.equals(user.getName())) {
currAnonLogins.incrementAndGet();
totalAnonLogins.incrementAndGet();
}
@@ -341,25 +341,25 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
synchronized (user) {// thread safety is needed. Since the login
occurrs
// at low frequency, this overhead is endurable
UserLogins statisticsTable = userLoginTable.get(user.getName());
+
if (statisticsTable == null) {
// the hash table that records the login information of the
user
// and its ip address.
InetAddress address = null;
+
if (session.getRemoteAddress() instanceof InetSocketAddress) {
- address = ((InetSocketAddress) session.getRemoteAddress())
- .getAddress();
+ address = ((InetSocketAddress)
session.getRemoteAddress()).getAddress();
}
+
statisticsTable = new UserLogins(address);
userLoginTable.put(user.getName(), statisticsTable);
} else {
statisticsTable.totalLogins.incrementAndGet();
if (session.getRemoteAddress() instanceof InetSocketAddress) {
- InetAddress address = ((InetSocketAddress) session
- .getRemoteAddress()).getAddress();
- statisticsTable.loginsFromInetAddress(address)
- .incrementAndGet();
+ InetAddress address = ((InetSocketAddress)
session.getRemoteAddress()).getAddress();
+
statisticsTable.loginsFromInetAddress(address).incrementAndGet();
}
}
@@ -381,13 +381,14 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
public synchronized void setLogout(final FtpIoSession session) {
User user = session.getUser();
+
if (user == null) {
return;
}
currLogins.decrementAndGet();
- if ("anonymous".equals(user.getName())) {
+ if (UserManager.ANONYMOUS.equals(user.getName())) {
currAnonLogins.decrementAndGet();
}
@@ -396,9 +397,9 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
if (userLogins != null) {
userLogins.totalLogins.decrementAndGet();
+
if (session.getRemoteAddress() instanceof InetSocketAddress) {
- InetAddress address = ((InetSocketAddress) session
- .getRemoteAddress()).getAddress();
+ InetAddress address = ((InetSocketAddress)
session.getRemoteAddress()).getAddress();
userLogins.loginsFromInetAddress(address).decrementAndGet();
}
}
@@ -413,14 +414,15 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- private void notifyUpload(final FtpIoSession session,
- final FtpFile file, long size) {
+ private void notifyUpload(final FtpIoSession session, final FtpFile file,
long size) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyUpload();
}
FileObserver fileObserver = this.fileObserver;
+
if (fileObserver != null) {
fileObserver.notifyUpload(session, file, size);
}
@@ -429,14 +431,15 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
/**
* {@inheritDoc}
*/
- private void notifyDownload(final FtpIoSession session,
- final FtpFile file, final long size) {
+ private void notifyDownload(final FtpIoSession session, final FtpFile
file, final long size) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyDownload();
}
FileObserver fileObserver = this.fileObserver;
+
if (fileObserver != null) {
fileObserver.notifyDownload(session, file, size);
}
@@ -447,11 +450,13 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyDelete(final FtpIoSession session, final FtpFile file) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyDelete();
}
FileObserver fileObserver = this.fileObserver;
+
if (fileObserver != null) {
fileObserver.notifyDelete(session, file);
}
@@ -462,11 +467,13 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyMkdir(final FtpIoSession session, final FtpFile file) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyMkdir();
}
FileObserver fileObserver = this.fileObserver;
+
if (fileObserver != null) {
fileObserver.notifyMkdir(session, file);
}
@@ -477,11 +484,13 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyRmdir(final FtpIoSession session, final FtpFile file) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyRmdir();
}
FileObserver fileObserver = this.fileObserver;
+
if (fileObserver != null) {
fileObserver.notifyRmdir(session, file);
}
@@ -492,6 +501,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyOpenConnection(final FtpIoSession session) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyOpenConnection();
}
@@ -502,6 +512,7 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyCloseConnection(final FtpIoSession session) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
observer.notifyCloseConnection();
}
@@ -512,15 +523,17 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyLogin(final FtpIoSession session) {
StatisticsObserver observer = this.observer;
- if (observer != null) {
+ if (observer != null) {
// is anonymous login
User user = session.getUser();
boolean anonymous = false;
+
if (user != null) {
String login = user.getName();
- anonymous = (login != null) && login.equals("anonymous");
+ anonymous = (login != null) &&
login.equals(UserManager.ANONYMOUS);
}
+
observer.notifyLogin(anonymous);
}
}
@@ -530,12 +543,9 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyLoginFail(final FtpIoSession session) {
StatisticsObserver observer = this.observer;
- if (observer != null) {
- if (session.getRemoteAddress() instanceof InetSocketAddress) {
- observer.notifyLoginFail(((InetSocketAddress) session
- .getRemoteAddress()).getAddress());
- }
+ if ( (observer != null) && (session.getRemoteAddress() instanceof
InetSocketAddress)) {
+ observer.notifyLoginFail(((InetSocketAddress)
session.getRemoteAddress()).getAddress());
}
}
@@ -544,14 +554,17 @@ public class DefaultFtpStatistics implements
ServerFtpStatistics {
*/
private void notifyLogout(final FtpIoSession session) {
StatisticsObserver observer = this.observer;
+
if (observer != null) {
// is anonymous login
User user = session.getUser();
boolean anonymous = false;
+
if (user != null) {
String login = user.getName();
- anonymous = (login != null) && login.equals("anonymous");
+ anonymous = (login != null) &&
login.equals(UserManager.ANONYMOUS);
}
+
observer.notifyLogout(anonymous);
}
}
diff --git
a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
index f3358ac8..833b041f 100644
---
a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
+++
b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpHandlerAdapter.java
@@ -48,12 +48,18 @@ public class FtpHandlerAdapter extends IoHandlerAdapter {
this.ftpHandler = ftpHandler;
}
+ /**
+ * {@inheritDoc}
+ */
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.exceptionCaught(ftpSession, cause);
}
+ /**
+ * {@inheritDoc}
+ */
public void messageReceived(IoSession session, Object message)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
@@ -62,16 +68,25 @@ public class FtpHandlerAdapter extends IoHandlerAdapter {
ftpHandler.messageReceived(ftpSession, request);
}
+ /**
+ * {@inheritDoc}
+ */
public void messageSent(IoSession session, Object message) throws
Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.messageSent(ftpSession, (FtpReply) message);
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionClosed(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionClosed(ftpSession);
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionCreated(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
MdcInjectionFilter.setProperty(session, "session",
ftpSession.getSessionId().toString());
@@ -80,12 +95,18 @@ public class FtpHandlerAdapter extends IoHandlerAdapter {
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionIdle(ftpSession, status);
}
+ /**
+ * {@inheritDoc}
+ */
public void sessionOpened(IoSession session) throws Exception {
FtpIoSession ftpSession = new FtpIoSession(session, context);
ftpHandler.sessionOpened(ftpSession);
diff --git
a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpLoggingFilter.java
b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpLoggingFilter.java
index 285da8b5..b8e0f262 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpLoggingFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpLoggingFilter.java
@@ -32,9 +32,10 @@ import org.slf4j.LoggerFactory;
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public class FtpLoggingFilter extends LoggingFilter {
-
+ /** A flag telling of the password should be masked in the logs. obvioulsy
SET TO TRUE! */
private boolean maskPassword = true;
+ /** The logger to use */
private final Logger logger;
/**
@@ -71,23 +72,15 @@ public class FtpLoggingFilter extends LoggingFilter {
* {@inheritDoc}
*/
@Override
- public void messageReceived(NextFilter nextFilter, IoSession session,
- Object message) throws Exception {
+ public void messageReceived(NextFilter nextFilter, IoSession session,
Object message) throws Exception {
String request = (String) message;
- String logMessage;
- if (maskPassword) {
-
- if (request.trim().toUpperCase().startsWith("PASS ")) {
- logMessage = "PASS *****";
- } else {
- logMessage = request;
- }
+ if (maskPassword && (request.trim().toUpperCase().startsWith("PASS
"))) {
+ logger.info("RECEIVED: PASS *****");
} else {
- logMessage = request;
+ logger.info("RECEIVED: {}", request);
}
- logger.info("RECEIVED: {}", logMessage);
nextFilter.messageReceived(session, message);
}
@@ -109,5 +102,4 @@ public class FtpLoggingFilter extends LoggingFilter {
public void setMaskPassword(boolean maskPassword) {
this.maskPassword = maskPassword;
}
-
}
diff --git
a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpResponseEncoder.java
b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpResponseEncoder.java
index 1704a839..4276f8f2 100644
---
a/core/src/main/java/org/apache/ftpserver/listener/nio/FtpResponseEncoder.java
+++
b/core/src/main/java/org/apache/ftpserver/listener/nio/FtpResponseEncoder.java
@@ -44,8 +44,7 @@ public class FtpResponseEncoder extends
ProtocolEncoderAdapter {
}
};
- public void encode(IoSession session, Object message,
- ProtocolEncoderOutput out) throws Exception {
+ public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
String value = message.toString();
IoBuffer buf = IoBuffer.allocate(value.length()).setAutoExpand(true);
diff --git
a/core/src/main/java/org/apache/ftpserver/message/impl/DefaultMessageResource.java
b/core/src/main/java/org/apache/ftpserver/message/impl/DefaultMessageResource.java
index 49411499..e7ffc5cf 100644
---
a/core/src/main/java/org/apache/ftpserver/message/impl/DefaultMessageResource.java
+++
b/core/src/main/java/org/apache/ftpserver/message/impl/DefaultMessageResource.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Properties;
import org.apache.ftpserver.FtpServerConfigurationException;
@@ -264,4 +265,70 @@ public class DefaultMessageResource implements
MessageResource {
messages.clear();
}
+
+ /**
+ * A string representation if the MessageResource instance
+ *
+ * @return The MessageRessource content
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("MessageResource:\n");
+
+ if (languages != null) {
+ sb.append(" Supported languages:\n");
+
+ for (String language:languages) {
+ sb.append(" ").append( language ).append( '\n');
+
+ PropertiesPair properties = messages.get(language);
+
+ sb.append(" Default properties:\n" );
+
+ for (Entry<Object, Object> entry :
properties.defaultProperties.entrySet()) {
+ sb.append(" <");
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue());
+ sb.append(">\n");
+ }
+
+ sb.append(" Custom properties:\n" );
+
+ for (Entry<Object, Object> entry :
properties.customProperties.entrySet()) {
+ sb.append(" <");
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue());
+ sb.append(">\n");
+ }
+ }
+ } else {
+ sb.append(" No supported language, using the default file\n");
+ PropertiesPair properties = messages.get(null);
+
+ sb.append(" Default properties:\n");
+
+ for (Entry<Object, Object> entry :
properties.defaultProperties.entrySet()) {
+ sb.append(" <");
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue());
+ sb.append(">\n");
+ }
+
+ sb.append(" Custom properties:\n");
+
+ for (Entry<Object, Object> entry :
properties.customProperties.entrySet()) {
+ sb.append(" <");
+ sb.append(entry.getKey());
+ sb.append(',');
+ sb.append(entry.getValue());
+ sb.append(">\n");
+ }
+ }
+
+ return sb.toString();
+ }
}
diff --git
a/core/src/main/java/org/apache/ftpserver/usermanager/PropertiesUserManagerFactory.java
b/core/src/main/java/org/apache/ftpserver/usermanager/PropertiesUserManagerFactory.java
index 918e8917..fb4777f8 100644
---
a/core/src/main/java/org/apache/ftpserver/usermanager/PropertiesUserManagerFactory.java
+++
b/core/src/main/java/org/apache/ftpserver/usermanager/PropertiesUserManagerFactory.java
@@ -38,8 +38,11 @@ public class PropertiesUserManagerFactory implements
UserManagerFactory {
private URL userDataURL;
- /** The default password encryption method*/
- private PasswordEncryptor passwordEncryptor = new Md5PasswordEncryptor();
+ /**
+ * The default password encryption method. It's a one way mechanism, ie
+ * a password is *never* unencrypted.
+ **/
+ private PasswordEncryptor passwordEncryptor = new
Sha512PasswordEncryptor();
/**
* Creates a {@link PropertiesUserManager} instance based on the provided
configuration
diff --git a/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java
b/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java
index 23390244..d62edee3 100644
--- a/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java
+++ b/core/src/main/java/org/apache/ftpserver/util/EncryptUtils.java
@@ -39,7 +39,7 @@ public class EncryptUtils {
*
* @param source The data to encrypt
* @param algorithm The algorithm to use
- * @throws NoSuchAlgorithmException If th algorithm does not exist
+ * @throws NoSuchAlgorithmException If the algorithm does not exist
* @return The encrypted data
*/
public static final byte[] encrypt(byte[] source, String algorithm) throws
NoSuchAlgorithmException {
@@ -98,7 +98,6 @@ public class EncryptUtils {
}
}
-
/**
* Encrypt string using SHA-256 algorithm
*
@@ -114,7 +113,6 @@ public class EncryptUtils {
}
}
-
/**
* Encrypt string using SHA-512 algorithm
*
diff --git a/pom.xml b/pom.xml
index fcb7143f..89a53112 100644
--- a/pom.xml
+++ b/pom.xml
@@ -151,7 +151,7 @@
<!-- doclint>none</doclint-->
<!-- Set versions for depending jars -->
- <commons.codec.version>1.17.1</commons.codec.version>
+ <commons.codec.version>1.17.2</commons.codec.version>
<commons.net.version>3.11.1</commons.net.version>
<ftpserver.version>${project.version}</ftpserver.version>
<hsqldb.version>1.8.0.10</hsqldb.version>
@@ -353,7 +353,7 @@
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
- <version>0.23.0</version>
+ <version>0.23.1</version>
<configuration>
<oldVersion>
<dependency>