GUAC-1364: Restrict use of reflection API to objects compatible with Java 6.

This commit is contained in:
Michael Jumper
2015-10-15 16:42:03 -07:00
parent 25dff1a322
commit 226f37e7e7

View File

@@ -22,8 +22,8 @@
package org.glyptodon.guacamole.net.basic.rest; package org.glyptodon.guacamole.net.basic.rest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import javax.ws.rs.FormParam; import javax.ws.rs.FormParam;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
@@ -56,32 +56,39 @@ public class RESTExceptionWrapper implements MethodInterceptor {
private final Logger logger = LoggerFactory.getLogger(RESTExceptionWrapper.class); private final Logger logger = LoggerFactory.getLogger(RESTExceptionWrapper.class);
/** /**
* Determines whether the given parameter is associated with the HTTP * Determines whether the given set of annotations describes an HTTP
* request parameter of the given name. For a parameter to be associated * request parameter of the given name. For a parameter to be associated
* with an HTTP request parameter, it must be annotated with either the * with an HTTP request parameter, it must be annotated with either the
* <code>@QueryParam</code> or <code>@FormParam</code> annotations. * <code>@QueryParam</code> or <code>@FormParam</code> annotations.
* *
* @param parameter * @param annotations
* The Java parameter to check. * The annotations associated with the Java parameter being checked.
* *
* @param name * @param name
* The name of the HTTP request parameter. * The name of the HTTP request parameter.
* *
* @return * @return
* true if the given parameter is associated with the HTTP request * true if the given set of annotations describes an HTTP request
* parameter having the given name, false otherwise. * parameter having the given name, false otherwise.
*/ */
private boolean isRequestParameter(Parameter parameter, String name) { private boolean isRequestParameter(Annotation[] annotations, String name) {
// Search annotations for associated HTTP parameters
for (Annotation annotation : annotations) {
// Check if parameter is associated with the HTTP query string // Check if parameter is associated with the HTTP query string
QueryParam queryParam = parameter.getAnnotation(QueryParam.class); if (annotation instanceof QueryParam && name.equals(((QueryParam) annotation).value()))
if (queryParam != null && name.equals(queryParam.value()))
return true; return true;
// Failing that, check whether the parameter is associated with the // Failing that, check whether the parameter is associated with the
// HTTP request body // HTTP request body
FormParam formParam = parameter.getAnnotation(FormParam.class); if (annotation instanceof FormParam && name.equals(((FormParam) annotation).value()))
return formParam != null && name.equals(formParam.value()); return true;
}
// No parameter annotations are present
return false;
} }
@@ -103,19 +110,24 @@ public class RESTExceptionWrapper implements MethodInterceptor {
Method method = invocation.getMethod(); Method method = invocation.getMethod();
// Iterate through all parameters, looking for the authentication token // Get the types and annotations associated with each parameter
Parameter[] parameters = method.getParameters(); Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < parameters.length; i++) { Class<?>[] parameterTypes = method.getParameterTypes();
// Get current parameter // The Java standards require these to be parallel arrays
Parameter parameter = parameters[i]; assert(parameterAnnotations.length == parameterTypes.length);
// Iterate through all parameters, looking for the authentication token
for (int i = 0; i < parameterTypes.length; i++) {
// Only inspect String parameters // Only inspect String parameters
if (parameter.getType() != String.class) Class<?> parameterType = parameterTypes[i];
if (parameterType != String.class)
continue; continue;
// Parameter must be declared as a REST service parameter // Parameter must be declared as a REST service parameter
if (!isRequestParameter(parameter, "token")) Annotation[] annotations = parameterAnnotations[i];
if (!isRequestParameter(annotations, "token"))
continue; continue;
// The token parameter has been found - return its value // The token parameter has been found - return its value