summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2016-01-20 14:24:20 -0500
committerRobert Speicher <rspeicher@gmail.com>2016-01-20 14:24:20 -0500
commit1553c560e0d02e670b7cec2b443545e67418b569 (patch)
tree81c4fbabbd376d80db86a09d39f79ea35abee068 /lib
parenta8a65afe1e953ce3a9fc151f9e033b99fc568fad (diff)
parent8536e083f7b2d7ed77ecae83774d75f68d66e0b4 (diff)
downloadgitlab-ce-1553c560e0d02e670b7cec2b443545e67418b569.tar.gz
Merge branch 'feature/check-against-rbl-only' into 'master'
Split from !2455 References #9092 See merge request !2515
Diffstat (limited to 'lib')
-rw-r--r--lib/dnsxl_check.rb105
-rw-r--r--lib/gitlab/ip_check.rb34
2 files changed, 139 insertions, 0 deletions
diff --git a/lib/dnsxl_check.rb b/lib/dnsxl_check.rb
new file mode 100644
index 00000000000..1e506b2d9cb
--- /dev/null
+++ b/lib/dnsxl_check.rb
@@ -0,0 +1,105 @@
+require 'resolv'
+
+class DNSXLCheck
+
+ class Resolver
+ def self.search(query)
+ begin
+ Resolv.getaddress(query)
+ true
+ rescue Resolv::ResolvError
+ false
+ end
+ end
+ end
+
+ IP_REGEXP = /\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/
+ DEFAULT_THRESHOLD = 0.33
+
+ def self.create_from_list(list)
+ dnsxl_check = DNSXLCheck.new
+
+ list.each do |entry|
+ dnsxl_check.add_list(entry.domain, entry.weight)
+ end
+
+ dnsxl_check
+ end
+
+ def test(ip)
+ if use_threshold?
+ test_with_threshold(ip)
+ else
+ test_strict(ip)
+ end
+ end
+
+ def test_with_threshold(ip)
+ return false if lists.empty?
+
+ search(ip)
+ final_score >= threshold
+ end
+
+ def test_strict(ip)
+ return false if lists.empty?
+
+ search(ip)
+ @score > 0
+ end
+
+ def use_threshold=(value)
+ @use_threshold = value == true
+ end
+
+ def use_threshold?
+ @use_threshold &&= true
+ end
+
+ def threshold=(threshold)
+ raise ArgumentError, "'threshold' value must be grather than 0 and less than or equal to 1" unless threshold > 0 && threshold <= 1
+ @threshold = threshold
+ end
+
+ def threshold
+ @threshold ||= DEFAULT_THRESHOLD
+ end
+
+ def add_list(domain, weight)
+ @lists ||= []
+ @lists << { domain: domain, weight: weight }
+ end
+
+ def lists
+ @lists ||= []
+ end
+
+ private
+
+ def search(ip)
+ raise ArgumentError, "'ip' value must be in #{IP_REGEXP} format" unless ip.match(IP_REGEXP)
+
+ @score = 0
+
+ reversed = reverse_ip(ip)
+ search_in_rbls(reversed)
+ end
+
+ def reverse_ip(ip)
+ ip.split('.').reverse.join('.')
+ end
+
+ def search_in_rbls(reversed_ip)
+ lists.each do |rbl|
+ query = "#{reversed_ip}.#{rbl[:domain]}"
+ @score += rbl[:weight] if Resolver.search(query)
+ end
+ end
+
+ def final_score
+ weights = lists.map{ |rbl| rbl[:weight] }.reduce(:+).to_i
+ return 0 if weights == 0
+
+ (@score.to_f / weights.to_f).round(2)
+ end
+end
diff --git a/lib/gitlab/ip_check.rb b/lib/gitlab/ip_check.rb
new file mode 100644
index 00000000000..f2e9b50d225
--- /dev/null
+++ b/lib/gitlab/ip_check.rb
@@ -0,0 +1,34 @@
+module Gitlab
+ class IpCheck
+
+ def initialize(ip)
+ @ip = ip
+
+ application_settings = ApplicationSetting.current
+ @ip_blocking_enabled = application_settings.ip_blocking_enabled
+ @dnsbl_servers_list = application_settings.dnsbl_servers_list
+ end
+
+ def spam?
+ @ip_blocking_enabled && blacklisted?
+ end
+
+ private
+
+ def blacklisted?
+ on_dns_blacklist?
+ end
+
+ def on_dns_blacklist?
+ dnsbl_check = DNSXLCheck.new
+ prepare_dnsbl_list(dnsbl_check)
+ dnsbl_check.test(@ip)
+ end
+
+ def prepare_dnsbl_list(dnsbl_check)
+ @dnsbl_servers_list.split(',').map(&:strip).reject(&:empty?).each do |domain|
+ dnsbl_check.add_list(domain, 1)
+ end
+ end
+ end
+end