From d00d0ca5da12ca540d824c182bf0590284a66642 Mon Sep 17 00:00:00 2001 From: Mark Johnson Date: Fri, 4 Feb 2011 23:14:45 +0000 Subject: [PATCH] You can now specify a client must require a secure channel to authenticate. If this is set, {Client.setRequireSecureAuth} then if the client fails to create a secure channel with the server, an auth request with no credentials will be sent. The supplied Authenticator will need to handle this situation to send the appropriate response back to the client (ie: tell it to download the latest version). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6480 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/client/BlockingCommunicator.java | 13 +++++++---- .../threerings/presents/client/Client.java | 19 +++++++++++++++ .../presents/net/AESAuthRequest.java | 23 +++++++++++++++++++ .../presents/net/SecureResponse.java | 12 ++++------ .../threerings/presents/util/SecureUtil.java | 2 +- 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/threerings/presents/client/BlockingCommunicator.java b/src/main/java/com/threerings/presents/client/BlockingCommunicator.java index 1f2d6e920..26d16f512 100644 --- a/src/main/java/com/threerings/presents/client/BlockingCommunicator.java +++ b/src/main/java/com/threerings/presents/client/BlockingCommunicator.java @@ -635,9 +635,10 @@ public class BlockingCommunicator extends Communicator response = (AuthResponse)receiveMessage(); // If we've recieved a secure response, proceed with authentication if (response instanceof SecureResponse) { - sendMessage(((SecureResponse)response).createAuthRequest( - pkcreds, _client.getCredentials(), - _client.getVersion(), _client.getBootGroups())); + sendMessage(AESAuthRequest.createAuthRequest( + _client.getCredentials(), _client.getVersion(), + _client.getBootGroups(), _client.requireSecureAuth(), + pkcreds, (SecureResponse)response)); // now wait for the auth response log.debug("Waiting for auth response."); @@ -646,8 +647,10 @@ public class BlockingCommunicator extends Communicator } else { // construct an auth request and send it - sendMessage(new AuthRequest( - _client.getCredentials(), _client.getVersion(), _client.getBootGroups())); + sendMessage(AESAuthRequest.createAuthRequest( + _client.getCredentials(), _client.getVersion(), + _client.getBootGroups(), _client.requireSecureAuth())); + // now wait for the auth response log.debug("Waiting for auth response."); diff --git a/src/main/java/com/threerings/presents/client/Client.java b/src/main/java/com/threerings/presents/client/Client.java index ee68a5f0c..f4b4969ff 100644 --- a/src/main/java/com/threerings/presents/client/Client.java +++ b/src/main/java/com/threerings/presents/client/Client.java @@ -238,6 +238,22 @@ public class Client return key == null ? false : setPublicKey(SecureUtil.stringToRSAPublicKey(key)); } + /** + * Sets if we require a secure authentication. + */ + public void setRequireSecureAuth (boolean requireSecureAuth) + { + _requireSecureAuth = requireSecureAuth; + } + + /** + * Returns true if we require secure authentication. + */ + public boolean requireSecureAuth () + { + return _requireSecureAuth; + } + /** * Returns the version string configured for this client. */ @@ -1029,6 +1045,9 @@ public class Client /** Our public key. */ protected PublicKey _publicKey; + /** If we require a secure connection to send our credentials. */ + protected boolean _requireSecureAuth = false; + /** The unique id of our connection. */ protected int _connectionId = -1; diff --git a/src/main/java/com/threerings/presents/net/AESAuthRequest.java b/src/main/java/com/threerings/presents/net/AESAuthRequest.java index f1ac6fc4d..fe8104364 100644 --- a/src/main/java/com/threerings/presents/net/AESAuthRequest.java +++ b/src/main/java/com/threerings/presents/net/AESAuthRequest.java @@ -40,6 +40,29 @@ import com.threerings.presents.util.SecureUtil; */ public class AESAuthRequest extends AuthRequest { + /** + * Creates an auth request, secured if able, unsecured if not. + */ + public static AuthRequest createAuthRequest ( + Credentials creds, String version, String[] bootGroups, boolean requireSecureAuth) + { + return createAuthRequest(creds, version, bootGroups, requireSecureAuth, null, null); + } + + /** + * Creates an auth request, secured if able, unsecured if not. + */ + public static AuthRequest createAuthRequest ( + Credentials creds, String version, String[] bootGroups, boolean requireSecureAuth, + PublicKeyCredentials pkcreds, SecureResponse resp) + { + byte[] secret = resp == null ? null : resp.getCodeBytes(pkcreds); + if (pkcreds == null || secret == null) { + return new AuthRequest(requireSecureAuth ? null : creds, version, bootGroups); + } + return new AESAuthRequest(secret, creds, version, bootGroups); + } + /** * Zero argument constructor used when unserializing an instance. */ diff --git a/src/main/java/com/threerings/presents/net/SecureResponse.java b/src/main/java/com/threerings/presents/net/SecureResponse.java index 2e0ddf8b0..ee5aa719d 100644 --- a/src/main/java/com/threerings/presents/net/SecureResponse.java +++ b/src/main/java/com/threerings/presents/net/SecureResponse.java @@ -70,15 +70,11 @@ public class SecureResponse extends AuthResponse } /** - * Creates a request based on the secure response. + * Returns the code bytes or null for a failed state. */ - public AuthRequest createAuthRequest ( - PublicKeyCredentials pkcreds, Credentials creds, String version, String[] bootGroups) + public byte[] getCodeBytes (PublicKeyCredentials pkcreds) { - if (_data.code.equals(FAILED_TO_SECURE)) { - return new AuthRequest(creds, version, bootGroups); - } - byte[] secret = SecureUtil.xorBytes(StringUtil.unhexlate(_data.code), pkcreds.getSecret()); - return new AESAuthRequest(secret, creds, version, bootGroups); + return pkcreds == null || _data.code == null || _data.code.equals(FAILED_TO_SECURE) ? + null : SecureUtil.xorBytes(StringUtil.unhexlate(_data.code), pkcreds.getSecret()); } } diff --git a/src/main/java/com/threerings/presents/util/SecureUtil.java b/src/main/java/com/threerings/presents/util/SecureUtil.java index 28f0d7e74..11c288b5f 100644 --- a/src/main/java/com/threerings/presents/util/SecureUtil.java +++ b/src/main/java/com/threerings/presents/util/SecureUtil.java @@ -252,7 +252,7 @@ public class SecureUtil } return secret; } catch (GeneralSecurityException gse) { - log.warning("Failed to dencrypt bytes", gse); + log.warning("Failed to decrypt bytes", gse); } return null; }