net.jradius.security.auth.JRadiusModule Maven / Gradle / Ivy
The newest version!
/**
* JRadius - A RADIUS Server Java Adapter
* Copyright (C) 2004-2005 PicoPoint, B.V.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.jradius.security.auth;
import java.io.IOException;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import net.jradius.client.RadiusClient;
import net.jradius.log.RadiusLog;
import net.jradius.packet.AccessAccept;
import net.jradius.packet.AccessRequest;
import net.jradius.packet.RadiusResponse;
import net.jradius.packet.attribute.AttributeFactory;
import net.jradius.packet.attribute.AttributeList;
import net.jradius.security.JRadiusPrincipal;
/**
* JRadius JAAS LoginModule.
* @author David Bird
*/
public class JRadiusModule implements LoginModule
{
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
private String userName;
private JRadiusPrincipal principal;
private RadiusClient radiusClient;
private AttributeList authAttributes;
private AttributeList acctAttributes;
private boolean debug = false;
private boolean authenticated = false;
private boolean committed = false;
private int retries = 3;
private int attempts = 0;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options)
{
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
debug = "true".equalsIgnoreCase((String)options.get("debug"));
}
public boolean commit() throws LoginException
{
if (!authenticated) return false;
principal = new JRadiusPrincipal(userName);
if (!subject.getPrincipals().contains(principal))
{
subject.getPrincipals().add(principal);
}
attempts = 0;
committed = true;
return true;
}
public boolean login() throws LoginException
{
if (callbackHandler == null)
{
throw new LoginException("No CallbackHandler for this JRadius LoginModule.");
}
if (radiusClient == null)
{
try {
radiusClient = new RadiusClient();
} catch (Exception e) {
throw new LoginException();
}
}
NameCallback nameCallback = new NameCallback("User Name: ");
PasswordCallback passwordCallback = new PasswordCallback("Password: ", true);
JRadiusCallback radiusCallback = new JRadiusCallback(radiusClient);
Callback[] callbacks = new Callback[3];
callbacks[0] = nameCallback;
callbacks[1] = passwordCallback;
callbacks[2] = radiusCallback;
try
{
callbackHandler.handle(callbacks);
}
catch (IOException ioex)
{
throw new LoginException(ioex.getMessage());
}
catch (UnsupportedCallbackException uscbex)
{
StringBuffer sb = new StringBuffer("Error: Callback ");
sb.append(uscbex.getCallback().toString());
sb.append(" not supported.");
throw new LoginException(sb.toString());
}
userName = nameCallback.getName();
String password = new String(passwordCallback.getPassword());
try
{
AccessRequest request = new AccessRequest(radiusClient, radiusCallback.getAuthAttributes());
request.addAttribute(AttributeFactory.newAttribute("User-Name", userName, "="));
request.addAttribute(AttributeFactory.newAttribute("User-Password", password, "="));
if (debug)
{
RadiusLog.debug("Sending:\n" + request.toString());
}
RadiusResponse reply = radiusClient.authenticate(request, radiusCallback.getRadiusAuthenticator(), retries);
if (reply == null) throw new LoginException("no reply from remote RADIUS server");
if (debug)
{
RadiusLog.debug("Received:\n" + reply.toString());
}
if (!(reply instanceof AccessAccept)) throw new CredentialExpiredException("authentication failed");
}
catch (Exception ioex)
{
throw new LoginException(ioex.getMessage());
}
authenticated = true;
return true;
}
public boolean logout() throws LoginException
{
subject.getPrincipals().remove(principal);
authenticated = false;
committed = false;
userName = null;
principal = null;
attempts = 0;
return true;
}
public boolean abort() throws LoginException
{
if (!authenticated) return false;
if (authenticated && !committed)
{
authenticated = false;
attempts = 0;
}
else
{
logout();
}
return true;
}
}