GUACAMOLE-96: Add skeleton TOTP authentication extension (hard-coded, fake TOTP).

This commit is contained in:
Michael Jumper
2017-11-19 21:14:18 -08:00
parent 1b262985b2
commit 264fd24b65
16 changed files with 1222 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
/*
* 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;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.UserContext;
/**
* AuthenticationProvider implementation which uses TOTP as an additional
* authentication factor for users which have already been authenticated by
* some other AuthenticationProvider.
*/
public class TOTPAuthenticationProvider implements AuthenticationProvider {
/**
* Injector which will manage the object graph of this authentication
* provider.
*/
private final Injector injector;
/**
* Creates a new TOTPAuthenticationProvider that verifies users using TOTP.
*
* @throws GuacamoleException
* If a required property is missing, or an error occurs while parsing
* a property.
*/
public TOTPAuthenticationProvider() throws GuacamoleException {
// Set up Guice injector.
injector = Guice.createInjector(
new TOTPAuthenticationProviderModule(this)
);
}
@Override
public String getIdentifier() {
return "totp";
}
@Override
public Object getResource() {
return null;
}
@Override
public AuthenticatedUser authenticateUser(Credentials credentials)
throws GuacamoleException {
return null;
}
@Override
public AuthenticatedUser updateAuthenticatedUser(AuthenticatedUser authenticatedUser,
Credentials credentials) throws GuacamoleException {
return authenticatedUser;
}
@Override
public UserContext getUserContext(AuthenticatedUser authenticatedUser)
throws GuacamoleException {
return null;
}
@Override
public UserContext updateUserContext(UserContext context,
AuthenticatedUser authenticatedUser, Credentials credentials)
throws GuacamoleException {
return context;
}
@Override
public UserContext decorate(UserContext context,
AuthenticatedUser authenticatedUser, Credentials credentials)
throws GuacamoleException {
UserVerificationService verificationService =
injector.getInstance(UserVerificationService.class);
// Verify identity of user
verificationService.verifyIdentity(context, authenticatedUser);
// User has been verified, and authentication should be allowed to
// continue
return context;
}
@Override
public UserContext redecorate(UserContext decorated, UserContext context,
AuthenticatedUser authenticatedUser, Credentials credentials)
throws GuacamoleException {
return context;
}
@Override
public void shutdown() {
// Do nothing
}
}

View File

@@ -0,0 +1,78 @@
/*
* 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;
import com.google.inject.AbstractModule;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.environment.LocalEnvironment;
import org.apache.guacamole.net.auth.AuthenticationProvider;
/**
* Guice module which configures TOTP-specific injections.
*/
public class TOTPAuthenticationProviderModule extends AbstractModule {
/**
* Guacamole server environment.
*/
private final Environment environment;
/**
* A reference to the TOTPAuthenticationProvider on behalf of which this
* module has configured injection.
*/
private final AuthenticationProvider authProvider;
/**
* Creates a new TOTP authentication provider module which configures
* injection for the TOTPAuthenticationProvider.
*
* @param authProvider
* The AuthenticationProvider for which injection is being configured.
*
* @throws GuacamoleException
* If an error occurs while retrieving the Guacamole server
* environment.
*/
public TOTPAuthenticationProviderModule(AuthenticationProvider authProvider)
throws GuacamoleException {
// Get local environment
this.environment = new LocalEnvironment();
// Store associated auth provider
this.authProvider = authProvider;
}
@Override
protected void configure() {
// Bind core implementations of guacamole-ext classes
bind(AuthenticationProvider.class).toInstance(authProvider);
bind(Environment.class).toInstance(environment);
// Bind TOTP-specific services
bind(UserVerificationService.class);
}
}

View File

@@ -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;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.form.Field;
import org.apache.guacamole.form.TextField;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.UserContext;
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
/**
* Service for verifying the identity of a user using TOTP.
*/
public class UserVerificationService {
/**
* The name of the HTTP parameter which will contain the TOTP code provided
* by the user to verify their identity.
*/
private static final String TOTP_PARAMETER_NAME = "guac-totp";
/**
* The field which should be exposed to the user to request that they
* provide their TOTP code.
*/
private static final Field TOTP_FIELD = new TextField(TOTP_PARAMETER_NAME);
/**
* CredentialsInfo object describing the credentials expected for a user
* who has verified their identity with TOTP.
*/
private static final CredentialsInfo TOTP_CREDENTIALS = new CredentialsInfo(
Collections.singletonList(TOTP_FIELD)
);
/**
* Verifies the identity of the given user using TOTP. If a authentication
* code from the user's TOTP device has not already been provided, a code is
* requested in the form of additional expected credentials. Any provided
* code is cryptographically verified. If no code is present, or the
* received code is invalid, an exception is thrown.
*
* @param context
* The UserContext provided for the user by another authentication
* extension.
*
* @param authenticatedUser
* The user whose identity should be verified using TOTP.
*
* @throws GuacamoleException
* If required TOTP-specific configuration options are missing or
* malformed, or if the user's identity cannot be verified.
*/
public void verifyIdentity(UserContext context,
AuthenticatedUser authenticatedUser) throws GuacamoleException {
// Pull the original HTTP request used to authenticate
Credentials credentials = authenticatedUser.getCredentials();
HttpServletRequest request = credentials.getRequest();
// Ignore anonymous users
if (authenticatedUser.getIdentifier().equals(AuthenticatedUser.ANONYMOUS_IDENTIFIER))
return;
// Retrieve TOTP from request
String totp = request.getParameter(TOTP_PARAMETER_NAME);
// If no TOTP provided, request one
if (totp == null)
throw new GuacamoleInsufficientCredentialsException(
"LOGIN.INFO_TOTP_REQUIRED", TOTP_CREDENTIALS);
// FIXME: Hard-coded code
if (!totp.equals("123456"))
throw new GuacamoleClientException("LOGIN.INFO_TOTP_VERIFICATION_FAILED");
}
}