ruby-radius 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|