Ruby Radius Dictionary

Hie,

Im trying to communicate with radius server using example file from
ruby-radius-0.9.9 and encountered with this error

“/usr/lib/ruby/site_ruby/1.8/radius/dictionary.rb:294:in
vsattr_numtype': undefined method[]’ for nil:NilClass (NoMethodError)
from /usr/lib/ruby/site_ruby/1.8/radius/packet.rb:145:in
`unpack’
from radiusclient.rb:50”

Can anyone help.

Thanks,
Aby Azid

hie thanks for the reply,

may i know which dictionary you are using?

thanks,

Aby Azid

I’m still new with radius protocol. Does the dictionary in radius client
have to be the same as dictionary in Radius Server?. I checked packet.rb
and found comment that the coding is referring to RFC 2138. The
dictionary in the Radius server is following the RFC 2865. Could this be
the problem?

Thanks

On Oct 26, 12:25 am, Aby azid Abu bakar [email protected] wrote:

Can anyone help.

Thanks,
Aby Azid

Posted viahttp://www.ruby-forum.com/.

I’m using that library, I just ran a test and that file worked fine
for me.

I am using the auth.rb file to simply check for authorization. It
works well for me.

First, I had to change this line in auth.rb

attr_reader :@packet

to
attr_reader :packet

Here is the class I made for checking authentication.

class RadiusUtils

def initialize(hostname,secret)
@hostname, @secret = hostname, secret
@dictionary = “/some/path/to/dictionary”
end

def authenticate(username,password,nasip=nil,timeout=nil)
nasip = nasip || “127.0.0.1”
timeout = timeout || 5
rad = Radius::Auth.new(@dictionary,@hostname,nasip,timeout)
rad.check_passwd(username,password,@secret)
end

end

radius = RadiusUtils.new(“x.x.x.x”,“secret”)
radius.authenticate(“username”,“password”)

If you are only trying to authenticate to radius, perhaps that will
work for you.

checked packet.rb
and found comment that the coding is referring to RFC 2138. The
dictionary in the Radius server is following the RFC 2865.
Could this be
the problem?

Thanks


Posted via http://www.ruby-forum.com/.

This is how dictionaries work:

A RADIUS packet is made up of a header and a payload. The header has the
following structure:
[ Code - 1 Octet ][ Identifier - 1 Octet ][ Length - 2 Octets ][
Authenticator - 16 Octets ]

Where the code is one of 1 - Access-Request, 2 - Access-Accept, 3 -
Access-Reject, 4 - Accounting-Request, 5 - Accounting-Reponse, 11
Access-Challenge and distinguishes the type of RADIUS packet.
The Identifier is used to perform threading and link initial requests
and
subsequest replies.
The Length is the sum of all fields in the packet (much be between 20
and
4096 octets. According to spec, longer messages get trimmed at 4096,
shorter
ones are thrown away.
The Authenticator region is used differently depending on whether the
type
is a request or a responose and contains either completely random data,
or
calculated using MD5 hashes on the value of the code, identifier, length
and
request-authenticator random payload, followed by packet payload and
shared
secret.

The header is followed by the payload, where each attribute and value
are
transmitted as such:
[ Number - 1 Octet ][ Length - > 3 ][ Value - dependent on attribute
number
]

The Number is between 1 and 255 and is what gets translated by the
dictionary. For example, Attribute-Number 39 is translated to
“Framed-AppleTalk-Zone” in the standard dictionaries, so that you can
refer
to it as such instead of using the number.
The Length is the length of the attribute-value pair, and must be larger
than 3 (1 octet for the Number, 1 octet for the Length, 1 octet for the
value)
The Value is dependent on the attribute name in that the dictionary also
specifies the type of value. An abbribute number is mapped to one of:
Integer (INT) (4 Octets, 32-bit unsigned)
Enumerated (ENUM) (4 Octets, 32-bit unsigned)
IP Address (IPADDR) (4 Octets, 32 bit)
Character String (STRING) (1-253 Octets, variable)
Date (DATE) (4 Octets, 32-bit unsigned)
Binary (BINARY) (1 bit)

So a dictionary entry such as
1 User-Name STRING

Signifies that Attribute Number 1 can be referred to as ‘User-Name’ and
carries as a value a string between 1 and 253 octets in length.

Since that means there can only be 255 higher order RADIUS attributes,
there
is also the special case of vvendor-specific attributes (VSAs). They
have
the Attribute-Number 26 and a payload consisting of:
[ ID - 4 octets ][ Number - 1 Octet ][ Length > 7 ][ Value - dependent
on
attribute number ]

Which essentially behaves much like an attribute/value pair wrapped in
an
attribute/value pair, adding a field for the Vendor ID. The vendor ID is
coded using NMPECs in network byte ordering and is unique to the vendor,
and
again described by an entry in a dictionary.

So therefore, client and server strictly speaking do not need to
implement
identical dictionaries, in that they can be free to change values in the
second column of format (“Attribute-Number”, “Human-Readable String”,
“Value
Kind”) so that the client can refer to Attribute-Number 1 as ‘User-Name’
while the server refers to it as ‘Username’. They do, however, usually
need
to have dictionary entries to be able to refer to the fields in some
way. If
your server is sending packets with AV-pairs that your client does not
have
dictionaries for, you’d have to go to a very low level to interpret them
on
byte level instead of being able to use the Ruby interface, which deals
with
the pairs once they’re translated from the dictionary.

Hope that helps,

Felix

On Oct 26, 9:49 pm, Aby azid Abu bakar [email protected] wrote:

hie thanks for the reply,

may i know which dictionary you are using?

thanks,

Aby Azid

Posted viahttp://www.ruby-forum.com/.

I’m using the one that comes with the program, but I just have the
basics returning from my radius server, so it works fine for me.

On Oct 26, 10:30 pm, Aby azid Abu bakar [email protected] wrote:

I’m still new with radius protocol. Does the dictionary in radius client
have to be the same as dictionary in Radius Server?. I checked packet.rb
and found comment that the coding is referring to RFC 2138. The
dictionary in the Radius server is following the RFC 2865. Could this be
the problem?

Thanks


Posted viahttp://www.ruby-forum.com/.

The dictionary is there to map the code in the packet to a friendly
name. So, it doesn’t really need to be the same, unless you are using
it to convert that code to text and then comparing the two. If you
stick with simply the code, then you are OK. But, most people use the
dictionaries.

I’d read RFC2865. Radius actually has some of the easier to read
RFC’s, that really explain the protocol well.

Here is another thing you could try. Download and install FreeRadius
(www.freeradius.org). That software comes with a bunch of
dictionaries. You’ll notice in them, they use $INCLUDE to include
other dictionaries. That isn’t going to work here, but you should be
able to copy/paste or cat a few of them together.

It also comes with a command line program called radclient that you
can use to send radius packets to the radius server and it will give
you a full print out of the return packet, including all the
attributes. I would use that to inspect the packet and see what
attributes are coming back to you. Then find that attribute in one of
the many dictionaries, then just copy that whole dictionary over to
your ruby program.

Of course, you could always use tcpdump and take a look at the packet
with wireshark (ethereal). I believe that also uses the freeradius
dictionaries.

Hope that is helpful.