RADIUS Server, RADIUS Client and TACACS+ Client APIs

Home

Search

Prices & Ordering

Support

RADIUS Server

RADIUS Client

TACACS+ Client

Other Java Software

Company

Contact

Privacy

Disclaimer


RADIUS Client Frequently Asked Questions

Linux: Why does the the server or client start and run very slowly?

On Linux the source for random data, /dev/random, is sometimes blocking for data. The server and client use a small amount of data to prime it's generator from time to time. Your program will block until some data is available.

Another generator, /dev/urandom, is available and does not run out of data. There are debates on its cryptographic strength.

There are two places to place the changes.

Command line:
-Djava.security.egd=file:/dev/urandom

Or

You can edit the file:
jre/lib/security/java.security

and change the property java.security.egd

In some versions of the JDK setting the property has no effect - see JDK bug 6202721). It seems to work for AXL Software products.

I get the exception 'java.lang.NoClassDefFoundError:' when I start the examples - what's wrong?

Your CLASSPATH is incorrect. The example classes are meant to run in the directory where they're found. The batch and shell files are set up to find the correct jar file (please look at the batch files to see how they're trying to access the jar file). If you have extracted everything correctly and set the CLASSPATH to include the extracted files it will all work. There are many Web resources to help you set up your CLASSPATH.

Why does the server say the password is bad, when it's obviously correct?

It is possible for the password to encoded properly (in any method but PAP) yet the shared secret is wrong. The server will deduce that the password is correct but the client will discover that the response packet's authenticator is incorrect (mis-signed). The client must treat the packet as an Access-Reject. Please see the section on Access-BadPacket.

What is a TLV attribute?

TLV stands for Tag / Length / Value. A RADIUS attribute consists of a tag field (one octet), a length field (one octet) and the value field. The length field include the tag and length field as well as the length of the data field. All attributes are TLV attributes.

Why does the RADIUS client displays the packet as an Access-Accept but the The RADIUSClient.authenticate() method returns 0?

See What does Access-BadPacket mean?

What does Access-BadPacket mean?

The authenticate() or accounting() methods return 0 (Access-BadPacket) if there are errors in the packet itself. Just receiving an Access-Accept from the server doesn't mean the packet is acceptable to the client. This can mean forgery of the reply but usually suggests misconfiguration. The RADIUSClient checks the packet for correctness and may issue an Access_BadPacket response in spite of the more favorable response attached to the packet.

The most common problem is mismatched secrets. The server response to a packet is to sign it with the shared secret. The client checks the signature using the secret. If the signatures don't match this is a bad packet.

The particular reason can be found using the RADIUSClient.getError() and getErrorString() methods.

Other errors include duplicate packet received, mismatched packet identifier numbers, or a bad Message-Authenticator attribute.

The corrupt attribute error may result from actual corrupt attributes or attributes with zero bytes of data. The latter problem can be generated by a server that's not following the RADIUS specifications. If your server is sending empty attributes and cannot be fixed use the RADIUSClient.allowEmptyAttributes(boolean enable) method to work around the problem.

How do I create attributes?

Use the class AttributeList. It has many ways to create attributes, merge attributes, and delete attributes.

How do I get the response attributes?

The RADIUSClient class makes these available as an AttributeList using the getAttributes() method. These are available after the authentication() or accounting() methods are called.

Why does the RADIUS server not respond?

There are many reasons for this. Please see the Trouble Shooting Guide.

How do I perform PAP authentication?

Use the RADIUSClient's authenticate(String name, String password, AttributeList alist) method.

How do I perform CHAP authentication?

There are two ways. The simplest is presented first:

// Create the required attributes
AttributeList aList = new AttributeList();
aList.addAttribute(Attribute.NAS_Identifier, Util.toUTF8("Pokey5")); aList.addAttribute(Attribute.User_Name,Util.toUTF8("Gumby"));

// Authenticate using CHAP
result = r.authenticate(password.getBytes(), aList);

Here's another way:

// Create the CHAP attributes and merge them into
// the required aList attributes.
rc.createCHAP(password, aList);
rc.authenticate(aList);

How do I perform a MSCHAP or MSCHAP2 authentication?

MSCHAP authentication attributes are created by the createMSCHAP(byte[] password, AttributeList list) method.

MSCHAP V2 authentication attributes are create by the createMSCHAP2(byte[] name, byte[] password, AttributeList list) method.

Both return an AttributeList which is merged with other Access-Request attributes.

// Create the required attributes
AttributeList aList = new AttributeList();
aList.addAttribute(Attribute.NAS_Identifier, Util.toUTF8("Pokey5")); aList.addAttribute(Attribute.User_Name,Util.toUTF8("Gumby")); // Create the MSCHAP attributes and merge them with the authentication // attributes.
r.createMSCHAP(password.getBytes(), aList); // Authenticate.
result = r.authenticate(aList);

MSCHAP V2 authentication is the same but uses the createMSCHAPV2() method.

Why don't the accent characters in the User-Name look correct?

