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 +4 -4
- data/lib/paraxial/checker.rb +130 -0
- data/lib/paraxial/cli.rb +16 -5
- data/lib/paraxial/helpers.rb +4 -0
- data/lib/paraxial/initializers/startup.rb +57 -50
- data/lib/paraxial/version.rb +1 -1
- data/lib/paraxial.rb +13 -8
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce7c75f780f9b356d4a15b4fb834bb6f064a8f5a39ead6e629a4f42ff2768010
|
4
|
+
data.tar.gz: 929b701d0e47c7a12b1654c3426e515b37824f591b7a65b2c9a22630c72bc8cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
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 = {
|
data/lib/paraxial/helpers.rb
CHANGED
@@ -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.
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
37
|
+
Thread.new do
|
38
|
+
Net::HTTP.post(uri, body.to_json, headers)
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
data/lib/paraxial/version.rb
CHANGED
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
|
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' }, [
|
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(
|
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
|
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.
|
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-
|
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
|