📄 radiuspacket.java
字号:
/**
* $Id: RadiusPacket.java,v 1.11 2006/02/20 23:44:49 wuttke Exp $
* Created on 07.04.2005
* Released under the LGPL
* @author Matthias Wuttke
* @version $Revision: 1.11 $
*/
package org.tinyradius.packet;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.tinyradius.attribute.RadiusAttribute;
import org.tinyradius.attribute.VendorSpecificAttribute;
import org.tinyradius.dictionary.AttributeType;
import org.tinyradius.dictionary.DefaultDictionary;
import org.tinyradius.dictionary.Dictionary;
import org.tinyradius.util.RadiusException;
import org.tinyradius.util.RadiusUtil;
/**
* This class represents a Radius packet. Subclasses provide convenience methods
* for special packet types.
*/
public class RadiusPacket {
/**
* Packet type codes.
*/
public static final int ACCESS_REQUEST = 1;
public static final int ACCESS_ACCEPT = 2;
public static final int ACCESS_REJECT = 3;
public static final int ACCOUNTING_REQUEST = 4;
public static final int ACCOUNTING_RESPONSE = 5;
public static final int ACCOUNTING_STATUS = 6;
public static final int PASSWORD_REQUEST = 7;
public static final int PASSWORD_ACCEPT = 8;
public static final int PASSWORD_REJECT = 9;
public static final int ACCOUNTING_MESSAGE = 10;
public static final int ACCESS_CHALLENGE = 11;
public static final int STATUS_SERVER = 12;
public static final int STATUS_CLIENT = 13;
public static final int DISCONNECT_REQUEST = 40; // RFC 2882
public static final int DISCONNECT_ACK = 41;
public static final int DISCONNECT_NAK = 42;
public static final int COA_REQUEST = 43;
public static final int COA_ACK = 44;
public static final int COA_NAK = 45;
public static final int STATUS_REQUEST = 46;
public static final int STATUS_ACCEPT = 47;
public static final int STATUS_REJECT = 48;
public static final int RESERVED = 255;
/**
* Maximum packet length.
*/
public static final int MAX_PACKET_LENGTH = 4096;
/**
* Packet header length.
*/
public static final int RADIUS_HEADER_LENGTH = 20;
/**
* Builds a Radius packet without attributes. Retrieves
* the next packet identifier.
* @param type packet type
*/
public RadiusPacket(final int type) {
this(type, getNextPacketIdentifier(), new ArrayList());
}
/**
* Builds a Radius packet with the given type and identifier
* and without attributes.
* @param type packet type
* @param identifier packet identifier
*/
public RadiusPacket(final int type, final int identifier) {
this(type, identifier, new ArrayList());
}
/**
* Builds a Radius packet with the given type, identifier and
* attributes.
* @param type packet type
* @param identifier packet identifier
* @param attributes list of RadiusAttribute objects
*/
public RadiusPacket(final int type, final int identifier, final List attributes) {
setPacketType(type);
setPacketIdentifier(identifier);
setAttributes(attributes);
}
/**
* Builds an empty Radius packet.
*/
public RadiusPacket() {
}
/**
* Returns the packet identifier for this Radius packet.
* @return packet identifier
*/
public int getPacketIdentifier() {
return packetIdentifier;
}
/**
* Sets the packet identifier for this Radius packet.
* @param identifier packet identifier, 0-255
*/
public void setPacketIdentifier(int identifier) {
if (identifier < 0 || identifier > 255)
throw new IllegalArgumentException("packet identifier out of bounds");
this.packetIdentifier = identifier;
}
/**
* Returns the type of this Radius packet.
* @return packet type
*/
public int getPacketType() {
return packetType;
}
/**
* Returns the type name of this Radius packet.
* @return name
*/
public String getPacketTypeName() {
switch (getPacketType()) {
case ACCESS_REQUEST: return "Access-Request";
case ACCESS_ACCEPT: return "Access-Accept";
case ACCESS_REJECT: return "Access-Reject";
case ACCOUNTING_REQUEST : return "Accounting-Request";
case ACCOUNTING_RESPONSE: return "Accounting-Response";
case ACCOUNTING_STATUS: return "Accounting-Status";
case PASSWORD_REQUEST: return "Password-Request";
case PASSWORD_ACCEPT: return "Password-Accept";
case PASSWORD_REJECT: return "Password-Reject";
case ACCOUNTING_MESSAGE: return "Accounting-Message";
case ACCESS_CHALLENGE: return "Access-Challenge";
case STATUS_SERVER: return "Status-Server";
case STATUS_CLIENT: return "Status-Client";
// RFC 2882
case DISCONNECT_REQUEST: return "Disconnect-Request";
case DISCONNECT_ACK: return "Disconnect-ACK";
case DISCONNECT_NAK: return "Disconnect-NAK";
case COA_REQUEST: return "CoA-Request";
case COA_ACK: return "CoA-ACK";
case COA_NAK: return "CoA-NAK";
case STATUS_REQUEST: return "Status-Request";
case STATUS_ACCEPT: return "Status-Accept";
case STATUS_REJECT: return "Status-Reject";
case RESERVED: return "Reserved";
default: return "Unknown (" + getPacketType() + ")";
}
}
/**
* Sets the type of this Radius packet.
* @param type packet type, 0-255
*/
public void setPacketType(int type) {
if (type < 1 || type > 255)
throw new IllegalArgumentException("packet type out of bounds");
this.packetType = type;
}
/**
* Sets the list of attributes for this Radius packet.
* @param attributes list of RadiusAttribute objects
*/
public void setAttributes(List attributes) {
if (attributes == null)
throw new NullPointerException("attributes list is null");
for (Iterator i = attributes.iterator(); i.hasNext();) {
Object element = i.next();
if (!(element instanceof RadiusAttribute))
throw new IllegalArgumentException("attribute not an instance of RadiusAttribute");
}
this.attributes = attributes;
}
/**
* Adds a Radius attribute to this packet. Can also be used
* to add Vendor-Specific sub-attributes. If a attribute with
* a vendor code != -1 is passed in, a VendorSpecificAttribute
* is created for the sub-attribute.
* @param attribute RadiusAttribute object
*/
public void addAttribute(RadiusAttribute attribute) {
if (attribute == null)
throw new NullPointerException("attribute is null");
attribute.setDictionary(getDictionary());
if (attribute.getVendorId() == -1)
this.attributes.add(attribute);
else {
VendorSpecificAttribute vsa = new VendorSpecificAttribute(attribute.getVendorId());
vsa.addSubAttribute(attribute);
this.attributes.add(vsa);
}
}
/**
* Adds a Radius attribute to this packet.
* Uses AttributeTypes to lookup the type code and converts
* the value.
* Can also be used to add sub-attributes.
* @param typeName name of the attribute, for example "NAS-Ip-Address"
* @param value value of the attribute, for example "127.0.0.1"
* @throws IllegalArgumentException if type name is unknown
*/
public void addAttribute(String typeName, String value) {
if (typeName == null || typeName.length() == 0)
throw new IllegalArgumentException("type name is empty");
if (value == null || value.length() == 0)
throw new IllegalArgumentException("value is empty");
AttributeType type = dictionary.getAttributeTypeByName(typeName);
if (type == null)
throw new IllegalArgumentException("unknown attribute type '" + typeName + "'");
RadiusAttribute attribute = RadiusAttribute.createRadiusAttribute(getDictionary(), type.getVendorId(), type.getTypeCode());
attribute.setAttributeValue(value);
addAttribute(attribute);
}
/**
* Removes the specified attribute from this packet.
* @param attribute RadiusAttribute to remove
*/
public void removeAttribute(RadiusAttribute attribute) {
if (attribute.getVendorId() == -1) {
if (!this.attributes.remove(attribute))
throw new IllegalArgumentException("no such attribute");
} else {
// remove Vendor-Specific sub-attribute
List vsas = getVendorAttributes(attribute.getVendorId());
for (Iterator i = vsas.iterator(); i.hasNext();) {
VendorSpecificAttribute vsa = (VendorSpecificAttribute)i.next();
List sas = vsa.getSubAttributes();
if (sas.contains(attribute)) {
vsa.removeSubAttribute(attribute);
if (sas.size() == 1)
// removed the last sub-attribute
// --> remove the whole Vendor-Specific attribute
removeAttribute(vsa);
}
}
}
}
/**
* Removes all attributes from this packet which have got
* the specified type.
* @param type attribute type to remove
*/
public void removeAttributes(int type) {
if (type < 1 || type > 255)
throw new IllegalArgumentException("attribute type out of bounds");
Iterator i = attributes.iterator();
while (i.hasNext()) {
RadiusAttribute attribute = (RadiusAttribute)i.next();
if (attribute.getAttributeType() == type)
i.remove();
}
}
/**
* Removes the last occurence of the attribute of the given
* type from the packet.
* @param type attribute type code
*/
public void removeLastAttribute(int type) {
List attrs = getAttributes(type);
if (attrs == null || attrs.size() == 0)
return;
RadiusAttribute lastAttribute =
(RadiusAttribute)attrs.get(attrs.size() - 1);
removeAttribute(lastAttribute);
}
/**
* Removes all sub-attributes of the given vendor and
* type.
* @param vendorId vendor ID
* @param typeCode attribute type code
*/
public void removeAttributes(int vendorId, int typeCode) {
if (vendorId == -1) {
removeAttributes(typeCode);
return;
}
List vsas = getVendorAttributes(vendorId);
for (Iterator i = vsas.iterator(); i.hasNext();) {
VendorSpecificAttribute vsa = (VendorSpecificAttribute)i.next();
List sas = vsa.getSubAttributes();
for (Iterator j = sas.iterator(); j.hasNext();) {
RadiusAttribute attr = (RadiusAttribute)j.next();
if (attr.getAttributeType() == typeCode &&
attr.getVendorId() == vendorId)
j.remove();
}
if (sas.size() == 0)
// removed the last sub-attribute
// --> remove the whole Vendor-Specific attribute
removeAttribute(vsa);
}
}
/**
* Returns all attributes of this packet of the given type.
* Returns an empty list if there are no such attributes.
* @param attributeType type of attributes to get
* @return list of RadiusAttribute objects, does not return null
*/
public List getAttributes(int attributeType) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -