From 323c280a38e4154740639162969b427545678005 Mon Sep 17 00:00:00 2001 From: John Dong Date: Thu, 16 Aug 2007 13:57:01 -0400 Subject: [PATCH] Use WHOIS to search up meaningful organizational data about voters. NOTE: Probably destroys performance when there's >= 100 voters. --- app/views/quickvote/results.rhtml | 5 +- lib/whois/data/ipv4.yaml | 201 ++++++++++++++++++++++++++++++ lib/whois/data/ipv6.yaml | 33 +++++ lib/whois/server/server.rb | 131 +++++++++++++++++++ lib/whois/whois.rb | 158 +++++++++++++++++++++++ 5 files changed, 526 insertions(+), 2 deletions(-) create mode 100644 lib/whois/data/ipv4.yaml create mode 100644 lib/whois/data/ipv6.yaml create mode 100644 lib/whois/server/server.rb create mode 100755 lib/whois/whois.rb diff --git a/app/views/quickvote/results.rhtml b/app/views/quickvote/results.rhtml index 3b3a54d..1df2856 100644 --- a/app/views/quickvote/results.rhtml +++ b/app/views/quickvote/results.rhtml @@ -1,4 +1,4 @@ -<%require 'IPAddr' %> +<%require 'whois/whois' %>

Results

<% if @election.shortdesc %> @@ -156,7 +156,8 @@ by several other names.

