lib/radiustar/request.rb in radiustar-0.0.3 vs lib/radiustar/request.rb in radiustar-0.0.5

- old
+ new

@@ -2,66 +2,142 @@ require 'socket' class Request - def initialize(server, my_ip = nil, dict_file = nil) - @dict = dict_file.nil? ? Dictionary.default : Dictionary.new(dict_file) + def initialize(server, options = {}) + @dict = options[:dict].nil? ? Dictionary.default : options[:dict] + @nas_ip = options[:nas_ip] || get_my_ip(@host) + @nas_identifier = options[:nas_identifier] || @nas_ip + @reply_timeout = options[:reply_timeout].nil? ? 60 : options[:reply_timeout].to_i + @retries_number = options[:retries_number].nil? ? 1 : options[:retries_number].to_i @host, @port = server.split(":") - - @my_ip = my_ip || get_my_ip(@host) @port = Socket.getservbyname("radius", "udp") unless @port @port = 1812 unless @port @port = @port.to_i # just in case @socket = UDPSocket.open @socket.connect(@host, @port) end - def authenticate(name, password, secret) + def authenticate(name, password, secret, user_attributes = {}) @packet = Packet.new(@dict, Process.pid & 0xff) + @packet.gen_auth_authenticator @packet.code = 'Access-Request' - @packet.gen_authenticator @packet.set_attribute('User-Name', name) - @packet.set_attribute('NAS-IP-Address', @my_ip) + @packet.set_attribute('NAS-Identifier', @nas_identifier) + @packet.set_attribute('NAS-IP-Address', @nas_ip) @packet.set_encoded_attribute('User-Password', password, secret) - send_packet - @recieved_packet = recv_packet - return @recieved_packet.code == 'Access-Accept' + + user_attributes.each_pair do |name, value| + @packet.set_attribute(name, value) + end + + retries = @retries_number + begin + send_packet + @received_packet = recv_packet(@reply_timeout) + rescue Exception => e + retry if (retries -= 1) > 0 + raise + end + + reply = { :code => @received_packet.code } + reply.merge @received_packet.attributes end + + def accounting_request(status_type, name, secret, sessionid, user_attributes = {}) - def get_attributes(name, password, secret) @packet = Packet.new(@dict, Process.pid & 0xff) - @packet.code = 'Access-Request' - @packet.gen_authenticator + @packet.code = 'Accounting-Request' + @packet.set_attribute('User-Name', name) - @packet.set_attribute('NAS-IP-Address', @my_ip) - @packet.set_encoded_attribute('User-Password', password, secret) - send_packet - @recieved_packet = recv_packet - recieved_thing = [@recieved_packet.code] - recieved_thing << @recieved_packet.attributes + @packet.set_attribute('NAS-Identifier', @nas_identifier) + @packet.set_attribute('NAS-IP-Address', @nas_ip) + @packet.set_attribute('Acct-Status-Type', status_type) + @packet.set_attribute('Acct-Session-Id', sessionid) + @packet.set_attribute('Acct-Authentic', 'RADIUS') + + user_attributes.each_pair do |name, value| + @packet.set_attribute(name, value) + end + + @packet.gen_acct_authenticator(secret) + + retries = @retries_number + begin + send_packet + @received_packet = recv_packet(@reply_timeout) + rescue Exception => e + retry if (retries -= 1) > 0 + raise + end + + return true end + def generic_request(code, secret, user_attributes = {}) + @packet = Packet.new(@dict, Process.pid & 0xff) + @packet.code = code + @packet.set_attribute('NAS-Identifier', @nas_identifier) + @packet.set_attribute('NAS-IP-Address', @nas_ip) + + user_attributes.each_pair do |name, value| + @packet.set_attribute(name, value) + end + + @packet.gen_acct_authenticator(secret) + + retries = @retries_number + begin + send_packet + @received_packet = recv_packet(@reply_timeout) + rescue Exception => e + retry if (retries -= 1) > 0 + raise + end + + return true + end + + def coa_request(secret, user_attributes = {}) + generic_request('CoA-Request', secret, user_attributes) + end + + def disconnect_request(secret, user_attributes = {}) + generic_request('Disconnect-Request', secret, user_attributes) + end + + def accounting_start(name, secret, sessionid, options = {}) + accounting_request('Start', name, secret, sessionid, options) + end + + def accounting_update(name, secret, sessionid, options = {}) + accounting_request('Interim-Update', name, secret, sessionid, options) + end + + def accounting_stop(name, secret, sessionid, options = {}) + accounting_request('Stop', name, secret, sessionid, options) + end + def inspect to_s end private def send_packet data = @packet.pack - @packet.increment_id @socket.send(data, 0) end - def recv_packet - if select([@socket], nil, nil, 60) == nil - raise "Timed out waiting for response packet from server" + def recv_packet(timeout) + if select([@socket], nil, nil, timeout.to_i) == nil + raise "Timed out waiting for response packet from server" end - data = @socket.recvfrom(64) + data = @socket.recvfrom(4096) # rfc2865 max packet length Packet.new(@dict, Process.pid & 0xff, data[0]) end #looks up the source IP address with a route to the specified destination def get_my_ip(dest_address) @@ -76,6 +152,6 @@ Socket.do_not_reverse_lookup = orig_reverse_lookup_setting end end -end \ No newline at end of file +end