Skip to content

Commit

Permalink
GUACAMOLE-1239: Make identifier comparison case-insensitive.
Browse files Browse the repository at this point in the history
  • Loading branch information
necouchman committed Sep 12, 2024
1 parent 073d1d4 commit bcca5e6
Show file tree
Hide file tree
Showing 22 changed files with 295 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,25 @@ public String getHttpAuthHeader() throws GuacamoleException {
"REMOTE_USER"
);
}

/**
* Returns true if the username provided to the header authentication
* module should be treated as case-sensitive, or false if the username
* provided should be treated as case-insensitive. The default is false,
* the username will be case-insensitive.
*
* @return
* True if the username should be treated as case-sensitive, otherwise
* false.
*
* @throws GuacamoleException
* If guacamole.properties cannot be parsed.
*/
public boolean getCaseSensitiveUsernames() throws GuacamoleException {
return environment.getProperty(
HTTPHeaderGuacamoleProperties.HTTP_AUTH_CASE_SENSITIVE_USERNAMES,
false
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

package org.apache.guacamole.auth.header;

import org.apache.guacamole.properties.IntegerGuacamoleProperty;
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
import org.apache.guacamole.properties.StringGuacamoleProperty;


Expand All @@ -36,13 +36,26 @@ public class HTTPHeaderGuacamoleProperties {
private HTTPHeaderGuacamoleProperties() {}

/**
* The header used for HTTP header authentication.
* A property used to configure the header used for HTTP header authentication.
*/
public static final StringGuacamoleProperty HTTP_AUTH_HEADER = new StringGuacamoleProperty() {

@Override
public String getName() { return "http-auth-header"; }

};

/**
* A property used to configure whether or not the username provided by the
* header module should be treated as case-sensitive. By default usernames
* will not be case-sensitive.
*/
public static final BooleanGuacamoleProperty HTTP_AUTH_CASE_SENSITIVE_USERNAMES =
new BooleanGuacamoleProperty() {

@Override
public String getName() { return "http-auth-case-sensitive-usernames"; }

};

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package org.apache.guacamole.auth.header.user;

import com.google.inject.Inject;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.header.ConfigurationService;
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials;
Expand All @@ -37,6 +39,12 @@ public class AuthenticatedUser extends AbstractAuthenticatedUser {
*/
@Inject
private AuthenticationProvider authProvider;

/**
* Service for retrieving header configuration information.
*/
@Inject
private ConfigurationService confService;

/**
* The credentials provided when this user was authenticated.
Expand All @@ -58,6 +66,16 @@ public void init(String username, Credentials credentials) {
setIdentifier(username.toLowerCase());
}

@Override
public boolean isCaseSensitive() {
try {
return confService.getCaseSensitiveUsernames();
}
catch (GuacamoleException e) {
return false;
}
}

@Override
public AuthenticationProvider getAuthenticationProvider() {
return authProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,18 @@ public boolean shouldUseBatchExecutor() {
return true;

}

/**
* Returns a boolean value that indicates whether or not usernames should
* be treated as case-sensitive.
*
* @return
* true if usernames should be treated as case-sensitive, or false if
* usernames should be treated as case-insensitive.
*
* @throws GuacamoleException
* If guacamole.properties cannot be parsed.
*/
public abstract boolean getCaseSensitiveUsernames() throws GuacamoleException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -194,5 +194,10 @@ public Set<String> getEffectiveUserGroups() {
public boolean isPrivileged() throws GuacamoleException {
return getUser().isPrivileged();
}

@Override
public boolean isCaseSensitive() {
return user.isCaseSensitive();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.guacamole.auth.jdbc.security.PasswordEncryptionService;
import org.apache.guacamole.auth.jdbc.security.SaltService;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.JDBCEnvironment;
import org.apache.guacamole.auth.jdbc.base.ModeledPermissions;
import org.apache.guacamole.form.BooleanField;
import org.apache.guacamole.form.DateField;
Expand Down Expand Up @@ -180,6 +181,13 @@ public class ModeledUser extends ModeledPermissions<UserModel> implements User {
*/
@Inject
private Provider<UserRecordSet> userRecordSetProvider;

/**
* The environment associated with this instance of the JDBC authentication
* module.
*/
@Inject
private JDBCEnvironment environment;

/**
* Whether attributes which control access restrictions should be exposed
Expand Down Expand Up @@ -780,5 +788,15 @@ public Permissions getEffectivePermissions() throws GuacamoleException {
public boolean isSkeleton() {
return (getModel().getEntityID() == null);
}

@Override
public boolean isCaseSensitive() {
try {
return environment.getCaseSensitiveUsernames();
}
catch (GuacamoleException e) {
return true;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,18 @@ public boolean enforceAccessWindowsForActiveSessions() throws GuacamoleException
// Enforce access window restrictions for active sessions unless explicitly disabled
return getProperty(
MySQLGuacamoleProperties.MYSQL_ENFORCE_ACCESS_WINDOWS_FOR_ACTIVE_SESSIONS,
true);
true
);
}

@Override
public boolean getCaseSensitiveUsernames() throws GuacamoleException {

return getProperty(
MySQLGuacamoleProperties.MYSQL_CASE_SENSITIVE_USERNAMES,
false
);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ private MySQLGuacamoleProperties() {}
@Override
public String getName() { return "mysql-batch-size"; }

};
};

public static final BooleanGuacamoleProperty MYSQL_CASE_SENSITIVE_USERNAMES =
new BooleanGuacamoleProperty() {

@Override
public String getName() { return "mysql-case-sensitive-usernames"; }

};

}
Original file line number Diff line number Diff line change
Expand Up @@ -398,5 +398,17 @@ public boolean enforceAccessWindowsForActiveSessions() throws GuacamoleException
PostgreSQLGuacamoleProperties.POSTGRESQL_ENFORCE_ACCESS_WINDOWS_FOR_ACTIVE_SESSIONS,
true);
}

@Override
public boolean getCaseSensitiveUsernames() throws GuacamoleException {

// By default, PostgreSQL does use case-sensitive string searches, so
// we will honor case-sensitive usernames.
return getProperty(
PostgreSQLGuacamoleProperties.POSTGRESQL_CASE_SENSITIVE_USERNAMES,
true
);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -314,5 +314,17 @@ private PostgreSQLGuacamoleProperties() {}
public String getName() { return "postgresql-batch-size"; }

};

/**
* A property that configures whether or not usernames should be treated as
* case-sensitive with the Postgres JDBC backend.
*/
public static final BooleanGuacamoleProperty POSTGRESQL_CASE_SENSITIVE_USERNAMES =
new BooleanGuacamoleProperty() {

@Override
public String getName() { return "postgresql-case-sensitive-usernames"; }

};

}
Original file line number Diff line number Diff line change
Expand Up @@ -328,5 +328,17 @@ public boolean trustAllServerCertificates() throws GuacamoleException {
SQLServerGuacamoleProperties.SQLSERVER_TRUST_ALL_SERVER_CERTIFICATES,
false);
}

@Override
public boolean getCaseSensitiveUsernames() throws GuacamoleException {

// SQL Server uses case-insensitive string searches by default, so
// we do not enforce case-sensitivity unless otherwise configured.
return getProperty(
SQLServerGuacamoleProperties.SQLSERVER_CASE_SENSITIVE_USERNAMES,
false
);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,13 @@ private SQLServerGuacamoleProperties() {}
public String getName() { return "sqlserver-trust-all-server-certificates"; }

};

public static final BooleanGuacamoleProperty SQLSERVER_CASE_SENSITIVE_USERNAMES =
new BooleanGuacamoleProperty() {

@Override
public String getName() { return "sqlserver-case-sensitive-usernames" ; }

};

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Collections;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
import org.apache.guacamole.properties.ByteArrayProperty;
import org.apache.guacamole.properties.StringGuacamoleProperty;

Expand All @@ -39,6 +40,20 @@ public class ConfigurationService {
@Inject
private Environment environment;

/**
* Whether or not usernames of users associated with the JSON module should
* be treated as case-sensitive.
*/
private static final BooleanGuacamoleProperty JSON_CASE_SENSITIVE_USERNAMES =
new BooleanGuacamoleProperty() {

@Override
public String getName() {
return "json-case-sensitive-usernames";
}

};

/**
* The encryption key to use for all decryption and signature verification.
*/
Expand All @@ -64,6 +79,23 @@ public String getName() {
}

};

/**
* Returns true if the usernames of users authenticated by the JSON module
* should be treated as case-sensitive, or false if the usernames should
* be treated as case-insensitive. The default is false, usernames will
* be treated as case-insensitive.
*
* @return
* True if the usernames of users authenticated by this module should
* be treated as case-sensitive, otherwise false.
*
* @throws GuacamoleException
* If guacamole.properties cannot be parsed.
*/
public boolean getCaseSensitiveUsernames() throws GuacamoleException {
return environment.getProperty(JSON_CASE_SENSITIVE_USERNAMES, false);
}

/**
* Returns the symmetric key which will be used to encrypt and sign all
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package org.apache.guacamole.auth.json.user;

import com.google.inject.Inject;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.json.ConfigurationService;
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials;
Expand All @@ -37,6 +39,13 @@ public class AuthenticatedUser extends AbstractAuthenticatedUser {
*/
@Inject
private AuthenticationProvider authProvider;

/**
* Reference to the configuration service associated with this
* authentication provider.
*/
@Inject
private ConfigurationService confService;

/**
* The credentials provided when this user was authenticated.
Expand Down Expand Up @@ -66,6 +75,16 @@ public void init(Credentials credentials, UserData userData) {
this.userData = userData;
setIdentifier(userData.getUsername());
}

@Override
public boolean isCaseSensitive() {
try {
return confService.getCaseSensitiveUsernames();
}
catch (GuacamoleException e) {
return false;
}
}

@Override
public AuthenticationProvider getAuthenticationProvider() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ public ConnectedLDAPConfiguration getLDAPConfiguration() {
return config;
}

@Override
public boolean isCaseSensitive() {
// LDAP authentication is almost universally case-insensitive
return false;
}

@Override
public AuthenticationProvider getAuthenticationProvider() {
return authProvider;
Expand Down
Loading

0 comments on commit bcca5e6

Please sign in to comment.