mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 06:01:22 +00:00
GUACAMOLE-197: Initial code for the guacamole-auth-radius authentication module.
This commit is contained in:
committed by
Nick Couchman
parent
9d587496b0
commit
d9d5573aa4
53
extensions/guacamole-auth-radius/src/main/assembly/dist.xml
Normal file
53
extensions/guacamole-auth-radius/src/main/assembly/dist.xml
Normal 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>
|
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.util.Collections;
|
||||
import org.apache.guacamole.auth.radius.user.AuthenticatedUser;
|
||||
import org.apache.guacamole.auth.radius.form.RadiusChallengeResponseField;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.form.Field;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
|
||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import net.jradius.exception.UnknownAttributeException;
|
||||
import net.jradius.packet.RadiusPacket;
|
||||
import net.jradius.packet.AccessAccept;
|
||||
import net.jradius.packet.AccessChallenge;
|
||||
import net.jradius.packet.AccessReject;
|
||||
import net.jradius.packet.AccessRequest;
|
||||
import net.jradius.packet.AccessResponse;
|
||||
import net.jradius.packet.attribute.RadiusAttribute;
|
||||
|
||||
/**
|
||||
* Service providing convenience functions for the RADIUS AuthenticationProvider
|
||||
* implementation.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class AuthenticationProviderService {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class);
|
||||
|
||||
/**
|
||||
* Service for creating and managing connections to RADIUS servers.
|
||||
*/
|
||||
@Inject
|
||||
private RadiusConnectionService radiusService;
|
||||
|
||||
/**
|
||||
* Service for retrieving RADIUS server configuration information.
|
||||
*/
|
||||
@Inject
|
||||
private ConfigurationService confService;
|
||||
|
||||
/**
|
||||
* Provider for AuthenticatedUser objects.
|
||||
*/
|
||||
@Inject
|
||||
private Provider<AuthenticatedUser> authenticatedUserProvider;
|
||||
|
||||
/**
|
||||
* Returns an AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials to use for authentication.
|
||||
*
|
||||
* @return
|
||||
* An AuthenticatedUser representing the user authenticated by the
|
||||
* given credentials.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while authenticating the user, or if access is
|
||||
* denied.
|
||||
*/
|
||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||
throws GuacamoleException {
|
||||
|
||||
// Attempt bind
|
||||
RadiusPacket radPack;
|
||||
try {
|
||||
radPack = radiusService.authenticate(credentials.getUsername(),
|
||||
credentials.getPassword());
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.error("Cannot configure RADIUS server: {}", e.getMessage());
|
||||
logger.debug("Error configuring RADIUS server.", e);
|
||||
radPack = null;
|
||||
}
|
||||
|
||||
// If configure fails, permission to login is denied
|
||||
if(radPack == null) {
|
||||
logger.debug("Nothing in the RADIUS packet.");
|
||||
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
||||
}
|
||||
else if(radPack instanceof AccessReject) {
|
||||
logger.debug("Login has been rejected by RADIUS server.");
|
||||
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
||||
}
|
||||
else if(radPack instanceof AccessChallenge) {
|
||||
try {
|
||||
String replyMsg = radPack.getAttributeValue("Reply-Message").toString();
|
||||
String radState = radPack.getAttributeValue("State").toString();
|
||||
logger.debug("RADIUS sent challenge response: {}", replyMsg);
|
||||
logger.debug("RADIUS sent state: {}", radState);
|
||||
Field radiusResponseField = new RadiusChallengeResponseField(replyMsg, radState);
|
||||
CredentialsInfo responseCredentials = new CredentialsInfo(Collections.singletonList(radiusResponseField));
|
||||
throw new GuacamoleInsufficientCredentialsException("LOGIN.INFO_RADIUS_ADDL_REQUIRED", responseCredentials);
|
||||
}
|
||||
catch(UnknownAttributeException e) {
|
||||
logger.error("Error in talks with RADIUS server.");
|
||||
logger.debug("RADIUS challenged by didn't provide right attributes.");
|
||||
throw new GuacamoleInvalidCredentialsException("Authentication error.", CredentialsInfo.USERNAME_PASSWORD);
|
||||
}
|
||||
}
|
||||
else if(radPack instanceof AccessAccept) {
|
||||
try {
|
||||
|
||||
// Return AuthenticatedUser if bind succeeds
|
||||
AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
|
||||
authenticatedUser.init(credentials);
|
||||
return authenticatedUser;
|
||||
}
|
||||
finally {
|
||||
radiusService.disconnect();
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new GuacamoleInvalidCredentialsException("Unknown error trying to authenticate.", CredentialsInfo.USERNAME_PASSWORD);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.environment.Environment;
|
||||
|
||||
/**
|
||||
* Service for retrieving configuration information regarding the RADIUS server.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class ConfigurationService {
|
||||
|
||||
/**
|
||||
* The Guacamole server environment.
|
||||
*/
|
||||
@Inject
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Returns the hostname of the RADIUS server as configured with
|
||||
* guacamole.properties. By default, this will be "localhost".
|
||||
*
|
||||
* @return
|
||||
* The hostname of the RADIUS server, as configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public String getRadiusServer() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_SERVER,
|
||||
"localhost"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication port of the RADIUS server configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* The authentication port of the RADIUS server, as configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public int getRadiusAuthPort() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_AUTH_PORT,
|
||||
1812
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the accounting port of the RADIUS server configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* The accouting port of the RADIUS server, as configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public int getRadiusAcctPort() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_ACCT_PORT,
|
||||
1813
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared secret of the RADIUS server configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* The shared secret of the RADIUS server, as configured with
|
||||
* guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public String getRadiusSharedSecret() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_SHARED_SECRET,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication protocol of the RADIUS server
|
||||
* from guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* The authentication protocol of the RADIUS server,
|
||||
* from guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If guacamole.properties cannot be parsed.
|
||||
*/
|
||||
public String getRadiusAuthProtocol() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_AUTH_PROTOCOL,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
public int getRadiusRetries() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_RETRIES,
|
||||
5
|
||||
);
|
||||
}
|
||||
|
||||
public int getRadiusTimeout() throws GuacamoleException {
|
||||
return environment.getProperty(
|
||||
RadiusGuacamoleProperties.RADIUS_TIMEOUT,
|
||||
60
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Allows users to be authenticated against an RADIUS server. Each user may have
|
||||
* any number of authorized configurations. Authorized configurations may be
|
||||
* shared.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class RadiusAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Injector which will manage the object graph of this authentication
|
||||
* provider.
|
||||
*/
|
||||
private final Injector injector;
|
||||
|
||||
/**
|
||||
* Creates a new RadiusAuthenticationProvider that authenticates users
|
||||
* against an RADIUS service.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If a required property is missing, or an error occurs while parsing
|
||||
* a property.
|
||||
*/
|
||||
public RadiusAuthenticationProvider() throws GuacamoleException {
|
||||
|
||||
// Set up Guice injector.
|
||||
injector = Guice.createInjector(
|
||||
new RadiusAuthenticationProviderModule(this)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "radius";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticatedUser authenticateUser(Credentials credentials) throws GuacamoleException {
|
||||
|
||||
AuthenticationProviderService authProviderService = injector.getInstance(AuthenticationProviderService.class);
|
||||
return authProviderService.authenticateUser(credentials);
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
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 RADIUS-specific injections.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class RadiusAuthenticationProviderModule extends AbstractModule {
|
||||
|
||||
/**
|
||||
* Guacamole server environment.
|
||||
*/
|
||||
private final Environment environment;
|
||||
|
||||
/**
|
||||
* A reference to the RadiusAuthenticationProvider on behalf of which this
|
||||
* module has configured injection.
|
||||
*/
|
||||
private final AuthenticationProvider authProvider;
|
||||
|
||||
/**
|
||||
* Creates a new RADIUS authentication provider module which configures
|
||||
* injection for the RadiusAuthenticationProvider.
|
||||
*
|
||||
* @param authProvider
|
||||
* The AuthenticationProvider for which injection is being configured.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while retrieving the Guacamole server
|
||||
* environment.
|
||||
*/
|
||||
public RadiusAuthenticationProviderModule(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 RADIUS-specific services
|
||||
bind(ConfigurationService.class);
|
||||
bind(RadiusConnectionService.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.GuacamoleUnsupportedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import net.jradius.client.RadiusClient;
|
||||
import net.jradius.exception.RadiusException;
|
||||
import net.jradius.packet.RadiusPacket;
|
||||
import net.jradius.packet.AccessRequest;
|
||||
import net.jradius.dictionary.*;
|
||||
import net.jradius.packet.attribute.AttributeList;
|
||||
import net.jradius.client.auth.RadiusAuthenticator;
|
||||
import net.jradius.packet.attribute.AttributeFactory;
|
||||
|
||||
/**
|
||||
* Service for creating and managing connections to RADIUS servers.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class RadiusConnectionService {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(RadiusConnectionService.class);
|
||||
|
||||
/**
|
||||
* Service for retrieving RADIUS server configuration information.
|
||||
*/
|
||||
@Inject
|
||||
private ConfigurationService confService;
|
||||
|
||||
|
||||
/**
|
||||
* The RADIUS client;
|
||||
*/
|
||||
private RadiusClient radiusClient;
|
||||
|
||||
/**
|
||||
* Creates a new instance of RadiusConnection, configured as required to use
|
||||
* whichever encryption method is requested within guacamole.properties.
|
||||
*
|
||||
* @return
|
||||
* A new RadiusConnection instance which has already been configured to
|
||||
* use the encryption method requested within guacamole.properties.
|
||||
*
|
||||
* @throws GuacamoleException
|
||||
* If an error occurs while parsing guacamole.properties, or if the
|
||||
* requested encryption method is actually not implemented (a bug).
|
||||
*/
|
||||
private void createRadiusConnection() {
|
||||
|
||||
/*
|
||||
// Map encryption method to proper connection and socket factory
|
||||
EncryptionMethod encryptionMethod = confService.getEncryptionMethod();
|
||||
switch (encryptionMethod) {
|
||||
|
||||
// Unencrypted RADIUS connection
|
||||
case NONE:
|
||||
logger.debug("Connection to RADIUS server without encryption.");
|
||||
radiusClient = new RadiusClient();
|
||||
return radiusClient;
|
||||
|
||||
// Radius over TTLS (EAP-TTLS)
|
||||
case TTLS:
|
||||
logger.debug("Connecting to RADIUS server using TTLS.");
|
||||
radiusClient = new RadiusClient();
|
||||
return radiusClient;
|
||||
|
||||
// We default to unencrypted connections.
|
||||
default:
|
||||
logger.debug("Defaulting an unencrypted RADIUS connection.");
|
||||
radiusClient = new RadiusClient();
|
||||
return radiusClient;
|
||||
|
||||
}
|
||||
*/
|
||||
try {
|
||||
radiusClient = new RadiusClient(InetAddress.getByName(confService.getRadiusServer()),
|
||||
confService.getRadiusSharedSecret(),
|
||||
confService.getRadiusAuthPort(),
|
||||
confService.getRadiusAcctPort(),
|
||||
confService.getRadiusTimeout());
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.error("Unable to initialize RADIUS client: {}", e.getMessage());
|
||||
logger.debug("Failed to init RADIUS client.", e);
|
||||
return;
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
logger.error("Unable to resolve host: {}", e.getMessage());
|
||||
logger.debug("Failed to resolve host.", e);
|
||||
return;
|
||||
}
|
||||
catch (IOException e) {
|
||||
logger.error("Unable to communicate with host: {}", e.getMessage());
|
||||
logger.debug("Failed to communicate with host.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public RadiusPacket authenticate(String username, String password)
|
||||
throws GuacamoleException {
|
||||
|
||||
createRadiusConnection();
|
||||
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
||||
|
||||
if(radiusClient == null)
|
||||
return null;
|
||||
|
||||
if(username == null || username.isEmpty()) {
|
||||
logger.warn("Anonymous access not allowed with RADIUS client.");
|
||||
return null;
|
||||
}
|
||||
if(password == null || password.isEmpty()) {
|
||||
logger.warn("Password required for RADIUS authentication.");
|
||||
return null;
|
||||
}
|
||||
|
||||
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
||||
if(radAuth == null)
|
||||
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
||||
try {
|
||||
AttributeList radAttrs = new AttributeList();
|
||||
radAttrs.add(new Attr_UserName(username));
|
||||
radAttrs.add(new Attr_UserPassword(password));
|
||||
AccessRequest radAcc = new AccessRequest(radiusClient, radAttrs);
|
||||
logger.debug("Sending authentication request to radius server for user {}.", username);
|
||||
radAuth.setupRequest(radiusClient, radAcc);
|
||||
radAuth.processRequest(radAcc);
|
||||
return radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
|
||||
}
|
||||
catch (RadiusException e) {
|
||||
logger.error("Unable to complete authentication.", e.getMessage());
|
||||
logger.debug("Authentication with RADIUS failed.", e);
|
||||
return null;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
logger.error("No such RADIUS algorithm: {}", e.getMessage());
|
||||
logger.debug("Unknown RADIUS algorithm.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public RadiusPacket authenticate(String username, String state, String response)
|
||||
throws GuacamoleException {
|
||||
|
||||
createRadiusConnection();
|
||||
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
||||
|
||||
if(radiusClient == null)
|
||||
return null;
|
||||
|
||||
if(username == null || username.isEmpty()) {
|
||||
logger.warn("Anonymous access not allowed with RADIUS client.");
|
||||
return null;
|
||||
}
|
||||
if(state == null || state.isEmpty()) {
|
||||
logger.warn("This method needs a previous RADIUS state to respond to.");
|
||||
return null;
|
||||
}
|
||||
if(response == null || response.isEmpty()) {
|
||||
logger.warn("Response required for RADIUS authentication.");
|
||||
return null;
|
||||
}
|
||||
|
||||
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
||||
if(radAuth == null)
|
||||
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
||||
try {
|
||||
AttributeList radAttrs = new AttributeList();
|
||||
radAttrs.add(new Attr_UserName(username));
|
||||
radAttrs.add(new Attr_State(state));
|
||||
radAttrs.add(new Attr_UserPassword(response));
|
||||
AccessRequest radAcc = new AccessRequest(radiusClient, radAttrs);
|
||||
logger.debug("Sending authentication response to radius server for user {}.", username);
|
||||
radAuth.setupRequest(radiusClient, radAcc);
|
||||
radAuth.processRequest(radAcc);
|
||||
return radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
|
||||
}
|
||||
catch (RadiusException e) {
|
||||
logger.error("Unable to complete authentication.", e.getMessage());
|
||||
logger.debug("Authentication with RADIUS failed.", e);
|
||||
return null;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
logger.error("No such RADIUS algorithm: {}", e.getMessage());
|
||||
logger.debug("Unknown RADIUS algorithm.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the given RADIUS connection, logging any failure to do so
|
||||
* appropriately.
|
||||
*
|
||||
* @param radiusConnection
|
||||
* The RADIUS connection to disconnect.
|
||||
*/
|
||||
public void disconnect() {
|
||||
|
||||
radiusClient.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.radius;
|
||||
|
||||
import org.apache.guacamole.properties.IntegerGuacamoleProperty;
|
||||
import org.apache.guacamole.properties.StringGuacamoleProperty;
|
||||
|
||||
|
||||
/**
|
||||
* Provides properties required for use of the RADIUS authentication provider.
|
||||
* These properties will be read from guacamole.properties when the RADIUS
|
||||
* authentication provider is used.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class RadiusGuacamoleProperties {
|
||||
|
||||
/**
|
||||
* This class should not be instantiated.
|
||||
*/
|
||||
private RadiusGuacamoleProperties() {}
|
||||
|
||||
/**
|
||||
* The port on the RADIUS server to connect to when authenticating users.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty RADIUS_AUTH_PORT = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-auth-port"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The port on the RADIUS server to connect to when accounting users.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty RADIUS_ACCT_PORT = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-acct-port"; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The hostname or ip of the RADIUS server to connect to when authenticating users.
|
||||
*/
|
||||
public static final StringGuacamoleProperty RADIUS_SERVER = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-server"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The shared secret of the RADIUS server to connect to when authenticating users.
|
||||
*/
|
||||
public static final StringGuacamoleProperty RADIUS_SHARED_SECRET = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-shared-secret"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The authentication protocol of the RADIUS server to connect to when authenticating users.
|
||||
*/
|
||||
public static final StringGuacamoleProperty RADIUS_AUTH_PROTOCOL = new StringGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-auth-protocol"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The number of retries when attempting a radius packet transaction.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty RADIUS_RETRIES = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-retries"; }
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The network timeout when attempting a radius packet transaction.
|
||||
*/
|
||||
public static final IntegerGuacamoleProperty RADIUS_TIMEOUT = new IntegerGuacamoleProperty() {
|
||||
|
||||
@Override
|
||||
public String getName() { return "radius-timeout"; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.radius.form;
|
||||
|
||||
import org.apache.guacamole.form.Field;
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RadiusChallengeResponseField extends Field {
|
||||
|
||||
/**
|
||||
* Logger for this class.
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(RadiusChallengeResponseField.class);
|
||||
|
||||
private static final String RADIUS_FIELD_NAME = "guac-radius-challenge-response";
|
||||
private static final String RADIUS_FIELD_TYPE = "GUAC_RADIUS_CHALLENGE_RESPONSE";
|
||||
private final String radiusState;
|
||||
private final String replyMsg;
|
||||
|
||||
public RadiusChallengeResponseField(String replyMsg, String radiusState) {
|
||||
super(RADIUS_FIELD_NAME, RADIUS_FIELD_TYPE);
|
||||
logger.debug("Initializing the RADIUS challenge/response field: {}", replyMsg);
|
||||
|
||||
this.replyMsg = replyMsg;
|
||||
this.radiusState = radiusState;
|
||||
|
||||
}
|
||||
|
||||
public String getRadiusState() {
|
||||
return radiusState;
|
||||
}
|
||||
|
||||
public String getReplyMsg() {
|
||||
return replyMsg;
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.radius.user;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
|
||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
|
||||
import org.apache.guacamole.net.auth.Credentials;
|
||||
|
||||
/**
|
||||
* An RADIUS-specific implementation of AuthenticatedUser, associating a
|
||||
* particular set of credentials with the RADIUS authentication provider.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class AuthenticatedUser extends AbstractAuthenticatedUser {
|
||||
|
||||
/**
|
||||
* Reference to the authentication provider associated with this
|
||||
* authenticated user.
|
||||
*/
|
||||
@Inject
|
||||
private AuthenticationProvider authProvider;
|
||||
|
||||
/**
|
||||
* The credentials provided when this user was authenticated.
|
||||
*/
|
||||
private Credentials credentials;
|
||||
|
||||
/**
|
||||
* Initializes this AuthenticatedUser using the given credentials.
|
||||
*
|
||||
* @param credentials
|
||||
* The credentials provided when this user was authenticated.
|
||||
*/
|
||||
public void init(Credentials credentials) {
|
||||
this.credentials = credentials;
|
||||
setIdentifier(credentials.getUsername().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationProvider getAuthenticationProvider() {
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Credentials getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Config block which registers Radius-specific field types.
|
||||
*/
|
||||
angular.module('guacRadius').config(['formServiceProvider',
|
||||
function guacRadiusConfig(formServiceProvider) {
|
||||
console.log("In guacRadiusConfig() method.");
|
||||
|
||||
// Define field for the signed response from the RADIUS service
|
||||
formServiceProvider.registerFieldType('GUAC_RADIUS_CHALLENGE_RESPONSE', {
|
||||
module : 'guacRadius',
|
||||
controller : 'guacRadiusController',
|
||||
templateUrl : 'app/ext/radius/templates/radiusChallengeResponseField.html'
|
||||
});
|
||||
|
||||
}]);
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controller for the "GUAC_RADIUS_CHALLENGE_RESPONSE" field which uses the DuoWeb
|
||||
* API to prompt the user for additional credentials, ultimately receiving a
|
||||
* signed response from the Duo service.
|
||||
*/
|
||||
angular.module('guacRadius').controller('guacRadiusController', ['$scope', '$element',
|
||||
function guacRadiusController($scope, $element) {
|
||||
console.log("In guacRadiusController() method.");
|
||||
|
||||
var radiusChallenge = $element.find(document.querySelector('#radius-challenge-text'));
|
||||
var radiusState = $element.find(document.querySelector('#radius-state'));
|
||||
console.log("RADIUS Reply Message: " + $scope.field.replyMsg);
|
||||
radiusChellenge.html($scope.field.replyMsg);
|
||||
console.log("RADIUS State: " + scope.field.radiusState);
|
||||
radiusState.value = $scope.field.radiusState;
|
||||
|
||||
}]);
|
@@ -0,0 +1,28 @@
|
||||
{
|
||||
|
||||
"guacamoleVersion" : "0.9.11-incubating",
|
||||
|
||||
"name" : "RADIUS Authentication Backend",
|
||||
"namespace" : "radius",
|
||||
|
||||
"authProviders" : [
|
||||
"org.apache.guacamole.auth.radius.RadiusAuthenticationProvider"
|
||||
],
|
||||
|
||||
"translations" : [
|
||||
"translations/en.json"
|
||||
],
|
||||
|
||||
"js" : [
|
||||
"radius.min.js"
|
||||
],
|
||||
|
||||
"css" : [
|
||||
"radius.min.css"
|
||||
],
|
||||
|
||||
"resources" : {
|
||||
"templates/radiusChallengeResponseField.html" : "text/html"
|
||||
}
|
||||
|
||||
}
|
@@ -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.
|
||||
*/
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
console.log("Loading guac-radius Angular module.");
|
||||
|
||||
/**
|
||||
* Module which provides handling for RADIUS challenge-response
|
||||
* authentication.
|
||||
*/
|
||||
angular.module('guacRadius', [
|
||||
'form'
|
||||
]);
|
||||
|
||||
// Ensure the guacDuo module is loaded along with the rest of the app
|
||||
angular.module('index').requires.push('guacRadius');
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
.radius-challenge-response-field-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: table;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.radius-challenge-response-field {
|
||||
width: 100%;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.radius-challenge-response-field input[type="submit"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.radius-challenge-response-field.loading iframe {
|
||||
opacity: 0;
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
<div class="radius-challenge-response-field-container">
|
||||
<div id="radius-challenge-text" />
|
||||
<div class="password-field">
|
||||
<input type="{{passwordInputType}}" ng-model="model" ng-trim="false" autocorrect="off" autocapitalize="off"/>
|
||||
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
|
||||
</div>
|
||||
<input type="hidden" id="radius-challenge-state" />
|
||||
<input type="submit" />
|
||||
</div>
|
@@ -0,0 +1,14 @@
|
||||
{
|
||||
|
||||
"DATA_SOURCE_RADIUS" : {
|
||||
"NAME" : "RADIUS Backend"
|
||||
},
|
||||
|
||||
"LOGIN" : {
|
||||
"FIELD_HEADER_RADIUS_RESPONSE" : "",
|
||||
"INFO_RADIUS_RESPONSE_INCORRECT" : "RADIUS response incorrect.",
|
||||
"INFO_RADIUS_AUTH_REQUIRED" : "Please authenticate with RADIUS to continue.",
|
||||
"INFO_RADIUS_ADDL_REQUIRED" : "Additional credentials required."
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user