ruby-radius 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +37 -0
- data/dictionary +289 -0
- data/examples/radiusclient.rb +51 -0
- data/examples/rclient.rb +24 -0
- data/lib/radius/auth.rb +131 -0
- data/lib/radius/dictionary.rb +350 -0
- data/lib/radius/packet.rb +504 -0
- data/test/test.pl +45 -0
- data/test/test.rb +34 -0
- metadata +53 -0
data/README
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
= Ruby-Radius - RADIUS interface for Ruby
|
2
|
+
|
3
|
+
This Ruby module provides an interface to the RADIUS protocol. It
|
4
|
+
provides these two classes:
|
5
|
+
|
6
|
+
+Radius::Packet+:: Deals with Radius Packets
|
7
|
+
+Radius::Dictionary+:: - Deals with RADIUS dictionaries
|
8
|
+
|
9
|
+
This module's API is based heavily on the Net::Radius Perl module
|
10
|
+
created by Christopher Masto, Luis Munoz, and Ian Smith.
|
11
|
+
|
12
|
+
== Installation
|
13
|
+
|
14
|
+
Since the module is pure Ruby, to install this all that needs to be
|
15
|
+
done is to run the 'install.rb' script.
|
16
|
+
|
17
|
+
This package supports the use of vendor-specific attributes. This
|
18
|
+
type of attribute is defined in RFC 2138 and is used to support
|
19
|
+
'proprietary' extensions on top of the base RADIUS specification.
|
20
|
+
|
21
|
+
The whole API is documented in rdoc-style comments within the source
|
22
|
+
itself. If you have extracted this from a distribution tarball, the
|
23
|
+
documentation should be included ready for you to read within the
|
24
|
+
'doc' subdirectory. If you've gotten this from CVS, you need rdoc to
|
25
|
+
extract the HTML documentation. Visit the rdoc website at
|
26
|
+
http://rdoc.sourceforge.net/ for more information.
|
27
|
+
|
28
|
+
= Other stuff
|
29
|
+
Author:: Rafael 'Dido' Sevilla <dido@imperium.ph>
|
30
|
+
Requires:: Ruby 1.6.7 or later (may work with older versions)
|
31
|
+
License:: Copyright (c) 2002 Rafael R. Sevilla
|
32
|
+
GNU Lesser General Public License, see the file COPYING.LIB
|
33
|
+
for more details.
|
34
|
+
|
35
|
+
All of the test and example programs are placed in the public domain.
|
36
|
+
|
37
|
+
$Id: README 2 2006-12-17 06:16:21Z dido $
|
data/dictionary
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
#
|
2
|
+
# This file contains dictionary translations for parsing
|
3
|
+
# requests and generating responses. All transactions are
|
4
|
+
# composed of Attribute/Value Pairs. The value of each attribute
|
5
|
+
# is specified as one of 4 data types. Valid data types are:
|
6
|
+
#
|
7
|
+
# string - 0-253 octets
|
8
|
+
# ipaddr - 4 octets in network byte order
|
9
|
+
# integer - 32 bit value in big endian order (high byte first)
|
10
|
+
# date - 32 bit value in big endian order - seconds since
|
11
|
+
# 00:00:00 GMT, Jan. 1, 1970
|
12
|
+
#
|
13
|
+
# Enumerated values are stored in the user file with dictionary
|
14
|
+
# VALUE translations for easy administration.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
#
|
18
|
+
# ATTRIBUTE VALUE
|
19
|
+
# --------------- -----
|
20
|
+
# Framed-Protocol = PPP
|
21
|
+
# 7 = 1 (integer encoding)
|
22
|
+
#
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# Proper names for everything - use this instead of the above
|
28
|
+
#
|
29
|
+
ATTRIBUTE User-Name 1 string
|
30
|
+
ATTRIBUTE User-Password 2 string
|
31
|
+
ATTRIBUTE CHAP-Password 3 string
|
32
|
+
ATTRIBUTE NAS-IP-Address 4 ipaddr
|
33
|
+
ATTRIBUTE NAS-Port 5 integer
|
34
|
+
ATTRIBUTE Service-Type 6 integer
|
35
|
+
ATTRIBUTE Framed-Protocol 7 integer
|
36
|
+
ATTRIBUTE Framed-IP-Address 8 ipaddr
|
37
|
+
ATTRIBUTE Framed-IP-Netmask 9 ipaddr
|
38
|
+
ATTRIBUTE Framed-Routing 10 integer
|
39
|
+
ATTRIBUTE Filter-Id 11 string
|
40
|
+
ATTRIBUTE Framed-MTU 12 integer
|
41
|
+
ATTRIBUTE Framed-Compression 13 integer
|
42
|
+
ATTRIBUTE Login-IP-Host 14 ipaddr
|
43
|
+
ATTRIBUTE Login-Service 15 integer
|
44
|
+
ATTRIBUTE Login-TCP-Port 16 integer
|
45
|
+
ATTRIBUTE Reply-Message 18 string
|
46
|
+
ATTRIBUTE Callback-Number 19 string
|
47
|
+
ATTRIBUTE Callback-Id 20 string
|
48
|
+
ATTRIBUTE Expiration 21 date
|
49
|
+
ATTRIBUTE Framed-Route 22 string
|
50
|
+
ATTRIBUTE Framed-IPX-Network 23 ipaddr
|
51
|
+
ATTRIBUTE State 24 string
|
52
|
+
ATTRIBUTE Class 25 octets
|
53
|
+
ATTRIBUTE Vendor-Specific 26 octets
|
54
|
+
ATTRIBUTE Session-Timeout 27 integer
|
55
|
+
ATTRIBUTE Idle-Timeout 28 integer
|
56
|
+
ATTRIBUTE Termination-Action 29 integer
|
57
|
+
ATTRIBUTE Called-Station-Id 30 string
|
58
|
+
ATTRIBUTE Calling-Station-Id 31 string
|
59
|
+
ATTRIBUTE NAS-Identifier 32 string
|
60
|
+
ATTRIBUTE Proxy-State 33 octets
|
61
|
+
ATTRIBUTE Login-LAT-Service 34 string
|
62
|
+
ATTRIBUTE Login-LAT-Node 35 string
|
63
|
+
ATTRIBUTE Login-LAT-Group 36 octets
|
64
|
+
ATTRIBUTE Framed-AppleTalk-Link 37 integer
|
65
|
+
ATTRIBUTE Framed-AppleTalk-Network 38 integer
|
66
|
+
ATTRIBUTE Framed-AppleTalk-Zone 39 string
|
67
|
+
ATTRIBUTE Acct-Status-Type 40 integer
|
68
|
+
ATTRIBUTE Acct-Delay-Time 41 integer
|
69
|
+
ATTRIBUTE Acct-Input-Octets 42 integer
|
70
|
+
ATTRIBUTE Acct-Output-Octets 43 integer
|
71
|
+
ATTRIBUTE Acct-Session-Id 44 string
|
72
|
+
ATTRIBUTE Acct-Authentic 45 integer
|
73
|
+
ATTRIBUTE Acct-Session-Time 46 integer
|
74
|
+
ATTRIBUTE Acct-Input-Packets 47 integer
|
75
|
+
ATTRIBUTE Acct-Ouput-Packets 48 integer
|
76
|
+
ATTRIBUTE Acct-Terminate-Cause 49 integer
|
77
|
+
ATTRIBUTE Event-Timestamp 55 date
|
78
|
+
ATTRIBUTE NAS-Port-Type 61 integer
|
79
|
+
ATTRIBUTE Port-Limit 62 integer
|
80
|
+
|
81
|
+
ATTRIBUTE CHAP-Challenge 60 octets
|
82
|
+
ATTRIBUTE Login-LAT-Port 63 string
|
83
|
+
|
84
|
+
|
85
|
+
ATTRIBUTE ARAP-Password 70 octets # 16 octets of data
|
86
|
+
ATTRIBUTE ARAP-Features 71 octets # 14 octets of data
|
87
|
+
ATTRIBUTE ARAP-Zone-Access 72 integer
|
88
|
+
ATTRIBUTE ARAP-Security 73 integer
|
89
|
+
ATTRIBUTE ARAP-Security-Data 74 string
|
90
|
+
ATTRIBUTE Password-Retry 75 integer
|
91
|
+
ATTRIBUTE Prompt 76 integer
|
92
|
+
ATTRIBUTE Connect-Info 77 string
|
93
|
+
ATTRIBUTE Configuration-Token 78 string
|
94
|
+
ATTRIBUTE EAP-Message 79 octets
|
95
|
+
ATTRIBUTE Message-Authenticator 80 octets
|
96
|
+
|
97
|
+
ATTRIBUTE ARAP-Challenge-Response 84 octets # 8 octets of data
|
98
|
+
ATTRIBUTE Acct-Interim-Interval 85 integer
|
99
|
+
# 86: RFC 2867
|
100
|
+
ATTRIBUTE NAS-Port-Id 87 string
|
101
|
+
ATTRIBUTE Framed-Pool 88 string
|
102
|
+
|
103
|
+
|
104
|
+
#
|
105
|
+
# Integer Translations
|
106
|
+
#
|
107
|
+
|
108
|
+
# Service types
|
109
|
+
VALUE Service-Type Login-User 1
|
110
|
+
VALUE Service-Type Framed-User 2
|
111
|
+
VALUE Service-Type Callback-Login-User 3
|
112
|
+
VALUE Service-Type Callback-Framed-User 4
|
113
|
+
VALUE Service-Type Outbound-User 5
|
114
|
+
VALUE Service-Type Administrative-User 6
|
115
|
+
VALUE Service-Type NAS-Prompt-User 7
|
116
|
+
VALUE Service-Type Authenticate-Only 8
|
117
|
+
VALUE Service-Type Callback-NAS-Prompt 9
|
118
|
+
VALUE Service-Type Call-Check 10
|
119
|
+
VALUE Service-Type Callback-Administrative 11
|
120
|
+
|
121
|
+
# Framed Protocols
|
122
|
+
|
123
|
+
VALUE Framed-Protocol PPP 1
|
124
|
+
VALUE Framed-Protocol SLIP 2
|
125
|
+
|
126
|
+
# Framed Routing Values
|
127
|
+
|
128
|
+
VALUE Framed-Routing None 0
|
129
|
+
VALUE Framed-Routing Broadcast 1
|
130
|
+
VALUE Framed-Routing Listen 2
|
131
|
+
VALUE Framed-Routing Broadcast-Listen 3
|
132
|
+
|
133
|
+
# Framed Compression Types
|
134
|
+
|
135
|
+
VALUE Framed-Compression None 0
|
136
|
+
VALUE Framed-Compression Van-Jacobson-TCP-IP 1
|
137
|
+
|
138
|
+
# Login Services
|
139
|
+
|
140
|
+
VALUE Login-Service Telnet 0
|
141
|
+
VALUE Login-Service Rlogin 1
|
142
|
+
VALUE Login-Service TCP-Clear 2
|
143
|
+
VALUE Login-Service PortMaster 3
|
144
|
+
|
145
|
+
# Status Types
|
146
|
+
|
147
|
+
VALUE Acct-Status-Type Start 1
|
148
|
+
VALUE Acct-Status-Type Stop 2
|
149
|
+
VALUE Acct-Status-Type Interim-Update 3
|
150
|
+
|
151
|
+
# Authentication Types
|
152
|
+
|
153
|
+
VALUE Acct-Authentic RADIUS 1
|
154
|
+
VALUE Acct-Authentic Local 2
|
155
|
+
VALUE Acct-Authentic PowerLink128 100
|
156
|
+
|
157
|
+
# Termination Options
|
158
|
+
|
159
|
+
VALUE Termination-Action Default 0
|
160
|
+
VALUE Termination-Action RADIUS-Request 1
|
161
|
+
|
162
|
+
# NAS Port Types, available in ComOS 3.3.1 and later
|
163
|
+
|
164
|
+
VALUE NAS-Port-Type Async 0
|
165
|
+
VALUE NAS-Port-Type Sync 1
|
166
|
+
VALUE NAS-Port-Type ISDN 2
|
167
|
+
VALUE NAS-Port-Type ISDN-V120 3
|
168
|
+
VALUE NAS-Port-Type ISDN-V110 4
|
169
|
+
|
170
|
+
# Acct Terminate Causes, available in ComOS 3.3.2 and later
|
171
|
+
|
172
|
+
VALUE Acct-Terminate-Cause User-Request 1
|
173
|
+
VALUE Acct-Terminate-Cause Lost-Carrier 2
|
174
|
+
VALUE Acct-Terminate-Cause Lost-Service 3
|
175
|
+
VALUE Acct-Terminate-Cause Idle-Timeout 4
|
176
|
+
VALUE Acct-Terminate-Cause Session-Timeout 5
|
177
|
+
VALUE Acct-Terminate-Cause Admin-Reset 6
|
178
|
+
VALUE Acct-Terminate-Cause Admin-Reboot 7
|
179
|
+
VALUE Acct-Terminate-Cause Port-Error 8
|
180
|
+
VALUE Acct-Terminate-Cause NAS-Error 9
|
181
|
+
VALUE Acct-Terminate-Cause NAS-Request 10
|
182
|
+
VALUE Acct-Terminate-Cause NAS-Reboot 11
|
183
|
+
VALUE Acct-Terminate-Cause Port-Unneeded 12
|
184
|
+
VALUE Acct-Terminate-Cause Port-Preempted 13
|
185
|
+
VALUE Acct-Terminate-Cause Port-Suspended 14
|
186
|
+
VALUE Acct-Terminate-Cause Service-Unavailable 15
|
187
|
+
VALUE Acct-Terminate-Cause Callback 16
|
188
|
+
VALUE Acct-Terminate-Cause User-Error 17
|
189
|
+
VALUE Acct-Terminate-Cause Host-Request 18
|
190
|
+
|
191
|
+
|
192
|
+
#
|
193
|
+
# Obsolete names for backwards compatibility with older users files
|
194
|
+
# If you want RADIUS accounting logs to use the new names instead of
|
195
|
+
# these, move this section to the beginning of the dictionary file
|
196
|
+
# and kill and restart radiusd
|
197
|
+
# If you don't have a RADIUS 1.16 users file that you're still using,
|
198
|
+
# you can delete or ignore this section.
|
199
|
+
#
|
200
|
+
ATTRIBUTE Client-Id 4 ipaddr
|
201
|
+
ATTRIBUTE Client-Port-Id 5 integer
|
202
|
+
ATTRIBUTE User-Service-Type 6 integer
|
203
|
+
ATTRIBUTE Framed-Address 8 ipaddr
|
204
|
+
ATTRIBUTE Framed-Netmask 9 ipaddr
|
205
|
+
ATTRIBUTE Framed-Filter-Id 11 string
|
206
|
+
ATTRIBUTE Login-Host 14 ipaddr
|
207
|
+
ATTRIBUTE Login-Port 16 integer
|
208
|
+
ATTRIBUTE Old-Password 17 string
|
209
|
+
ATTRIBUTE Port-Message 18 string
|
210
|
+
ATTRIBUTE Dialback-No 19 string
|
211
|
+
ATTRIBUTE Dialback-Name 20 string
|
212
|
+
ATTRIBUTE Challenge-State 24 string
|
213
|
+
VALUE Service-Type Dialback-Login-User 3
|
214
|
+
VALUE Service-Type Dialback-Framed-User 4
|
215
|
+
VALUE Service-Type Shell-User 6
|
216
|
+
VALUE Framed-Compression Van-Jacobsen-TCP-IP 1
|
217
|
+
#VALUE Auth-Type Unix 1
|
218
|
+
#
|
219
|
+
# END of obsolete names for backwards compatibility
|
220
|
+
#
|
221
|
+
|
222
|
+
#
|
223
|
+
# Configuration Values
|
224
|
+
# uncomment out these two lines to turn account expiration on
|
225
|
+
#
|
226
|
+
|
227
|
+
#VALUE Server-Config Password-Expiration 30
|
228
|
+
#VALUE Server-Config Password-Warning 5
|
229
|
+
|
230
|
+
##
|
231
|
+
## VENDOR SPECIFIC ATTRIBUTES
|
232
|
+
##
|
233
|
+
## The following entries demonstrate the use of VSAs
|
234
|
+
##
|
235
|
+
|
236
|
+
# cisco-avpair is used for various functions by cisco IOS. Most
|
237
|
+
# notably, it's used to create VPDN tunnels.
|
238
|
+
#
|
239
|
+
VENDORATTR 9 cisco-avpair 1 string
|
240
|
+
|
241
|
+
# Symbol attributes
|
242
|
+
|
243
|
+
# Access request attribute's
|
244
|
+
VENDORATTR 388 Symbol-Service-Type 1 integer
|
245
|
+
# SSID in the access request
|
246
|
+
VENDORATTR 388 Symbol-Wlan-Index 2 string
|
247
|
+
# Wlan index in the Access Request, deprecated in WING 5.0, this check item is replaced by VSA - Symbol-Allowed-ESSID
|
248
|
+
VENDORATTR 388 Symbol-Attr-4 4 string
|
249
|
+
VENDORATTR 388 Symbol-Allowed-ESSID 3 string
|
250
|
+
# Reply Attribute which sends the expiry date & time for the guest users
|
251
|
+
VENDORATTR 388 Guest-User-Expiry-Date-Time 7 string
|
252
|
+
# Reply Attribute which sends the start date & time for the guest users
|
253
|
+
VENDORATTR 388 Guest-User-Start-Date-Time 8 string
|
254
|
+
# Rate Limit Parameters
|
255
|
+
VENDORATTR 388 Symbol-Downlink-Limit-Kbps 10 integer
|
256
|
+
VENDORATTR 388 Symbol-Uplink-Limit-Kbps 11 integer
|
257
|
+
# User group name
|
258
|
+
VENDORATTR 388 Symbol-User-Group 12 string
|
259
|
+
VENDORATTR 388 Symbol-User-Device-Type 13 string
|
260
|
+
VENDORATTR 388 Symbol-User-OS 14 string
|
261
|
+
VENDORATTR 388 Symbol-User-Browser 15 string
|
262
|
+
VENDORATTR 388 Symbol-Login-Service 100 integer
|
263
|
+
|
264
|
+
# Aruba attributes
|
265
|
+
|
266
|
+
VENDORATTR 14823 Aruba-User-Role 1 string
|
267
|
+
VENDORATTR 14823 Aruba-User-Vlan 2 integer
|
268
|
+
VENDORATTR 14823 Aruba-Priv-Admin-User 3 integer
|
269
|
+
VENDORATTR 14823 Aruba-Admin-Role 4 string
|
270
|
+
VENDORATTR 14823 Aruba-Essid-Name 5 string
|
271
|
+
VENDORATTR 14823 Aruba-Location-Id 6 string
|
272
|
+
VENDORATTR 14823 Aruba-Port-Id 7 string
|
273
|
+
VENDORATTR 14823 Aruba-Template-User 8 string
|
274
|
+
VENDORATTR 14823 Aruba-Named-User-Vlan 9 string
|
275
|
+
VENDORATTR 14823 Aruba-AP-Group 10 string
|
276
|
+
VENDORATTR 14823 Aruba-Framed-IPv6-Address 11 string
|
277
|
+
|
278
|
+
# Airespace attributes
|
279
|
+
VENDORATTR 14179 Airespace-Wlan-Id 1 integer
|
280
|
+
VENDORATTR 14179 Airespace-QOS-Level 2 integer
|
281
|
+
VENDORATTR 14179 Airespace-DSCP 3 integer
|
282
|
+
VENDORATTR 14179 Airespace-8021p-Tag 4 integer
|
283
|
+
VENDORATTR 14179 Airespace-Interface-Name 5 string
|
284
|
+
VENDORATTR 14179 Airespace-ACL-Name 6 string
|
285
|
+
|
286
|
+
VENDORVALUE 14179 Airespace-QOS-Level Bronze 3
|
287
|
+
VENDORVALUE 14179 Airespace-QOS-Level Silver 0
|
288
|
+
VENDORVALUE 14179 Airespace-QOS-Level Gold 1
|
289
|
+
VENDORVALUE 14179 Airespace-QOS-Level Platinum 2
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
#
|
3
|
+
# Sample RADIUS client
|
4
|
+
#
|
5
|
+
# This code is provided for illustrative purposes only and is placed
|
6
|
+
# in the public domain.
|
7
|
+
#
|
8
|
+
# $Id: radiusclient.rb 2 2006-12-17 06:16:21Z dido $
|
9
|
+
#
|
10
|
+
require 'radius/dictionary'
|
11
|
+
require 'radius/packet'
|
12
|
+
require 'socket'
|
13
|
+
|
14
|
+
user = 'test'
|
15
|
+
pass = 'test'
|
16
|
+
authhost = '127.0.0.1';
|
17
|
+
authport = '1812';
|
18
|
+
secret = 'h1dd3n';
|
19
|
+
dictfile = "../dictionary"
|
20
|
+
|
21
|
+
dict = Radius::Dict.new
|
22
|
+
File.open(dictfile) {
|
23
|
+
|fn|
|
24
|
+
dict.read(fn)
|
25
|
+
}
|
26
|
+
|
27
|
+
def bigrand()
|
28
|
+
return([rand(65536), rand(65536), rand(65536), rand(65536),
|
29
|
+
rand(65536), rand(65536), rand(65536), rand(65536)].pack("n8"))
|
30
|
+
end
|
31
|
+
|
32
|
+
ident = 170;
|
33
|
+
req = Radius::Packet.new(dict)
|
34
|
+
req.code = 'Access-Request'
|
35
|
+
req.identifier = ident
|
36
|
+
req.authenticator = bigrand()
|
37
|
+
req.set_attr('NAS-IP-Address', '127.0.0.1')
|
38
|
+
req.set_attr('User-Name', user)
|
39
|
+
req.set_password(pass, secret)
|
40
|
+
print req.to_s(nil) + "\n"
|
41
|
+
p = req.pack
|
42
|
+
print p.unpack("H*"), "\n"
|
43
|
+
print "Socket connecting\n"
|
44
|
+
sock = UDPSocket.open
|
45
|
+
sock.connect(authhost, authport)
|
46
|
+
print "Socket sending\n"
|
47
|
+
sock.send(p, 0)
|
48
|
+
rec = sock.recvfrom(65536)
|
49
|
+
resp = Radius::Packet.new(dict)
|
50
|
+
resp.unpack(rec[0])
|
51
|
+
print resp.to_s(nil)
|
data/examples/rclient.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
#
|
3
|
+
# Sample RADIUS client using the new Radius::Auth class
|
4
|
+
#
|
5
|
+
# This code is provided for illustrative purposes only and is placed
|
6
|
+
# in the public domain.
|
7
|
+
#
|
8
|
+
# $Id: rclient.rb 2 2006-12-17 06:16:21Z dido $
|
9
|
+
#
|
10
|
+
require 'radius/auth'
|
11
|
+
|
12
|
+
auth = Radius::Auth.new('../dictionary', '127.0.0.1', 5)
|
13
|
+
secret = 'h1dd3n'
|
14
|
+
print "login: "
|
15
|
+
user = $stdin.readline
|
16
|
+
user.chomp!
|
17
|
+
print "Password: "
|
18
|
+
pass = $stdin.readline
|
19
|
+
pass.chomp!
|
20
|
+
if (auth.check_passwd(user, pass, secret, '127.0.0.1'))
|
21
|
+
print "Authentication successful.\n"
|
22
|
+
else
|
23
|
+
print "Authentication failed.\n"
|
24
|
+
end
|
data/lib/radius/auth.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# RADIUS authenticator
|
2
|
+
# Copyright (C) 2002 Rafael R. Sevilla <dido@imperium.ph>
|
3
|
+
# This file is part of the Radius Authentication Module for Ruby
|
4
|
+
#
|
5
|
+
# The Radius Authentication Module for Ruby is free software; you can
|
6
|
+
# redistribute it and/or modify it under the terms of the GNU Lesser
|
7
|
+
# General Public License as published by the Free Software
|
8
|
+
# Foundation; either version 2.1 of the License, or (at your option)
|
9
|
+
# any later version.
|
10
|
+
#
|
11
|
+
# The Radius Authentication Module is distributed in the hope that it
|
12
|
+
# will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
13
|
+
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
14
|
+
# See the GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with the GNU C Library; if not, write to the Free
|
18
|
+
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
19
|
+
# 02111-1307 USA.
|
20
|
+
#
|
21
|
+
# Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
|
22
|
+
# Copyright:: Copyright (c) 2002 Rafael R. Sevilla
|
23
|
+
# License:: GNU Lesser General Public License
|
24
|
+
# $Id: auth.rb 2 2006-12-17 06:16:21Z dido $
|
25
|
+
#
|
26
|
+
|
27
|
+
module Radius
|
28
|
+
require 'radius/packet'
|
29
|
+
require 'radius/dictionary'
|
30
|
+
require 'socket'
|
31
|
+
|
32
|
+
class Auth
|
33
|
+
# We can inspect and alter the contents of the internal RADIUS
|
34
|
+
# packet here (although this is probably not required for simple
|
35
|
+
# work)
|
36
|
+
attr_reader :packet
|
37
|
+
|
38
|
+
# This method initializes the Auth object, given a dictionary
|
39
|
+
# filename to read, the RADIUS host[:port] to connect to, and a
|
40
|
+
# timeout value in seconds for the connection.
|
41
|
+
# =====Parameters
|
42
|
+
# +dictfilename+:: Dictionary filename to read
|
43
|
+
# +radhost+:: name of RADIUS server optionally followed by port number
|
44
|
+
# +myip+:: the client's own IP address (NAS IP address)
|
45
|
+
# +timeout+:: Timeout time
|
46
|
+
def initialize(radhost, myip, timeout, dictfilename = File.dirname(__FILE__) + "/../../dictionary")
|
47
|
+
@dict = Radius::Dictionary.new
|
48
|
+
if dictfilename != nil
|
49
|
+
File.open(dictfilename) do |fn|
|
50
|
+
@dict.read(fn)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@packet = Radius::Packet.new(@dict)
|
54
|
+
|
55
|
+
# this is probably better than starting identifiers at 0
|
56
|
+
@packet.identifier = Kernel.rand(65535)
|
57
|
+
@myip = myip
|
58
|
+
@host, @port = radhost.split(":")
|
59
|
+
@port = Socket.getservbyname("radius", "udp") unless @port
|
60
|
+
@port = 1812 unless @port
|
61
|
+
@port = @port.to_i # just in case
|
62
|
+
@timeout = timeout
|
63
|
+
@sock = UDPSocket.open
|
64
|
+
@sock.connect(@host, @port)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Verifies a username/password pair against the RADIUS server
|
68
|
+
# associated with the Auth object.
|
69
|
+
#
|
70
|
+
# =====Parameters
|
71
|
+
# +name+:: The user name to verify
|
72
|
+
# +pwd+:: The password associated with this name
|
73
|
+
# +secret+:: The RADIUS secret of the system
|
74
|
+
# =====Return value
|
75
|
+
# returns true or false depending on whether or not the attempt succeeded or failed.
|
76
|
+
def check_passwd(name, pwd, secret)
|
77
|
+
send_check_passwd(name, pwd, secret)
|
78
|
+
recv_check_passwd
|
79
|
+
end
|
80
|
+
|
81
|
+
def send_check_passwd(name, pwd, secret)
|
82
|
+
@packet.code = 'Access-Request'
|
83
|
+
gen_authenticator
|
84
|
+
@packet.set_attr('User-Name', name)
|
85
|
+
@packet.set_attr('NAS-IP-Address', @myip)
|
86
|
+
@packet.set_password(pwd, secret)
|
87
|
+
send_packet
|
88
|
+
end
|
89
|
+
|
90
|
+
def recv_check_passwd
|
91
|
+
recv_packet
|
92
|
+
return(@packet.code == 'Access-Accept')
|
93
|
+
end
|
94
|
+
|
95
|
+
# Generate an authenticator, placing it in the @packet object's
|
96
|
+
# authenticator attribute. It will try to use /dev/urandom if
|
97
|
+
# possible, or the system rand call if that's not available.
|
98
|
+
def gen_authenticator
|
99
|
+
# get authenticator data from /dev/urandom if possible
|
100
|
+
if (File.exist?("/dev/urandom"))
|
101
|
+
File.open("/dev/urandom") do |urandom|
|
102
|
+
@packet.authenticator = urandom.read(16)
|
103
|
+
end
|
104
|
+
else
|
105
|
+
# use the Kernel:rand method. This is quite probably not
|
106
|
+
# as secure as using /dev/urandom, be wary...
|
107
|
+
@packet.authenticator = [rand(65536), rand(65536), rand(65536),
|
108
|
+
rand(65536), rand(65536), rand(65536), rand(65536),
|
109
|
+
rand(65536)].pack("n8")
|
110
|
+
end
|
111
|
+
return(@packet.authenticator)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Sends a packet to the server via UDP.
|
115
|
+
def send_packet
|
116
|
+
data = @packet.pack
|
117
|
+
@packet.identifier = (@packet.identifier + 1) & 0xff
|
118
|
+
@sock.send(data, 0)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Receive a packet from the server via UDP.
|
122
|
+
def recv_packet
|
123
|
+
if select([@sock], nil, nil, @timeout) == nil
|
124
|
+
raise "Timed out waiting for response packet from server"
|
125
|
+
end
|
126
|
+
data = @sock.recvfrom(65536)
|
127
|
+
@packet.unpack(data[0])
|
128
|
+
return(@packet)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|