summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/server
diff options
context:
space:
mode:
authorSimon Rettberg2014-04-24 18:59:35 +0200
committerSimon Rettberg2014-04-24 18:59:35 +0200
commited787b6f67954faab790cab107503eac8e6aad3c (patch)
tree6f05300170e670ab5db0ccda62bb918d0371b7ad /src/main/java/org/openslx/imagemaster/server
parentFix name of format style (diff)
parentAdd FTPS to MasterFtpServer (diff)
downloadmasterserver-ed787b6f67954faab790cab107503eac8e6aad3c.tar.gz
masterserver-ed787b6f67954faab790cab107503eac8e6aad3c.tar.xz
masterserver-ed787b6f67954faab790cab107503eac8e6aad3c.zip
Merge branch 'master' of dnbd3:bwlp/masterserver
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/server')
-rw-r--r--src/main/java/org/openslx/imagemaster/server/ApiServer.java153
-rw-r--r--src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java63
-rw-r--r--src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java141
-rw-r--r--src/main/java/org/openslx/imagemaster/server/MasterFtplet.java55
4 files changed, 248 insertions, 164 deletions
diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
index df0aa3a..c88bd05 100644
--- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
@@ -4,6 +4,7 @@ import java.io.File;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
+import org.openslx.imagemaster.App;
import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.db.DbSatellite;
import org.openslx.imagemaster.db.ImageProcessor;
@@ -39,8 +40,9 @@ import org.openslx.imagemaster.thrift.iface.UserInfo;
* This will be accessed from multiple threads, so use synchronization when
* needed (or in doubt)
*/
-public class ApiServer {
- private static Logger log = Logger.getLogger(ApiServer.class);
+public class ApiServer
+{
+ private static Logger log = Logger.getLogger( ApiServer.class );
/**
* Request for authentication
@@ -50,17 +52,18 @@ public class ApiServer {
* @return SessionData struct with session id/token iff login successful
* @throws AuthenticationException if login not successful
*/
- public static SessionData authenticate(String login, String password)
- throws AuthenticationException {
- if (login == null || password == null) {
+ public static SessionData authenticate( String login, String password )
+ throws AuthenticationException
+ {
+ if ( login == null || password == null ) {
throw new AuthenticationException(
AuthenticationError.INVALID_CREDENTIALS,
- "Empty username or password!");
+ "Empty username or password!" );
}
- final User user = Authenticator.authenticate(login, password);
+ final User user = Authenticator.authenticate( login, password );
- final Session session = new Session(user);
- return SessionManager.addSession(session);
+ final Session session = new Session( user );
+ return SessionManager.addSession( session );
}
/**
@@ -70,121 +73,131 @@ public class ApiServer {
* @return UserInfo struct for given token's user
* @throws InvalidTokenException if no user matches the given token
*/
- public static UserInfo getUserFromToken(String token)
- throws InvalidTokenException {
- final Session session = SessionManager.getSession(token);
- if (session == null)
+ public static UserInfo getUserFromToken( String token )
+ throws InvalidTokenException
+ {
+ final Session session = SessionManager.getSession( token );
+ if ( session == null )
throw new InvalidTokenException();
- return new UserInfo(session.getUserId(), session.getFirstName(),
- session.getLastName(), session.getEMail());
+ return new UserInfo( session.getUserId(), session.getFirstName(),
+ session.getLastName(), session.getEMail() );
}
/**
* Request ftp credentials to upload a new image to the masterserver.
+ *
* @param imageDescription MetaData of the new image
* @param serverSessionData the session data of the authenticated uni/hs server
* @return the genereated ftp credentials
* @throws AuthorizationException if the uni/hs server has no valid session
* @throws TException
*/
- public static FtpCredentials submitImage(String serverSessionId,
- ImageData imageDescription) throws AuthorizationException,
- TException {
- if (ServerSessionManager.getSession(serverSessionId) == null) {
- throw new AuthorizationException(AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData");
+ public static FtpCredentials submitImage( String serverSessionId,
+ ImageData imageDescription ) throws AuthorizationException,
+ TException
+ {
+ if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
+ throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
}
-
+
// create new user
- FtpCredentials ftpCredentials = Globals.ftpServer.addUser(serverSessionId);
-
- if (ftpCredentials == null) {
- log.error("Could not create ftp credentials");
+ FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId );
+
+ if ( ftpCredentials == null ) {
+ log.error( "Could not create ftp credentials" );
return null;
}
-
- if (!ImageProcessor.addImageDataToProcess(imageDescription, ftpCredentials.username)) {
- Globals.ftpServer.removeUser(serverSessionId);
- throw new TException("ImageData is not valid.");
+
+ if ( !ImageProcessor.addImageDataToProcess( imageDescription, ftpCredentials.username ) ) {
+ App.ftpServer.removeUser( serverSessionId );
+ throw new TException( "ImageData is not valid." );
}
-
+
return ftpCredentials;
}
/**
* Start the server authentication of a uni/hs satellite server.
+ *
* @param organization the organization that the server belongs to
* @return a random string that needs to be encrypted with the private
- * key of the requesting satellite server
+ * key of the requesting satellite server
* @throws ServerAuthenticationException when organization is invalid/unknown
*/
- public static String startServerAuthentication(String organization)
- throws ServerAuthenticationException {
- if (organization == null || organization == "") {
- throw new ServerAuthenticationException(ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization");
+ public static String startServerAuthentication( String organization )
+ throws ServerAuthenticationException
+ {
+ if ( organization == null || organization == "" ) {
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization" );
}
- if (DbSatellite.fromOrganization(organization) == null) {
- throw new ServerAuthenticationException(ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization");
+ if ( DbSatellite.fromOrganization( organization ) == null ) {
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
}
- return ServerAuthenticator.startServerAuthentication(organization);
+ return ServerAuthenticator.startServerAuthentication( organization );
}
/**
* Authenticate the uni/hs satellite server with the encrypted string.
+ *
* @param organization the organization that the server belongs to
* @param challengeResponse the encrypted string
* @return session data iff the authentication was successful
* @throws AuthenticationException
* @throws TException
*/
- public static ServerSessionData serverAuthenticate(String organization,
- String challengeResponse) throws AuthenticationException,
- TException {
- if (organization == null || challengeResponse == null) {
- throw new ServerAuthenticationException(ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization or challengeResponse");
+ public static ServerSessionData serverAuthenticate( String organization,
+ String challengeResponse ) throws AuthenticationException,
+ TException
+ {
+ if ( organization == null || challengeResponse == null ) {
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization or challengeResponse" );
}
- DbSatellite satellite = DbSatellite.fromOrganization(organization);
- if (satellite == null) {
- throw new ServerAuthenticationException(ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization");
+ DbSatellite satellite = DbSatellite.fromOrganization( organization );
+ if ( satellite == null ) {
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
}
final ServerUser serverUser = ServerAuthenticator.serverAuthenticate(
- organization, satellite.getAddress(), challengeResponse);
-
- final ServerSession session = new ServerSession(serverUser);
- return ServerSessionManager.addSession(session);
+ organization, satellite.getAddress(), challengeResponse );
+
+ final ServerSession session = new ServerSession( serverUser );
+ return ServerSessionManager.addSession( session );
}
/**
* Tell the masterserver that the image upload finished.
+ *
* @param serverSessionId The session id of the hs/uni server
* @param imageDescription the description of the uploaded image
* @return if nothing went wrong
* @throws AuthorizationException if no valid session exists
*/
- public static boolean finishedUpload(String serverSessionId,
- ImageData imageDescription) throws AuthorizationException {
+ public static boolean finishedUpload( String serverSessionId,
+ ImageData imageDescription ) throws AuthorizationException
+ {
// check if valid session exists
- if (ServerSessionManager.getSession(serverSessionId) == null) {
- throw new AuthorizationException(AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData");
+ if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
+ throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
}
-
+
// process the image
- String username = Globals.ftpServer.getCredentialsFromSessionId(serverSessionId).username;
-
- File userDirectory = new File(Globals.properties.getProperty(Globals.ftpBaseDir) + "/" + username);
+ String username = App.ftpServer.getCredentialsFromSessionId( serverSessionId ).username;
+
+ File userDirectory = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username );
File[] list = userDirectory.listFiles();
-
- if (list.length != 1) return false;
-
- log.info(username + " is done with upload");
-
+
+ if ( list.length != 1 )
+ return false;
+
+ log.info( username + " is done with upload" );
+
// remove user that is not needed anymore
- Globals.ftpServer.removeUser(username);
- log.info("Removed user: " + username);
-
- ImageProcessor.processImageAfterUpload(username, list[0].getName());
-
- Globals.ftpServer.removeUser(serverSessionId);
-
+ App.ftpServer.removeUser( username );
+ log.info( "Removed user: " + username );
+
+ ImageProcessor.processImageAfterUpload( username, list[0].getName() );
+
+ App.ftpServer.removeUser( serverSessionId );
+
return true;
}
diff --git a/src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java b/src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java
new file mode 100644
index 0000000..ba88f33
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java
@@ -0,0 +1,63 @@
+package org.openslx.imagemaster.server;
+
+import java.io.File;
+import java.util.Date;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.log4j.Logger;
+import org.openslx.imagemaster.App;
+import org.openslx.imagemaster.Globals;
+import org.openslx.imagemaster.thrift.iface.FtpCredentials;
+import org.openslx.imagemaster.util.Util;
+
+public class FtpCredentialsScheduler extends TimerTask
+{
+ private static Logger log = Logger.getLogger( FtpCredentialsScheduler.class );
+
+ public static final long timeout = Long.valueOf( Globals.getPropertyInt( Globals.PropInt.FTPTIMEOUT ) ) * 60L * 1000L; // timeout in ms
+
+ @Override
+ public void run()
+ {
+ // check all folders
+ for ( Map.Entry<String, FtpCredentials> entry : App.ftpServer.users.entrySet() ) {
+ String sessionId = entry.getKey();
+ String username = entry.getValue().username;
+ File dir = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username );
+ if ( !dir.exists() )
+ continue;
+ File[] list = dir.listFiles();
+ if ( list.length == 1 ) {
+ if ( ( new Date().getTime() - list[0].lastModified() ) >= timeout ) {
+ log.info( username + "'s files are too old. Deleting him and his folder." );
+ Util.deleteFolder( dir );
+ App.ftpServer.removeUser( sessionId );
+ }
+ } else if ( list.length > 1 ) {
+ log.info( username + " uploaded too many files. Deleting his account and his folder." );
+ Util.deleteFolder( dir );
+ App.ftpServer.removeUser( sessionId );
+ } else {
+ // check the creation time of the user
+ if ( ( new Date().getTime() - App.ftpServer.timeouts.get( username ).getTime() ) >= timeout ) {
+ // remove user and his folder
+ Util.deleteFolder( dir );
+ App.ftpServer.removeUser( sessionId );
+ log.info( username + " did nothing for too long. Deleting him and his folder" );
+ }
+ }
+ }
+ //TODO: remove image from process list
+ }
+
+ public static void startScheduling()
+ {
+ Timer timer = new Timer();
+
+ // start timer now and fire every 60 seconds
+ timer.schedule( new FtpCredentialsScheduler(), 0, 60000 );
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java b/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java
index d1ec14f..de0d758 100644
--- a/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java
@@ -13,6 +13,7 @@ import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
+import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
import org.apache.ftpserver.usermanager.impl.BaseUser;
@@ -22,7 +23,8 @@ import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.thrift.iface.FtpCredentials;
import org.openslx.imagemaster.util.RandomString;
-public class MasterFtpServer implements Runnable {
+public class MasterFtpServer implements Runnable
+{
private static Logger log = Logger.getLogger( MasterFtpServer.class );
private FtpServer server;
private UserManager userManager;
@@ -30,96 +32,111 @@ public class MasterFtpServer implements Runnable {
public final HashMap<String, FtpCredentials> users = new HashMap<>();
// key: ftpUsername, value: createTime
public final HashMap<String, Date> timeouts = new HashMap<>();
-
- public MasterFtpServer(int port, String adminUsername, String adminPassword, String ftproot) {
+ private boolean ini = false;
+
+ public void init( int port )
+ {
+ if ( ini )
+ return;
+
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
+
+ // config ssl
+ SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory();
+ sslConfigFactory.setKeystoreFile( new File( "./keyfiles/ftp.jks" ) );
+ sslConfigFactory.setKeyAlias( "ftp" );
+ sslConfigFactory.setKeystorePassword( "password" );
+
// set the port of the listener
- factory.setPort(port);
-
+ factory.setPort( port );
+ factory.setSslConfiguration( sslConfigFactory.createSslConfiguration() );
+ factory.setImplicitSsl( true );
+
// replace the default listener
- serverFactory.addListener("default", factory.createListener());
-
+ serverFactory.addListener( "default", factory.createListener() );
+
// create user manager
- PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
- userManagerFactory.setFile(new File("src/main/properties/ftp.properties"));
- userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
- userManager = userManagerFactory.createUserManager();
-
- // create new admin user
- //addUser(adminUsername, adminPassword, ftproot, true);
- serverFactory.setUserManager(userManager);
-
+ PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
+ userManagerFactory.setFile( new File( "src/main/properties/ftp.properties" ) );
+ userManagerFactory.setPasswordEncryptor( new SaltedPasswordEncryptor() );
+ userManager = userManagerFactory.createUserManager();
+ serverFactory.setUserManager( userManager );
+
// add the Ftplet
HashMap<String, Ftplet> map = new HashMap<String, Ftplet>();
- map.put("Ftplet1", new MasterFtplet());
- serverFactory.setFtplets(map);
-
+ map.put( "Ftplet1", new MasterFtplet() );
+ serverFactory.setFtplets( map );
+
// start the server
server = serverFactory.createServer();
+ ini = true;
}
- public FtpCredentials addUser(final String serverSessionId) {
- // TODO: enable SSL
-
+ public FtpCredentials addUser( final String serverSessionId )
+ {
FtpCredentials ftpCredentials = null;
-
- String generatedUser = RandomString.generate(10, false);
- String generatedPass = RandomString.generate(16, true);
-
- String dir = Globals.properties.getProperty(Globals.ftpBaseDir) + "/"
+
+ String generatedUser = RandomString.generate( 10, false );
+ String generatedPass = RandomString.generate( 16, true );
+
+ String dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/"
+ generatedUser + "/";
-
- if (!new File(dir).mkdir()) {
+
+ if ( !new File( dir ).mkdir() ) {
return ftpCredentials;
}
- BaseUser user = new BaseUser();
- user.setName(generatedUser);
- user.setPassword(generatedPass);
- user.setHomeDirectory(dir);
-
- List<Authority> authorities = new ArrayList<Authority>();
- authorities.add(new WritePermission());
- user.setAuthorities(authorities);
-
- try {
- userManager.save(user);
- ftpCredentials = new FtpCredentials(generatedUser, generatedPass);
- users.put(serverSessionId, ftpCredentials);
- timeouts.put(ftpCredentials.username, new Date());
- } catch (FtpException e) {
- }
-
- log.info("Generated user/pass: " + generatedUser + "\t"
- + generatedPass + "\n with home dir: " + dir);
-
- return ftpCredentials;
+ BaseUser user = new BaseUser();
+ user.setName( generatedUser );
+ user.setPassword( generatedPass );
+ user.setHomeDirectory( dir );
+
+ List<Authority> authorities = new ArrayList<Authority>();
+ authorities.add( new WritePermission() );
+ user.setAuthorities( authorities );
+
+ try {
+ userManager.save( user );
+ ftpCredentials = new FtpCredentials( generatedUser, generatedPass );
+ users.put( serverSessionId, ftpCredentials );
+ timeouts.put( ftpCredentials.username, new Date() );
+ } catch ( FtpException e ) {
+ }
+
+ log.info( "Generated user/pass: " + generatedUser + "\t"
+ + generatedPass + "\n with home dir: " + dir );
+
+ return ftpCredentials;
}
-
- public boolean removeUser(final String serverSessionId) {
- if (!users.containsKey(serverSessionId)) return false;
-
+
+ public boolean removeUser( final String serverSessionId )
+ {
+ if ( !users.containsKey( serverSessionId ) )
+ return false;
+
try {
- userManager.delete(users.get(serverSessionId).username);
+ userManager.delete( users.get( serverSessionId ).username );
// remove user from both maps
- timeouts.remove(users.remove(serverSessionId).username);
+ timeouts.remove( users.remove( serverSessionId ).username );
return true;
- } catch (FtpException e) {
+ } catch ( FtpException e ) {
return false;
}
}
-
- public FtpCredentials getCredentialsFromSessionId(String serverSessionId) {
- return users.get(serverSessionId);
+
+ public FtpCredentials getCredentialsFromSessionId( String serverSessionId )
+ {
+ return users.get( serverSessionId );
}
@Override
- public void run() {
+ public void run()
+ {
try {
log.info( "Starting FTP Sever" );
server.start();
- } catch (FtpException e1) {
+ } catch ( FtpException e1 ) {
e1.printStackTrace();
}
}
diff --git a/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java b/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java
index 479729d..a8c1cbe 100644
--- a/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java
+++ b/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java
@@ -9,63 +9,54 @@ import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.FtpletContext;
import org.apache.ftpserver.ftplet.FtpletResult;
-import org.apache.ftpserver.ftplet.UserManager;
import org.apache.log4j.Logger;
-import org.openslx.imagemaster.db.ImageProcessor;
-public class MasterFtplet implements Ftplet {
- private static Logger log = Logger.getLogger(Ftplet.class);
- private UserManager userManager;
+public class MasterFtplet implements Ftplet
+{
+ private static Logger log = Logger.getLogger( Ftplet.class );
@Override
- public void init(FtpletContext ftpletContext) throws FtpException {
- userManager = ftpletContext.getUserManager();
+ public void init( FtpletContext ftpletContext ) throws FtpException
+ {
+ // not used
}
@Override
- public void destroy() {
+ public void destroy()
+ {
// not used
}
@Override
- public FtpletResult beforeCommand(FtpSession session, FtpRequest request)
- throws FtpException, IOException {
- if (session.getUser() != null) {
- log.info(session.getUser().getName() + " issued command: " + request.getRequestLine());
+ public FtpletResult beforeCommand( FtpSession session, FtpRequest request )
+ throws FtpException, IOException
+ {
+ if ( session.getUser() != null ) {
+ log.info( session.getUser().getName() + " issued command: " + request.getRequestLine() );
}
return null;
}
@Override
- public FtpletResult afterCommand(FtpSession session, FtpRequest request,
- FtpReply reply) throws FtpException, IOException {
- if (session.getUser() != null) {
- String username = session.getUser().getName();
- String command = request.getRequestLine();
- log.info(username + " is done with command: " + command);
- if (request.getCommand().equals("STOR")) {
- try {
- userManager.delete(username);
- } catch (FtpException e) {
- } finally {
- log.info("Stored file and deleted user: '" + username + "'");
- ImageProcessor.processImageAfterUpload(username, command.split(" ")[1]);
- }
- }
- }
+ public FtpletResult afterCommand( FtpSession session, FtpRequest request,
+ FtpReply reply ) throws FtpException, IOException
+ {
+ // not used
return null;
}
@Override
- public FtpletResult onConnect(FtpSession session) throws FtpException,
- IOException {
+ public FtpletResult onConnect( FtpSession session ) throws FtpException,
+ IOException
+ {
// not used
return null;
}
@Override
- public FtpletResult onDisconnect(FtpSession session) throws FtpException,
- IOException {
+ public FtpletResult onDisconnect( FtpSession session ) throws FtpException,
+ IOException
+ {
// not used
return null;
}