This is usually because the User-Name is not being correctly encoded using the Util.toUTF8() method. the default encoding for the platform may not be UTF8 (when doing IO or using String().getBytes()). Similarly the data creating the name uses a Windows encoding that wasn't using Unicode or UFT8 encoding. You may have to decode the data differently before encoding it for the RADIUS client in UTF8.

Sometimes this can be seen in the length of the displayed User-Name attribute. The Attribute.toString() or AttributeList.toString() methods will display the User-Name. Accent characters should take up two octets, while Windows page code will only produce one character accent octets, usually in high ASCII values.

How do I create Vendor-Specific attributes (VSA)?

The VendorSpecific class builds VSA's. Vendor-Specific attributes allow a company to create extensions to the RADIUS attributes. Each vendor has a specific vendor number assigned to them.

First a little background: VSA's are attributes that contain sub-attributes. That is to say each VSA will contain one or more RADIUS style Tag/Length/Value (TLV) attributes. This allows the AttributeList class the create the sub-attributes. While it's possible to place a number of VSA sub-attributes in one Vendor-Specific attribute many RADIUS servers only examine the first sub-attribute. It's safer to use one VSA per attribute value.

Here's an example of creating an Ascend VSA:

// Create and populate the request attribute list.
AttributeList requestList = new AttributeList();
...
// Create the Ascend VSA.
VendorSpecific vs = new VendorSpecific(Ascend.VENDORID);
vs.addAttribute(Ascend.Ascend_Disconnect_Cause, 1);
Attribute vsAttr = vs.getAttribute();
// Merge the completed VSA with the request attributes.
requestList.addAttribute(vsAttr);

There are more examples of creating and extracting VSA's in the API documentation for the VendorSpecific class.

What about Cisco Vendor-Specific attributes?

Cisco's VSA's are a legacy from their proprietary TACACS protocol that offers services similar to RADIUS. Cisco VSA's use what are called Attribute Value Pairs (AVPairs). These are strings that represent the attribute name and it's value. An example might help illustrate this.

VendorSpecific vs = new VendorSpecific(Cisco.VENDORID);
vs.addAttribute(Cisco.323_credit_amount, "323_credit_amount=1");

Or this:

VendorSpecific vs = new VendorSpecific(Cisco.VENDORID);
vs.addAttribute(Cisco.avpair, "323_credit_amount=1");

Good descriptions of AVPairs are available at Cisco.

Is it possible to disconnect a authenticated user after they have been online for a certain period of time?

There are two time out attributes the server can send to the client. Idle-Timeout and Session_Timeout. Both use a four byte integer usually interpreted as seconds so twelve minutes won't be a problem. This is typically sent to a dial-up hardware NAS which automatically disconnects after either value is reached. You could do the same in a software client. For example, the Session_Timeout value is used in the AXL FTP server when it authenticates against a RADIUS server.

How can an authentication succeed (Access-Accept is returned) even though there was a secret mismatch between the server and client?

Only PAP authentications are sensitive to mismatched secrets.

Other forms of authentication like CHAP and MSCHAP don't use the shared secret to perform the authentication. The server will certainly find the encoded password acceptable. Although the server may send back an Access-Accept the client is responsible for checking the signed authenticator and rejecting the message if the signature isn't correct.

For example, a CHAP client uses an MD5 hash of a random challenge and the plain text password to produce a hash of the password. The server checks the MD5 of the password and the challenge and compares the two results. If they're the same the password is correct.

The server resigns the packet using the original authenticator, the secret, and the entire packet's contents. This is checked by the client and if there's a mismatch the client MUST reject the packet even if it's an Access-Accept.

The presence of a Message-Authenticator (MA) attribute in the client fixes the problem. The MA signs the authentication packet. The server checks the signature which includes the shared secret. The response packet also is provided with an MA and the client must check the response MA for correctness. The AXL RADIUS Client can include an MA by creating an Attribute.Message_Authenticator with any contents (even empty). The contents are discarded by the client and replaced with the signature.

Why do I get nothing but Access-Challenge responses from my Access-Requests?

You must pass all State attributes from the Access-Challenge to the new Access-Request packet.

The RADIUS protocol is a 'stateless' protocol. Each Access-Request acts like a new request each time. The server tracks information that ties challenges to subsequent requests by using the State attribute's value. This is opaque information and must be returned without modification to the server. Although the standards say only on State attribute is permitted some implementations include more State attributes. You can extract all State attributes and merge them with your new request as follows.

RADIUSClient rc = new RADIUSClient(...)
// Authenticate somehow
...
// Get the response attributes.
AttributeList response = rc.getAttributes();
// Extract all State attributes.
AttributeList state = response.getAttributeList(Attribute.State);
// Do something with Access-Challenge.
AttributeList request = new AttributeList();
...
// Merge the state attributes with the new request attributes.
request.mergeAttributes(state);
// Send the new authentication request.
...

What causes to server to say the packet is malformed?

If the RADIUS server is compliant with the basic packet construction the AXL RADIUS Client will construct correct packets. However it's possible to create attributes with a tag value of 0 or with an empty data value. Both of these conditions are forbidden by servers. There is no such attribute tag as 0 (valid values are 1 to 255). Attributes must always have data with a length greater than 1 byte. Attribute values with no value must not be sent.

 

TOP