diff options
author | Nils Schwabe | 2014-04-25 14:28:56 +0200 |
---|---|---|
committer | Nils Schwabe | 2014-04-25 14:28:56 +0200 |
commit | 40d528627efc309681496b47d66558e15eb3fe5e (patch) | |
tree | 4cb7ba77b4b55ecb0b29a734c782b68d6926d441 /src/main/java | |
parent | Add FTPS to MasterFtpServer (diff) | |
download | masterserver-40d528627efc309681496b47d66558e15eb3fe5e.tar.gz masterserver-40d528627efc309681496b47d66558e15eb3fe5e.tar.xz masterserver-40d528627efc309681496b47d66558e15eb3fe5e.zip |
Finally: Add _real_ server authentication. (this challengeresponse thing)
Diffstat (limited to 'src/main/java')
11 files changed, 151 insertions, 26 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java index 85ec50b..a73e1ef 100644 --- a/src/main/java/org/openslx/imagemaster/App.java +++ b/src/main/java/org/openslx/imagemaster/App.java @@ -6,8 +6,8 @@ import java.util.List; import org.apache.log4j.Logger; import org.openslx.imagemaster.Globals.PropInt; -import org.openslx.imagemaster.server.FtpCredentialsScheduler; -import org.openslx.imagemaster.server.MasterFtpServer; +import org.openslx.imagemaster.ftp.FtpCredentialsScheduler; +import org.openslx.imagemaster.ftp.MasterFtpServer; import org.openslx.imagemaster.thrift.server.BinaryListener; public class App diff --git a/src/main/java/org/openslx/imagemaster/Globals.java b/src/main/java/org/openslx/imagemaster/Globals.java index 717cb1e..166e629 100644 --- a/src/main/java/org/openslx/imagemaster/Globals.java +++ b/src/main/java/org/openslx/imagemaster/Globals.java @@ -7,7 +7,6 @@ import java.util.Properties; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; -import org.openslx.imagemaster.server.MasterFtpServer; public class Globals { @@ -23,7 +22,7 @@ public class Globals public static enum PropString { - IMAGEDIR, KEYSTORE, LDAPHOST, LDAPBINDQUERY, LDAPSEARCHBASEDN, LDAPSEARCHFILTER, FTPBASEDIR + IMAGEDIR, KEYSTOREFILE, KEYSTOREALIAS, KEYSTOREPASSWORD, LDAPHOST, LDAPBINDQUERY, LDAPSEARCHBASEDN, LDAPSEARCHFILTER, FTPBASEDIR } public static enum PropBool @@ -64,8 +63,12 @@ public class Globals || Globals.getPropertyString( PropString.LDAPSEARCHFILTER ).isEmpty() || Globals.getPropertyString( PropString.FTPBASEDIR ) == null || Globals.getPropertyString( PropString.FTPBASEDIR ).isEmpty() - || Globals.getPropertyString( PropString.KEYSTORE ) == null - || Globals.getPropertyString( PropString.KEYSTORE ).isEmpty() + || Globals.getPropertyString( PropString.KEYSTOREFILE ) == null + || Globals.getPropertyString( PropString.KEYSTOREFILE ).isEmpty() + || Globals.getPropertyString( PropString.KEYSTOREALIAS ) == null + || Globals.getPropertyString( PropString.KEYSTOREALIAS ).isEmpty() + || Globals.getPropertyString( PropString.KEYSTOREPASSWORD ) == null + || Globals.getPropertyString( PropString.KEYSTOREPASSWORD ).isEmpty() || Globals.getPropertyInt( PropInt.LDAPPORT ) == 0 || Globals.getPropertyInt( PropInt.SESSIONTIMEOUTUSER ) == 0 @@ -88,7 +91,7 @@ public class Globals } // check keystore - if ( !Globals.getPropertyString( PropString.KEYSTORE ).endsWith( ".jks" )) { + if ( !Globals.getPropertyString( PropString.KEYSTOREFILE ).endsWith( ".jks" )) { log.error( "Keystore is not in jks format." ); return false; } @@ -146,6 +149,15 @@ public class Globals case IMAGEDIR: result = properties.getProperty( "image_dir" ); break; + case KEYSTOREFILE: + result = properties.getProperty( "keystore_file" ); + break; + case KEYSTOREALIAS: + result = properties.getProperty( "keystore_alias" ); + break; + case KEYSTOREPASSWORD: + result = properties.getProperty( "keystore_password" ); + break; case LDAPHOST: result = properties.getProperty( "ldap_host" ); break; diff --git a/src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java b/src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java index ba88f33..b0b23aa 100644 --- a/src/main/java/org/openslx/imagemaster/server/FtpCredentialsScheduler.java +++ b/src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java @@ -1,4 +1,4 @@ -package org.openslx.imagemaster.server; +package org.openslx.imagemaster.ftp; import java.io.File; import java.util.Date; diff --git a/src/main/java/org/openslx/imagemaster/db/ImageProcessor.java b/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java index d0ac5c6..4c09907 100644 --- a/src/main/java/org/openslx/imagemaster/db/ImageProcessor.java +++ b/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java @@ -1,10 +1,11 @@ -package org.openslx.imagemaster.db; +package org.openslx.imagemaster.ftp; import java.io.File; import java.util.HashMap; import org.apache.log4j.Logger; import org.openslx.imagemaster.Globals; +import org.openslx.imagemaster.db.DbImage; import org.openslx.imagemaster.thrift.iface.ImageData; public class ImageProcessor diff --git a/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java index de0d758..992c49a 100644 --- a/src/main/java/org/openslx/imagemaster/server/MasterFtpServer.java +++ b/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java @@ -1,4 +1,4 @@ -package org.openslx.imagemaster.server; +package org.openslx.imagemaster.ftp; import java.io.File; import java.util.ArrayList; @@ -20,6 +20,7 @@ import org.apache.ftpserver.usermanager.impl.BaseUser; import org.apache.ftpserver.usermanager.impl.WritePermission; import org.apache.log4j.Logger; import org.openslx.imagemaster.Globals; +import org.openslx.imagemaster.Globals.PropString; import org.openslx.imagemaster.thrift.iface.FtpCredentials; import org.openslx.imagemaster.util.RandomString; @@ -44,9 +45,9 @@ public class MasterFtpServer implements Runnable // config ssl SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory(); - sslConfigFactory.setKeystoreFile( new File( "./keyfiles/ftp.jks" ) ); - sslConfigFactory.setKeyAlias( "ftp" ); - sslConfigFactory.setKeystorePassword( "password" ); + sslConfigFactory.setKeystoreFile( new File( Globals.getPropertyString( PropString.KEYSTOREFILE ) ) ); + sslConfigFactory.setKeyAlias( Globals.getPropertyString( PropString.KEYSTOREALIAS ) ); + sslConfigFactory.setKeystorePassword( Globals.getPropertyString( PropString.KEYSTOREPASSWORD ) ); // set the port of the listener factory.setPort( port ); diff --git a/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java index a8c1cbe..3c73dba 100644 --- a/src/main/java/org/openslx/imagemaster/server/MasterFtplet.java +++ b/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java @@ -1,4 +1,4 @@ -package org.openslx.imagemaster.server; +package org.openslx.imagemaster.ftp; import java.io.IOException; diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java index c88bd05..7479fd3 100644 --- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java +++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java @@ -1,13 +1,14 @@ package org.openslx.imagemaster.server; import java.io.File; +import java.nio.ByteBuffer; 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; +import org.openslx.imagemaster.ftp.ImageProcessor; import org.openslx.imagemaster.serversession.ServerAuthenticator; import org.openslx.imagemaster.serversession.ServerSession; import org.openslx.imagemaster.serversession.ServerSessionManager; @@ -146,7 +147,7 @@ public class ApiServer * @throws TException */ public static ServerSessionData serverAuthenticate( String organization, - String challengeResponse ) throws AuthenticationException, + ByteBuffer challengeResponse ) throws AuthenticationException, TException { if ( organization == null || challengeResponse == null ) { diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java b/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java index 726b062..24e2928 100644 --- a/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java +++ b/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java @@ -1,10 +1,14 @@ package org.openslx.imagemaster.serversession; +import java.nio.ByteBuffer; import java.util.HashMap; import org.apache.log4j.Logger; import org.apache.thrift.TException; +import org.openslx.imagemaster.Globals; +import org.openslx.imagemaster.Globals.PropString; import org.openslx.imagemaster.thrift.iface.AuthenticationException; +import org.openslx.imagemaster.util.AsymMessageSign; import org.openslx.imagemaster.util.RandomString; public class ServerAuthenticator @@ -12,6 +16,22 @@ public class ServerAuthenticator private static Logger log = Logger.getLogger( ServerAuthenticator.class ); // map of currently authenticating servers private static HashMap<String, String> authenticatingServers = new HashMap<String, String>(); + private static AsymMessageSign messageSign = null; + + /** + * Initialize the message signer/verifier + */ + static { + try { + messageSign = new AsymMessageSign( Globals.getPropertyString( PropString.KEYSTOREALIAS ), + Globals.getPropertyString( PropString.KEYSTOREPASSWORD ), + Globals.getPropertyString( PropString.KEYSTOREFILE ) ); + log.info( "Loaded keystore" ); + } catch ( Exception e ) { + log.error( "Error loading the keystore", e ); + System.exit(1); + } + } /** * Start the server authentification. @@ -43,20 +63,26 @@ public class ServerAuthenticator * @throws TException */ public static ServerUser serverAuthenticate( String organization, - String address, String challengeResponse ) + String address, ByteBuffer challengeResponse ) throws AuthenticationException, TException { - /* - * TODO: Decrypt the given challengeResponse and check whether it was - * right or not. Authenticate server if so. - */ - if ( !challengeResponse.equals( authenticatingServers.get( organization ) ) ) { + byte[] bytes = challengeResponse.array(); + log.info( "Response was: " + challengeResponse + " with length: " + bytes.length); + + boolean result = false; + + try { + result = messageSign.verifyMessage( bytes, authenticatingServers.get( organization ).getBytes() ); + } catch (Exception e) { + log.error( "Error while verifying message", e ); + } + + if ( !result ) { throw new AuthenticationException(); } log.info( "Server of organinzation '" + organization - + " authenticated. With response: '" + challengeResponse - + "'" ); + + " authenticated."); authenticatingServers.remove( organization ); 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 16496a2..5cc82fc 100644 --- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java +++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java @@ -1,5 +1,7 @@ package org.openslx.imagemaster.thrift.server; +import java.nio.ByteBuffer; + import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.openslx.imagemaster.server.ApiServer; @@ -9,6 +11,7 @@ import org.openslx.imagemaster.thrift.iface.FtpCredentials; import org.openslx.imagemaster.thrift.iface.ImageData; import org.openslx.imagemaster.thrift.iface.ImageServer; import org.openslx.imagemaster.thrift.iface.InvalidTokenException; +import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException; import org.openslx.imagemaster.thrift.iface.ServerSessionData; import org.openslx.imagemaster.thrift.iface.SessionData; import org.openslx.imagemaster.thrift.iface.UserInfo; @@ -48,7 +51,7 @@ public class ImageServerHandler implements ImageServer.Iface @Override public ServerSessionData serverAuthenticate( String organization, - String challengeResponse ) throws AuthenticationException, + ByteBuffer challengeResponse ) throws AuthenticationException, TException { return ApiServer.serverAuthenticate( organization, challengeResponse ); diff --git a/src/main/java/org/openslx/imagemaster/util/AsymMessageSign.java b/src/main/java/org/openslx/imagemaster/util/AsymMessageSign.java new file mode 100644 index 0000000..134b399 --- /dev/null +++ b/src/main/java/org/openslx/imagemaster/util/AsymMessageSign.java @@ -0,0 +1,63 @@ +package org.openslx.imagemaster.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; + +public class AsymMessageSign +{ + + KeyPair pair; + +// String alias = "ftp"; +// String password = "password"; +// String file = "./config/keystore.jks"; + + + public AsymMessageSign(String alias, String password, String file) throws NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, KeyStoreException, UnrecoverableKeyException + { + KeyStore keystore = KeyStore.getInstance( "JKS" ); + keystore.load( new FileInputStream( new File( file ) ), password.toCharArray() ); + Certificate cert = null; + + Key key = keystore.getKey( alias, + password.toCharArray() ); + + if ( key instanceof PrivateKey ) { + cert = keystore.getCertificate( alias ); + PublicKey publicKey = cert.getPublicKey(); + pair = new KeyPair( publicKey, (PrivateKey)key ); + } + } + + public byte[] signMessage( String message ) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException + { + Signature signature = Signature.getInstance( "SHA256WITHRSA" ); + signature.initSign( pair.getPrivate() ); + signature.update( message.getBytes() ); + return signature.sign(); + } + + public boolean verifyMessage( byte[] signedMessage, byte[] realMessage ) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException + { + Signature signature = Signature.getInstance( "SHA256WITHRSA" ); + signature.initVerify( pair.getPublic() ); + signature.update( realMessage ); + return signature.verify( signedMessage ); + } + +} diff --git a/src/main/java/org/openslx/imagemaster/util/Util.java b/src/main/java/org/openslx/imagemaster/util/Util.java index 0df4212..9805c21 100644 --- a/src/main/java/org/openslx/imagemaster/util/Util.java +++ b/src/main/java/org/openslx/imagemaster/util/Util.java @@ -1,9 +1,27 @@ package org.openslx.imagemaster.util; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; import java.util.Random; import org.apache.log4j.Logger; +import org.openslx.imagemaster.Globals; +import org.openslx.imagemaster.Globals.PropString; public class Util { @@ -70,5 +88,5 @@ public class Util } folder.delete(); } - + } |