summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/thrift/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/imagemaster/thrift/server')
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java10
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java121
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/MasterServerHandler.java305
3 files changed, 311 insertions, 125 deletions
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java b/src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java
index d7a3c12..d18e8a8 100644
--- a/src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/BinaryListener.java
@@ -18,14 +18,16 @@ import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;
+import org.openslx.bwlp.thrift.iface.MasterServer;
import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.thrift.iface.ImageServer;
+import org.openslx.thrifthelper.TBinaryProtocolSafe;
public class BinaryListener implements Runnable
{
private static final int MAX_MSG_LEN = 30 * 1000 * 1000;
- private final ImageServer.Processor<ImageServerHandler> processor = new ImageServer.Processor<ImageServerHandler>( new ImageServerHandler() );
+ private final MasterServer.Processor<MasterServerHandler> processor = new MasterServer.Processor<MasterServerHandler>(
+ new MasterServerHandler() );
final TProtocolFactory protFactory = new TBinaryProtocolSafe.Factory( true, true );
private static Logger log = Logger.getLogger( BinaryListener.class );
@@ -49,7 +51,7 @@ public class BinaryListener implements Runnable
}
/**
- * Listen with TLS wrapping - has to use the threadpool server, since encrypted
+ * Listen with TLS wrapping - has to use the thread pool server, since encrypted
* servers cannot use nonblocking sockets :(
*
* @param port listen port
@@ -76,7 +78,7 @@ public class BinaryListener implements Runnable
args.protocolFactory( protFactory );
args.processor( processor );
args.minWorkerThreads( 4 ).maxWorkerThreads( 256 );
- args.requestTimeout( 30 ).requestTimeoutUnit( TimeUnit.SECONDS );
+ args.requestTimeout( 2 ).requestTimeoutUnit( TimeUnit.MINUTES );
args.transportFactory( new TFramedTransport.Factory( MAX_MSG_LEN ) );
return new TThreadPoolServer( args );
}
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
deleted file mode 100644
index f2f88d0..0000000
--- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.openslx.imagemaster.thrift.server;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import org.apache.thrift.TException;
-import org.openslx.imagemaster.server.ApiServer;
-import org.openslx.imagemaster.thrift.iface.AuthenticationException;
-import org.openslx.imagemaster.thrift.iface.AuthorizationException;
-import org.openslx.imagemaster.thrift.iface.DownloadData;
-import org.openslx.imagemaster.thrift.iface.ImageData;
-import org.openslx.imagemaster.thrift.iface.ImageDataException;
-import org.openslx.imagemaster.thrift.iface.ImageServer;
-import org.openslx.imagemaster.thrift.iface.InvalidTokenException;
-import org.openslx.imagemaster.thrift.iface.OrganizationData;
-import org.openslx.imagemaster.thrift.iface.ServerSessionData;
-import org.openslx.imagemaster.thrift.iface.SessionData;
-import org.openslx.imagemaster.thrift.iface.UploadData;
-import org.openslx.imagemaster.thrift.iface.UploadException;
-import org.openslx.imagemaster.thrift.iface.UserInfo;
-
-public class ImageServerHandler implements ImageServer.Iface
-{
-
- @Override
- public boolean ping()
- {
- return true;
- }
-
- @Override
- public SessionData authenticate( String username, String password )
- throws AuthenticationException
- {
- return ApiServer.authenticate( username, password );
- }
-
- @Override
- public UserInfo getUserFromToken( String token )
- throws InvalidTokenException
- {
- return ApiServer.getUserFromToken( token );
- }
-
- @Override
- public ByteBuffer startServerAuthentication( String organization )
- throws AuthenticationException
- {
- return ApiServer.startServerAuthentication( organization );
- }
-
- @Override
- public ServerSessionData serverAuthenticate( String organization,
- ByteBuffer challengeResponse ) throws AuthenticationException
- {
- return ApiServer.serverAuthenticate( organization, challengeResponse );
- }
-
- @Override
- public UploadData submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums )
- throws AuthorizationException, ImageDataException, UploadException
- {
- return ApiServer.submitImage( serverSessionId, imageDescription, crcSums );
- }
-
- @Override
- public DownloadData getImage( String serverSessionId, String uuid ) throws AuthorizationException, ImageDataException
- {
- return ApiServer.getImage( uuid, serverSessionId );
- }
-
- @Override
- public boolean isServerAuthenticated( String serverSessionId )
- {
- return ApiServer.isServerAuthenticated( serverSessionId );
- }
-
- @Override
- public List<OrganizationData> getOrganizations()
- {
- return ApiServer.getOrganizations();
- }
-
- @Override
- public List<UserInfo> findUser( String sessionId, String organizationId, String searchTerm ) throws AuthorizationException
- {
- return ApiServer.findUser( sessionId, organizationId, searchTerm );
- }
-
- @Override
- public boolean publishUser( String serverSessionId, UserInfo user )
- throws AuthorizationException
- {
- return ApiServer.publishUser( serverSessionId, user );
- }
-
- @Override
- public List<ImageData> getPublicImages( String sessionId, int page ) throws AuthorizationException
- {
- return ApiServer.getPublicImages( sessionId, page );
- }
-
- @Override
- public boolean registerSatellite( String organizationId, String address, String modulus, String exponent )
- {
- return ApiServer.registerSatellite( organizationId, address, modulus, exponent );
- }
-
- @Override
- public boolean updateSatelliteAddress( String serverSessionId, String address ) throws TException
- {
- return ApiServer.updateSatelliteAddress( serverSessionId, address );
- }
-
- @Override
- public ServerSessionData addSession( String localPassword, UserInfo userInfo ) throws TException
- {
- // TODO Should be called from local web authenticator doing the ECP stuff
- return null;
- }
-}
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/MasterServerHandler.java b/src/main/java/org/openslx/imagemaster/thrift/server/MasterServerHandler.java
new file mode 100644
index 0000000..ec13a6f
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/MasterServerHandler.java
@@ -0,0 +1,305 @@
+package org.openslx.imagemaster.thrift.server;
+
+import java.nio.ByteBuffer;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.thrift.iface.AuthorizationError;
+import org.openslx.bwlp.thrift.iface.ClientSessionData;
+import org.openslx.bwlp.thrift.iface.ImagePublishData;
+import org.openslx.bwlp.thrift.iface.InvocationError;
+import org.openslx.bwlp.thrift.iface.MasterServer;
+import org.openslx.bwlp.thrift.iface.MasterSoftware;
+import org.openslx.bwlp.thrift.iface.MasterTag;
+import org.openslx.bwlp.thrift.iface.OperatingSystem;
+import org.openslx.bwlp.thrift.iface.Organization;
+import org.openslx.bwlp.thrift.iface.Satellite;
+import org.openslx.bwlp.thrift.iface.ServerSessionData;
+import org.openslx.bwlp.thrift.iface.SessionData;
+import org.openslx.bwlp.thrift.iface.TAuthorizationException;
+import org.openslx.bwlp.thrift.iface.TInvalidTokenException;
+import org.openslx.bwlp.thrift.iface.TInvocationException;
+import org.openslx.bwlp.thrift.iface.TNotFoundException;
+import org.openslx.bwlp.thrift.iface.TTransferRejectedException;
+import org.openslx.bwlp.thrift.iface.TransferInformation;
+import org.openslx.bwlp.thrift.iface.UserInfo;
+import org.openslx.bwlp.thrift.iface.Virtualizer;
+import org.openslx.encryption.AsymKeyHolder;
+import org.openslx.imagemaster.db.mappers.DbOrganization;
+import org.openslx.imagemaster.db.mappers.DbOsVirt;
+import org.openslx.imagemaster.db.mappers.DbPendingSatellite;
+import org.openslx.imagemaster.db.mappers.DbSatellite;
+import org.openslx.imagemaster.db.mappers.DbUser;
+import org.openslx.imagemaster.db.models.LocalSatellite;
+import org.openslx.imagemaster.serversession.ServerAuthenticator;
+import org.openslx.imagemaster.serversession.ServerSession;
+import org.openslx.imagemaster.serversession.ServerSessionManager;
+import org.openslx.imagemaster.session.Authenticator;
+import org.openslx.imagemaster.session.Session;
+import org.openslx.imagemaster.session.SessionManager;
+import org.openslx.imagemaster.util.Util;
+
+public class MasterServerHandler implements MasterServer.Iface
+{
+
+ private static final Logger LOGGER = Logger.getLogger( MasterServerHandler.class );
+
+ @Override
+ public boolean ping()
+ {
+ return true;
+ }
+
+ @Override
+ public SessionData authenticate( String login, String password ) throws TAuthorizationException, TInvocationException
+ {
+ ClientSessionData csd = localAccountLogin( login, password );
+ String serverAddress = null;
+ if ( csd.satellites != null && !csd.satellites.isEmpty() ) {
+ for ( Satellite sat : csd.satellites ) {
+ if ( sat.addressList == null || sat.addressList.isEmpty() )
+ continue;
+ if ( serverAddress == null || ( sat.displayName != null && sat.displayName.equals( "default" ) ) ) {
+ serverAddress = sat.addressList.get( 0 );
+ }
+ }
+ }
+ return new SessionData( csd.sessionId, csd.authToken, serverAddress );
+ }
+
+ /**
+ * Request for authentication
+ *
+ * @param login The user's login in the form "user@organization.com"
+ * @param password user's password
+ * @return SessionData struct with session id/token iff login successful
+ * @throws TAuthorizationException if login not successful
+ */
+ @Override
+ public ClientSessionData localAccountLogin( String login, String password )
+ throws TAuthorizationException, TInvocationException
+ {
+ if ( login == null || password == null ) {
+ throw new TAuthorizationException(
+ AuthorizationError.INVALID_CREDENTIALS,
+ "Empty username or password!" );
+ }
+ final UserInfo user = Authenticator.authenticate( login, password );
+
+ final Session session = new Session( user );
+ return SessionManager.addSession( session );
+ }
+
+ @Override
+ public List<UserInfo> findUser( String sessionId, String organizationId, String searchTerm )
+ throws TAuthorizationException, TInvocationException
+ {
+ // Needs to be a logged in user
+ if ( SessionManager.getSessionFromSessionId( sessionId ) == null )
+ throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "Session ID not valid" );
+ // Search string needs to be at least 2 characters (FIXME: quick and dirty ignoring LIKE chars)
+ if ( searchTerm == null || searchTerm.length() < 2 || searchTerm.replaceAll( "[%_]", "" ).length() < 2 )
+ return new ArrayList<>( 0 );
+ return DbUser.findUser( organizationId, searchTerm );
+ }
+
+ @Override
+ public List<ImagePublishData> getPublicImages( String sessionId, int page )
+ throws TAuthorizationException, TInvocationException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void invalidateSession( String sessionId ) throws TInvalidTokenException
+ {
+ SessionManager.invalidate( sessionId );
+ }
+
+ /**
+ * Request information about user for given token
+ *
+ * @param token a user's token
+ * @return UserInfo struct for given token's user
+ * @throws InvalidTokenException if no user matches the given token
+ */
+ @Override
+ public UserInfo getUserFromToken( String token ) throws TInvalidTokenException
+ {
+ final Session session = SessionManager.getSessionFromToken( token );
+ if ( session == null )
+ throw new TInvalidTokenException();
+ return new UserInfo( session.getLogin(), session.getFirstName(),
+ session.getLastName(), session.getEMail(), session.getOrgenizationId() );
+ }
+
+ @Override
+ public boolean isServerAuthenticated( String serverSessionId )
+ {
+ return ( ServerSessionManager.getSession( serverSessionId ) != null );
+ }
+
+ /**
+ * 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
+ * @throws ServerAuthenticationException when organization is invalid/unknown
+ */
+ @Override
+ public ByteBuffer startServerAuthentication( int satelliteId ) throws TAuthorizationException, TInvocationException
+ {
+ LocalSatellite satellite = DbSatellite.get( satelliteId );
+ if ( satellite == null )
+ throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION, "Unknown satellite id: " + satelliteId );
+ if ( satellite.getPubkey() == null )
+ throw new TAuthorizationException( AuthorizationError.INVALID_KEY, "There is no public key known for your satellite." );
+ return ServerAuthenticator.startServerAuthentication( satelliteId );
+ }
+
+ /**
+ * 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
+ */
+ @Override
+ public ServerSessionData serverAuthenticate( int satelliteId, ByteBuffer challengeResponse )
+ throws TAuthorizationException, TInvocationException
+ {
+ if ( challengeResponse == null )
+ throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION, "Empty organization or challengeResponse" );
+ LocalSatellite satellite = DbSatellite.get( satelliteId );
+ if ( satellite == null )
+ throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION, "Unknown satellite id: " + satelliteId );
+ if ( satellite.getPubkey() == null )
+ throw new TAuthorizationException( AuthorizationError.INVALID_KEY, "There is no public key known for your satellite." );
+
+ ServerAuthenticator.serverAuthenticate( satellite, challengeResponse );
+
+ final ServerSession session = new ServerSession( satellite );
+ return ServerSessionManager.addSession( session );
+ }
+
+ @Override
+ public ImagePublishData getImageData( String serverSessionId, String imageVersionId )
+ throws TAuthorizationException, TInvocationException, TNotFoundException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public TransferInformation submitImage( String serverSessionId, ImagePublishData imageDescription, List<ByteBuffer> blockHashes )
+ throws TAuthorizationException, TInvocationException, TTransferRejectedException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public TransferInformation downloadImage( String sessionId, String imageVersionId )
+ throws TAuthorizationException, TInvocationException, TNotFoundException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<Organization> getOrganizations() throws TInvocationException
+ {
+ try {
+ return DbOrganization.getAll();
+ } catch ( SQLException e ) {
+ throw new TInvocationException();
+ }
+ }
+
+ @Override
+ public List<OperatingSystem> getOperatingSystems() throws TInvocationException
+ {
+ try {
+ return DbOsVirt.getOsList();
+ } catch ( SQLException e ) {
+ throw new TInvocationException();
+ }
+ }
+
+ @Override
+ public List<Virtualizer> getVirtualizers() throws TInvocationException
+ {
+ try {
+ return DbOsVirt.getVirtualizerList();
+ } catch ( SQLException e ) {
+ throw new TInvocationException();
+ }
+ }
+
+ @Override
+ public List<MasterTag> getTags( long startDate ) throws TInvocationException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<MasterSoftware> getSoftware( long startDate ) throws TInvocationException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int registerSatellite( String userToken, String displayName, List<String> addresses, String modulus,
+ String exponent, ByteBuffer certSha256 ) throws TInvocationException
+ {
+ if ( userToken == null || exponent == null || modulus == null )
+ throw new TInvocationException( InvocationError.MISSING_DATA, "A required parameter is null" );
+ final Session session = SessionManager.getSessionFromToken( userToken );
+ if ( session == null || session.getUserInfo() == null )
+ throw new TInvocationException( InvocationError.UNKNOWN_USER, "Not a valid user token" );
+ String organizationId = session.getUserInfo().organizationId;
+ Key newKey;
+ try {
+ newKey = new AsymKeyHolder( null, Util.tryToParseBigInt( exponent ), Util.tryToParseBigInt( modulus ) ).getPublicKey();
+ } catch ( NoSuchAlgorithmException | InvalidKeySpecException e ) {
+ LOGGER.warn( "Invalid public key in registerOrganization for " + organizationId + " (By " + session.getLogin() + ")", e );
+ throw new TInvocationException( InvocationError.INVALID_DATA, "Cannot reconstruct public key" );
+ }
+ if ( newKey == null ) {
+ LOGGER.warn( "Uninstantiable public key in registerOrganization for " + organizationId + " (By " + session.getLogin() + ")" );
+ throw new TInvocationException( InvocationError.INVALID_DATA, "Cannot reconstruct public key" );
+ }
+ LocalSatellite existing = DbSatellite.get( organizationId, displayName );
+ if ( existing != null ) {
+ Key existingKey = existing.getPubkey();
+ if ( existingKey != null && Util.keysEqual( newKey, existingKey ) )
+ return existing.satelliteId;
+ }
+ try {
+ return DbPendingSatellite.add( session.getUserInfo(), displayName, addresses, modulus, exponent );
+ } catch ( SQLException e ) {
+ throw new TInvocationException();
+ }
+ }
+
+ @Override
+ public boolean updateSatellite( String serverSessionId, String displayName, List<String> addresses )
+ throws TAuthorizationException, TInvocationException
+ {
+ ServerSession session = ServerSessionManager.getSession( serverSessionId );
+ if ( session == null )
+ throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionId" );
+ // TODO
+ return false;
+ }
+
+}