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 CHANGED
@@ -1,7 +1,4 @@
1
- == 0.0.5 / 2011-04-29
2
- * Fixed a bug in Request::recv_packet
3
-
4
- == 0.0.4 / 2010-12-04
1
+ == 0.0.4 / 2010-12/04
5
2
  * github fork (dguerri)
6
3
  * bugfixes
7
4
  * added multiple dictionary files support
@@ -2,13 +2,20 @@ module Radiustar
2
2
 
3
3
  class AttributesCollection < Array
4
4
 
5
- def initialize
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
- @collection[name] ||= Attribute.new(name, id.to_i, 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
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
@@ -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[name] = nil
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 = Hash.new
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 pack
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.each_pair do |attribute_s, value|
104
- attribute = @dict.find_attribute_by_name(attribute_s)
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.index(@code)
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
- inet_ntoa(attribute_value.unpack("N")[0])
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
@@ -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(MAX_RADIUS_REPLAY_PACKET_LEN)
105
+ data = @socket.recvfrom(64)
108
106
  Packet.new(@dict, Process.pid & 0xff, data[0])
109
107
  end
110
108
 
@@ -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"
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-04-29}
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 = %q{davide.guerri@gmail.com}
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.5
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: 21
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 5
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-04-29 00:00:00 +02:00
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: davide.guerri@gmail.com
54
+ email:
55
+ - pj.davis@gmail.com
56
+ - davide.guerri@gmail.com
57
+ - jamesotron@gmail.com
40
58
  executables: []
41
59
 
42
60
  extensions: []