radiusserver.java
来自「TinyRadius is a simple, small and fast J」· Java 代码 · 共 545 行 · 第 1/2 页
JAVA
545 行
/**
* $Id: RadiusServer.java,v 1.10 2007/03/27 14:24:47 wuttke Exp $
* Created on 09.04.2005
* @author Matthias Wuttke
* @version $Revision: 1.10 $
*/
package org.tinyradius.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tinyradius.attribute.RadiusAttribute;
import org.tinyradius.packet.AccessRequest;
import org.tinyradius.packet.AccountingRequest;
import org.tinyradius.packet.RadiusPacket;
/**
* Implements a simple Radius server. This class must be subclassed to
* provide an implementation for getSharedSecret() and getUserPassword().
* If the server supports accounting, it must override
* accountingRequestReceived().
*/
public abstract class RadiusServer {
/**
* Returns the shared secret used to communicate with the client with the
* passed IP address or null if the client is not allowed at this server.
* @param client IP address and port number of client
* @return shared secret or null
*/
public abstract String getSharedSecret(InetSocketAddress client);
/**
* Returns the password of the passed user. Either this
* method or accessRequestReceived() should be overriden.
* @param userName user name
* @return plain-text password or null if user unknown
*/
public abstract String getUserPassword(String userName);
/**
* Constructs an answer for an Access-Request packet. Either this
* method or isUserAuthenticated should be overriden.
* @param accessRequest Radius request packet
* @param client address of Radius client
* @return response packet or null if no packet shall be sent
* @exception RadiusException malformed request packet; if this
* exception is thrown, no answer will be sent
*/
public RadiusPacket accessRequestReceived(AccessRequest accessRequest, InetSocketAddress client)
throws RadiusException {
String plaintext = getUserPassword(accessRequest.getUserName());
int type = RadiusPacket.ACCESS_REJECT;
if (plaintext != null && accessRequest.verifyPassword(plaintext))
type = RadiusPacket.ACCESS_ACCEPT;
RadiusPacket answer = new RadiusPacket(type, accessRequest.getPacketIdentifier());
copyProxyState(accessRequest, answer);
return answer;
}
/**
* Constructs an answer for an Accounting-Request packet. This method
* should be overriden if accounting is supported.
* @param accountingRequest Radius request packet
* @param client address of Radius client
* @return response packet or null if no packet shall be sent
* @exception RadiusException malformed request packet; if this
* exception is thrown, no answer will be sent
*/
public RadiusPacket accountingRequestReceived(AccountingRequest accountingRequest, InetSocketAddress client)
throws RadiusException {
RadiusPacket answer = new RadiusPacket(RadiusPacket.ACCOUNTING_RESPONSE, accountingRequest.getPacketIdentifier());
copyProxyState(accountingRequest, answer);
return answer;
}
/**
* Starts the Radius server.
* @param listenAuth open auth port?
* @param listenAcct open acct port?
*/
public void start(boolean listenAuth, boolean listenAcct) {
if (listenAuth) {
new Thread() {
public void run() {
setName("Radius Auth Listener");
try {
logger.info("starting RadiusAuthListener on port " + getAuthPort());
listenAuth();
logger.info("RadiusAuthListener is being terminated");
} catch(Exception e) {
e.printStackTrace();
logger.fatal("auth thread stopped by exception", e);
} finally {
authSocket.close();
logger.debug("auth socket closed");
}
}
}.start();
}
if (listenAcct) {
new Thread() {
public void run() {
setName("Radius Acct Listener");
try {
logger.info("starting RadiusAcctListener on port " + getAcctPort());
listenAcct();
logger.info("RadiusAcctListener is being terminated");
} catch(Exception e) {
e.printStackTrace();
logger.fatal("acct thread stopped by exception", e);
} finally {
acctSocket.close();
logger.debug("acct socket closed");
}
}
}.start();
}
}
/**
* Stops the server and closes the sockets.
*/
public void stop() {
logger.info("stopping Radius server");
closing = true;
if (authSocket != null)
authSocket.close();
if (acctSocket != null)
acctSocket.close();
}
/**
* Returns the auth port the server will listen on.
* @return auth port
*/
public int getAuthPort() {
return authPort;
}
/**
* Sets the auth port the server will listen on.
* @param authPort auth port, 1-65535
*/
public void setAuthPort(int authPort) {
if (authPort < 1 || authPort > 65535)
throw new IllegalArgumentException("bad port number");
this.authPort = authPort;
this.authSocket = null;
}
/**
* Returns the socket timeout (ms).
* @return socket timeout
*/
public int getSocketTimeout() {
return socketTimeout;
}
/**
* Sets the socket timeout.
* @param socketTimeout socket timeout, >0 ms
* @throws SocketException
*/
public void setSocketTimeout(int socketTimeout)
throws SocketException {
if (socketTimeout < 1)
throw new IllegalArgumentException("socket tiemout must be positive");
this.socketTimeout = socketTimeout;
if (authSocket != null)
authSocket.setSoTimeout(socketTimeout);
if (acctSocket != null)
acctSocket.setSoTimeout(socketTimeout);
}
/**
* Sets the acct port the server will listen on.
* @param acctPort acct port 1-65535
*/
public void setAcctPort(int acctPort) {
if (acctPort < 1 || acctPort > 65535)
throw new IllegalArgumentException("bad port number");
this.acctPort = acctPort;
this.acctSocket = null;
}
/**
* Returns the acct port the server will listen on.
* @return acct port
*/
public int getAcctPort() {
return acctPort;
}
/**
* Returns the duplicate interval in ms.
* A packet is discarded as a duplicate if in the duplicate interval
* there was another packet with the same identifier originating from the
* same address.
* @return duplicate interval (ms)
*/
public long getDuplicateInterval() {
return duplicateInterval;
}
/**
* Sets the duplicate interval in ms.
* A packet is discarded as a duplicate if in the duplicate interval
* there was another packet with the same identifier originating from the
* same address.
* @param duplicateInterval duplicate interval (ms), >0
*/
public void setDuplicateInterval(long duplicateInterval) {
if (duplicateInterval <= 0)
throw new IllegalArgumentException("duplicate interval must be positive");
this.duplicateInterval = duplicateInterval;
}
/**
* Returns the IP address the server listens on.
* Returns null if listening on the wildcard address.
* @return listen address or null
*/
public InetAddress getListenAddress() {
return listenAddress;
}
/**
* Sets the address the server listens on.
* Must be called before start().
* Defaults to null, meaning listen on every
* local address (wildcard address).
* @param listenAddress listen address or null
*/
public void setListenAddress(InetAddress listenAddress) {
this.listenAddress = listenAddress;
}
/**
* Copies all Proxy-State attributes from the request
* packet to the response packet.
* @param request request packet
* @param answer response packet
*/
protected void copyProxyState(RadiusPacket request, RadiusPacket answer) {
List proxyStateAttrs = request.getAttributes(33);
for (Iterator i = proxyStateAttrs.iterator(); i.hasNext();) {
RadiusAttribute proxyStateAttr = (RadiusAttribute)i.next();
answer.addAttribute(proxyStateAttr);
}
}
/**
* Listens on the auth port (blocks the current thread).
* Returns when stop() is called.
* @throws SocketException
* @throws InterruptedException
*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?