paraxial 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea5f2156685b5204495019d6a72ad0f433326438abfef4e70e26b39ab62bf58b
4
- data.tar.gz: 4dd855ada83c429df5422b42177af07863041ef94feb14912375df5f8d18e807
3
+ metadata.gz: ce7c75f780f9b356d4a15b4fb834bb6f064a8f5a39ead6e629a4f42ff2768010
4
+ data.tar.gz: 929b701d0e47c7a12b1654c3426e515b37824f591b7a65b2c9a22630c72bc8cc
5
5
  SHA512:
6
- metadata.gz: 5f458988de37e4a6c9c0a8f8e1489b613925faf48d11dc59c1addbcca49acc740292cddae12bd675c25c8c640a2f45133e5ed6d9232c8319f74fe868c2e2396e
7
- data.tar.gz: 81504558ae7231a7f5f5397f6ca640faf63532c15686d61942d54a306c0d28b865f3e11e8c17973729a1b200c74ad3246f149ca46a53635e91dfa229fe57a998
6
+ metadata.gz: b1d9decea112098e9c71cf36d071fe1fbe86028ac23b34d4b9a704771d7a007a42f56abbaea51dc65825067e0ac5d029781b7c344c82a3cd339716908f6d8451
7
+ data.tar.gz: 54bff15c7c351b7f3e74eae787d2858f12e4ded57be06cb3f5872147cdccae90819396837fa60e5ddeda6fff758eddeef0868fed4d02748c3873282c6c59306e
@@ -0,0 +1,130 @@
1
+ require 'rpatricia'
2
+ module Paraxial
3
+ module Checker
4
+ @allows = { 'v4' => Patricia.new, 'v6' => Patricia.new(:AF_INET6) }
5
+ @bans = { 'v4' => Patricia.new, 'v6' => Patricia.new(:AF_INET6) }
6
+
7
+ @thread = Thread.new do
8
+ loop do
9
+ get_abr
10
+ sleep(10)
11
+ end
12
+ end
13
+
14
+ def self.get_abr
15
+ uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/abr')
16
+ headers = { 'Content-Type': 'application/json' }
17
+
18
+ body = { api_key: ENV['PARAXIAL_API_KEY'] }
19
+ r = Net::HTTP.post(uri, body.to_json, headers)
20
+ if r.code == '200'
21
+ put_abr(JSON.parse(r.body))
22
+ else
23
+ 'ab_failed'
24
+ end
25
+ end
26
+
27
+ def self.put_abr(abr)
28
+ # Expected input: a hash
29
+ # {"allows"=>[{"address"=>[96, 56, 162, 210], "netmask"=>32}],
30
+ # "bans"=>
31
+ # [{"address"=>[8193, 3512, 34211, 0, 0, 35374, 880, 29492], "netmask"=>128},
32
+ # {"address"=>[111, 56, 162, 210], "netmask"=>32}],
33
+ # "rules"=>[]}
34
+ ipv4_a = []
35
+ ipv4_b = []
36
+ ipv6_a = []
37
+ ipv6_b = []
38
+ abr.each do |key, value|
39
+ next if key == 'rules' # skip rules for now
40
+
41
+ value.each do |ip|
42
+ address = ip['address']
43
+ if address.length == 4
44
+ if key == 'allows'
45
+ ipv4_a << address.join('.')
46
+ elsif key == 'bans'
47
+ ipv4_b << address.join('.')
48
+ end
49
+ elsif key == 'allows'
50
+ ipv6_a << address.map { |n| n.to_s(16).rjust(4, '0') }.join(':')
51
+ elsif key == 'bans'
52
+ ipv6_b << address.map { |n| n.to_s(16).rjust(4, '0') }.join(':')
53
+ end
54
+ end
55
+ end
56
+
57
+ ab = { 'allows' => { 'v4' => ipv4_a, 'v6' => ipv6_a }, 'bans' => { 'v4' => ipv4_b, 'v6' => ipv6_b } }
58
+ Paraxial::Checker.put(ab)
59
+ end
60
+
61
+ def self.put(allow_ban)
62
+ allows = allow_ban['allows']
63
+ bans = allow_ban['bans']
64
+ @allows = { 'v4' => create_patricia(allows['v4'], 'v4'), 'v6' => create_patricia(allows['v6'], 'v6') }
65
+ @bans = { 'v4' => create_patricia(bans['v4'], 'v4'), 'v6' => create_patricia(bans['v6'], 'v6') }
66
+ :ok
67
+ end
68
+
69
+ def self.create_patricia(list, type)
70
+ if type == 'v4'
71
+ p = Patricia.new
72
+ list.each do |ip|
73
+ p.add(ip)
74
+ end
75
+ p
76
+ elsif type == 'v6'
77
+ p = Patricia.new(:AF_INET6)
78
+ list.each do |ip|
79
+ p.add(ip)
80
+ end
81
+ p
82
+ else
83
+ raise 'Wrong type in Paraxial::Checker.create_patricia'
84
+ end
85
+ end
86
+
87
+ def self.ban_ip(ip)
88
+ if ip.include?('.')
89
+ # IPv4
90
+ current_t = @bans['v4']
91
+ current_t.add(ip)
92
+ @bans['v4'] = current_t
93
+ else
94
+ # IPv6
95
+ current_t = @bans['v6']
96
+ current_t.add(ip)
97
+ @bans['v6'] = current_t
98
+ end
99
+
100
+ uri = URI.parse(Paraxial::Helpers.get_ban_url)
101
+ headers = { 'Content-Type': 'application/json' }
102
+
103
+ body = { api_key: ENV['PARAXIAL_API_KEY'], ip_address: ip }
104
+ r = Net::HTTP.post(uri, body.to_json, headers)
105
+ if r.code == '200'
106
+ :ok
107
+ else
108
+ :error
109
+ end
110
+ end
111
+
112
+ def self.allow_ip?(ip)
113
+ if ip.include?('.')
114
+ if !@allows['v4'].search_best(ip).nil? # v4 on allow list
115
+ true
116
+ elsif !@bans['v4'].search_best(ip).nil? # v4 on ban list
117
+ false
118
+ else # v4 on no list
119
+ true
120
+ end
121
+ elsif !@allows['v6'].search_best(ip).nil? # v6 on allow list
122
+ true
123
+ elsif !@bans['v6'].search_best(ip).nil? # v6 on ban list
124
+ false
125
+ else # v6 on no list
126
+ true
127
+ end
128
+ end
129
+ end
130
+ end
data/lib/paraxial/cli.rb CHANGED
@@ -42,18 +42,29 @@ module Paraxial
42
42
  uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/ruby_scan')
43
43
  headers = { 'Content-Type': 'application/json' }
44
44
 
45
- body = { rubocop:, lockfile:, api_key:, timestamp: Paraxial.get_timestamp }
45
+ body = { rubocop: rubocop, lockfile: lockfile, api_key: api_key, timestamp: Paraxial.get_timestamp }
46
46
  response = Net::HTTP.post(uri, body.to_json, headers)
47
- puts "[Paraxial] scan result: #{response.body}"
47
+ m = JSON.parse(response.body)
48
+ findings = m['ok']['findings']
49
+ puts
50
+ puts "[Paraxial] Scan count #{findings.length}"
51
+ puts
52
+ findings.each do |finding|
53
+ puts finding
54
+ puts
55
+ end
56
+ puts "[Paraxial] Scan UUID #{m['ok']['scan_uuid']}"
57
+ puts "[Paraxial] Scan URL #{m['ok']['scan_url']}"
48
58
  github_valid = (!!github_app and !!install_id and !!repo_owner and !!repo_name and !!pr_number)
49
59
 
50
60
  if github_app and github_valid == false
51
61
  puts '[Paraxial] --github_app missing arguments'
52
62
  puts '[Paraxial] Required: --github_app, --install_id, --repo_owner, --repo_name, --pr_number'
53
63
  elsif github_app and github_valid
54
- uuid_regex = /UUID\s+(\S+)/
55
- match = response.body.match(uuid_regex)
56
- uuid = match[1] if match
64
+ # uuid_regex = /UUID\s+(\S+)/
65
+ # match = response.body.match(uuid_regex)
66
+ # uuid = match[1] if match
67
+ uuid = m['ok']['scan_uuid']
57
68
  if uuid
58
69
  final_uuid = uuid.chomp('.')
