paraxial 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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