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; }