dguerri-radiustar 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +1 -4
- data/lib/radiustar/dictionary/attributes.rb +21 -5
- data/lib/radiustar/packet.rb +130 -45
- data/lib/radiustar/request.rb +1 -3
- data/lib/radiustar/vendor.rb +2 -2
- data/radiustar.gemspec +7 -4
- data/version.txt +1 -1
- metadata +23 -5
data/History.txt
CHANGED
@@ -2,13 +2,20 @@ module Radiustar
|
|
2
2
|
|
3
3
|
class AttributesCollection < Array
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :vendor
|
6
|
+
|
7
|
+
def initialize vendor=nil
|
6
8
|
@collection = {}
|
7
9
|
@revcollection = {}
|
10
|
+
@vendor = vendor if vendor
|
8
11
|
end
|
9
12
|
|
10
13
|
def add(name, id, type)
|
11
|
-
|
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
|
12
19
|
@revcollection[id.to_i] ||= @collection[name]
|
13
20
|
self << @collection[name]
|
14
21
|
end
|
@@ -21,19 +28,24 @@ module Radiustar
|
|
21
28
|
@revcollection[id]
|
22
29
|
end
|
23
30
|
|
31
|
+
def vendor?
|
32
|
+
!!@vendor
|
33
|
+
end
|
34
|
+
|
24
35
|
end
|
25
36
|
|
26
37
|
class Attribute
|
27
38
|
|
28
39
|
include Radiustar
|
29
40
|
|
30
|
-
attr_reader :name, :id, :type
|
41
|
+
attr_reader :name, :id, :type, :vendor
|
31
42
|
|
32
|
-
def initialize(name, id, type)
|
43
|
+
def initialize(name, id, type, vendor=nil)
|
33
44
|
@values = ValuesCollection.new
|
34
45
|
@name = name
|
35
46
|
@id = id.to_i
|
36
47
|
@type = type
|
48
|
+
@vendor = vendor if vendor
|
37
49
|
end
|
38
50
|
|
39
51
|
def add_value(name, id)
|
@@ -56,6 +68,10 @@ module Radiustar
|
|
56
68
|
@values
|
57
69
|
end
|
58
70
|
|
71
|
+
def vendor?
|
72
|
+
!!@vendor
|
73
|
+
end
|
74
|
+
|
59
75
|
end
|
60
76
|
|
61
|
-
end
|
77
|
+
end
|
data/lib/radiustar/packet.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Radiustar
|
2
2
|
|
3
3
|
require 'digest/md5'
|
4
|
+
require 'ipaddr_extensions'
|
4
5
|
|
5
6
|
class Packet
|
6
7
|
|
@@ -15,7 +16,7 @@ module Radiustar
|
|
15
16
|
P_ATTR = "CCa*" # pack template for attribute
|
16
17
|
|
17
18
|
attr_accessor :code
|
18
|
-
attr_reader :id, :attributes
|
19
|
+
attr_reader :id, :attributes, :authenticator
|
19
20
|
|
20
21
|
def initialize(dictionary, id, data = nil)
|
21
22
|
@dict = dictionary
|
@@ -75,55 +76,63 @@ module Radiustar
|
|
75
76
|
@authenticator = "\000"*16
|
76
77
|
@authenticator = Digest::MD5.digest(pack + secret)
|
77
78
|
@packed = nil
|
79
|
+
@authenticator
|
80
|
+
end
|
81
|
+
|
82
|
+
def gen_response_authenticator(secret, request_authenticator)
|
83
|
+
@authenticator = request_authenticator
|
84
|
+
@authenticator = Digest::MD5.digest(pack + secret)
|
85
|
+
@packed = nil
|
86
|
+
@authenticator
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_acct_authenticator(secret)
|
90
|
+
if @authenticator
|
91
|
+
original_authenticator = @authenticator
|
92
|
+
if gen_acct_authenticator(secret) == original_authenticator
|
93
|
+
true
|
94
|
+
else
|
95
|
+
@authenticator = original_authenticator
|
96
|
+
false
|
97
|
+
end
|
98
|
+
else
|
99
|
+
false
|
100
|
+
end
|
78
101
|
end
|
79
102
|
|
80
103
|
def set_attribute(name, value)
|
81
|
-
@attributes[name] = value
|
104
|
+
@attributes[name] = Attribute.new(@dict, name, value)
|
82
105
|
end
|
83
106
|
|
84
107
|
def unset_attribute(name)
|
85
|
-
@attributes
|
108
|
+
@attributes.delete(name)
|
86
109
|
end
|
87
110
|
|
88
111
|
def attribute(name)
|
89
|
-
@attributes[name]
|
112
|
+
if @attributes[name]
|
113
|
+
@attributes[name].value
|
114
|
+
end
|
90
115
|
end
|
91
116
|
|
92
117
|
def unset_all_attributes
|
93
|
-
@attributes =
|
118
|
+
@attributes = {}
|
94
119
|
end
|
95
120
|
|
96
121
|
def set_encoded_attribute(name, value, secret)
|
97
|
-
@attributes[name] = encode(value, secret)
|
122
|
+
@attributes[name] = Attribute.new(@dict, name, encode(value, secret))
|
98
123
|
end
|
99
124
|
|
100
|
-
def
|
125
|
+
def decode_attribute(name, secret)
|
126
|
+
if @attributes[name]
|
127
|
+
decode(@attributes[name].value.to_s, secret)
|
128
|
+
end
|
129
|
+
end
|
101
130
|
|
131
|
+
def pack
|
102
132
|
attstr = ""
|
103
|
-
@attributes.
|
104
|
-
|
105
|
-
raise "Undefned attribute '#{attribute_s}'." if attribute.nil?
|
106
|
-
anum = attribute.id
|
107
|
-
val = case attribute.type
|
108
|
-
when "string"
|
109
|
-
value
|
110
|
-
when "integer"
|
111
|
-
if attribute.has_values?
|
112
|
-
raise "Invalid value name '#{value}'" if attribute.find_values_by_name(value).nil?
|
113
|
-
end
|
114
|
-
[attribute.has_values? ? attribute.find_values_by_name(value).id : value].pack("N")
|
115
|
-
when "ipaddr"
|
116
|
-
[inet_aton(value)].pack("N")
|
117
|
-
when "date"
|
118
|
-
[value].pack("N")
|
119
|
-
when "time"
|
120
|
-
[value].pack("N")
|
121
|
-
else
|
122
|
-
next
|
123
|
-
end
|
124
|
-
attstr += [attribute.id, val.length + 2, val].pack(P_ATTR)
|
133
|
+
@attributes.values.each do |attribute|
|
134
|
+
attstr += attribute.pack
|
125
135
|
end
|
126
|
-
|
127
136
|
@packed = [CODES[@code], @id, attstr.length + HDRLEN, @authenticator, attstr].pack(P_HDR)
|
128
137
|
end
|
129
138
|
|
@@ -131,7 +140,7 @@ module Radiustar
|
|
131
140
|
|
132
141
|
def unpack
|
133
142
|
@code, @id, len, @authenticator, attribute_data = @packed.unpack(P_HDR)
|
134
|
-
@code = CODES.
|
143
|
+
@code = CODES.key(@code)
|
135
144
|
|
136
145
|
unset_all_attributes
|
137
146
|
|
@@ -147,7 +156,7 @@ module Radiustar
|
|
147
156
|
when 'integer'
|
148
157
|
attribute.has_values? ? attribute.find_values_by_id(attribute_value.unpack("N")[0]).name : attribute_value.unpack("N")[0]
|
149
158
|
when 'ipaddr'
|
150
|
-
|
159
|
+
attribute_value.unpack("N")[0].to_ip.to_s
|
151
160
|
when 'time'
|
152
161
|
attribute_value.unpack("N")[0]
|
153
162
|
when 'date'
|
@@ -159,22 +168,11 @@ module Radiustar
|
|
159
168
|
end
|
160
169
|
end
|
161
170
|
|
162
|
-
def inet_aton(hostname)
|
163
|
-
if (hostname =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/)
|
164
|
-
return (($1.to_i & 0xff) << 24) + (($2.to_i & 0xff) << 16) + (($3.to_i & 0xff) << 8) + (($4.to_i & 0xff))
|
165
|
-
end
|
166
|
-
0
|
167
|
-
end
|
168
|
-
|
169
|
-
def inet_ntoa(iaddr)
|
170
|
-
sprintf("%d.%d.%d.%d", (iaddr >> 24) & 0xff, (iaddr >> 16) & 0xff, (iaddr >> 8) & 0xff, (iaddr) & 0xff)
|
171
|
-
end
|
172
|
-
|
173
171
|
def xor_str(str1, str2)
|
174
172
|
i = 0
|
175
173
|
newstr = ""
|
176
174
|
str1.each_byte do |c1|
|
177
|
-
c2 = str2[i]
|
175
|
+
c2 = str2.bytes.to_a[i]
|
178
176
|
newstr = newstr << (c1 ^ c2)
|
179
177
|
i = i+1
|
180
178
|
end
|
@@ -206,5 +204,92 @@ module Radiustar
|
|
206
204
|
return decoded_value
|
207
205
|
end
|
208
206
|
|
207
|
+
class Attribute
|
208
|
+
|
209
|
+
attr_reader :dict, :name, :vendor
|
210
|
+
attr_accessor :value
|
211
|
+
|
212
|
+
def initialize dict, name, value, vendor=nil
|
213
|
+
@dict = dict
|
214
|
+
# This is the cheapest and easiest way to add VSA's!
|
215
|
+
if (name && (chunks = name.split('/')) && (chunks.size == 2))
|
216
|
+
@vendor = chunks[0]
|
217
|
+
@name = chunks[1]
|
218
|
+
else
|
219
|
+
@name = name
|
220
|
+
end
|
221
|
+
@vendor ||= vendor
|
222
|
+
@value = value.is_a?(Attribute) ? value.to_s : value
|
223
|
+
end
|
224
|
+
|
225
|
+
def vendor?
|
226
|
+
!!@vendor
|
227
|
+
end
|
228
|
+
|
229
|
+
def pack
|
230
|
+
attribute = if (vendor? && (@dict.vendors.find_by_name(@vendor)))
|
231
|
+
@dict.vendors.find_by_name(@vendor).attributes.find_by_name(@name)
|
232
|
+
else
|
233
|
+
@dict.find_attribute_by_name(@name)
|
234
|
+
end
|
235
|
+
raise "Undefined attribute '#{@name}'." if attribute.nil?
|
236
|
+
|
237
|
+
if vendor?
|
238
|
+
pack_vendor_specific_attribute attribute
|
239
|
+
else
|
240
|
+
pack_attribute attribute
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def inspect
|
245
|
+
@value
|
246
|
+
end
|
247
|
+
|
248
|
+
def to_s
|
249
|
+
@value
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
|
254
|
+
def pack_vendor_specific_attribute attribute
|
255
|
+
inside_attribute = pack_attribute attribute
|
256
|
+
vid = attribute.vendor.id.to_i
|
257
|
+
header = [ 26, inside_attribute.size + 6 ].pack("CC") # 26: Type = Vendor-Specific, 4: length of Vendor-Id field
|
258
|
+
header += [ 0, vid >> 16, vid >> 8, vid ].pack("CCCC") # first byte of Vendor-Id is 0
|
259
|
+
header + inside_attribute
|
260
|
+
end
|
261
|
+
|
262
|
+
def pack_attribute attribute
|
263
|
+
anum = attribute.id
|
264
|
+
val = case attribute.type
|
265
|
+
when "string"
|
266
|
+
@value
|
267
|
+
when "integer"
|
268
|
+
raise "Invalid value name '#{@value}'." if attribute.has_values? && attribute.find_values_by_name(@value).nil?
|
269
|
+
[attribute.has_values? ? attribute.find_values_by_name(@value).id : @value].pack("N")
|
270
|
+
when "ipaddr"
|
271
|
+
[@value.to_ip.to_i].pack("N")
|
272
|
+
when "ipv6addr"
|
273
|
+
ipi = @value.to_ip.to_i
|
274
|
+
[ ipi >> 96, ipi >> 64, ipi >> 32, ipi ].pack("NNNN")
|
275
|
+
when "date"
|
276
|
+
[@value].pack("N")
|
277
|
+
when "time"
|
278
|
+
[@value].pack("N")
|
279
|
+
else
|
280
|
+
""
|
281
|
+
end
|
282
|
+
begin
|
283
|
+
[anum,
|
284
|
+
val.length + 2,
|
285
|
+
val
|
286
|
+
].pack(P_ATTR)
|
287
|
+
rescue
|
288
|
+
puts "#{@name} => #{@value}"
|
289
|
+
puts [anum, val.length + 2, val].inspect
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
209
294
|
end
|
210
|
-
end
|
295
|
+
end
|
data/lib/radiustar/request.rb
CHANGED
@@ -2,8 +2,6 @@ module Radiustar
|
|
2
2
|
|
3
3
|
require 'socket'
|
4
4
|
|
5
|
-
MAX_RADIUS_REPLAY_PACKET_LEN = 512
|
6
|
-
|
7
5
|
class Request
|
8
6
|
|
9
7
|
def initialize(server, options = {})
|
@@ -104,7 +102,7 @@ module Radiustar
|
|
104
102
|
if select([@socket], nil, nil, timeout.to_i) == nil
|
105
103
|
raise "Timed out waiting for response packet from server"
|
106
104
|
end
|
107
|
-
data = @socket.recvfrom(
|
105
|
+
data = @socket.recvfrom(64)
|
108
106
|
Packet.new(@dict, Process.pid & 0xff, data[0])
|
109
107
|
end
|
110
108
|
|
data/lib/radiustar/vendor.rb
CHANGED
@@ -32,7 +32,7 @@ module Radiustar
|
|
32
32
|
def initialize(name, id)
|
33
33
|
@name = name
|
34
34
|
@id = id
|
35
|
-
@attributes = AttributesCollection.new
|
35
|
+
@attributes = AttributesCollection.new self
|
36
36
|
end
|
37
37
|
|
38
38
|
def add_attribute(name, id, type)
|
@@ -57,4 +57,4 @@ module Radiustar
|
|
57
57
|
|
58
58
|
end
|
59
59
|
|
60
|
-
end
|
60
|
+
end
|
data/radiustar.gemspec
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{dguerri-radiustar}
|
5
|
-
s.version = "0.0
|
5
|
+
s.version = "0.1.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["PJ Davis", "Davide Guerri"]
|
9
|
-
s.date = %q{2011-
|
8
|
+
s.authors = ["PJ Davis", "Davide Guerri", "James Harton"]
|
9
|
+
s.date = %q{2011-09-28}
|
10
10
|
s.description = %q{Ruby Radius Library}
|
11
|
-
s.email =
|
11
|
+
s.email = ["pj.davis@gmail.com", "davide.guerri@gmail.com", "jamesotron@gmail.com"]
|
12
12
|
s.extra_rdoc_files = ["History.txt", "README.rdoc", "templates/default.txt", "version.txt"]
|
13
13
|
s.files = [".gitignore", "History.txt", "README.rdoc", "Rakefile", "lib/radiustar.rb", "lib/radiustar/dictionary.rb", "lib/radiustar/dictionary/attributes.rb", "lib/radiustar/dictionary/values.rb", "lib/radiustar/packet.rb", "lib/radiustar/radiustar.rb", "lib/radiustar/request.rb", "lib/radiustar/vendor.rb", "radiustar.gemspec", "spec/radiustar_spec.rb", "spec/spec_helper.rb", "templates/default.txt", "templates/dictionary.digium", "templates/gandalf.dictionary", "test/test_radiustar.rb", "version.txt"]
|
14
14
|
s.homepage = %q{http://github.com/dguerri/radiustar}
|
@@ -25,10 +25,13 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
27
|
s.add_development_dependency(%q<bones>, [">= 3.4.1"])
|
28
|
+
s.add_development_dependency(%q<ipaddr_extensions>)
|
28
29
|
else
|
29
30
|
s.add_dependency(%q<bones>, [">= 3.4.1"])
|
31
|
+
s.add_dependency(%q<ipaddr_extensions>)
|
30
32
|
end
|
31
33
|
else
|
32
34
|
s.add_dependency(%q<bones>, [">= 3.4.1"])
|
35
|
+
s.add_dependency(%q<ipaddr_extensions>)
|
33
36
|
end
|
34
37
|
end
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
metadata
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dguerri-radiustar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.5
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- PJ Davis
|
14
14
|
- Davide Guerri
|
15
|
+
- James Harton
|
15
16
|
autorequire:
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2011-
|
20
|
+
date: 2011-09-28 00:00:00 +02:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -35,8 +36,25 @@ dependencies:
|
|
35
36
|
version: 3.4.1
|
36
37
|
type: :development
|
37
38
|
version_requirements: *id001
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: ipaddr_extensions
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 3
|
48
|
+
segments:
|
49
|
+
- 0
|
50
|
+
version: "0"
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
38
53
|
description: Ruby Radius Library
|
39
|
-
email:
|
54
|
+
email:
|
55
|
+
- pj.davis@gmail.com
|
56
|
+
- davide.guerri@gmail.com
|
57
|
+
- jamesotron@gmail.com
|
40
58
|
executables: []
|
41
59
|
|
42
60
|
extensions: []
|