/**
* This file is part of Waarp Project.
*
* Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
* COPYRIGHT.txt in the distribution for a full listing of individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Waarp . If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.waarp.ftp.simpleimpl.file;
import java.io.File;
import org.waarp.common.command.NextCommandReply;
import org.waarp.common.command.ReplyCode;
import org.waarp.common.command.exception.Reply421Exception;
import org.waarp.common.command.exception.Reply502Exception;
import org.waarp.common.command.exception.Reply530Exception;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.ftp.core.command.FtpCommandCode;
import org.waarp.ftp.core.file.FtpDir;
import org.waarp.ftp.core.session.FtpSession;
import org.waarp.ftp.filesystembased.FilesystemBasedFtpAuth;
import org.waarp.ftp.simpleimpl.config.FileBasedConfiguration;
/**
* FtpAuth implementation based on a list of (user/password/account) stored in a xml file load at
* startup from configuration. Not to be used in production!
*
* @author Frederic Bregier
*
*/
public class FileBasedAuth extends FilesystemBasedFtpAuth {
/**
* Internal Logger
*/
private static final WaarpLogger logger = WaarpLoggerFactory
.getLogger(FileBasedAuth.class);
/**
* Current authentication
*/
private SimpleAuth currentAuth = null;
/**
* @param session
*/
public FileBasedAuth(FtpSession session) {
super(session);
}
@Override
protected void businessClean() {
currentAuth = null;
}
/**
* @param user
* the user to set
* @return (NOOP,230) if the user is OK, else return the following command that must follow
* (usually PASS) and the associated reply
* @throws Reply421Exception
* if there is a problem during the authentication
* @throws Reply530Exception
* if there is a problem during the authentication
*/
@Override
protected NextCommandReply setBusinessUser(String user)
throws Reply421Exception, Reply530Exception {
SimpleAuth auth = ((FileBasedConfiguration) ((FtpSession) getSession())
.getConfiguration()).getSimpleAuth(user);
if (auth == null) {
setIsIdentified(false);
currentAuth = null;
throw new Reply530Exception("User name not allowed");
}
currentAuth = auth;
// logger.debug("User: {}", user);
return new NextCommandReply(FtpCommandCode.PASS,
ReplyCode.REPLY_331_USER_NAME_OKAY_NEED_PASSWORD, null);
}
/**
* Set the password according to any implementation and could set the rootFromAuth. If NOOP is
* returned, isIdentifed must be TRUE. A special case is implemented for test user.
*
* @param password
* @return (NOOP,230) if the Password is OK, else return the following command that must follow
* (usually ACCT) and the associated reply
* @throws Reply421Exception
* if there is a problem during the authentication
* @throws Reply530Exception
* if there is a problem during the authentication
*/
@Override
protected NextCommandReply setBusinessPassword(String password)
throws Reply421Exception, Reply530Exception {
if (currentAuth == null) {
setIsIdentified(false);
throw new Reply530Exception("PASS needs a USER first");
}
if (currentAuth.isPasswordValid(password)) {
if (user.equals("test")) {
// logger.debug("User test");
try {
return setAccount("test");
} catch (Reply502Exception e) {
}
}
return new NextCommandReply(FtpCommandCode.ACCT,
ReplyCode.REPLY_332_NEED_ACCOUNT_FOR_LOGIN, null);
}
throw new Reply530Exception("Password is not valid");
}
/**
* Set the account according to any implementation and could set the rootFromAuth. If NOOP is
* returned, isIdentifed must be TRUE.
*
* @param account
* @return (NOOP,230) if the Account is OK, else return the following command that must follow
* and the associated reply
* @throws Reply421Exception
* if there is a problem during the authentication
* @throws Reply530Exception
* if there is a problem during the authentication
*/
@Override
protected NextCommandReply setBusinessAccount(String account)
throws Reply421Exception, Reply530Exception {
if (currentAuth == null) {
throw new Reply530Exception("ACCT needs a USER first");
}
if (currentAuth.isAccountValid(account)) {
// logger.debug("Account: {}", account);
setIsIdentified(true);
logger.info("User {} is authentified with account {}", user,
account);
return new NextCommandReply(FtpCommandCode.NOOP,
ReplyCode.REPLY_230_USER_LOGGED_IN, null);
}
throw new Reply530Exception("Account is not valid");
}
public boolean isBusinessPathValid(String newPath) {
if (newPath == null) {
return false;
}
return newPath.startsWith(getBusinessPath());
}
@Override
protected String setBusinessRootFromAuth() throws Reply421Exception {
String path = null;
if (account == null) {
path = FtpDir.SEPARATOR + user;
} else {
path = FtpDir.SEPARATOR + user + FtpDir.SEPARATOR +
account;
}
String fullpath = getAbsolutePath(path);
File file = new File(fullpath);
if (!file.isDirectory()) {
throw new Reply421Exception("Filesystem not ready");
}
return path;
}
public boolean isAdmin() {
return currentAuth.isAdmin();
}
}