net.jradius.client.RadiusClientTransport Maven / Gradle / Ivy
The newest version!
/**
* JRadius - A RADIUS Server Java Adapter
* Copyright (c) 2009 Coova Technologies, LLC
*
* 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.client;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import net.jradius.exception.RadiusException;
import net.jradius.exception.RadiusSecurityException;
import net.jradius.exception.TimeoutException;
import net.jradius.log.RadiusLog;
import net.jradius.packet.AccessRequest;
import net.jradius.packet.RadiusPacket;
import net.jradius.packet.RadiusRequest;
import net.jradius.packet.RadiusResponse;
import net.jradius.packet.attribute.AttributeDictionary;
import net.jradius.util.MessageAuthenticator;
public abstract class RadiusClientTransport
{
protected InetAddress localInetAddress;
protected InetAddress remoteInetAddress;
protected String sharedSecret;
protected int authPort;
protected int acctPort;
public static final int defaultTimeout = 60;
protected int socketTimeout = defaultTimeout * 1000;
protected RadiusClient radiusClient;
protected abstract void send(RadiusRequest req, int attempt) throws Exception;
protected abstract RadiusResponse receive(RadiusRequest req) throws Exception;
public abstract void close();
protected TransportStatusListener statusListener;
/**
* Send and receive RadiusPackets
* @param p The RadiusPacket being sent
* @param a The Internet Address sending to
* @param port The port sending to
* @param retries Number of times to retry (without response)
* @return Returns the returned RadiusPacket
*/
public RadiusResponse sendReceive(RadiusRequest p, int retries) throws RadiusException
{
RadiusResponse r = null;
int tries = 0;
if (p instanceof AccessRequest)
{
try
{
generateMessageAuthenticator(p);
}
catch(Exception e)
{
throw new RadiusException(e);
}
}
if (retries < 0) retries = 0; retries++; // do at least one
while (tries < retries)
{
try
{
send(p, tries);
r = receive(p);
break;
}
catch (SocketTimeoutException e)
{
RadiusLog.warn("Unable to send or receive radius packet", e);
}
catch (IOException e)
{
RadiusLog.warn("Unable to send or receive radius packet", e);
}
catch (Exception e)
{
e.printStackTrace();
}
tries++;
}
if (tries == retries)
{
throw new TimeoutException("Timeout: No Response from RADIUS Server");
}
if (!verifyAuthenticator(p, r))
{
throw new RadiusSecurityException("Invalid RADIUS Authenticator");
}
if (!verifyMessageAuthenticator(p, r, (r.findAttribute(AttributeDictionary.EAP_MESSAGE) != null)))
{
throw new RadiusSecurityException("Invalid RADIUS Message-Authenticator");
}
return r;
}
/**
* Add the Message-Authentivator attribute to the given RadiusPacket
* @param request The RadiusPacket
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
protected void generateMessageAuthenticator(RadiusPacket request) throws IOException, InvalidKeyException, NoSuchAlgorithmException
{
MessageAuthenticator.generateRequestMessageAuthenticator(request, sharedSecret);
}
/**
* Verify the Message-Authenticator based on RFC 2869
* @param request The RADIUS request send
* @param reply The RADIUS reply received
* @param required Whether or not the Message-Authenticator is required (as for EAP)
* @return Returns true if there is no Message-Authenticator or if it present and correct
*/
public boolean verifyMessageAuthenticator(RadiusRequest request, RadiusResponse reply, boolean required)
{
return verifyMessageAuthenticator(request, reply, sharedSecret, required);
}
public static boolean verifyMessageAuthenticator(RadiusRequest request, RadiusResponse reply, String sharedSecret, boolean required)
{
return verifyMessageAuthenticator(request.getAuthenticator(), reply, sharedSecret, required);
}
public static boolean verifyMessageAuthenticator(byte[] requestAuth, RadiusResponse reply, String sharedSecret, boolean required)
{
try
{
Boolean verified = MessageAuthenticator.verifyReply(requestAuth, reply, sharedSecret);
if (verified == null && required) return false;
if (verified == null) return true;
return verified.booleanValue();
}
catch(Exception e)
{
return false;
}
}
/**
* Verify the RADIUS Authenticator
* @param request The RADIUS request send
* @param reply The RADIUS reply received
* @return Returns true if there is no Authenticator is correct
*/
public boolean verifyAuthenticator(RadiusRequest request, RadiusResponse reply)
{
return reply.verifyAuthenticator(request.getAuthenticator(), getSharedSecret());
}
public static boolean verifyAuthenticator(RadiusRequest request, RadiusResponse reply, String sharedSecret)
{
return reply.verifyAuthenticator(request.getAuthenticator(), sharedSecret);
}
public static boolean verifyAuthenticator(byte[] requestAuth, RadiusResponse reply, String sharedSecret)
{
return reply.verifyAuthenticator(requestAuth, sharedSecret);
}
public InetAddress getRemoteInetAddress() {
return remoteInetAddress;
}
public void setRemoteInetAddress(InetAddress remoteInetAddress) {
this.remoteInetAddress = remoteInetAddress;
}
public InetAddress getLocalInetAddress() {
return localInetAddress;
}
public void setLocalInetAddress(InetAddress localInetAddress) {
this.localInetAddress = localInetAddress;
}
public String getSharedSecret() {
return sharedSecret;
}
public void setSharedSecret(String sharedSecret) {
this.sharedSecret = sharedSecret;
}
public int getAuthPort() {
return authPort;
}
public void setAuthPort(int authPort) {
this.authPort = authPort;
}
public int getAcctPort() {
return acctPort;
}
public void setAcctPort(int acctPort) {
this.acctPort = acctPort;
}
/**
* @return Returns the socket timeout (in seconds)
*/
public int getSocketTimeout()
{
return socketTimeout / 1000;
}
/**
* @param socketTimeout The socket timeout (in seconds)
*/
public void setSocketTimeout(int socketTimeout)
{
this.socketTimeout = socketTimeout * 1000;
}
public RadiusClient getRadiusClient() {
return radiusClient;
}
public void setRadiusClient(RadiusClient radiusClient) {
this.radiusClient = radiusClient;
}
public void setStatusListener(TransportStatusListener statusListener) {
this.statusListener = statusListener;
}
}