package org.openslx.satellitedaemon.filetransfer; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.security.InvalidKeyException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.List; import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.openslx.imagemaster.crcchecker.CrcFile; import org.openslx.imagemaster.thrift.iface.AuthorizationError; 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.ImageDataError; import org.openslx.imagemaster.thrift.iface.ImageDataException; import org.openslx.imagemaster.thrift.iface.ImageServer; import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException; import org.openslx.imagemaster.thrift.iface.ServerSessionData; import org.openslx.imagemaster.thrift.iface.UploadError; import org.openslx.imagemaster.thrift.iface.UploadException; import org.openslx.imagemaster.thrift.iface.UploadData; import org.openslx.satellitedaemon.Globals; import org.openslx.satellitedaemon.db.DbImage; import org.openslx.satellitedaemon.db.DbImage.Status; import org.openslx.satellitedaemon.util.EncryptWithServerIdPublicKey; // TODO: Handle all the auto-generated catch blocks in a meaningful way /***********************************************************************************************/ /** * Handles the authentication with the Satellite Server and sends the * FILTRANSFERCredentials, which are necessary for the upload of the image. */ public class ThriftConnection { private static ImageServer.Client client = null; private static ServerSessionData sSD = null; private static Logger log = Logger.getLogger(ThriftConnection.class); private static CrcFile crc = null; /***********************************************************************************************/ /** * Method for getting UploadeInfos * * when the CRCsum need to be transfered. The method calls getConnection() * to check if the connection is ok and to get the ServerSessionData. If * connection is ok, it calls submitImage with CRCsum in List. * * @return returns 'null' if there is a problem. */ public static UploadData getUploadInfos(ImageData imDat, String filename) { ImageServer.Client theClient = null; try { theClient = getConnection(); if (theClient == null) { log.error("Client was null!"); return null; } crc = new CrcFile(filename); log.info("Made CRCFile from " + filename); log.info("crc.getCrcSums( ).size = " + crc.getCrcSums().size()); // log.info( "crc.getMasterSum() : " + crc.getMasterSum() ); // for ( int i = 0; i < crc.getCrcSums().size() - 1; i++ ) { // log.info( "crc.getCRCSum() : " + crc.getCRCSum( i ) ); // } return theClient .submitImage(sSD.sessionId, imDat, crc.getCrcSums()); } catch (ImageDataException e) { if (e.isSetNumber() && e.getNumber().equals(ImageDataError.INVALID_DATA)) { e.printStackTrace(); // Data in the db is not valid // TODO: add e.message into DB; } else { e.printStackTrace(); } } catch (UploadException e) { if (e.isSetNumber() && e.getNumber().equals(UploadError.BROKEN_BLOCK)) { // A Block was transmitted 20 times unsuccessfully. // TODO: Mark the Image as corrupted. } else if (e.getNumber().equals(UploadError.INVALID_CRC)) { // The CRC sum contained errors try { crc = new CrcFile(filename); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if (!crc.isValid()) { // TODO: Mark CRC-file as corrupted. } } else { e.printStackTrace(); } } catch (AuthorizationException e) { if (e.isSetNumber() && e.getNumber().equals( AuthorizationError.NOT_AUTHENTICATED)) { // SessionID is not valid // TODO: Code for new SSID } else if (e.getNumber().equals(AuthorizationError.NO_PERMISSION)) { // not yet implemented. } else { e.printStackTrace(); } } catch (UnrecoverableKeyException e) { log.error("UnrecoverableKeyException"); e.printStackTrace(); } catch (InvalidKeyException e) { log.error("InvalidKeyException"); e.printStackTrace(); } catch (NoSuchAlgorithmException e) { log.error("NoSuchAlgorithmException"); e.printStackTrace(); } catch (CertificateException e) { log.error("CertificateException"); e.printStackTrace(); } catch (FileNotFoundException e) { log.error("FileNotFoundException"); e.printStackTrace(); } catch (KeyStoreException e) { log.error("KeyStoreException"); e.printStackTrace(); } catch (SignatureException e) { log.error("SignatureException"); e.printStackTrace(); } catch (IOException e) { log.error("IOException"); e.printStackTrace(); } catch (TException e) { log.error("TException"); e.printStackTrace(); } return null; } /***********************************************************************************************/ /** * Method for getting DonwloadInfos. Calls getConnection if client was null. * You need to spezifie all Blocks you want to have in an List. * * @return returns 'null' if there is a problem. */ public static DownloadData getDownloadInfos(DbImage imDat) { ImageServer.Client theClient = null; try { theClient = getConnection(); if (theClient == null) { log.error("Client was null!"); return null; } return theClient.getImage(imDat.guid, sSD.sessionId); } catch (ImageDataException e) { if (e.isSetNumber() && e.getNumber().equals(ImageDataError.INVALID_DATA)) { // Data in the db is not valid // TODO: add e.message into DB; } else if (e.getNumber().equals(ImageDataError.UNKNOWN_IMAGE)) { // The image requested is not known. // TODO: change field image_syncMode, so the image is not asked // for again. // For now just changed status of image. Currently no possibility // for creating new useful state in DB. (Offenburg) log.info("Image not known. For skipping next time, mark as only_local."); imDat.updateStatus(Status.only_local); // Plus add a note in some way to mark as unknown by Server } else { e.printStackTrace(); } } catch (AuthorizationException e) { if (e.isSetNumber() && e.getNumber().equals( AuthorizationError.NOT_AUTHENTICATED)) { // SessionID is not valid // TODO: Code for new SSID } else if (e.getNumber().equals(AuthorizationError.NO_PERMISSION)) { } else { e.printStackTrace(); } } catch (UnrecoverableKeyException e) { log.error("UnrecoverableKeyException"); e.printStackTrace(); } catch (InvalidKeyException e) { log.error("InvalidKeyException"); e.printStackTrace(); } catch (NoSuchAlgorithmException e) { log.error("NoSuchAlgorithmException"); e.printStackTrace(); } catch (CertificateException e) { log.error("CertificateException"); e.printStackTrace(); } catch (FileNotFoundException e) { log.error("FileNotFoundException"); e.printStackTrace(); } catch (KeyStoreException e) { log.error("KeyStoreException"); e.printStackTrace(); } catch (SignatureException e) { log.error("SignatureException"); e.printStackTrace(); } catch (IOException e) { log.error("IOException"); e.printStackTrace(); } catch (TException e) { log.error("TException"); e.printStackTrace(); } return null; } /***********************************************************************************************/ /** * This method checks if there is already a working connection. If not, * newClient() establishes one. Also it does the Authentication if not done * yet. * * @return returns the client if successful. */ private static ImageServer.Client getConnection() throws UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, KeyStoreException, IOException, InvalidKeyException, SignatureException { ImageServer.Client theClient = null; boolean isAuthenticated = false; if (client == null) { log.info("The global client was null. Making a new client ..."); theClient = newClient(); if (theClient == null) { log.debug("ThriftConnection: The client was null after newClient()"); return null; } } else { log.info("The global Client was already used. Setting isAuthenticated = true."); theClient = client; isAuthenticated = true; } // here the client was already used so we are just assuming that the client is still // authenticated. Should be checked with the ping() method. // try { // isAuthenticated = theClient.ping(); // } catch ( TException x ) { // theClient = newClient(); // if ( theClient == null ) { // return null; // } // } if (!isAuthenticated) { log.info("ThriftConnection: Client not yet Authenticated. Trying..."); String toEncrypt; if (theClient == null) { log.debug("The client was null"); return null; } try { toEncrypt = theClient.startServerAuthentication(Globals .getOrganizationName()); log.info("The random String we want to encrypt: " + toEncrypt); log.info("Length of the random String : " + toEncrypt.length()); EncryptWithServerIdPublicKey rse = new EncryptWithServerIdPublicKey( Globals.getThriftKeystoreAlias(), Globals.getThriftKeystorePassword(), Globals.getThriftKeystorePath()); byte[] byteArray = rse.encryptString(toEncrypt); log.info( "Length of the byteArray of the random string after encryption :" + byteArray.length ); ByteBuffer b = ByteBuffer.wrap( byteArray ); log.info( "Length of the byteBuffer after encryption :" + b.remaining() ); sSD = theClient.serverAuthenticate( Globals.getOrganizationName(), ByteBuffer.wrap(byteArray)); } catch (ServerAuthenticationException e) { log.error("ThriftConnection: ServerAuthenticationException: Server Authetication was not sucessful."); e.printStackTrace(); return null; } catch (TException e) { log.error("ThriftConnection: TException: Server Authetication was not sucessful."); e.printStackTrace(); return null; } log.info("is Authenticated."); } client = theClient; return theClient; } /***********************************************************************************************/ /** * Method for creating a new Client for Thrift communication. * * @throws IOException */ private static ImageServer.Client newClient() throws IOException { ImageServer.Client newClient = null; try { TTransport transport = new TFramedTransport( new TSocket( Globals.getMasterserverHost(), Globals.getThriftPort())); transport.open(); TProtocol protocol = new TBinaryProtocol(transport); newClient = new ImageServer.Client(protocol); log.debug("ThriftConnection: Made a new Client"); } catch (TTransportException tte) { log.error("Transport could not be opened. Couldn't create new client."); tte.printStackTrace(); return null; } return newClient; } }