/*
* Data Hub Service (DHuS) - For Space data distribution.
* Copyright (C) 2013,2014,2015 GAEL Systems
*
* This file is part of DHuS software sources.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.gael.dhus.server.ftp;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import fr.gael.dhus.database.object.User.PasswordEncryption;
import fr.gael.dhus.service.UserService;
import fr.gael.dhus.service.exception.UserBadEncryptionException;
import fr.gael.dhus.spring.context.ApplicationContextProvider;
import fr.gael.dhus.system.config.ConfigurationManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.ftpserver.ftplet.Authentication;
import org.apache.ftpserver.ftplet.AuthenticationFailedException;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.usermanager.AnonymousAuthentication;
import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission;
import org.apache.ftpserver.usermanager.impl.TransferRatePermission;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.security.crypto.codec.Hex;
/**
* @author pidancier
*
*/
public class DHuSFtpUserManager implements UserManager
{
private static final Logger LOGGER = LogManager.getLogger(DHuSFtpUserManager.class);
private UserService userService;
public DHuSFtpUserManager (UserService userService)
{
this.userService = userService;
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#authenticate(
* org.apache.ftpserver.ftplet.Authentication)
*/
@Override
public User authenticate(final Authentication authentication)
throws AuthenticationFailedException
{
if (authentication instanceof UsernamePasswordAuthentication)
{
UsernamePasswordAuthentication upauth =
(UsernamePasswordAuthentication) authentication;
String username = upauth.getUsername();
String password = upauth.getPassword();
User user = null;
LOGGER.debug("Trying to log as " + username);
try
{
user = getUserByName (username);
fr.gael.dhus.database.object.User u = userService.getUserNoCheck (
username);
PasswordEncryption encryption = u.getPasswordEncryption ();
if (encryption != PasswordEncryption.NONE) // when configurable
{
try
{
MessageDigest md =
MessageDigest.getInstance(encryption.getAlgorithmKey());
password = new String(Hex.encode(
md.digest(password.getBytes("UTF-8"))));
}
catch (Exception e)
{
throw new UserBadEncryptionException (
"There was an error while encrypting password.", e);
}
}
}
catch (FtpException e)
{
throw new AuthenticationFailedException("Authentication failed", e);
}
// Something missing in username
if ((user == null) || (username == null))
{
throw new AuthenticationFailedException(
"Authentication failed (user not correct)");
}
// User not enable
if (!user.getEnabled())
throw new AuthenticationFailedException("User disabled.");
// Simple auth with db infos (no pwd = free)
if ((user.getPassword() == null) ||
(user.getPassword().equals("")) ||
(user.getPassword().equals(password)))
{
return user;
}
throw new AuthenticationFailedException(
"Authentication failed (wrong password)");
}
else if (authentication instanceof AnonymousAuthentication)
{
throw new AuthenticationFailedException(
"Anonymous Authentication not authorized");
}
else
{
throw new IllegalArgumentException(
"Authentication not supported by this user manager");
}
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#delete(java.lang.String)
*/
@Override
public void delete(String name) throws FtpException
{
throw new UnsupportedOperationException("Cannot delete User \"" + name +
"\".");
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#doesExist(java.lang.String)
*/
@Override
public boolean doesExist(String name)
{
return userService.getUserNoCheck (name) == null ? false: true;
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#getAdminName()
*/
@Override
public String getAdminName() throws FtpException
{
return ApplicationContextProvider.getBean (ConfigurationManager.class)
.getAdministratorConfiguration ().getName ();
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#getAllUserNames()
*/
@Override
public String[] getAllUserNames() throws FtpException
{
DetachedCriteria criteria = DetachedCriteria.forClass (
fr.gael.dhus.database.object.User.class);
criteria.add (Restrictions.eq ("deleted", false));
List<fr.gael.dhus.database.object.User> users = userService.getUsers (
criteria, 0, 0);
List<String> names = new LinkedList<> ();
for (fr.gael.dhus.database.object.User user : users)
{
names.add (user.getUsername ());
}
return names.toArray(new String[names.size()]);
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#getUserByName(
* java.lang.String)
*/
@Override
public User getUserByName(final String name) throws FtpException
{
if (name == null) return null;
fr.gael.dhus.database.object.User u = userService.getUserNoCheck (name);
if (u==null) return null;
BaseUser user = new BaseUser();
user.setName(u.getUsername());
user.setPassword(u.getPassword());
user.setEnabled(
u.isEnabled() &&
u.isAccountNonExpired() &&
u.isAccountNonLocked() &&
u.isCredentialsNonExpired() &&
!u.isDeleted());
user.setHomeDirectory("/");
List<Authority> authorities = new ArrayList<>();
authorities.add(new WritePermission ());
// No special limit
int maxLogin = 0;
int maxLoginPerIP = 0;
authorities.add(new ConcurrentLoginPermission(maxLogin, maxLoginPerIP));
int uploadRate = 0;
int downloadRate = 0;
authorities.add(new TransferRatePermission(downloadRate, uploadRate));
user.setAuthorities(authorities);
user.setMaxIdleTime(1000);
return user;
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#isAdmin(java.lang.String)
*/
@Override
public boolean isAdmin(String s) throws FtpException
{
return getAdminName().equals(s);
}
/* (non-Javadoc)
* @see org.apache.ftpserver.ftplet.UserManager#save(
* org.apache.ftpserver.ftplet.User)
*/
@Override
public void save(User user) throws FtpException
{
throw new FtpException ("Not allowed to save user by ftp.");
}
}