summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-09-29 18:16:52 +0200
committerSimon Rettberg2014-09-29 18:16:52 +0200
commit9af765479c941d3664516ebcb8e203f4331264a9 (patch)
tree4a9e775d82542da320ef3b9d268316d99ad9ff61
parent[Db*] Fix SELECT for DbImage, change Timestamp to long, load public key from ... (diff)
downloadmasterserver-9af765479c941d3664516ebcb8e203f4331264a9.tar.gz
masterserver-9af765479c941d3664516ebcb8e203f4331264a9.tar.xz
masterserver-9af765479c941d3664516ebcb8e203f4331264a9.zip
Use KeyPair classes for satellite authentication
-rw-r--r--src/main/java/org/openslx/imagemaster/db/MySQL.java1
-rw-r--r--src/main/java/org/openslx/imagemaster/server/ApiServer.java23
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java68
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java2
-rw-r--r--src/main/java/org/openslx/imagemaster/util/RandomString.java14
5 files changed, 56 insertions, 52 deletions
diff --git a/src/main/java/org/openslx/imagemaster/db/MySQL.java b/src/main/java/org/openslx/imagemaster/db/MySQL.java
index 3b5438d..9443879 100644
--- a/src/main/java/org/openslx/imagemaster/db/MySQL.java
+++ b/src/main/java/org/openslx/imagemaster/db/MySQL.java
@@ -67,6 +67,7 @@ class MySQL
ds.setDatabaseName( dbname );
ds.setUser( user );
ds.setPassword( password );
+ ds.setEncoding( "UTF-8" );
db = Database.forDataSource( ds );
} catch ( Exception e ) {
log.fatal( "Error initializing mysql data source!" );
diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
index ce20020..b39a517 100644
--- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
@@ -119,15 +119,17 @@ public class ApiServer
* key of the requesting satellite server
* @throws ServerAuthenticationException when organization is invalid/unknown
*/
- public static String startServerAuthentication( String organization )
+ public static ByteBuffer startServerAuthentication( String organization )
throws ServerAuthenticationException
{
- if ( organization == null || organization.isEmpty() ) {
+ if ( organization == null || organization.isEmpty() )
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization" );
- }
- if ( DbSatellite.fromOrganization( organization ) == null ) {
- throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
- }
+
+ DbSatellite satellite = DbSatellite.fromOrganization( organization );
+ if ( satellite == null )
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization: '" + organization + "'" );
+ if ( satellite.getPubkey() == null )
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_KEY, "There is no public key known for your organization." );
return ServerAuthenticator.startServerAuthentication( organization );
}
@@ -148,11 +150,12 @@ public class ApiServer
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization or challengeResponse" );
}
DbSatellite satellite = DbSatellite.fromOrganization( organization );
- if ( satellite == null ) {
+ if ( satellite == null )
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
- }
- final ServerUser serverUser = ServerAuthenticator.serverAuthenticate(
- organization, satellite.getAddress(), challengeResponse );
+ if ( satellite.getPubkey() == null )
+ throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_KEY, "There is no public key known for your organization." );
+
+ final ServerUser serverUser = ServerAuthenticator.serverAuthenticate( satellite, 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
index 6ef037c..d851c4e 100644
--- a/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerAuthenticator.java
@@ -1,14 +1,15 @@
package org.openslx.imagemaster.serversession;
import java.nio.ByteBuffer;
-import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
-import org.openslx.imagemaster.thrift.iface.AuthenticationException;
+import org.openslx.encryption.AsymEncryptionHandler;
+import org.openslx.imagemaster.db.DbSatellite;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationError;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException;
-import org.openslx.imagemaster.util.AsymMessageVerifier;
import org.openslx.imagemaster.util.RandomString;
/**
@@ -18,8 +19,11 @@ 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>();
+
+ /**
+ * Servers currently doing authentication. Maps from organization to the challenge we sent.
+ */
+ private static Map<String, byte[]> authenticatingServers = new ConcurrentHashMap<>();
/**
* Start the server authentification.
@@ -28,16 +32,14 @@ public class ServerAuthenticator
* the organization of the server
* @return encrypted random string
*/
- public static String startServerAuthentication( String organization )
+ public static ByteBuffer startServerAuthentication( String organization )
{
- String secret = RandomString.generate( 100, false );
- synchronized ( authenticatingServers ) {
- authenticatingServers.put( organization, secret );
- log.info( "Server of organinzation '" + organization
- + "' starts to authenticate. And got string: '" + secret
- + "'" );
- }
- return secret;
+ byte[] secret = RandomString.generateBinary( 100 );
+ authenticatingServers.put( organization, secret );
+ log.info( "Server of organinzation '" + organization
+ + "' starts to authenticate. And got string: '" + secret.length
+ + "'" );
+ return ByteBuffer.wrap( secret );
}
/**
@@ -47,40 +49,24 @@ public class ServerAuthenticator
* @param address
* @param challengeResponse
* @return
- * @throws AuthenticationException
+ * @throws ServerAuthenticationException
* @throws TException
*/
- public static ServerUser serverAuthenticate( String organization,
- String address, ByteBuffer challengeResponse )
- throws AuthenticationException, TException
+ public static ServerUser serverAuthenticate( DbSatellite satellite, ByteBuffer challengeResponse )
+ throws ServerAuthenticationException
{
- byte[] bytes = new byte[ 512 ];
- challengeResponse.get( bytes );
-
- boolean result = false;
-
- AsymMessageVerifier verifier = null;
- try {
- verifier = new AsymMessageVerifier( organization );
- } catch ( Exception e ) {
- throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Organization not found." );
- }
+ byte[] encryptedBytes = new byte[ challengeResponse.remaining() ];
+ challengeResponse.get( encryptedBytes );
- try {
- result = verifier.verifyMessage( bytes, authenticatingServers.get( organization ).getBytes() );
- } catch ( Exception e ) {
- log.error( "Error while verifying message", e );
- throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_KEY, "Could not verfiy key." );
- }
+ AsymEncryptionHandler verifier = new AsymEncryptionHandler( satellite.getPubkey() );
- if ( !result ) {
- throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_KEY, "Could not verfiy key." );
- }
+ if ( !verifier.verifyMessage( encryptedBytes, authenticatingServers.get( satellite.getOrganization() ) ) )
+ throw new ServerAuthenticationException( ServerAuthenticationError.CHALLENGE_FAILED, "You failed the encryption challenge. private and public key don't seem to match." );
- log.info( "Server of organinzation '" + organization + " authenticated." );
+ log.info( "Server of organinzation '" + satellite.getOrganization() + " authenticated." );
- authenticatingServers.remove( organization );
+ authenticatingServers.remove( satellite.getOrganization() );
- return new ServerUser( organization, address );
+ return new ServerUser( satellite.getOrganization(), satellite.getAddress() );
}
}
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 84e3ede..af78258 100644
--- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
@@ -48,7 +48,7 @@ public class ImageServerHandler implements ImageServer.Iface
}
@Override
- public String startServerAuthentication( String organization )
+ public ByteBuffer startServerAuthentication( String organization )
throws ServerAuthenticationException
{
return ApiServer.startServerAuthentication( organization );
diff --git a/src/main/java/org/openslx/imagemaster/util/RandomString.java b/src/main/java/org/openslx/imagemaster/util/RandomString.java
index fc4f9d3..0120344 100644
--- a/src/main/java/org/openslx/imagemaster/util/RandomString.java
+++ b/src/main/java/org/openslx/imagemaster/util/RandomString.java
@@ -29,4 +29,18 @@ public class RandomString
}
return result;
}
+
+ /**
+ * Generate random binary data.
+ *
+ * @param length number of bytes to generate
+ * @return the generated binary data, as byte array
+ */
+ public static byte[] generateBinary( int length )
+ {
+ byte[] result = new byte[ length ];
+ random.nextBytes( result );
+ return result;
+ }
+
}