59
70
  censored_backend_map = {
@@ -3,5 +3,9 @@ module Paraxial
3
3
  def self.get_paraxial_url
4
4
  @paraxial_url ||= ENV['PARAXIAL_URL'] || 'https://app.paraxial.io/'
5
5
  end
6
+
7
+ def self.get_ban_url
8
+ get_paraxial_url + '/api/ban_ip'
9
+ end
6
10
  end
7
11
  end
@@ -2,65 +2,72 @@ require 'bundler'
2
2
  require 'paraxial'
3
3
  require 'rpatricia'
4
4
  require_relative '../helpers'
5
+ require_relative '../checker'
5
6
 
6
7
  Bundler.setup
7
8
 
8
- Rails.application.config.to_prepare do
9
- puts '[Paraxial] Init start'
10
- api_key = ENV['PARAXIAL_API_KEY']
9
+ unless Rails.env.test? || File.basename($0) == 'rake' || defined?(Rails::Generators)
10
+ Rails.application.config.to_prepare do
11
+ puts '[Paraxial] Init start'
12
+ api_key = ENV['PARAXIAL_API_KEY']
11
13
 
12
- if api_key.nil?
13
- puts '[Paraxial] Init PARAXIAL_API_KEY key not set, agent not started'
14
- elsif Rails.env.test?
15
- puts '[Paraxial] Init Test environment detected, agent not started'
16
- else
17
- begin
18
- puts '[Paraxial] Init config valid, agent starting'
19
- deps_and_licenses = []
20
- Bundler.load.specs.each do |spec|
21
- # Print the gem name and license
22
- h = { name: spec.name, version: spec.version.to_s, description: Paraxial.trim_dep(spec.description),
23
- license: spec.license || 'None' }
24
- deps_and_licenses << h
25
- end
26
- deps_and_licenses << { name: 'ruby', version: RUBY_VERSION, description: 'The Ruby Programming Language',
27
- license: 'Ruby' }
28
- uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/ruby_app_lic')
29
- headers = { 'Content-Type': 'application/json' }
14
+ if api_key.nil?
15
+ puts '[Paraxial] Init PARAXIAL_API_KEY key not set, agent not started'
16
+ elsif Rails.env.test?
17
+ puts '[Paraxial] Init Test environment detected, agent not started'
18
+ else
19
+ begin
20
+ puts '[Paraxial] Init config valid, agent starting'
21
+ deps_and_licenses = []
22
+ Bundler.load.specs.each do |spec|
23
+ # Print the gem name and license
24
+ h = { name: spec.name, version: spec.version.to_s, description: Paraxial.trim_dep(spec.description),
25
+ license: spec.license || 'None' }
26
+ deps_and_licenses << h
27
+ end
28
+ deps_and_licenses << { name: 'ruby', version: RUBY_VERSION, description: 'The Ruby Programming Language',
29
+ license: 'Ruby' }
30
+ uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/ruby_app_lic')
31
+ headers = { 'Content-Type': 'application/json' }
30
32
 
31
- body = { app_lic: deps_and_licenses, api_key:, timestamp: Paraxial.get_timestamp }
32
- cloud_uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/cloud_ip_list')
33
- response = Net::HTTP.get(cloud_uri)
33
+ body = { app_lic: deps_and_licenses, api_key:, timestamp: Paraxial.get_timestamp }
34
+ cloud_uri = URI.parse(Paraxial::Helpers.get_paraxial_url + '/api/cloud_ip_list')
35
+ response = Net::HTTP.get(cloud_uri)
34
36
 
35
- Thread.new do
36
- Net::HTTP.post(uri, body.to_json, headers)
37
- end
37
+ Thread.new do
38
+ Net::HTTP.post(uri, body.to_json, headers)
39
+ end
38
40
 
39
- # https://github.com/jkitching/rpatricia
40
- pt_v4 = Patricia.new
41
- pt_v6 = Patricia.new(:AF_INET6)
42
- cloud_list = JSON.parse(response)
43
- cloud_list.each do |k, v|
44
- if k.include?('::')
45
- pt_v6.add(k, v)
46
- else
47
- pt_v4.add(k, v)
41
+ # https://github.com/jkitching/rpatricia
42
+ pt_v4 = Patricia.new
43
+ pt_v6 = Patricia.new(:AF_INET6)
44
+ cloud_list = JSON.parse(response)
45
+ cloud_list.each do |k, v|
46
+ if k.include?('::')
47
+ pt_v6.add(k, v)
48
+ else
49
+ pt_v4.add(k, v)
50
+ end
48
51
  end
52
+ puts '[Paraxial] Cloud IPs set'
53
+ # puts '[Paraxial] pt_v4.num_nodes'
54
+ # puts pt_v4.num_nodes
55
+ # puts 'pt_v6.num_nodes'
56
+ # puts pt_v6.num_nodes
57
+ PARAXIAL_IPV4 = pt_v4
58
+ PARAXIAL_IPV6 = pt_v6
59
+ # ab = Paraxial.get_abr
60
+ # puts "[Paraxial] Allows/Bans set: #{ab}"
61
+ rescue Errno::ECONNREFUSED => _e
62
+ puts '[Paraxial] Init HTTP request failed, check configuration'
63
+ PARAXIAL_IPV4 = Patricia.new unless defined?(PARAXIAL_IPV4)
64
+ PARAXIAL_IPV6 = Patricia.new(:AF_INET6) unless defined?(PARAXIAL_IPV4)
65
+ rescue StandardError => e
66
+ puts e
67
+ puts '[Paraxial] Init error, check configuration'
68
+ PARAXIAL_IPV4 = Patricia.new unless defined?(PARAXIAL_IPV4)
69
+ PARAXIAL_IPV6 = Patricia.new(:AF_INET6) unless defined?(PARAXIAL_IPV4)
49
70
  end
50
- # puts '[Paraxial] pt_v4.num_nodes'
51
- # puts pt_v4.num_nodes
52
- # puts 'pt_v6.num_nodes'
53
- # puts pt_v6.num_nodes
54
- PARAXIAL_IPV4 = pt_v4
55
- PARAXIAL_IPV6 = pt_v6
56
- rescue Errno::ECONNREFUSED => _e
57
- puts '[Paraxial] Init HTTP request failed, check configuration'
58
- PARAXIAL_IPV4 = Patricia.new
59
- PARAXIAL_IPV6 = Patricia.new(:AF_INET6)
60
- rescue StandardError => _e
61
- puts '[Paraxial] Init error, check configuration'
62
- PARAXIAL_IPV4 = Patricia.new
63
- PARAXIAL_IPV6 = Patricia.new(:AF_INET6)
64
71
  end
65
72
  end
66
73
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Paraxial
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.0'
5
5
  end
data/lib/paraxial.rb CHANGED
@@ -9,10 +9,9 @@ require_relative 'rubocop/cop/paraxial/send'
9
9
  require_relative 'rubocop/cop/paraxial/constantize'
10
10
  require_relative 'rubocop/cop/paraxial/html_safe'
11
11
  require_relative 'rubocop/cop/paraxial/sql'
12
- require_relative "paraxial/version"
12
+ require_relative 'paraxial/version'
13
13
  require_relative 'paraxial/cli'
14
14
 
15
-
16
15
  module Paraxial
17
16
  class Error < StandardError; end
18
17
  # Your code goes here...
@@ -27,7 +26,7 @@ module Paraxial
27
26
 
28
27
  if request_path.end_with?('.php')
29
28
  # Return a 404 response if the request path ends with '.php'
30
- [404, { 'Content-Type' => 'text/plain' }, ["Not Found from Paraxial.io"]]
29
+ [404, { 'Content-Type' => 'text/plain' }, ['Not Found from Paraxial.io']]
31
30
  else
32
31
  # Pass the request to the next middleware or the application
33
32
  @app.call(env)
@@ -37,15 +36,23 @@ module Paraxial
37
36
 
38
37
  def self.get_timestamp
39
38
  utc_time = Time.now.utc
40
- utc_time.strftime("%Y-%m-%d %H:%M:%S.%6N") + "Z"
39
+ utc_time.strftime('%Y-%m-%d %H:%M:%S.%6N') + 'Z'
41
40
  end
42
41
 
43
42
  def self.cloud_ip?(ip)
44
43
  !!(PARAXIAL_IPV4.search_best(ip) or PARAXIAL_IPV6.search_best(ip))
45
44
  end
46
45
 
46
+ def self.ban_ip(ip)
47
+ Paraxial::Checker.ban_ip(ip)
48
+ end
49
+
50
+ def self.allow_ip?(ip)
51
+ Paraxial::Checker.allow_ip?(ip)
52
+ end
53
+
47
54
  def self.trim_dep(input)
48
- if input == nil
55
+ if input.nil?
49
56
  nil
50
57
  else
51
58
  cleaned_string = input.gsub(/\n/, '')
@@ -54,9 +61,7 @@ module Paraxial
54
61
  period_index = cleaned_string.index('.')
55
62
 
56
63
  # If there's a period, truncate the string up to that point
57
- if period_index
58
- cleaned_string = cleaned_string[0..period_index]
59
- end
64
+ cleaned_string = cleaned_string[0..period_index] if period_index
60
65
 
61
66
  cleaned_string
62
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paraxial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Lubas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-13 00:00:00.000000000 Z
11
+ date: 2024-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -80,6 +80,7 @@ files:
80
80
  - Rakefile
81
81
  - exe/paraxial
82
82
  - lib/paraxial.rb
83
+ - lib/paraxial/checker.rb
83
84
  - lib/paraxial/cli.rb
84
85
  - lib/paraxial/engine.rb
85
86
  - lib/paraxial/helpers.rb