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,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>dist</id>
<baseDirectory>${project.artifactId}-${project.version}</baseDirectory>
<!-- Output tar.gz -->
<formats>
<format>tar.gz</format>
</formats>
<!-- Include licenses and extension .jar -->
<fileSets>
<!-- Include licenses -->
<fileSet>
<outputDirectory></outputDirectory>
<directory>src/licenses</directory>
</fileSet>
<!-- Include extension .jar -->
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>

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");
}
}

View File

@@ -0,0 +1,16 @@
{
"guacamoleVersion" : "0.9.14",
"name" : "TOTP TFA Authentication Backend",
"namespace" : "totp",
"authProviders" : [
"org.apache.guacamole.auth.totp.TOTPAuthenticationProvider"
],
"translations" : [
"translations/en.json"
]
}

View File

@@ -0,0 +1,18 @@
/*
* 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.
*/

View File

@@ -0,0 +1,13 @@
{
"DATA_SOURCE_TOTP" : {
"NAME" : "TOTP TFA Backend"
},
"LOGIN" : {
"FIELD_HEADER_GUAC_TOTP" : "Authentication Code",
"INFO_TOTP_REQUIRED" : "Please enter your authentication code to verify your identity.",
"INFO_TOTP_VERIFICATION_FAILED" : "Verification failed. Please try again."
}
}