blob: f89e028cb7f3e84b722243bdd3ff8226df38b7ef (
plain) (
tree)
|
|
package org.openslx.imagemaster.serverconnection;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.apache.log4j.Logger;
import org.openslx.filetransfer.Downloader;
import org.openslx.filetransfer.IncomingEvent;
import org.openslx.filetransfer.Listener;
import org.openslx.filetransfer.Uploader;
import org.openslx.imagemaster.Globals;
/**
* Class to handle all incoming and outgoing connections.
*/
public class ConnectionHandler implements IncomingEvent
{
private static Logger log = Logger.getLogger( ConnectionHandler.class );
private static SSLContext sslContext;
private static Map<String, Connection> connections = new ConcurrentHashMap<>();
private static IncomingEvent eventHandler = new ConnectionHandler();
private static Listener listener;
static {
log.debug( "Starting listener on port " + Globals.getSslSocketPort() );
try {
String pathToKeyStore = Globals.getSslKeystoreFile();
char[] passphrase = Globals.getSslKeystorePassword().toCharArray();
KeyStore keystore = KeyStore.getInstance( "JKS" );
keystore.load( new FileInputStream( pathToKeyStore ), passphrase );
KeyManagerFactory kmf = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
kmf.init( keystore, passphrase );
sslContext = SSLContext.getInstance( "SSLv3" );
KeyManager[] keyManagers = kmf.getKeyManagers();
sslContext.init( keyManagers, null, null );
listener = new Listener( eventHandler, sslContext, Globals.getSslSocketPort() );
listener.start();
} catch ( FileNotFoundException e ) {
log.error( "Could not find keystore." );
System.exit( 2 );
} catch ( KeyStoreException e ) {
log.error( "KeyStore implemenation not supported." );
System.exit( 2 );
} catch ( NoSuchAlgorithmException e ) {
log.error( "Could not find such Algorithm" );
System.exit( 2 );
} catch ( CertificateException e ) {
log.error( "Certificate unvalid." );
System.exit( 2 );
} catch ( IOException e ) {
log.error( "Could not read keyfile" );
System.exit( 2 );
} catch ( UnrecoverableKeyException e ) {
log.error( "Key in keystore is not valid" );
System.exit( 2 );
} catch ( KeyManagementException e ) {
log.error( "Context initialization failed." );
System.exit( 2 );
}
}
/**
* Add a new connection with a unique token.
* To up- or download the file in file path.
*
* @param token The unique token
* @param filepath The file to up- or download
* @param type True if upload or false if download
* @return The created connection
*/
public static Connection addConnection( String token, String filepath, boolean type )
{
log.debug( "Added connection (" + ( ( type ) ? "uploading" : "downloading" ) + ") with token: '" + token + "'" );
Connection connection = new Connection( filepath, type );
synchronized ( connections ) {
connections.put( token, connection );
}
return connection;
}
public static boolean hasConnection( String token )
{
return connections.containsKey( token );
}
public static void removeConnection( String token )
{
synchronized ( connections ) {
connections.remove( token ); // token is remove, so connections are rejected
}
}
/**
* Server is uploading - client is downloading!
*/
@Override
public void incomingUploader( Uploader uploader ) throws IOException
{
// try to read meta data
if ( !uploader.readMetaData() ) return;
String token = uploader.getToken();
log.debug( "Got token :'" + token + "'" );
// check token to identify the client
if ( !connections.containsKey( token ) ) {
uploader.sendErrorCode( "Token not accepted." );
uploader.close();
return;
}
// check if he was a downloading client
if ( connections.get( token ).type == Connection.UPLOADING ) {
uploader.sendErrorCode( "You can not download, if you are uploading." );
uploader.close();
return;
}
List<Integer> list = connections.get( token ).client.getLastRequestedBlocks( token );
// TODO: check which range needs to be sent and send this range
// logik von michael
long length = ( new File( connections.get( token ).filepath ) ).length();
uploader.sendRange( 0, (int)length );
uploader.sendFile( connections.get( token ).filepath );
uploader.close();
}
/**
* Server is downloading - client is uploading!
*/
@Override
public void incomingDownloader( Downloader downloader ) throws IOException
{
int startOfRange = 0;
int endOfRange = 0;
int diffOfRange = 0;
String token = "";
// try to read meta data
while ( downloader.readMetaData() ) {
// check token to identify the client
token = downloader.getToken();
if ( !connections.containsKey( token ) ) {
downloader.sendErrorCode( "Token not accepted." );
downloader.close();
return;
}
// get range
startOfRange = downloader.getStartOfRange();
endOfRange = downloader.getEndOfRange();
diffOfRange = downloader.getDiffOfRange();
// check if he was a uploading client
if ( connections.get( token ).type == Connection.DOWNLOADING ) {
downloader.sendErrorCode( "You can not upload, if you are downloading." );
downloader.close();
return;
}
downloader.setOutputFilename( connections.get( token ).filepath );
downloader.readBinary();
// calculate and register the incoming blocks
if ( diffOfRange == 0 )
return;
for ( int i = startOfRange / Globals.blockSize; i < endOfRange / Globals.blockSize; i += Globals.blockSize ) {
connections.get( token ).image.setNeedsCheck( i );
}
}
downloader.close();
}
}
|