咳といいます。

TCPServerで使用する、アクセス制御リスト(ほんとにこんな名前かしら?)を
書いてみました。Apacheで言うところの mod_access みたいのです。

本当はdRubyを実用で使うために書いたのですが、
一般化してみました。

TCPServerを使ったサーバのメインループで、クライアントの
マシン名、IPアドレスをもとにアクセスを拒否したりするのに使います。

使い方)

  acl = ACL.new(%w(deny all
                   allow 192.168.*.*
                   allow myhost.*
                   allow *.mydomain.jp
                   allow localhost))
  
  としておいて、

  ns = soc.accept
  unless acl.allow_socket?(ns)
    アクセス拒否の処理
  end
  
  hostの指示は次のものがあります。
  o 全部 … all または *
  o IPアドレス … 192.168.1.1 や 192.*.*.*, *.168.*.* など。
  o マシン名 … host.foo.bar.jp や host.*、*.bar.jp など
 

きっとへんなところがあると思います。
指摘まってますです。



#/usr/local/bin/ruby # acl.rb - simple Access Control List # # $Date: 2000/05/04 15:56:42 $ # Copyright (c) 2000 Masatoshi SEKI # # acl.rb is copyrighted free software by Masatoshi SEKI. # You can redistribute it and/or modify it under the same term as Ruby. class ACL class ACLEntry def initialize(str) if str == '*' or str == 'all' @pat = [:all] elsif str =~ /^[0-9*]+\.[0-9*]+\.[0-9*]+\.[0-9*]+$/ @pat = [:ip, dot_pat(str)] else @pat = [:name, dot_pat(str)] end end def dot_pat(str) list = str.split('.').collect { |s| (s == '*') ? '.*' : s } str = list.join("\\.") exp = "^" + str + "$" Regexp.new(exp) end private :dot_pat def match(addr) case @pat[0] when :all true when :ip @pat[1] =~ addr[3] when :name @pat[1] =~ addr[2] else nil end end end class ACLList def initialize @list = [] end def match(addr) @list.each do |e| return true if e.match(addr) end false end def add(str) @list.push(ACLEntry.new(str)) end end DENY_ALLOW = 0 ALLOW_DENY = 1 def initialize(list=nil, order = DENY_ALLOW) @order = order @deny = ACLList.new @allow = ACLList.new install_list(list) if list end attr_reader(:order, :deny, :allow) def allow_socket?(soc) allow_addr?(soc.peeraddr) end def allow_addr?(addr) case @order when DENY_ALLOW return true if @allow.match(addr) return false if @deny.match(addr) return true when ALLOW_DENY return false if @deny.match(addr) return true if @allow.match(addr) return false else false end end def install_list(list) for i in (0..(list.size/2-1)) case list[i*2].downcase when 'allow' @allow.add(list[i*2+1]) when 'deny' @deny.add(list[i*2+1]) else raise "Invalid ACL entry #{list.to_s}" end end end end if __FILE__ == $0 list = %w(deny all allow 192.168.1.1 allow 192.168.1.2) addr = ["AF_INET", 10, "lc630", "192.168.1.3"] acl = ACL.new(nil, ACL::DENY_ALLOW) p acl.allow_addr?(addr) acl.install_list(list) p acl.allow_addr?(addr) acl = ACL.new(list, ACL::DENY_ALLOW) p acl.allow_addr?(addr) end