/** * 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. * * This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation; either version 3.0 of the * License, or (at your option) any later version. * * This software 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.waarp.gateway.ftp.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.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.filesystembased.FilesystemBasedFtpRestart; import org.waarp.gateway.ftp.config.FileBasedConfiguration; import org.waarp.gateway.ftp.database.DbConstant; import org.waarp.gateway.kernel.exec.AbstractExecutor.CommandExecutor; import org.waarp.gateway.kernel.session.HttpAuthInterface; /** * FtpAuth implementation based on a list of (user/password/account) stored in a xml file load at * startup from configuration. * * @author Frederic Bregier * */ public class FileBasedAuth extends FilesystemBasedFtpAuth implements HttpAuthInterface { /** * Internal Logger */ private static final WaarpLogger logger = WaarpLoggerFactory .getLogger(FileBasedAuth.class); /** * Current authentication */ private SimpleAuth currentAuth = null; /** * Special Id for the current transfer */ private long specialId = DbConstant.ILLEGALVALUE; /** * @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)) { 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() { if (currentAuth == null) return false; return currentAuth.isAdmin(); } /** * Special Authentication for local execution * * @param hostid */ public void specialNoSessionAuth(String hostid) { this.isIdentified = true; SimpleAuth auth = new SimpleAuth(hostid, hostid, null, null, 0, null, 0); currentAuth = auth; setIsIdentified(true); user = auth.getUser(); account = auth.getUser(); ((FtpSession) getSession()).setSpecialInit(this, new FileBasedDir(((FtpSession) getSession())), new FilesystemBasedFtpRestart(((FtpSession) getSession()))); try { setBusinessRootFromAuth(); } catch (Reply421Exception e) { } getSession().getDir().initAfterIdentification(); currentAuth.setAdmin(true); } /** * @return the specialId */ public long getSpecialId() { return specialId; } /** * @param specialId * the specialId to set */ public void setSpecialId(long specialId) { this.specialId = specialId; } /** * * @return the associated Command Executor */ public CommandExecutor getCommandExecutor() { return this.currentAuth.getCommandExecutor(); } }