<%= voter.ipaddress %> <% begin %> - <%= `host #{IPAddr.new(voter.ipaddress).to_s}`.sub(/^.*pointer (.*)\.$/, '\1') %> + <% raise ArgumentError.new if voter.ipaddress == "127.0.0.1" %> + <%= Whois::Whois.new(IPAddr.new(voter.ipaddress).to_s).search_whois.grep(/^OrgName/)[0].sub(/^OrgName\:/,'').strip %> <% rescue ArgumentError => err %> <%= voter.ipaddress %> diff --git a/lib/whois/data/ipv4.yaml b/lib/whois/data/ipv4.yaml new file mode 100644 index 0000000..13e2724 --- /dev/null +++ b/lib/whois/data/ipv4.yaml @@ -0,0 +1,201 @@ +--- +222.96.0.0/12: Nicor +218.160.0.0/12: Twnic +209.94.192.0/19: Lacnic +155.232.0.0/13: Afrinic +164.146.0.0/15: Afrinic +202.16.0.0/14: Nicad +218.216.0.0/13: Nicad +202.0.0.0/7: Apnic +192.71.0.0/16: Ripe +61.112.0.0/12: Nicad +141.64.0.0/12: Ripe +43.0.0.0/8: V6nic +211.112.0.0/13: Nicor +211.20.0.0/15: Twnic +202.224.0.0/11: Nicad +151.100.0.0/16: Ripe +160.124.0.0/16: Afrinic +214.0.0.0/7: Arin +210.242.0.0/15: Twnic +61.192.0.0/12: Nicad +163.156.0.0/14: Ripe +171.16.0.0/12: Ripe +200.128.0.0/9: Nicbr +219.96.0.0/11: Nicad +149.240.0.0/13: Ripe +164.0.0.0/11: Ripe +151.0.0.0/10: Ripe +192.72.253.0/24: Arin +221.144.0.0/12: Nicor +203.66.0.0/16: Twnic +202.11.0.0/16: Nicad +0.0.0.0/1: Arin +149.248.0.0/14: Ripe +59.0.0.0/11: Nicor +41.0.0.0/8: Afrinic +149.204.0.0/16: Ripe +218.232.0.0/13: Nicor +218.224.0.0/13: Nicad +210.248.0.0/13: Nicad +210.204.0.0/14: Nicor +116.0.0.0/6: Apnic +202.24.0.0/15: Nicad +200.0.0.0/7: Lacnic +200.17.0.0/16: Nicbr +125.128.0.0/11: Nicor +150.254.0.0/16: Ripe +164.32.0.0/13: Ripe +211.192.0.0/10: Nicor +203.69.0.0/16: Twnic +192.118.0.0/16: Ripe +202.39.128.0/17: Twnic +220.149.0.0/16: Nicor +212.0.0.0/7: Ripe +211.128.0.0/13: Nicad +211.120.0.0/13: Nicad +210.71.128.0/16: Twnic +203.140.0.0/15: Nicad +96.0.0.0/3: +196.0.0.0/6: Arin +192.164.0.0/14: Ripe +165.144.0.0/14: Afrinic +155.240.0.0/16: Afrinic +218.36.0.0/14: Nicor +213.154.64.0/19: Afrinic +210.240.0.0/16: Twnic +210.128.0.0/11: Nicad +210.59.128.0/17: Twnic +223.0.0.0/8: +219.248.0.0/13: Nicor +211.72.0.0/16: Twnic +203.74.0.0/15: Twnic +203.0.0.0/10: Apnic +196.0.0.0/8: Afrinic +149.202.0.0/15: Ripe +210.241.224.0/19: Twnic +96.0.0.0/6: Arin +171.32.0.0/15: Ripe +220.64.0.0/11: Nicor +219.240.0.0/15: Nicor +210.0.0.0/7: Apnic +211.16.0.0/14: Nicad +210.92.0.0/14: Nicor +202.32.0.0/14: Nicad +220.103.0.0/16: Nicor +211.75.0.0/16: Twnic +202.20.128.0/17: Nicor +208.0.0.0/7: Arin +202.48.0.0/16: Nicad +163.200.0.0/14: Afrinic +61.208.0.0/13: Nicad +139.24.0.0/14: Ripe +62.0.0.0/8: Ripe +222.232.0.0/13: Nicor +61.84.0.0/15: Nicor +194.0.0.0/7: Ripe +126.0.0.0/8: Apnic +150.183.0.0/16: Nicor +141.80.0.0/14: Ripe +163.195.0.0/16: Afrinic +160.115.0.0/16: Afrinic +211.32.0.0/11: Nicor +192.72.0.0/16: Apnic +164.40.0.0/16: Ripe +210.61.0.0/16: Twnic +160.120.0.0/14: Afrinic +221.160.0.0/13: Nicor +160.44.0.0/14: Ripe +151.96.0.0/14: Ripe +220.0.0.0/6: Apnic +222.112.0.0/13: Nicor +220.104.0.0/13: Nicad +203.136.0.0/14: Nicad +149.208.0.0/12: Ripe +141.0.0.0/10: Ripe +192.116.0.0/15: Ripe +192.106.0.0/16: Ripe +202.30.0.0/15: Nicor +60.0.0.0/7: Apnic +200.18.0.0/15: Nicbr +160.220.0.0/16: Ripe +124.0.0.0/7: Apnic +58.0.0.0/7: Apnic +218.0.0.0/7: Apnic +204.0.0.0/14: Ginntt +193.0.0.0/8: Ripe +200.20.0.0/16: Nicbr +192.162.0.0/16: Ripe +202.15.0.0/16: Nicad +163.196.0.0/14: Afrinic +222.122.0.0/16: Nicor +221.138.0.0/13: Nicor +121.128.0.0/10: Nicor +211.0.0.0/12: Nicad +210.241.0.0/15: Twnic +210.216.0.0/13: Nicor +61.72.0.0/13: Nicor +192.114.0.0/15: Ripe +80.0.0.0/5: Ripe +210.188.0.0/14: Nicad +210.178.0.0/15: Nicor +210.90.0.0/15: Nicor +203.180.0.0/14: Nicad +202.208.0.0/12: Nicad +146.48.0.0/16: Ripe +163.160.0.0/12: Ripe +192.72.254.0/24: Arin +213.154.32.0/19: Afrinic +211.168.0.0/13: Nicor +211.22.0.0/16: Twnic +210.180.0.0/14: Nicor +139.28.0.0/15: Ripe +165.148.0.0/15: Afrinic +222.120.0.0/15: Nicor +220.96.0.0/14: Nicad +216.0.0.0/8: Arin +210.96.0.0/11: Nicor +192.0.0.0/8: Arin +133.0.0.0/8: Nicad +149.206.0.0/15: Ripe +160.116.0.0/14: Afrinic +218.144.0.0/12: Nicor +217.0.0.0/8: Ripe +210.224.0.0/12: Nicad +210.160.0.0/12: Nicad +210.65.0.0/16: Twnic +160.216.0.0/14: Ripe +92.0.0.0/7: Ripe +164.148.0.0/14: Afrinic +189.0.0.0/8: Lacnic +202.23.0.0/16: Nicad +145.0.0.0/8: Ripe +204.0.0.0/6: Arin +165.143.0.0/16: Afrinic +169.208.0.0/12: Apnic +211.104.0.0/13: Nicor +210.196.0.0/14: Nicad +24.132.0.0/14: Ripe +149.224.0.0/12: Ripe +202.26.0.0/16: Nicad +218.48.0.0/13: Nicor +218.40.0.0/13: Nicad +211.176.0.0/12: Nicor +203.178.0.0/15: Nicad +139.20.0.0/14: Ripe +151.64.0.0/11: Ripe +190.0.0.0/8: Lacnic +200.96.0.0/13: Nicbr +61.80.0.0/14: Nicor +164.128.0.0/12: Ripe +160.48.0.0/12: Ripe +128.0.0.0/2: Arin +141.84.0.0/15: Ripe +210.62.252.0/22: Twnic +203.224.0.0/11: Nicor +77.0.0.0/8: Ripe +120.0.0.0/6: Apnic +88.0.0.0/6: Ripe +188.0.0.0/8: Ripe +202.13.0.0/16: Nicad +78.0.0.0/7: Ripe diff --git a/lib/whois/data/ipv6.yaml b/lib/whois/data/ipv6.yaml new file mode 100644 index 0000000..1e3e31c --- /dev/null +++ b/lib/whois/data/ipv6.yaml @@ -0,0 +1,33 @@ +--- +2001:4A00::/23: Ripe +2001:4600::/23: Ripe +2001:4200::/23: Afrinic +2001:0200::/23: Apnic +2400:0000::/12: Apnic +2001:1C00::/22: Ripe +2001:8000::/18: Apnic +2001:1800::/23: Arin +2001:0600::/23: Ripe +3FFE:0000::/16: Ipv6Bone +2001:5000::/20: Ripe +2001:1A00::/23: Ripe +2001:0C00::/22: Apnic +2001:0800::/22: Ripe +2800:0000::/12: Lacnic +2620:0000::/23: Arin +2001:0400::/23: Arin +2C00:0000::/12: Afrinic +2610:0000::/23: Arin +2003:0000::/18: Ripe +2001:4000::/23: Ripe +2600:0000::/12: Arin +2002:0000::/16: Ipv6ToIpv4 +2001:2000::/19: Ripe +2001:0000::/32: Teredo +2A00:0000::/12: Ripe +2001:4C00::/22: Ripe +2400:0000::/20: Kornet +2001:4800::/23: Arin +2001:4400::/23: Apnic +2001:1400::/22: Ripe +2001:1000::/22: Lacnic diff --git a/lib/whois/server/server.rb b/lib/whois/server/server.rb new file mode 100644 index 0000000..43a6c86 --- /dev/null +++ b/lib/whois/server/server.rb @@ -0,0 +1,131 @@ +module Server + + # Define if the module has or not the Class in this module + def self.class_exist? str + begin + self.class_eval str.to_s + return true + rescue NameError + return false + end + end + + # Class For define a model of Server + class Server + attr_reader :server + end + + # Class for the server Afrinic + class Afrinic < Server + + def initialize + @server = 'whois.afrinic.net' + end + end + + # Class for the Server Apnic + class Apnic < Server + + def initialize + @server = 'whois.apnic.net' + end + end + + # Class for the Server Ripe + class Ripe < Server + def initialize + @server = 'whois.ripe.net' + end + end + + # Class for the Server Arin + class Arin < Server + def initialize + @server = 'whois.arin.net' + end + end + + # Class for the Server Lacnic + class Lacnic < Server + def initialize + @server = 'whois.lacnic.net' + end + end + + # Class for Server whois.nic.or.kr + class Nicor < Server + def initialize + @server = 'whois.nic.or.kr' + end + end + + # Class for Server whois.nic.ad.jp + class Nicad < Server + def initialize + @server = 'whois.nic.ad.jp' + end + end + + # Class for Server whois.nic.br + class Nicbr < Server + def initialize + @server = 'whois.nic.br' + end + end + + # Class for the teredo RFC 4773 + class Teredo < Server + def initialize + @server = nil + end + end + + # Class for 6To4 RFC 3056 + class Ipv6ToIpv4 < Server + def initialize + @server = nil + end + end + + # Class for server whois.kornet.net + class Kornet < Server + def initialize + @server = 'whois.kornet.net' + end + end + + # Class for server whois.v6nic.net + class V6nic < Server + def initialize + @server = 'whois.v6nic.net' + end + end + + # Class for server whois.twnic.net + class Twnic < Server + def initialize + @server = 'whois.twnic.net' + end + end + + # Class for server whois.verio.net + class Verio < Server + def initialize + @server = 'whois.verio.net' + end + end + + # Class for server whois.6bone.net + class Ipv6Bone < Server + def initialize + @server = 'whois.6bone.net' + end + end + + class Ginntt < Server + def initialize + @server = 'rwhois.gin.ntt.net' + end + end + +end diff --git a/lib/whois/whois.rb b/lib/whois/whois.rb new file mode 100755 index 0000000..9b07aef --- /dev/null +++ b/lib/whois/whois.rb @@ -0,0 +1,158 @@ +#!/usr/bin/ruby -w + +require 'socket' +require 'resolv' +require 'ipaddr' +require 'yaml' +require File.dirname(__FILE__) + '/server/server' + +# Module for manage all Whois Class +module Whois + + # Base exception of Whois + class WhoisException < Exception + end + + # Exception of Whois who made report a bug + class WhoisExceptionError < WhoisException + def initialize (i) + WhoisException.initialize('Report a bug with error #{i} to http://rubyforge.org/projects/whois/') + end + end + + # Class to get all information about Host or IP with the Whois request + class Whois + + Version = '0.4.0' + + attr_reader :all + attr_reader :server + attr_reader :ip + attr_reader :host + attr_accessor :host_search + + # Initialize with a request. The request must be an IPv4, or a host string + # + # The first params now is : + # * a string which a Ipv4, Ipv6 or a host. + # * A IPAddr instance + # + # A second param, host_search is optionnal. By default he is false. + # If this value is true, a resolv host is made for know the host to this IPv4 + def initialize(request, host_search=false) + @host_search = host_search + @host = nil + if request.instance_of? IPAddr + if request.ipv4? + @ip = request + @server = server_ipv4 + elsif request.ipv6? + @ip = request + @server = server_ipv6 + else + raise WhoisExceptionError.new(1) + end + elsif Resolv::IPv4::Regex =~ request + ipv4_init request + unless self.server + raise WhoisException.new("no server found for this IPv4 : #{request}") + end + elsif Resolv::IPv6::Regex =~ request + ipv6_init request + unless self.server + raise WhoisException.new("no server found for this Ipv6 : #{request}") + end + else + # Test if the request is an host or not + begin + ip = Resolv.getaddress request + @ip = IPAddr.new ip + @server = server_ipv4 + @host = request + rescue Resolv::ResolvError + raise WhoisException.new('host #{request} has no DNS result') + end + end + + search_host unless @host + end + + # Ask of whois server + def search_whois + s = TCPsocket.open(self.server.server, 43) + s.write("#{self.ip.to_s}\n") + ret = '' + while s.gets do ret += $_ end + s.close + @all = ret + end + + + # Search the host for this IPv4, if the value host_search is true, else host = nil + def search_host + begin + if @host_search + @host = Resolv.getname self.ip.to_s + else + @host = nil + end + rescue Resolv::ResolvError + @host = nil + end + end + + private + + # Init value for a ipv4 request + def ipv4_init (ip) + @ip = IPAddr.new ip + @server = server_ipv4 + end + + # Init value for a ipv6 request + def ipv6_init (ip) + @ip = IPAddr.new ip + @server = server_ipv6 + end + + # Return the Server with the hash of mask + def server_with_hash(ip_hash) + # Sort by mask of Ip Range + arr_tmp = ip_hash.sort{|b,c| c[0][/\/(.+)/, 1].to_i <=> b[0][/\/(.+)/, 1].to_i} + arr_tmp.each do |l| + ip_range = IPAddr.new l[0] + if ip_range.include? self.ip + return Object.instance_eval("Server::#{l[1]}.new") + end + end + end + + # Define the server of Whois in IPC6 list of YAML + def server_ipv6 + ipv6_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv6.yaml') + server = server_with_hash(ipv6_list) + unless server.kind_of? Server::Server + raise WhoisException.new("no server found for this IPv6 : #{self.ip}") + else + return server + end + end + + # Define the server of Whois in IPV4 list of YAML + def server_ipv4 + ipv4_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv4.yaml') + server = server_with_hash(ipv4_list) + unless server.kind_of? Server::Server + raise WhoisException.new("no server found for this IPv4 : #{self.ip}") + else + return server + end + end + end +end + + +if $0 == __FILE__ + w = Whois::Whois.new '218.14.221.147' + puts w.search_whois +end -- 2.30.2