radiusrb 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/GPLv3.txt +674 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +15 -0
- data/RADIUS/default-radius.dict +207 -0
- data/README.rdoc +74 -0
- data/Rakefile +55 -0
- data/lib/radiusrb/dictionary/attributes.rb +77 -0
- data/lib/radiusrb/dictionary/values.rb +43 -0
- data/lib/radiusrb/dictionary.rb +157 -0
- data/lib/radiusrb/packet.rb +312 -0
- data/lib/radiusrb/request.rb +141 -0
- data/lib/radiusrb/vendor.rb +77 -0
- data/lib/radiusrb/version.rb +27 -0
- data/lib/radiusrb.rb +75 -0
- data/test/helper.rb +18 -0
- data/test/test_radiusrb.rb +7 -0
- metadata +175 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
ipaddr_extensions (2012.1.13)
|
6
|
+
jeweler (1.6.4)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
json (1.6.5)
|
11
|
+
rake (0.9.2.2)
|
12
|
+
rcov (1.0.0)
|
13
|
+
rdoc (3.12)
|
14
|
+
json (~> 1.4)
|
15
|
+
shoulda (3.0.1)
|
16
|
+
shoulda-context (~> 1.0.0)
|
17
|
+
shoulda-matchers (~> 1.0.0)
|
18
|
+
shoulda-context (1.0.0)
|
19
|
+
shoulda-matchers (1.0.0)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
bundler (~> 1.0.0)
|
26
|
+
ipaddr_extensions
|
27
|
+
jeweler (~> 1.6.4)
|
28
|
+
rcov
|
29
|
+
rdoc (>= 2.4.2)
|
30
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (c) 2011 Davide Guerri <davide.guerri@gmail.com>
|
2
|
+
|
3
|
+
This program is free software; you can redistribute it and/or
|
4
|
+
modify it under the terms of the GNU General Public License
|
5
|
+
as published by the Free Software Foundation; either version 3
|
6
|
+
of the License, or (at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
You should have received a copy of the GNU General Public License
|
14
|
+
along with this program; if not, write to the Free Software
|
15
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
@@ -0,0 +1,207 @@
|
|
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 Session-Timeout 27 integer
|
53
|
+
ATTRIBUTE Idle-Timeout 28 integer
|
54
|
+
ATTRIBUTE Termination-Action 29 integer
|
55
|
+
ATTRIBUTE Called-Station-Id 30 string
|
56
|
+
ATTRIBUTE Calling-Station-Id 31 string
|
57
|
+
ATTRIBUTE Acct-Status-Type 40 integer
|
58
|
+
ATTRIBUTE Acct-Delay-Time 41 integer
|
59
|
+
ATTRIBUTE Acct-Input-Octets 42 integer
|
60
|
+
ATTRIBUTE Acct-Output-Octets 43 integer
|
61
|
+
ATTRIBUTE Acct-Session-Id 44 string
|
62
|
+
ATTRIBUTE Acct-Authentic 45 integer
|
63
|
+
ATTRIBUTE Acct-Session-Time 46 integer
|
64
|
+
ATTRIBUTE Acct-Terminate-Cause 49 integer
|
65
|
+
ATTRIBUTE NAS-Port-Type 61 integer
|
66
|
+
ATTRIBUTE Port-Limit 62 integer
|
67
|
+
|
68
|
+
|
69
|
+
#
|
70
|
+
# Integer Translations
|
71
|
+
#
|
72
|
+
|
73
|
+
# User Types
|
74
|
+
|
75
|
+
VALUE Service-Type Login-User 1
|
76
|
+
VALUE Service-Type Framed-User 2
|
77
|
+
VALUE Service-Type Callback-Login-User 3
|
78
|
+
VALUE Service-Type Callback-Framed-User 4
|
79
|
+
VALUE Service-Type Outbound-User 5
|
80
|
+
VALUE Service-Type Administrative-User 6
|
81
|
+
VALUE Service-Type NAS-Prompt-User 7
|
82
|
+
|
83
|
+
# Framed Protocols
|
84
|
+
|
85
|
+
VALUE Framed-Protocol PPP 1
|
86
|
+
VALUE Framed-Protocol SLIP 2
|
87
|
+
|
88
|
+
# Framed Routing Values
|
89
|
+
|
90
|
+
VALUE Framed-Routing None 0
|
91
|
+
VALUE Framed-Routing Broadcast 1
|
92
|
+
VALUE Framed-Routing Listen 2
|
93
|
+
VALUE Framed-Routing Broadcast-Listen 3
|
94
|
+
|
95
|
+
# Framed Compression Types
|
96
|
+
|
97
|
+
VALUE Framed-Compression None 0
|
98
|
+
VALUE Framed-Compression Van-Jacobson-TCP-IP 1
|
99
|
+
|
100
|
+
# Login Services
|
101
|
+
|
102
|
+
VALUE Login-Service Telnet 0
|
103
|
+
VALUE Login-Service Rlogin 1
|
104
|
+
VALUE Login-Service TCP-Clear 2
|
105
|
+
VALUE Login-Service PortMaster 3
|
106
|
+
|
107
|
+
# Status Types
|
108
|
+
|
109
|
+
VALUE Acct-Status-Type Start 1
|
110
|
+
VALUE Acct-Status-Type Stop 2
|
111
|
+
|
112
|
+
# Authentication Types
|
113
|
+
|
114
|
+
VALUE Acct-Authentic RADIUS 1
|
115
|
+
VALUE Acct-Authentic Local 2
|
116
|
+
VALUE Acct-Authentic PowerLink128 100
|
117
|
+
|
118
|
+
# Termination Options
|
119
|
+
|
120
|
+
VALUE Termination-Action Default 0
|
121
|
+
VALUE Termination-Action RADIUS-Request 1
|
122
|
+
|
123
|
+
# NAS Port Types, available in ComOS 3.3.1 and later
|
124
|
+
|
125
|
+
VALUE NAS-Port-Type Async 0
|
126
|
+
VALUE NAS-Port-Type Sync 1
|
127
|
+
VALUE NAS-Port-Type ISDN 2
|
128
|
+
VALUE NAS-Port-Type ISDN-V120 3
|
129
|
+
VALUE NAS-Port-Type ISDN-V110 4
|
130
|
+
|
131
|
+
# Acct Terminate Causes, available in ComOS 3.3.2 and later
|
132
|
+
|
133
|
+
VALUE Acct-Terminate-Cause User-Request 1
|
134
|
+
VALUE Acct-Terminate-Cause Lost-Carrier 2
|
135
|
+
VALUE Acct-Terminate-Cause Lost-Service 3
|
136
|
+
VALUE Acct-Terminate-Cause Idle-Timeout 4
|
137
|
+
VALUE Acct-Terminate-Cause Session-Timeout 5
|
138
|
+
VALUE Acct-Terminate-Cause Admin-Reset 6
|
139
|
+
VALUE Acct-Terminate-Cause Admin-Reboot 7
|
140
|
+
VALUE Acct-Terminate-Cause Port-Error 8
|
141
|
+
VALUE Acct-Terminate-Cause NAS-Error 9
|
142
|
+
VALUE Acct-Terminate-Cause NAS-Request 10
|
143
|
+
VALUE Acct-Terminate-Cause NAS-Reboot 11
|
144
|
+
VALUE Acct-Terminate-Cause Port-Unneeded 12
|
145
|
+
VALUE Acct-Terminate-Cause Port-Preempted 13
|
146
|
+
VALUE Acct-Terminate-Cause Port-Suspended 14
|
147
|
+
VALUE Acct-Terminate-Cause Service-Unavailable 15
|
148
|
+
VALUE Acct-Terminate-Cause Callback 16
|
149
|
+
VALUE Acct-Terminate-Cause User-Error 17
|
150
|
+
VALUE Acct-Terminate-Cause Host-Request 18
|
151
|
+
|
152
|
+
|
153
|
+
#
|
154
|
+
# Obsolete names for backwards compatibility with older users files
|
155
|
+
# If you want RADIUS accounting logs to use the new names instead of
|
156
|
+
# these, move this section to the beginning of the dictionary file
|
157
|
+
# and kill and restart radiusd
|
158
|
+
# If you don't have a RADIUS 1.16 users file that you're still using,
|
159
|
+
# you can delete or ignore this section.
|
160
|
+
#
|
161
|
+
ATTRIBUTE Client-Id 4 ipaddr
|
162
|
+
ATTRIBUTE Client-Port-Id 5 integer
|
163
|
+
ATTRIBUTE User-Service-Type 6 integer
|
164
|
+
ATTRIBUTE Framed-Address 8 ipaddr
|
165
|
+
ATTRIBUTE Framed-Netmask 9 ipaddr
|
166
|
+
ATTRIBUTE Framed-Filter-Id 11 string
|
167
|
+
ATTRIBUTE Login-Host 14 ipaddr
|
168
|
+
ATTRIBUTE Login-Port 16 integer
|
169
|
+
ATTRIBUTE Old-Password 17 string
|
170
|
+
ATTRIBUTE Port-Message 18 string
|
171
|
+
ATTRIBUTE Dialback-No 19 string
|
172
|
+
ATTRIBUTE Dialback-Name 20 string
|
173
|
+
ATTRIBUTE Challenge-State 24 string
|
174
|
+
VALUE Service-Type Dialback-Login-User 3
|
175
|
+
VALUE Service-Type Dialback-Framed-User 4
|
176
|
+
VALUE Service-Type Shell-User 6
|
177
|
+
VALUE Framed-Compression Van-Jacobsen-TCP-IP 1
|
178
|
+
#VALUE Auth-Type Unix 1
|
179
|
+
#
|
180
|
+
# END of obsolete names for backwards compatibility
|
181
|
+
#
|
182
|
+
|
183
|
+
#
|
184
|
+
# Configuration Values
|
185
|
+
# uncomment out these two lines to turn account expiration on
|
186
|
+
#
|
187
|
+
|
188
|
+
#VALUE Server-Config Password-Expiration 30
|
189
|
+
#VALUE Server-Config Password-Warning 5
|
190
|
+
|
191
|
+
##
|
192
|
+
## VENDOR SPECIFIC ATTRIBUTES
|
193
|
+
##
|
194
|
+
## The following entries demonstrate the use of VSAs
|
195
|
+
##
|
196
|
+
|
197
|
+
# cisco-avpair is used for various functions by cisco IOS. Most
|
198
|
+
# notably, it's used to create VPDN tunnels.
|
199
|
+
#
|
200
|
+
VENDORATTR 9 cisco-avpair 1 string
|
201
|
+
|
202
|
+
# This is a fake attribute to demonstrate how to write named-value
|
203
|
+
# attributes.
|
204
|
+
VENDORATTR 1 ibm-enum 254 integer
|
205
|
+
VENDORVALUE 1 ibm-enum value-1 1
|
206
|
+
VENDORVALUE 1 ibm-enum value-2 2
|
207
|
+
VENDORVALUE 1 ibm-enum value-3 3
|
data/README.rdoc
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
= RadiusRB
|
2
|
+
|
3
|
+
A ruby RADIUS client library that supports:
|
4
|
+
|
5
|
+
* Authentication
|
6
|
+
* Accounting
|
7
|
+
* Custom dictionaries
|
8
|
+
* Vendor Specific Attributes (Thanks to James Harton aka jamesotron)
|
9
|
+
|
10
|
+
RadiusRB is derived from from PJ Davis's Radiustar library (https://github.com/pjdavis/radiustar).
|
11
|
+
|
12
|
+
= Installation
|
13
|
+
|
14
|
+
# git clone git://github.com/dguerri/radiusrb.git
|
15
|
+
# cd radiusrb
|
16
|
+
# bundle install
|
17
|
+
# rake install
|
18
|
+
|
19
|
+
= Usage
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'radiusrb'
|
23
|
+
|
24
|
+
# Load dictionaries from freeradius directory
|
25
|
+
dict = RadiusRB::Dictionary.new('/usr/share/freeradius/')
|
26
|
+
|
27
|
+
# Lets get authenticated
|
28
|
+
auth_custom_attr = {
|
29
|
+
'Framed-Address' => '127.0.0.1',
|
30
|
+
'NAS-Port' => 0,
|
31
|
+
'NAS-Port-Type' => 'Ethernet'
|
32
|
+
}
|
33
|
+
|
34
|
+
req = RadiusRB::Request.new('127.0.0.1', { :dict => dict })
|
35
|
+
reply = req.authenticate('John Doe', 'hello', 'testing123', auth_custom_attr)
|
36
|
+
|
37
|
+
if reply[:code] == 'Access-Accept'
|
38
|
+
req = RadiusRB::Request.new('127.0.0.1:1813', { :dict => dict })
|
39
|
+
|
40
|
+
acct_custom_attr = {
|
41
|
+
'Framed-Address' => '127.0.0.1',
|
42
|
+
'NAS-Port' => 0,
|
43
|
+
'NAS-Port-Type' => 'Ethernet',
|
44
|
+
'Acct-Session-Time' => 0
|
45
|
+
}
|
46
|
+
|
47
|
+
timings = Time.now
|
48
|
+
reply = req.accounting_start('John Doe', 'testing123', '123456', acct_custom_attr)
|
49
|
+
|
50
|
+
sleep(rand 5)
|
51
|
+
acct_custom_attr['Acct-Session-Time'] = Time.now - timings
|
52
|
+
reply = req.accounting_update('John Doe', 'testing123', '123456', acct_custom_attr)
|
53
|
+
|
54
|
+
sleep(rand 5)
|
55
|
+
acct_custom_attr['Acct-Session-Time'] = Time.now - timings
|
56
|
+
reply = req.accounting_stop('John Doe', 'testing123', '123456', acct_custom_attr)
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
== Contributing to RadiusRB
|
61
|
+
|
62
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
63
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
64
|
+
* Fork the project
|
65
|
+
* Start a feature/bugfix branch
|
66
|
+
* Commit and push until you are happy with your contribution
|
67
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
68
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
69
|
+
|
70
|
+
== Copyright
|
71
|
+
|
72
|
+
Copyright (c) 2011 Davide Guerri <davide.guerri@gmail.com>.
|
73
|
+
See LICENSE.txt for further details.
|
74
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
require './lib/radiusrb/version.rb'
|
16
|
+
Jeweler::Tasks.new do |gem|
|
17
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
18
|
+
gem.name = "radiusrb"
|
19
|
+
gem.homepage = "http://github.com/dguerri/radiusrb"
|
20
|
+
gem.license = "GPLv3"
|
21
|
+
gem.summary = %Q{RadiusRB, a ruby RADIUS client library}
|
22
|
+
gem.description = %Q{RadiusRB, a ruby RADIUS client library that supports: Authentication, Accounting, Custom dictionaries and Vendor Specific Attributes.}
|
23
|
+
gem.email = "davide.guerri@gmail.com"
|
24
|
+
gem.authors = ["Davide Guerri"]
|
25
|
+
gem.version = RadiusRB::Version::STRING
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
Rake::TestTask.new(:test) do |test|
|
32
|
+
test.libs << 'lib' << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rcov/rcovtask'
|
38
|
+
Rcov::RcovTask.new do |test|
|
39
|
+
test.libs << 'test'
|
40
|
+
test.pattern = 'test/**/test_*.rb'
|
41
|
+
test.verbose = true
|
42
|
+
test.rcov_opts << '--exclude "gems/*"'
|
43
|
+
end
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rdoc/task'
|
48
|
+
RDoc::Task.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "netflowfu #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module RadiusRB
|
2
|
+
|
3
|
+
class AttributesCollection < Array
|
4
|
+
|
5
|
+
attr_accessor :vendor
|
6
|
+
|
7
|
+
def initialize vendor=nil
|
8
|
+
@collection = {}
|
9
|
+
@revcollection = {}
|
10
|
+
@vendor = vendor if vendor
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(name, id, type)
|
14
|
+
if vendor?
|
15
|
+
@collection[name] ||= Attribute.new(name, id.to_i, type, @vendor)
|
16
|
+
else
|
17
|
+
@collection[name] ||= Attribute.new(name, id.to_i, type)
|
18
|
+
end
|
19
|
+
@revcollection[id.to_i] ||= @collection[name]
|
20
|
+
self << @collection[name]
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_by_name(name)
|
24
|
+
@collection[name]
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_by_id(id)
|
28
|
+
@revcollection[id]
|
29
|
+
end
|
30
|
+
|
31
|
+
def vendor?
|
32
|
+
!!@vendor
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class Attribute
|
38
|
+
|
39
|
+
include RadiusRB
|
40
|
+
|
41
|
+
attr_reader :name, :id, :type, :vendor
|
42
|
+
|
43
|
+
def initialize(name, id, type, vendor=nil)
|
44
|
+
@values = ValuesCollection.new
|
45
|
+
@name = name
|
46
|
+
@id = id.to_i
|
47
|
+
@type = type
|
48
|
+
@vendor = vendor if vendor
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_value(name, id)
|
52
|
+
@values.add(name, id.to_i)
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_values_by_name(name)
|
56
|
+
@values.find_by_name(name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_values_by_id(id)
|
60
|
+
@values.find_by_id(id.to_i)
|
61
|
+
end
|
62
|
+
|
63
|
+
def has_values?
|
64
|
+
!@values.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
def values
|
68
|
+
@values
|
69
|
+
end
|
70
|
+
|
71
|
+
def vendor?
|
72
|
+
!!@vendor
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RadiusRB
|
2
|
+
|
3
|
+
class ValuesCollection < Array
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@collection = {}
|
7
|
+
@revcollection = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(name, id)
|
11
|
+
@collection[name] ||= Value.new(name, id)
|
12
|
+
@revcollection[id.to_i] ||= @collection[name]
|
13
|
+
self << @collection[name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_by_name(name)
|
17
|
+
@collection[name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_id(id)
|
21
|
+
@revcollection[id]
|
22
|
+
end
|
23
|
+
|
24
|
+
def empty?
|
25
|
+
@collection.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
class Value
|
31
|
+
|
32
|
+
include RadiusRB
|
33
|
+
|
34
|
+
attr_accessor :name, :id
|
35
|
+
|
36
|
+
def initialize(name, id)
|
37
|
+
@name = name
|
38
|
+
@id = id.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# This file is part of the RadiusRB library for Ruby.
|
2
|
+
# Copyright (C) 2011 Davide Guerri <davide.guerri@gmail.com>
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or
|
5
|
+
# modify it under the terms of the GNU General Public License
|
6
|
+
# as published by the Free Software Foundation; either version 3
|
7
|
+
# of the License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
17
|
+
|
18
|
+
module RadiusRB
|
19
|
+
|
20
|
+
class Dictionary
|
21
|
+
|
22
|
+
include RadiusRB
|
23
|
+
|
24
|
+
DEFAULT_DICTIONARIES_PATH = ::File.join(::File.dirname(__FILE__), '..', '..', 'templates')
|
25
|
+
|
26
|
+
def initialize(initial_path = nil)
|
27
|
+
@attributes = AttributesCollection.new
|
28
|
+
@vendors = VendorCollection.new
|
29
|
+
|
30
|
+
read_files initial_path if initial_path
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_files(path)
|
34
|
+
dict_files = File.join(path, "*")
|
35
|
+
Dir.glob(dict_files) { |file|
|
36
|
+
read_attributes(file)
|
37
|
+
}
|
38
|
+
Dir.glob(dict_files) { |file|
|
39
|
+
read_values(file)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_attribute_by_name(name)
|
44
|
+
@attributes.find_by_name(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_attribute_by_id(id)
|
48
|
+
@attributes.find_by_id(id)
|
49
|
+
end
|
50
|
+
|
51
|
+
def attribute_name_defined?(name)
|
52
|
+
!@attributes.find_by_name(name).nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
def attribute_id_defined?(id)
|
56
|
+
!@attributes.find_by_id(id).nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def vendors
|
60
|
+
@vendors
|
61
|
+
end
|
62
|
+
|
63
|
+
def attributes
|
64
|
+
@attributes
|
65
|
+
end
|
66
|
+
|
67
|
+
def name
|
68
|
+
"Dictionary"
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
|
73
|
+
def default
|
74
|
+
new DEFAULT_DICTIONARIES_PATH
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def read_attributes(path)
|
82
|
+
file = File.open(path) do |f|
|
83
|
+
current_vendor = nil
|
84
|
+
f.each_line do |line|
|
85
|
+
next if line =~ /^\#/ # discard comments
|
86
|
+
split_line = line.split(/\s+/)
|
87
|
+
next if split_line == []
|
88
|
+
case split_line.first.upcase
|
89
|
+
when "ATTRIBUTE"
|
90
|
+
current_vendor.nil? ? set_attr(split_line) : set_vendor_attr(current_vendor, split_line)
|
91
|
+
when "VENDOR"
|
92
|
+
add_vendor(split_line)
|
93
|
+
when "BEGIN-VENDOR"
|
94
|
+
current_vendor = set_vendor(split_line)
|
95
|
+
when "END-VENDOR"
|
96
|
+
current_vendor = nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def read_values(path)
|
103
|
+
file = File.open(path) do |f|
|
104
|
+
current_vendor = nil
|
105
|
+
f.each_line do |line|
|
106
|
+
next if line =~ /^\#/ # discard comments
|
107
|
+
split_line = line.split(/\s+/)
|
108
|
+
next if split_line == []
|
109
|
+
case split_line.first.upcase
|
110
|
+
when "VALUE"
|
111
|
+
if current_vendor.nil?
|
112
|
+
set_value(split_line)
|
113
|
+
else
|
114
|
+
begin
|
115
|
+
set_vendor_value(current_vendor, split_line)
|
116
|
+
rescue
|
117
|
+
set_value(split_line)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
when "BEGIN-VENDOR"
|
121
|
+
current_vendor = set_vendor(split_line)
|
122
|
+
when "END-VENDOR"
|
123
|
+
current_vendor = nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def set_attr(line)
|
132
|
+
@attributes.add(line[1], line[2], line[3])
|
133
|
+
end
|
134
|
+
|
135
|
+
def set_value(line)
|
136
|
+
@attributes.find_by_name(line[1]).add_value(line[2], line[3])
|
137
|
+
end
|
138
|
+
|
139
|
+
def add_vendor(line)
|
140
|
+
@vendors.add(line[2], line[1])
|
141
|
+
end
|
142
|
+
|
143
|
+
def set_vendor(line)
|
144
|
+
@vendors.find_by_name(line[1])
|
145
|
+
end
|
146
|
+
|
147
|
+
def set_vendor_attr(vendor, line)
|
148
|
+
vendor.add_attribute(line[1], line[2], line[3])
|
149
|
+
end
|
150
|
+
|
151
|
+
def set_vendor_value(vendor, line)
|
152
|
+
vendor.find_attribute_by_name(line[1]).add_value(line[2], line[3])
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|