mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUACAMOLE-96: Add skeleton TOTP authentication extension (hard-coded, fake TOTP).
This commit is contained in:
		| @@ -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 | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -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); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -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"); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user