diff --git a/CHANGES b/CHANGES index 17867751..f76a14d5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ TinyRadius Change Log +1.1.2: +Support of 2 byte attribute tag length + Plans for 1.0: Asynchronous Radius client (see TODO) 0.9.9: diff --git a/pom.xml b/pom.xml index 302f9b86..ffc34c45 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.tinyradius tinyradius - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT jar TinyRadius Java Radius Library diff --git a/src/main/java/org/tinyradius/attribute/RadiusAttribute.java b/src/main/java/org/tinyradius/attribute/RadiusAttribute.java index 2059b79a..e5108802 100644 --- a/src/main/java/org/tinyradius/attribute/RadiusAttribute.java +++ b/src/main/java/org/tinyradius/attribute/RadiusAttribute.java @@ -77,8 +77,9 @@ public int getAttributeType() { * type code, 0-255 */ public void setAttributeType(int attributeType) { - if (attributeType < 0 || attributeType > 255) - throw new IllegalArgumentException("attribute type invalid: " + attributeType); + // Vendor specific attribute has values > 255 and < 1 + /*if (attributeType < 0 || attributeType > 255) + throw new IllegalArgumentException("attribute type invalid: " + attributeType);*/ this.attributeType = attributeType; } @@ -165,6 +166,28 @@ public byte[] writeAttribute() { return attr; } + /** + * Returns this attribute encoded as a byte array. + * + * @return attribute + */ + public byte[] write2ByteAttribute() { + if (getAttributeType() == -1) + throw new IllegalArgumentException("attribute type not set"); + if (attributeData == null) + throw new NullPointerException("attribute data not set"); + + byte[] attr = new byte[4 + attributeData.length]; + attr[0] = (byte) (getAttributeType() >> 8 & 0x0ff); + attr[1] = (byte) (getAttributeType() & 0x0ff); + int data_length = 2 + attributeData.length; + attr[2] = (byte) (data_length >> 8 & 0x0ff); + attr[3] = (byte) (data_length & 0x0ff); + System.arraycopy(attributeData, 0, attr, 4, attributeData.length); + return attr; + } + + /** * Reads in this attribute from the passed byte array. * @@ -181,6 +204,28 @@ public void readAttribute(byte[] data, int offset, int length) throws RadiusExce setAttributeData(attrData); } + /** + * Reads in this attribute from the passed byte array. + * + * @param data + */ + public void read2ByteAttribute(byte[] data, int offset, int length) throws RadiusException { + if (length < 2) + throw new RadiusException("attribute length too small: " + length); + int attrType = (usByteToInt(data[offset]) << 8 | usByteToInt(data[offset + 1])); + int attrLen = (usByteToInt(data[offset + 2]) << 8 | usByteToInt(data[offset + 3])); + byte[] attrData = new byte[attrLen - 4]; + System.arraycopy(data, offset + 4, attrData, 0, attrLen - 4); + setAttributeType(attrType); + setAttributeData(attrData); + } + + private static int usByteToInt(byte b) { + return b & 0xFF; + } + + + /** * String representation for debugging purposes. * diff --git a/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java b/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java index 5adf0767..e9cfed81 100644 --- a/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java +++ b/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java @@ -149,8 +149,10 @@ public List getSubAttributes() { * @return list of RadiusAttribute objects, does not return null */ public List getSubAttributes(int attributeType) { + // Vendor specific attribute has values > 255 and < 1 + /* if (attributeType < 1 || attributeType > 255) - throw new IllegalArgumentException("sub-attribute type out of bounds"); + throw new IllegalArgumentException("sub-attribute type out of bounds");*/ LinkedList result = new LinkedList(); for (Iterator i = subAttributes.iterator(); i.hasNext();) { @@ -243,7 +245,10 @@ public byte[] writeAttribute() { try { for (Iterator i = subAttributes.iterator(); i.hasNext();) { RadiusAttribute a = (RadiusAttribute) i.next(); - bos.write(a.writeAttribute()); + if(getChildVendorId() == 8164) + bos.write(a.write2ByteAttribute()); + else + bos.write(a.writeAttribute()); } } catch (IOException ioe) { @@ -296,22 +301,43 @@ public void readAttribute(byte[] data, int offset, int length) throws RadiusExce int count = 0; while (pos < vsaLen) { if (pos + 1 >= vsaLen) - throw new RadiusException("Vendor-Specific attribute malformed"); + throw new RadiusException("Vendor-Specific attribute malformed [pos +1 >= vsaLen]"); // int vsaSubType = data[(offset + 6) + pos] & 0x0ff; - int vsaSubLen = data[(offset + 6) + pos + 1] & 0x0ff; + int vsaSubLen = 0; + if(vendorId ==8164) //Starent NW 2 byte tag & length + { + vsaSubLen = (unsignedByteToInt(data[(offset + 6) + pos + 2]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 3])); + } + else + vsaSubLen = data[(offset + 6) + pos + 1] & 0x0ff; + if(vsaSubLen < 2) + throw new RadiusException("Vendor-Specific attribute malformed: attr length: " + vsaSubLen); pos += vsaSubLen; count++; } if (pos != vsaLen) - throw new RadiusException("Vendor-Specific attribute malformed"); + throw new RadiusException("Vendor-Specific attribute malformed [pos != vsaLen]"); subAttributes = new ArrayList(count); pos = 0; while (pos < vsaLen) { - int subtype = data[(offset + 6) + pos] & 0x0ff; - int sublength = data[(offset + 6) + pos + 1] & 0x0ff; + int subtype = 0; + int sublength = 0; + if(vendorId ==8164) //Starent NW 2 byte tag & length + { + subtype = (unsignedByteToInt(data[(offset + 6) + pos]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 1])); + sublength = (unsignedByteToInt(data[(offset + 6) + pos + 2]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 3])); + } + else + { + subtype = data[(offset + 6) + pos] & 0x0ff; + sublength = data[(offset + 6) + pos + 1] & 0x0ff; + } RadiusAttribute a = createRadiusAttribute(getDictionary(), vendorId, subtype); - a.readAttribute(data, (offset + 6) + pos, sublength); + if(vendorId ==8164) //Starent NW 2 byte tag & length + a.read2ByteAttribute(data, (offset + 6) + pos, sublength); + else + a.readAttribute(data, (offset + 6) + pos, sublength); subAttributes.add(a); pos += sublength; } diff --git a/src/main/java/org/tinyradius/dictionary/AttributeType.java b/src/main/java/org/tinyradius/dictionary/AttributeType.java index 5b62600e..cc549736 100644 --- a/src/main/java/org/tinyradius/dictionary/AttributeType.java +++ b/src/main/java/org/tinyradius/dictionary/AttributeType.java @@ -1,5 +1,10 @@ /** * $Id: AttributeType.java,v 1.3 2005/09/06 18:06:33 wuttke Exp $ + * Copyright by teuto.net Netzdienste GmbH 2005. All rights reserved. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. Commercial licenses also available. + * See the accompanying file LICENSE for details. * * @author Matthias Wuttke * @version $Revision: 1.3 $ @@ -68,8 +73,9 @@ public int getTypeCode() { * type code, 1-255 */ public void setTypeCode(int code) { - if (code < 1 || code > 255) - throw new IllegalArgumentException("code out of bounds"); + // Vendor specific attribute has values > 255 and < 1 + /*if (code < 1 || code > 255) + throw new IllegalArgumentException("code out of bounds");*/ this.typeCode = code; } diff --git a/src/main/java/org/tinyradius/packet/RadiusPacket.java b/src/main/java/org/tinyradius/packet/RadiusPacket.java index e8f34af1..6d6135cf 100644 --- a/src/main/java/org/tinyradius/packet/RadiusPacket.java +++ b/src/main/java/org/tinyradius/packet/RadiusPacket.java @@ -215,8 +215,10 @@ public String getPacketTypeName() { * packet type, 0-255 */ public void setPacketType(int type) { + // Vendor specific attribute has values > 255 and < 1 + /* if (type < 1 || type > 255) - throw new IllegalArgumentException("packet type out of bounds"); + throw new IllegalArgumentException("packet type out of bounds");*/ this.packetType = type; } @@ -325,8 +327,10 @@ public void removeAttribute(RadiusAttribute attribute) { * attribute type to remove */ public void removeAttributes(int type) { + // Vendor specific attribute has values > 255 and < 1 + /* if (type < 1 || type > 255) - throw new IllegalArgumentException("attribute type out of bounds"); + throw new IllegalArgumentException("attribute type out of bounds");*/ Iterator i = attributes.iterator(); while (i.hasNext()) { @@ -393,8 +397,10 @@ public void removeAttributes(int vendorId, int typeCode) { * @return list of RadiusAttribute objects, does not return null */ public List getAttributes(int attributeType) { + // Vendor specific attribute has values > 255 and < 1 + /* if (attributeType < 1 || attributeType > 255) - throw new IllegalArgumentException("attribute type out of bounds"); + throw new IllegalArgumentException("attribute type out of bounds");*/ LinkedList result = new LinkedList(); for (Iterator i = attributes.iterator(); i.hasNext();) {