GUAC-586: Ensure default authentication can tolerate the lack of a user-mapping.xml, as it is always enabled now.

This commit is contained in:
Michael Jumper
2015-08-26 17:12:52 -07:00
parent 7a5690b605
commit f190f7f1a7
7 changed files with 58 additions and 30 deletions

View File

@@ -36,7 +36,7 @@ import org.glyptodon.guacamole.net.auth.simple.SimpleAuthenticationProvider;
import org.glyptodon.guacamole.net.basic.auth.Authorization; import org.glyptodon.guacamole.net.basic.auth.Authorization;
import org.glyptodon.guacamole.net.basic.auth.UserMapping; import org.glyptodon.guacamole.net.basic.auth.UserMapping;
import org.glyptodon.guacamole.xml.DocumentHandler; import org.glyptodon.guacamole.xml.DocumentHandler;
import org.glyptodon.guacamole.net.basic.xml.user_mapping.UserMappingTagHandler; import org.glyptodon.guacamole.net.basic.xml.usermapping.UserMappingTagHandler;
import org.glyptodon.guacamole.properties.FileGuacamoleProperty; import org.glyptodon.guacamole.properties.FileGuacamoleProperty;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -58,17 +58,19 @@ public class BasicFileAuthenticationProvider extends SimpleAuthenticationProvide
/** /**
* Logger for this class. * Logger for this class.
*/ */
private Logger logger = LoggerFactory.getLogger(BasicFileAuthenticationProvider.class); private final Logger logger = LoggerFactory.getLogger(BasicFileAuthenticationProvider.class);
/** /**
* The time the user mapping file was last modified. * The time the user mapping file was last modified. If the file has never
* been read, and thus no modification time exists, this will be
* Long.MIN_VALUE.
*/ */
private long mod_time; private long lastModified = Long.MIN_VALUE;
/** /**
* The parsed UserMapping read when the user mapping file was last parsed. * The parsed UserMapping read when the user mapping file was last parsed.
*/ */
private UserMapping user_mapping; private UserMapping cachedUserMapping;
/** /**
* Guacamole server environment. * Guacamole server environment.
@@ -109,24 +111,37 @@ public class BasicFileAuthenticationProvider extends SimpleAuthenticationProvide
* guacamole.properties. If the XML file has been modified or has not yet * guacamole.properties. If the XML file has been modified or has not yet
* been read, this function may reread the file. * been read, this function may reread the file.
* *
* @return A UserMapping containing all authorization data within the * @return
* user mapping XML file. * A UserMapping containing all authorization data within the user
* @throws GuacamoleException If the user mapping property is missing or * mapping XML file, or null if the file cannot be found/parsed.
* an error occurs while parsing the XML file.
*/ */
private UserMapping getUserMapping() throws GuacamoleException { private UserMapping getUserMapping() {
// Get user mapping file, defaulting to GUACAMOLE_HOME/user-mapping.xml // Get user mapping file, defaulting to GUACAMOLE_HOME/user-mapping.xml
File user_mapping_file = environment.getProperty(BASIC_USER_MAPPING); File userMappingFile;
if (user_mapping_file == null) try {
user_mapping_file = new File(environment.getGuacamoleHome(), DEFAULT_USER_MAPPING); userMappingFile = environment.getProperty(BASIC_USER_MAPPING);
if (userMappingFile == null)
userMappingFile = new File(environment.getGuacamoleHome(), DEFAULT_USER_MAPPING);
}
// If user_mapping not yet read, or user_mapping has been modified, reread // Abort if property cannot be parsed
if (user_mapping == null || catch (GuacamoleException e) {
(user_mapping_file.exists() logger.warn("Unable to read user mapping filename from properties: {}", e.getMessage());
&& mod_time < user_mapping_file.lastModified())) { logger.debug("Error parsing user mapping property.", e);
return null;
}
logger.debug("Reading user mapping file: \"{}\"", user_mapping_file); // Abort if user mapping does not exist
if (!userMappingFile.exists()) {
logger.debug("User mapping file \"{}\" does not exist and will not be read.", userMappingFile);
return null;
}
// Refresh user mapping if file has changed
if (lastModified < userMappingFile.lastModified()) {
logger.debug("Reading user mapping file: \"{}\"", userMappingFile);
// Parse document // Parse document
try { try {
@@ -144,26 +159,34 @@ public class BasicFileAuthenticationProvider extends SimpleAuthenticationProvide
parser.setContentHandler(contentHandler); parser.setContentHandler(contentHandler);
// Read and parse file // Read and parse file
InputStream input = new BufferedInputStream(new FileInputStream(user_mapping_file)); InputStream input = new BufferedInputStream(new FileInputStream(userMappingFile));
parser.parse(new InputSource(input)); parser.parse(new InputSource(input));
input.close(); input.close();
// Store mod time and user mapping // Store mod time and user mapping
mod_time = user_mapping_file.lastModified(); lastModified = userMappingFile.lastModified();
user_mapping = userMappingHandler.asUserMapping(); cachedUserMapping = userMappingHandler.asUserMapping();
} }
// If the file is unreadable, return no mapping
catch (IOException e) { catch (IOException e) {
throw new GuacamoleException("Error reading basic user mapping file.", e); logger.warn("Unable to read user mapping file \"{}\": {}", userMappingFile, e.getMessage());
logger.debug("Error reading user mapping file.", e);
return null;
} }
// If the file cannot be parsed, return no mapping
catch (SAXException e) { catch (SAXException e) {
throw new GuacamoleException("Error parsing basic user mapping XML.", e); logger.warn("User mapping file \"{}\" is not valid: {}", userMappingFile, e.getMessage());
logger.debug("Error parsing user mapping file.", e);
return null;
} }
} }
// Return (possibly cached) user mapping // Return (possibly cached) user mapping
return user_mapping; return cachedUserMapping;
} }
@@ -172,6 +195,11 @@ public class BasicFileAuthenticationProvider extends SimpleAuthenticationProvide
getAuthorizedConfigurations(Credentials credentials) getAuthorizedConfigurations(Credentials credentials)
throws GuacamoleException { throws GuacamoleException {
// Abort authorization if no user mapping exists
UserMapping userMapping = getUserMapping();
if (userMapping == null)
return null;
// Validate and return info for given user and pass // Validate and return info for given user and pass
Authorization auth = getUserMapping().getAuthorization(credentials.getUsername()); Authorization auth = getUserMapping().getAuthorization(credentials.getUsername());
if (auth != null && auth.validate(credentials.getUsername(), credentials.getPassword())) if (auth != null && auth.validate(credentials.getUsername(), credentials.getPassword()))

View File

@@ -20,7 +20,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;
import org.glyptodon.guacamole.net.basic.auth.Authorization; import org.glyptodon.guacamole.net.basic.auth.Authorization;
import org.glyptodon.guacamole.net.basic.auth.UserMapping; import org.glyptodon.guacamole.net.basic.auth.UserMapping;

View File

@@ -20,7 +20,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;
import org.glyptodon.guacamole.net.basic.auth.Authorization; import org.glyptodon.guacamole.net.basic.auth.Authorization;
import org.glyptodon.guacamole.xml.TagHandler; import org.glyptodon.guacamole.xml.TagHandler;

View File

@@ -20,7 +20,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;
import org.glyptodon.guacamole.xml.TagHandler; import org.glyptodon.guacamole.xml.TagHandler;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;

View File

@@ -20,7 +20,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;
import org.glyptodon.guacamole.xml.TagHandler; import org.glyptodon.guacamole.xml.TagHandler;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration; import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;

View File

@@ -20,7 +20,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;
import org.glyptodon.guacamole.net.basic.auth.UserMapping; import org.glyptodon.guacamole.net.basic.auth.UserMapping;
import org.glyptodon.guacamole.xml.TagHandler; import org.glyptodon.guacamole.xml.TagHandler;

View File

@@ -23,5 +23,5 @@
/** /**
* Classes related to parsing the user-mapping.xml file. * Classes related to parsing the user-mapping.xml file.
*/ */
package org.glyptodon.guacamole.net.basic.xml.user_mapping; package org.glyptodon.guacamole.net.basic.xml.usermapping;