class SpamProtection

Constants

HOST_RBLS
IP_RBLS
SECOND_LEVEL

Attributes

this_blog[RW]

Public Class Methods

new(a_blog) click to toggle source
# File lib/spam_protection.rb, line 12
def initialize(a_blog)
  self.this_blog = a_blog
end

Public Instance Methods

is_spam?(string) click to toggle source
# File lib/spam_protection.rb, line 16
def is_spam?(string)
  return false unless this_blog.sp_global
  return false if string.blank?

  reason = catch(:hit) do
    case string
    when Format::IP_ADDRESS then scan_ip(string)
    when Format::HTTP_URI then scan_uris([string])
    else scan_text(string)
    end
  end

  if reason
    logger.info("[SP] Hit: #{reason}")
    true
  end
end

Protected Instance Methods

check_uri_count(uris) click to toggle source
# File lib/spam_protection.rb, line 51
def check_uri_count(uris)
  limit = this_blog.sp_url_limit
  return if limit.to_i.zero?

  throw :hit, "Hard URL Limit hit: #{uris.size} > #{limit}" if uris.size > limit
end
logger() click to toggle source
# File lib/spam_protection.rb, line 100
def logger
  @logger ||= ::Rails.logger || Logger.new($stdout)
end
query_rbls(rbls, *subdomains) click to toggle source
# File lib/spam_protection.rb, line 82
def query_rbls(rbls, *subdomains)
  rbls.each do |rbl|
    subdomains.uniq.each do |d|
      begin
        response = IPSocket.getaddress([d, rbl].join("."))
        if response.start_with?("127.0.0.")
          throw :hit,
                "#{rbl} positively resolved subdomain #{d} => #{response}"
        end
      rescue SocketError
        # NXDOMAIN response => negative:  d is not in RBL
        next
      end
    end
  end
  false
end
scan_ip(ip_address) click to toggle source
# File lib/spam_protection.rb, line 36
def scan_ip(ip_address)
  logger.info("[SP] Scanning IP #{ip_address}")
  query_rbls(IP_RBLS, ip_address.split(".").reverse.join("."))
end
scan_text(string) click to toggle source
# File lib/spam_protection.rb, line 41
def scan_text(string)
  # FIXME: Unify HTTP URI matchers
  uri_list = string.scan(%r{(http://[^\s"]+)}m).flatten

  check_uri_count(uri_list)
  scan_uris(uri_list)

  false
end
scan_uris(uris = []) click to toggle source
# File lib/spam_protection.rb, line 58
def scan_uris(uris = [])
  uris.each do |uri|
    host = begin
             URI.parse(uri).host
           rescue URI::InvalidURIError
             next
           end
    return scan_ip(host) if Format::IP_ADDRESS.match?(host)

    host_parts = host.split(".").reverse
    domain = []

    # Check for two level TLD
    (SECOND_LEVEL.include?(host_parts[1]) ? 3 : 2).times do
      domain.unshift(host_parts.shift)
    end

    logger.info("[SP] Scanning domain #{domain.join(".")}")
    query_rbls(HOST_RBLS, host, domain.join("."))
    logger.info("[SP] Finished domain scan #{domain.join(".")}")
    return false
  end
end