mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUACAMOLE-96: Block external access to TOTP-internal attributes.
This commit is contained in:
@@ -19,9 +19,11 @@
|
||||
|
||||
package org.apache.guacamole.auth.totp;
|
||||
|
||||
import org.apache.guacamole.auth.totp.user.UserVerificationService;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.auth.totp.user.TOTPUserContext;
|
||||
import org.apache.guacamole.net.auth.AuthenticatedUser;
|
||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
@@ -104,7 +106,7 @@ public class TOTPAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
// User has been verified, and authentication should be allowed to
|
||||
// continue
|
||||
return context;
|
||||
return new TOTPUserContext(context);
|
||||
|
||||
}
|
||||
|
||||
@@ -112,7 +114,7 @@ public class TOTPAuthenticationProvider implements AuthenticationProvider {
|
||||
public UserContext redecorate(UserContext decorated, UserContext context,
|
||||
AuthenticatedUser authenticatedUser, Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
return context;
|
||||
return new TOTPUserContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.apache.guacamole.auth.totp;
|
||||
|
||||
import org.apache.guacamole.auth.totp.user.UserVerificationService;
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.auth.totp.conf.ConfigurationService;
|
||||
|
@@ -32,7 +32,7 @@ import java.net.URI;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.auth.totp.UserTOTPKey;
|
||||
import org.apache.guacamole.auth.totp.user.UserTOTPKey;
|
||||
import org.apache.guacamole.auth.totp.conf.ConfigurationService;
|
||||
import org.apache.guacamole.form.Field;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.totp.user;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.guacamole.net.auth.DelegatingUser;
|
||||
import org.apache.guacamole.net.auth.User;
|
||||
|
||||
/**
|
||||
* TOTP-specific User implementation which wraps a User from another extension,
|
||||
* hiding and blocking access to the core attributes used by TOTP.
|
||||
*/
|
||||
public class TOTPUser extends DelegatingUser {
|
||||
|
||||
/**
|
||||
* The name of the user attribute which stores the TOTP key.
|
||||
*/
|
||||
public static final String TOTP_KEY_SECRET_ATTRIBUTE_NAME = "guac-totp-key-secret";
|
||||
|
||||
/**
|
||||
* The name of the user attribute defines whether the TOTP key has been
|
||||
* confirmed by the user, and the user is thus fully enrolled.
|
||||
*/
|
||||
public static final String TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME = "guac-totp-key-confirmed";
|
||||
|
||||
/**
|
||||
* The User object wrapped by this TOTPUser.
|
||||
*/
|
||||
private final User undecorated;
|
||||
|
||||
/**
|
||||
* Wraps the given User object, hiding and blocking access to the core
|
||||
* attributes used by TOTP.
|
||||
*
|
||||
* @param user
|
||||
* The User object to wrap.
|
||||
*/
|
||||
public TOTPUser(User user) {
|
||||
super(user);
|
||||
this.undecorated = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the User object wrapped by this TOTPUser.
|
||||
*
|
||||
* @return
|
||||
* The wrapped User object.
|
||||
*/
|
||||
public User getUndecorated() {
|
||||
return undecorated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAttributes() {
|
||||
|
||||
// Create independent, mutable copy of attributes
|
||||
Map<String, String> attributes =
|
||||
new HashMap<String, String>(super.getAttributes());
|
||||
|
||||
// Do not expose any TOTP-related attributes outside this extension
|
||||
attributes.remove(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
|
||||
attributes.remove(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME);
|
||||
|
||||
// Expose only non-TOTP attributes
|
||||
return attributes;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(Map<String, String> attributes) {
|
||||
|
||||
// Create independent, mutable copy of attributes
|
||||
attributes = new HashMap<String, String>(attributes);
|
||||
|
||||
// Do not expose any TOTP-related attributes outside this extension
|
||||
attributes.remove(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
|
||||
attributes.remove(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME);
|
||||
|
||||
// Set only non-TOTP attributes
|
||||
super.setAttributes(attributes);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.totp.user;
|
||||
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.net.auth.DecoratingDirectory;
|
||||
import org.apache.guacamole.net.auth.DelegatingUserContext;
|
||||
import org.apache.guacamole.net.auth.Directory;
|
||||
import org.apache.guacamole.net.auth.User;
|
||||
import org.apache.guacamole.net.auth.UserContext;
|
||||
|
||||
/**
|
||||
* TOTP-specific UserContext implementation which wraps the UserContext of
|
||||
* some other extension, providing (or hiding) additional data.
|
||||
*/
|
||||
public class TOTPUserContext extends DelegatingUserContext {
|
||||
|
||||
/**
|
||||
* Creates a new TOTPUserContext which wraps the given UserContext,
|
||||
* providing (or hiding) additional TOTP-specific data.
|
||||
*
|
||||
* @param userContext
|
||||
* The UserContext to wrap.
|
||||
*/
|
||||
public TOTPUserContext(UserContext userContext) {
|
||||
super(userContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Directory<User> getUserDirectory() throws GuacamoleException {
|
||||
return new DecoratingDirectory<User>(super.getUserDirectory()) {
|
||||
|
||||
@Override
|
||||
protected User decorate(User object) {
|
||||
return new TOTPUser(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected User undecorate(User object) {
|
||||
assert(object instanceof TOTPUser);
|
||||
return ((TOTPUser) object).getUndecorated();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.totp;
|
||||
package org.apache.guacamole.auth.totp.user;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.guacamole.auth.totp;
|
||||
package org.apache.guacamole.auth.totp.user;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.google.inject.Inject;
|
||||
@@ -53,17 +53,6 @@ public class UserVerificationService {
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(UserVerificationService.class);
|
||||
|
||||
/**
|
||||
* The name of the user attribute which stores the TOTP key.
|
||||
*/
|
||||
private static final String TOTP_KEY_SECRET_ATTRIBUTE_NAME = "guac-totp-key-secret";
|
||||
|
||||
/**
|
||||
* The name of the user attribute defines whether the TOTP key has been
|
||||
* confirmed by the user, and the user is thus fully enrolled.
|
||||
*/
|
||||
private static final String TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME = "guac-totp-key-confirmed";
|
||||
|
||||
/**
|
||||
* BaseEncoding instance which decoded/encodes base32.
|
||||
*/
|
||||
@@ -111,7 +100,7 @@ public class UserVerificationService {
|
||||
Map<String, String> attributes = context.self().getAttributes();
|
||||
|
||||
// If no key is defined, attempt to generate a new key
|
||||
String secret = attributes.get(TOTP_KEY_SECRET_ATTRIBUTE_NAME);
|
||||
String secret = attributes.get(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME);
|
||||
if (secret == null) {
|
||||
|
||||
// Generate random key for user
|
||||
@@ -140,7 +129,7 @@ public class UserVerificationService {
|
||||
}
|
||||
|
||||
// Otherwise, parse value from attributes
|
||||
boolean confirmed = "true".equals(attributes.get(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME));
|
||||
boolean confirmed = "true".equals(attributes.get(TOTPUser.TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME));
|
||||
return new UserTOTPKey(username, key, confirmed);
|
||||
|
||||
}
|
||||
@@ -173,14 +162,14 @@ public class UserVerificationService {
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
|
||||
// Set/overwrite current TOTP key state
|
||||
attributes.put(TOTP_KEY_SECRET_ATTRIBUTE_NAME, BASE32.encode(key.getSecret()));
|
||||
attributes.put(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME, key.isConfirmed() ? "true" : "false");
|
||||
attributes.put(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME, BASE32.encode(key.getSecret()));
|
||||
attributes.put(TOTPUser.TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME, key.isConfirmed() ? "true" : "false");
|
||||
self.setAttributes(attributes);
|
||||
|
||||
// Confirm that attributes have actually been set
|
||||
Map<String, String> setAttributes = self.getAttributes();
|
||||
if (!setAttributes.containsKey(TOTP_KEY_SECRET_ATTRIBUTE_NAME)
|
||||
|| !setAttributes.containsKey(TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME))
|
||||
if (!setAttributes.containsKey(TOTPUser.TOTP_KEY_SECRET_ATTRIBUTE_NAME)
|
||||
|| !setAttributes.containsKey(TOTPUser.TOTP_KEY_CONFIRMED_ATTRIBUTE_NAME))
|
||||
return false;
|
||||
|
||||
// Update user object
|
Reference in New Issue
Block a user