GUAC-1109: Do not rely on SHA2(). Handle password hashing in Java.

This commit is contained in:
Michael Jumper
2015-03-04 14:23:56 -08:00
parent 969db70be9
commit a4a3de002b
3 changed files with 23 additions and 36 deletions

View File

@@ -32,23 +32,6 @@ import org.apache.ibatis.annotations.Param;
*/
public interface UserMapper extends DirectoryObjectMapper<UserModel> {
/**
* Returns the user having the given username and password, if any. If no
* such user exists, null is returned.
*
* @param username
* The username of the user to return.
*
* @param password
* The password of the user to return.
*
* @return
* The user having the given username and password, or null if no such
* user exists.
*/
UserModel selectOneByCredentials(@Param("username") String username,
@Param("password") String password);
/**
* Returns the user having the given username, if any. If no such user
* exists, null is returned.

View File

@@ -24,6 +24,7 @@ package org.glyptodon.guacamole.auth.jdbc.user;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.glyptodon.guacamole.net.auth.Credentials;
@@ -33,6 +34,7 @@ import org.glyptodon.guacamole.GuacamoleClientException;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.auth.jdbc.permission.ObjectPermissionMapper;
import org.glyptodon.guacamole.auth.jdbc.permission.UserPermissionMapper;
import org.glyptodon.guacamole.auth.jdbc.security.PasswordEncryptionService;
import org.glyptodon.guacamole.net.auth.User;
import org.glyptodon.guacamole.net.auth.permission.ObjectPermissionSet;
import org.glyptodon.guacamole.net.auth.permission.SystemPermission;
@@ -64,6 +66,12 @@ public class UserService extends DirectoryObjectService<ModeledUser, User, UserM
@Inject
private Provider<ModeledUser> userProvider;
/**
* Service for hashing passwords.
*/
@Inject
private PasswordEncryptionService encryptionService;
@Override
protected DirectoryObjectMapper<UserModel> getObjectMapper() {
return userMapper;
@@ -169,11 +177,15 @@ public class UserService extends DirectoryObjectService<ModeledUser, User, UserM
String username = credentials.getUsername();
String password = credentials.getPassword();
// Retrieve user model, if the user exists
UserModel userModel = userMapper.selectOneByCredentials(username, password);
// Retrieve corresponding user model, if such a user exists
UserModel userModel = userMapper.selectOne(username);
if (userModel == null)
return null;
// If password hash matches, return the retrieved user
byte[] hash = encryptionService.createPasswordHash(password, userModel.getPasswordSalt());
if (Arrays.equals(hash, userModel.getPasswordHash())) {
// Return corresponding user, set up cyclic reference
ModeledUser user = getObjectInstance(null, userModel);
user.setCurrentUser(new AuthenticatedUser(user, credentials));
@@ -181,4 +193,9 @@ public class UserService extends DirectoryObjectService<ModeledUser, User, UserM
}
// Otherwise, the credentials do not match
return null;
}
}

View File

@@ -87,19 +87,6 @@
</select>
<!-- Select single user by credentials -->
<select id="selectOneByCredentials" resultMap="UserResultMap">
SELECT
user_id,
username,
password_hash,
password_salt
FROM guacamole_user
WHERE
username = #{username,jdbcType=VARCHAR}
AND password_hash = UNHEX(SHA2(CONCAT(#{password,jdbcType=VARCHAR}, HEX(password_salt)), 256))
</select>
<!-- Select single user by username -->
<select id="selectOne" resultMap="UserResultMap">