sparoid 1.0.17 → 1.0.19
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/.github/workflows/main.yml +9 -9
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +6 -0
- data/lib/sparoid/cli.rb +4 -8
- data/lib/sparoid/version.rb +1 -1
- data/lib/sparoid.rb +40 -17
- data/sparoid.gemspec +1 -0
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa860bf3df506199abf0f4abb417458de5758c1f87d2c7226688ed57f8f7a089
|
4
|
+
data.tar.gz: 46d9e5756c5eaaf85cd5cd51ebcf67aadc48929cb161d11a15236b24ddf02086
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6601f26feedc978e69aee6c10b573fb7a0cf0304da6a083f7236ccfaa4b12ea0586b263845a65bcb7bde7ba217bae299f3c941eaa8592e16291851a3395b82f8
|
7
|
+
data.tar.gz: 6e71a0ee6ab5627e589808f753aed3d6dc39c6c04ada839fccbc85138d6bf46c391b7cb0565a738179d143b9e17a9cde8c37b6fbe28d525b734346690ba09434
|
data/.github/workflows/main.yml
CHANGED
@@ -4,15 +4,15 @@ on: [push,pull_request]
|
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
ruby: [ 2.7, '3.0', 3.1, ruby-head ]
|
7
11
|
runs-on: ubuntu-latest
|
8
12
|
steps:
|
9
|
-
- uses: actions/checkout@
|
10
|
-
-
|
11
|
-
uses: ruby/setup-ruby@v1
|
13
|
+
- uses: actions/checkout@v3
|
14
|
+
- uses: ruby/setup-ruby@v1
|
12
15
|
with:
|
13
|
-
ruby-version:
|
14
|
-
-
|
15
|
-
|
16
|
-
gem install bundler -v 2.2.14
|
17
|
-
bundle install
|
18
|
-
bundle exec rake
|
16
|
+
ruby-version: ${{ matrix.ruby }}
|
17
|
+
- run: bundle install
|
18
|
+
- run: bundle exec rake
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/lib/sparoid/cli.rb
CHANGED
@@ -21,12 +21,8 @@ module Sparoid
|
|
21
21
|
desc "connect HOST PORT [SPA-PORT]", "Send a SPA, TCP connect, and then pass the FD back to the parent"
|
22
22
|
method_option :config, desc: "Path to a config file, INI format, with key and hmac-key", default: "~/.sparoid.ini"
|
23
23
|
def connect(host, port, spa_port = 8484)
|
24
|
-
|
25
|
-
|
26
|
-
rescue Errno::ENOENT
|
27
|
-
warn "Sparoid: Config not found"
|
28
|
-
end
|
29
|
-
Sparoid.fdpass(host, port)
|
24
|
+
ips = send_auth(host, spa_port, options[:config])
|
25
|
+
Sparoid.fdpass(ips, port)
|
30
26
|
rescue StandardError => e
|
31
27
|
abort "Sparoid: #{e.message} (#{host})"
|
32
28
|
end
|
@@ -56,8 +52,8 @@ module Sparoid
|
|
56
52
|
File.readlines(File.expand_path(path)).map! { |line| line.split("=", 2).map!(&:strip) }.to_h
|
57
53
|
rescue Errno::ENOENT
|
58
54
|
{
|
59
|
-
"key" => ENV
|
60
|
-
"hmac-key" => ENV
|
55
|
+
"key" => ENV.fetch("SPAROID_KEY", nil),
|
56
|
+
"hmac-key" => ENV.fetch("SPAROID_HMAC_KEY", nil)
|
61
57
|
}
|
62
58
|
end
|
63
59
|
|
data/lib/sparoid/version.rb
CHANGED
data/lib/sparoid.rb
CHANGED
@@ -6,24 +6,26 @@ require "openssl"
|
|
6
6
|
require "resolv"
|
7
7
|
|
8
8
|
# Single Packet Authorisation client
|
9
|
-
module Sparoid
|
9
|
+
module Sparoid # rubocop:disable Metrics/ModuleLength
|
10
10
|
extend self
|
11
11
|
|
12
12
|
SPAROID_CACHE_PATH = ENV.fetch("SPAROID_CACHE_PATH", "/tmp/.sparoid_public_ip")
|
13
13
|
|
14
14
|
# Send an authorization packet
|
15
15
|
def auth(key, hmac_key, host, port)
|
16
|
-
|
17
|
-
raise(ResolvError, "Sparoid failed to resolv #{host}") if
|
16
|
+
addrs = Addrinfo.getaddrinfo(host, port, :INET, :DGRAM)
|
17
|
+
raise(ResolvError, "Sparoid failed to resolv #{host}") if addrs.empty?
|
18
18
|
|
19
19
|
msg = message(cached_public_ip)
|
20
20
|
data = prefix_hmac(hmac_key, encrypt(key, msg))
|
21
|
-
sendmsg(
|
21
|
+
sendmsg(addrs, data)
|
22
22
|
|
23
23
|
# wait some time for the server to actually open the port
|
24
24
|
# if we don't wait the next SYN package will be dropped
|
25
25
|
# and it have to be redelivered, adding 1 second delay
|
26
26
|
sleep 0.02
|
27
|
+
|
28
|
+
addrs.map(&:ip_address) # return resolved IP(s)
|
27
29
|
end
|
28
30
|
|
29
31
|
# Generate new aes and hmac keys, print to stdout
|
@@ -36,23 +38,44 @@ module Sparoid
|
|
36
38
|
end
|
37
39
|
|
38
40
|
# Connect to a TCP server and pass the FD to the parent
|
39
|
-
def fdpass(
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
def fdpass(ips, port, connect_timeout: 10) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
42
|
+
# try connect to all IPs
|
43
|
+
sockets = ips.map do |ip|
|
44
|
+
Socket.new(Socket::AF_INET, Socket::SOCK_STREAM).tap do |s|
|
45
|
+
s.connect_nonblock(Socket.sockaddr_in(port, ip), exception: false)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# wait for any socket to be connected
|
49
|
+
until sockets.empty?
|
50
|
+
_, writeable, = IO.select(nil, sockets, nil, connect_timeout)
|
51
|
+
break if writeable.nil? # All sockets timedout
|
52
|
+
|
53
|
+
writeable.each do |s|
|
54
|
+
idx = sockets.index(s)
|
55
|
+
sockets.delete_at(idx) # don't retry this socket again
|
56
|
+
ip = ips.delete_at(idx) # find the IP for the socket
|
57
|
+
s.connect_nonblock(Socket.sockaddr_in(port, ip)) # check for errors
|
58
|
+
# pass the connected FD to the parent process over STDOUT
|
59
|
+
Socket.for_fd(1).sendmsg "\0", 0, nil, Socket::AncillaryData.unix_rights(s)
|
60
|
+
exit 0 # exit as fast as possible so that other sockets don't connect
|
61
|
+
rescue SystemCallError
|
62
|
+
next # ignore connection errors, hopefully at least one succeeds
|
63
|
+
end
|
64
|
+
end
|
65
|
+
exit 1 # all connections failed
|
43
66
|
end
|
44
67
|
|
45
68
|
private
|
46
69
|
|
47
|
-
def sendmsg(
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
warn "Sparoid error: #{e.message}"
|
54
|
-
end
|
70
|
+
def sendmsg(addrs, data)
|
71
|
+
socket = Socket.new Socket::AF_INET, Socket::SOCK_DGRAM
|
72
|
+
addrs.each do |addr|
|
73
|
+
socket.sendmsg data, 0, addr
|
74
|
+
rescue StandardError => e
|
75
|
+
warn "Sparoid error: #{e.message}"
|
55
76
|
end
|
77
|
+
ensure
|
78
|
+
socket.close
|
56
79
|
end
|
57
80
|
|
58
81
|
def encrypt(key, data)
|
@@ -108,7 +131,7 @@ module Sparoid
|
|
108
131
|
Resolv::IPv4.create f.read
|
109
132
|
end
|
110
133
|
rescue ArgumentError => e
|
111
|
-
return write_cache if
|
134
|
+
return write_cache if /cannot interpret as IPv4 address/.match?(e.message)
|
112
135
|
|
113
136
|
raise e
|
114
137
|
end
|
data/sparoid.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carl Hörberg
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description:
|
28
28
|
email:
|
29
29
|
- carl@84codes.com
|
30
30
|
executables:
|
@@ -54,7 +54,8 @@ metadata:
|
|
54
54
|
homepage_uri: https://github.com/84codes/sparoid.rb
|
55
55
|
source_code_uri: https://github.com/84codes/sparoid.rb
|
56
56
|
changelog_uri: https://raw.githubusercontent.com/84codes/sparoid.rb/main/CHANGELOG.md
|
57
|
-
|
57
|
+
rubygems_mfa_required: 'true'
|
58
|
+
post_install_message:
|
58
59
|
rdoc_options: []
|
59
60
|
require_paths:
|
60
61
|
- lib
|
@@ -69,8 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
70
|
- !ruby/object:Gem::Version
|
70
71
|
version: '0'
|
71
72
|
requirements: []
|
72
|
-
rubygems_version: 3.
|
73
|
-
signing_key:
|
73
|
+
rubygems_version: 3.3.7
|
74
|
+
signing_key:
|
74
75
|
specification_version: 4
|
75
76
|
summary: Single Packet Authorisation client
|
76
77
|
test_files: []
|