Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / drb / acl.rb
blob861c8a514d20bf21f0988160911cc3c9e7390f72
1 # acl-2.0 - simple Access Control List
3 # Copyright (c) 2000,2002,2003 Masatoshi SEKI
5 # acl.rb is copyrighted free software by Masatoshi SEKI.
6 # You can redistribute it and/or modify it under the same terms as Ruby.
8 require 'ipaddr'
10 class ACL
11   VERSION=["2.0.0"]
12   class ACLEntry
13     def initialize(str)
14       if str == '*' or str == 'all'
15         @pat = [:all]
16       elsif str.include?('*')
17         @pat = [:name, dot_pat(str)]
18       else
19         begin
20           @pat = [:ip, IPAddr.new(str)]
21         rescue ArgumentError
22           @pat = [:name, dot_pat(str)]
23         end
24       end
25     end
27     private
28     def dot_pat_str(str)
29       list = str.split('.').collect { |s|
30         (s == '*') ? '.+' : s
31       }
32       list.join("\\.")
33     end
35     private
36     def dot_pat(str)
37       exp = "^" + dot_pat_str(str) + "$"
38       Regexp.new(exp)
39     end
41     public
42     def match(addr)
43       case @pat[0]
44       when :all
45         true
46       when :ip
47         begin
48           ipaddr = IPAddr.new(addr[3])
49           ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
50         rescue ArgumentError
51           return false
52         end
53         (@pat[1].include?(ipaddr)) ? true : false
54       when :name
55         (@pat[1] =~ addr[2]) ? true : false
56       else
57         false
58       end
59     end
60   end
62   class ACLList
63     def initialize
64       @list = []
65     end
67     public
68     def match(addr)
69       @list.each do |e|
70         return true if e.match(addr)
71       end
72       false
73     end
75     public
76     def add(str)
77       @list.push(ACLEntry.new(str))
78     end
79   end
81   DENY_ALLOW = 0
82   ALLOW_DENY = 1
84   def initialize(list=nil, order = DENY_ALLOW)
85     @order = order
86     @deny = ACLList.new
87     @allow = ACLList.new
88     install_list(list) if list
89   end
91   public
92   def allow_socket?(soc)
93     allow_addr?(soc.peeraddr)
94   end
96   public
97   def allow_addr?(addr)
98     case @order
99     when DENY_ALLOW
100       return true if @allow.match(addr)
101       return false if @deny.match(addr)
102       return true
103     when ALLOW_DENY
104       return false if @deny.match(addr)
105       return true if @allow.match(addr)
106       return false
107     else
108       false
109     end
110   end
112   public
113   def install_list(list)
114     i = 0
115     while i < list.size
116       permission, domain = list.slice(i,2)
117       case permission.downcase
118       when 'allow'
119         @allow.add(domain)
120       when 'deny'
121         @deny.add(domain)
122       else
123         raise "Invalid ACL entry #{list.to_s}"
124       end
125       i += 2
126     end
127   end
130 if __FILE__ == $0
131   # example
132   list = %w(deny all
133             allow 192.168.1.1
134             allow ::ffff:192.168.1.2
135             allow 192.168.1.3
136             )
138   addr = ["AF_INET", 10, "lc630", "192.168.1.3"]
140   acl = ACL.new
141   p acl.allow_addr?(addr)
143   acl = ACL.new(list, ACL::DENY_ALLOW)
144   p acl.allow_addr?(addr)