summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNils Schwabe2014-04-10 11:58:34 +0200
committerNils Schwabe2014-04-10 11:58:34 +0200
commitd5e1e558f22de9e20fbee6c1e8a884e65fa7cbbc (patch)
treec9895bd99ed579d421343b41e9611da23eb1a4c1
parentadded new thrift methods: (diff)
downloadmasterserver-d5e1e558f22de9e20fbee6c1e8a884e65fa7cbbc.tar.gz
masterserver-d5e1e558f22de9e20fbee6c1e8a884e65fa7cbbc.tar.xz
masterserver-d5e1e558f22de9e20fbee6c1e8a884e65fa7cbbc.zip
Added authentification for uni/hs server
--> added serversession, serversessionmanager --> missing implementation for server authentication
-rw-r--r--src/main/java/org/openslx/imagemaster/App.java36
-rw-r--r--src/main/java/org/openslx/imagemaster/Globals.java4
-rw-r--r--src/main/java/org/openslx/imagemaster/server/ApiServer.java118
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java40
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerSession.java35
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerSessionManager.java69
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerUser.java11
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java14
-rw-r--r--src/main/java/org/openslx/imagemaster/util/RandomString.java30
-rw-r--r--src/main/thrift/imagemaster.thrift2
10 files changed, 295 insertions, 64 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java
index 62e06a4..3a309c5 100644
--- a/src/main/java/org/openslx/imagemaster/App.java
+++ b/src/main/java/org/openslx/imagemaster/App.java
@@ -1,15 +1,12 @@
package org.openslx.imagemaster;
import java.io.BufferedInputStream;
-import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
-import org.openslx.imagemaster.server.MasterFtpServer;
import org.openslx.imagemaster.thrift.server.BinaryListener;
public class App {
@@ -51,39 +48,10 @@ public class App {
// Create Ftp Server
Thread f;
- MasterFtpServer ftpServer = new MasterFtpServer(2221, "admin",
- "SI*HoZCC!]V)p>B2", Globals.properties.getProperty("ftp_base_dir"));
- f = new Thread(ftpServer, "FtpServer");
+ f = new Thread(Globals.ftpServer, "FtpServer");
servers.add(f);
f.start();
- /*
- * FTP Users can be added later with:
- * ftpServer.addUser(username, password, ftp_root);
- *
- * And removed with:
- * removeUser(username);
- */
-
- ////////////////////////////////////////////////
- SecureRandom random = new SecureRandom();
- String lettersP="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-$%&/()=?@";
- String lettersU="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
- String generatedUser = "";
- String generatedPass = "";
- for (int i = 0; i < 16; i++) {
- int index = (int)(random.nextDouble()*lettersU.length());
- generatedUser += lettersU.substring(index, index + 1);
- index = (int)(random.nextDouble()*lettersP.length());
- generatedPass += lettersP.substring(index, index + 1);
- }
- String dir = Globals.properties.getProperty("ftp_base_dir") + "/" + generatedUser + "/";
- if (new File(dir).mkdir()) {
- ftpServer.addUser(generatedUser, generatedPass, dir, true);
- log.info("Generated user/pass: " + generatedUser + "\t" + generatedPass + "\n with home dir: " + dir);
- }
- ////////////////////////////////////////////////
-
// Run more servers
// ...
// Wait for all servers to die
@@ -99,8 +67,6 @@ public class App {
}
}
- ftpServer.removeUser(generatedUser);
-
log.info("All Servers shut down, exiting...");
}
}
diff --git a/src/main/java/org/openslx/imagemaster/Globals.java b/src/main/java/org/openslx/imagemaster/Globals.java
index 0cca10d..b766b27 100644
--- a/src/main/java/org/openslx/imagemaster/Globals.java
+++ b/src/main/java/org/openslx/imagemaster/Globals.java
@@ -2,6 +2,10 @@ package org.openslx.imagemaster;
import java.util.Properties;
+import org.openslx.imagemaster.server.MasterFtpServer;
+
public class Globals {
public static final Properties properties = new Properties();
+ public static final MasterFtpServer ftpServer = new MasterFtpServer(2221, "admin",
+ "SI*HoZCC!]V)p>B2", Globals.properties.getProperty("ftp_base_dir"));
}
diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
index ba15623..3799079 100644
--- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
@@ -1,15 +1,29 @@
package org.openslx.imagemaster.server;
+import java.io.File;
+
import org.apache.log4j.Logger;
+import org.apache.thrift.TException;
+import org.openslx.imagemaster.Globals;
+import org.openslx.imagemaster.db.DbSatellite;
+import org.openslx.imagemaster.serversession.ServerAuthenticator;
+import org.openslx.imagemaster.serversession.ServerSession;
+import org.openslx.imagemaster.serversession.ServerSessionManager;
+import org.openslx.imagemaster.serversession.ServerUser;
import org.openslx.imagemaster.session.Authenticator;
import org.openslx.imagemaster.session.Session;
import org.openslx.imagemaster.session.SessionManager;
import org.openslx.imagemaster.session.User;
import org.openslx.imagemaster.thrift.iface.AuthenticationError;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
+import org.openslx.imagemaster.thrift.iface.AuthorizationException;
+import org.openslx.imagemaster.thrift.iface.FtpCredentials;
+import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.InvalidTokenException;
+import org.openslx.imagemaster.thrift.iface.ServerSessionData;
import org.openslx.imagemaster.thrift.iface.SessionData;
import org.openslx.imagemaster.thrift.iface.UserInfo;
+import org.openslx.imagemaster.util.RandomString;
/**
* API Server This is where all the requests from the outside arrive. We don't
@@ -22,42 +36,106 @@ 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
-{
- @SuppressWarnings( "unused" )
- private static Logger log = Logger.getLogger( ApiServer.class );
+public class ApiServer {
+ private static Logger log = Logger.getLogger(ApiServer.class);
/**
* Request for authentication
- * @param login (username@organization)
+ *
+ * @param login
+ * (username@organization)
* @param password
* @return SessionData struct with session id/token iff login successful
- * @throws AuthenticationException if login not successful
+ * @throws AuthenticationException
+ * if login not successful
*/
- public static SessionData authenticate( String login, String password )
+ 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!" );
+ if (login == null || password == null) {
+ throw new AuthenticationException(
+ AuthenticationError.INVALID_CREDENTIALS,
+ "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);
}
/**
* Request information about user for given token
- * @param token - a user's token
+ *
+ * @param token
+ * - a user's token
* @return UserInfo struct for given token's user
- * @throws InvalidTokenException if no user matches the given token
+ * @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());
+ }
+
+ public static FtpCredentials submitImage(ImageData imageDescription,
+ ServerSessionData serverSessionData) throws AuthorizationException,
+ TException {
+ /*
+ * TODO:
+ * Check if session is ok.
+ * create and return FtpCredentials
+ */
+
+ /*
+ * FTP Users can be added later with: ftpServer.addUser(username,
+ * password, ftp_root);
+ *
+ * And removed with: removeUser(username);
+ */
+
+ String generatedUser = RandomString.generate(10, false);
+ String generatedPass = RandomString.generate(16, true);
+ String dir = Globals.properties.getProperty("ftp_base_dir") + "/"
+ + generatedUser + "/";
+ if (new File(dir).mkdir()) {
+ Globals.ftpServer.addUser(generatedUser, generatedPass, dir, true);
+ log.info("Generated user/pass: " + generatedUser + "\t"
+ + generatedPass + "\n with home dir: " + dir);
+ }
+ // TODO: remove old user
+
+ return new FtpCredentials(generatedUser, generatedPass);
+ }
+
+ public static String startServerAuthentication(String organization)
+ throws TException {
+ if (organization == null || organization == "") {
+ throw new TException("Empty organization");
+ }
+ if (DbSatellite.fromOrganization(organization) == null) {
+ throw new TException("Unkown organization");
+ }
+ return ServerAuthenticator.startServerAuthentication(organization);
+ }
+
+ public static ServerSessionData serverAuthenticate(String organization,
+ String challengeResponse) throws AuthenticationException,
+ TException {
+ if (organization == null || challengeResponse == null) {
+ throw new TException("Empty organization org challengeResponse");
+ }
+ DbSatellite satellite = DbSatellite.fromOrganization(organization);
+ if (satellite == null) {
+ throw new TException("Unkown organization");
+ }
+ final ServerUser serverUser = ServerAuthenticator.serverAuthenticate(
+ organization, satellite.getAddress(), challengeResponse);
+
+ final ServerSession session = new ServerSession(serverUser);
+ return ServerSessionManager.addSession(session);
}
}
diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java b/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java
new file mode 100644
index 0000000..b16766a
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java
@@ -0,0 +1,40 @@
+package org.openslx.imagemaster.serversession;
+
+import java.util.HashMap;
+
+import org.apache.thrift.TException;
+import org.openslx.imagemaster.thrift.iface.AuthenticationException;
+import org.openslx.imagemaster.util.RandomString;
+
+public class ServerAuthenticator {
+ private static HashMap<String, String> authenticatingServers = new HashMap<String, String>();
+ /**
+ * Start the server authentification.
+ * @param organization the organization of the server
+ * @return encrypted random string
+ */
+ public static String startServerAuthentication(String organization) {
+ /*
+ * TODO:
+ * Create random string, send it to server.
+ * Remember organization for later authentification.
+ */
+ String secret = RandomString.generate(100, false);
+ synchronized (authenticatingServers) {
+ authenticatingServers.put(organization, secret);
+ }
+ return secret;
+ }
+
+
+ public static ServerUser serverAuthenticate(String organization, String address,
+ String challengeResponse) throws AuthenticationException,
+ TException {
+ /*
+ * TODO:
+ * Decrypt the given challengeResponse and check whether it was right or not.
+ * Authenticate server if so.
+ */
+ return new ServerUser(organization, address);
+ }
+}
diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java b/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java
new file mode 100644
index 0000000..e15f863
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java
@@ -0,0 +1,35 @@
+package org.openslx.imagemaster.serversession;
+
+public class ServerSession {
+
+ private static final long TIMEOUT = 600L * 1000L; // TODO: config
+
+ private long timeOut = 0;
+ private final ServerUser serverUser;
+
+ public ServerSession(final ServerUser serverUser)
+ {
+ this.serverUser = serverUser;
+ this.timeOut = System.currentTimeMillis() + TIMEOUT;
+ }
+
+ public synchronized void refresh()
+ {
+ if ( timedOut() )
+ return; // Don't allow refreshing timed out session
+ this.timeOut = System.currentTimeMillis() + TIMEOUT;
+ }
+
+ public synchronized boolean timedOut()
+ {
+ return System.currentTimeMillis() > this.timeOut;
+ }
+
+ public String getOrganization() {
+ return serverUser.organization;
+ }
+
+ public String getAddress() {
+ return serverUser.address;
+ }
+}
diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerSessionManager.java b/src/main/java/org/openslx/imagemaster/serversession/ServerSessionManager.java
new file mode 100644
index 0000000..1fd4322
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerSessionManager.java
@@ -0,0 +1,69 @@
+package org.openslx.imagemaster.serversession;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.openslx.imagemaster.session.SessionManager;
+import org.openslx.imagemaster.thrift.iface.ServerSessionData;
+import org.openslx.imagemaster.util.Hash;
+
+public class ServerSessionManager {
+
+ private static Logger log = Logger.getLogger( SessionManager.class );
+
+ // Map of currently known sessions
+ private static final Map<String, ServerSession> serverSessions = new LinkedHashMap<String, ServerSession>();
+ private static final Thread gcThread;
+
+ public static ServerSessionData addSession( ServerSession serverSession )
+ {
+ final String sessionId = Hash.sha256( UUID.randomUUID().toString() );
+
+ synchronized ( serverSessions ) {
+ serverSessions.put( sessionId, serverSession );
+ }
+ return new ServerSessionData( sessionId );
+ }
+
+ public static ServerSession getSession( String sessionId )
+ {
+ final ServerSession serverSession;
+ synchronized ( serverSessions ) {
+ serverSession = serverSessions.get( sessionId );
+ }
+ if ( serverSession == null || serverSession.timedOut() ) {
+ return null;
+ }
+ return serverSession;
+ }
+
+ static {
+ gcThread = new Thread( new Runnable() {
+ @Override
+ public void run()
+ {
+ for ( ;; ) {
+ try {
+ Thread.sleep( 1800L * 1000L );
+ } catch ( InterruptedException e ) {
+ }
+ synchronized ( serverSessions ) {
+ Iterator<ServerSession> it = serverSessions.values().iterator();
+ while ( it.hasNext() ) {
+ final ServerSession s = it.next();
+ if ( s.timedOut() ) {
+ log.debug( "Removing old session of " + s.getOrganization() );
+ it.remove();
+ }
+ }
+ }
+ }
+ }
+ } );
+ gcThread.start();
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerUser.java b/src/main/java/org/openslx/imagemaster/serversession/ServerUser.java
new file mode 100644
index 0000000..48815a8
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerUser.java
@@ -0,0 +1,11 @@
+package org.openslx.imagemaster.serversession;
+
+public class ServerUser {
+ public final String organization, address;
+
+ public ServerUser(String organization, String address) {
+ this.organization = organization;
+ this.address = address;
+ }
+
+}
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
index dc1b8f1..858f682 100644
--- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
@@ -42,23 +42,21 @@ public class ImageServerHandler implements ImageServer.Iface
@Override
public String startServerAuthentication(String organization)
throws TException {
- // TODO Auto-generated method stub
- return null;
+ return ApiServer.startServerAuthentication(organization);
}
@Override
public ServerSessionData serverAuthenticate(String organization,
String challengeResponse) throws AuthenticationException,
TException {
- // TODO Auto-generated method stub
- return null;
+ return ApiServer.serverAuthenticate(organization, challengeResponse);
}
@Override
- public FtpCredentials submitImage(ImageData imageDescription)
- throws AuthorizationException, TException {
- // TODO Auto-generated method stub
- return null;
+ public FtpCredentials submitImage(ImageData imageDescription,
+ ServerSessionData serverSessionData) throws AuthorizationException,
+ TException {
+ return ApiServer.submitImage(imageDescription, serverSessionData);
}
}
diff --git a/src/main/java/org/openslx/imagemaster/util/RandomString.java b/src/main/java/org/openslx/imagemaster/util/RandomString.java
new file mode 100644
index 0000000..a0e9419
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/util/RandomString.java
@@ -0,0 +1,30 @@
+package org.openslx.imagemaster.util;
+
+import java.security.SecureRandom;
+
+/**
+ * Generate secure random strings
+ * @author nils
+ *
+ */
+public class RandomString {
+ private static final String lettersSpecial="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-$%&/()=?@";
+ private static final String letters="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ private static final SecureRandom random = new SecureRandom();
+
+ /**
+ * Generate a random string.
+ * @param length the length of the string
+ * @param specialChars whether to use special charachters or not
+ * @return the generated string
+ */
+ public static String generate(int length, boolean specialChars) {
+ String used = (specialChars)? lettersSpecial : letters;
+ String result = "";
+ for (int i = 0; i < length; i++) {
+ int index = (int)(random.nextDouble()*used.length());
+ result += used.substring( index, index + 1 );
+ }
+ return result;
+ }
+}
diff --git a/src/main/thrift/imagemaster.thrift b/src/main/thrift/imagemaster.thrift
index 7f50dfc..8a4afcf 100644
--- a/src/main/thrift/imagemaster.thrift
+++ b/src/main/thrift/imagemaster.thrift
@@ -75,7 +75,7 @@ service ImageServer {
ServerSessionData serverAuthenticate(1:string organization, 2:string challengeResponse) throws (1:AuthenticationException failure),
- FtpCredentials submitImage(1:ImageData imageDescription) throws (1:AuthorizationException failure)
+ FtpCredentials submitImage(1:ImageData imageDescription, 2:ServerSessionData serverSessionData) throws (1:AuthorizationException failure)
}