sparoid 1.0.16 → 1.0.18
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 +10 -0
- data/lib/sparoid/cli.rb +11 -8
- data/lib/sparoid/version.rb +1 -1
- data/lib/sparoid.rb +38 -15
- data/sparoid.gemspec +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d3f9a0d1d95953662422a99f8d0170ce0db8df6ec82042e7f7d6d32e1721853
|
4
|
+
data.tar.gz: b2f702533aa2d6e1a96aed917a8cc77f8aa8916395944174c74644379392d7b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1803bdedaca58f7e172516864f502693e2478e43b7d9d5b8a0b5f306bb6284d4d19066e23235e9825c5f87ba0567f71388f19df52148cbce2637a17b8afd6d3
|
7
|
+
data.tar.gz: beb7813a740aa8d52d2689ee26c65872a45f991a9c2d2b937a46ba9451926471a064ca6635056441609a7bc8dfade4ef97aed2de130615b23d269e4ef308469e
|
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
@@ -1,3 +1,13 @@
|
|
1
|
+
## [1.0.18] - 2022-10-10
|
2
|
+
|
3
|
+
- Only resolv the IP(s) once
|
4
|
+
- TCP connect to IPs in parallel
|
5
|
+
- Fix bug where 3 UDP packets was sent to each IP
|
6
|
+
|
7
|
+
## [1.0.17] - 2021-11-15
|
8
|
+
|
9
|
+
- Raise more specific error when failing to resolv hostname
|
10
|
+
|
1
11
|
## [1.0.16] - 2021-08-23
|
2
12
|
|
3
13
|
- Resolv host IPs before generating message (in case resolving takes a lot of time)
|
data/lib/sparoid/cli.rb
CHANGED
@@ -6,6 +6,8 @@ require_relative "../sparoid"
|
|
6
6
|
module Sparoid
|
7
7
|
# CLI
|
8
8
|
class CLI < Thor
|
9
|
+
map "-v" => :version
|
10
|
+
|
9
11
|
desc "auth HOST [PORT]", "Send a authorization packet"
|
10
12
|
method_option :config, desc: "Path to a config file, INI format, with key and hmac-key", default: "~/.sparoid.ini"
|
11
13
|
def auth(host, port = 8484)
|
@@ -19,12 +21,8 @@ module Sparoid
|
|
19
21
|
desc "connect HOST PORT [SPA-PORT]", "Send a SPA, TCP connect, and then pass the FD back to the parent"
|
20
22
|
method_option :config, desc: "Path to a config file, INI format, with key and hmac-key", default: "~/.sparoid.ini"
|
21
23
|
def connect(host, port, spa_port = 8484)
|
22
|
-
|
23
|
-
|
24
|
-
rescue Errno::ENOENT
|
25
|
-
warn "Sparoid: Config not found"
|
26
|
-
end
|
27
|
-
Sparoid.fdpass(host, port)
|
24
|
+
ips = send_auth(host, spa_port, options[:config])
|
25
|
+
Sparoid.fdpass(ips, port)
|
28
26
|
rescue StandardError => e
|
29
27
|
abort "Sparoid: #{e.message} (#{host})"
|
30
28
|
end
|
@@ -34,6 +32,11 @@ module Sparoid
|
|
34
32
|
Sparoid.keygen
|
35
33
|
end
|
36
34
|
|
35
|
+
desc "version", "Show version and exit"
|
36
|
+
def version
|
37
|
+
puts "#{Sparoid::VERSION} (ruby)"
|
38
|
+
end
|
39
|
+
|
37
40
|
def self.exit_on_failure?
|
38
41
|
true
|
39
42
|
end
|
@@ -49,8 +52,8 @@ module Sparoid
|
|
49
52
|
File.readlines(File.expand_path(path)).map! { |line| line.split("=", 2).map!(&:strip) }.to_h
|
50
53
|
rescue Errno::ENOENT
|
51
54
|
{
|
52
|
-
"key" => ENV
|
53
|
-
"hmac-key" => ENV
|
55
|
+
"key" => ENV.fetch("SPAROID_KEY", nil),
|
56
|
+
"hmac-key" => ENV.fetch("SPAROID_HMAC_KEY", nil)
|
54
57
|
}
|
55
58
|
end
|
56
59
|
|
data/lib/sparoid/version.rb
CHANGED
data/lib/sparoid.rb
CHANGED
@@ -13,17 +13,19 @@ module Sparoid
|
|
13
13
|
|
14
14
|
# Send an authorization packet
|
15
15
|
def auth(key, hmac_key, host, port)
|
16
|
-
|
17
|
-
raise(
|
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,42 @@ 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)
|
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
|
+
writeable.each do |s|
|
52
|
+
idx = sockets.index(s)
|
53
|
+
sockets.delete_at(idx) # don't retry this socket again
|
54
|
+
ip = ips.delete_at(idx) # find the IP for the socket
|
55
|
+
s.connect_nonblock(Socket.sockaddr_in(port, ip)) # check for errors
|
56
|
+
# pass the connected FD to the parent process over STDOUT
|
57
|
+
Socket.for_fd(1).sendmsg "\0", 0, nil, Socket::AncillaryData.unix_rights(s)
|
58
|
+
exit 0 # exit as fast as possible so that other sockets don't connect
|
59
|
+
rescue SystemCallError
|
60
|
+
next # ignore connection errors, hopefully at least one succeeds
|
61
|
+
end
|
62
|
+
end
|
63
|
+
exit 1 # all connections failed
|
43
64
|
end
|
44
65
|
|
45
66
|
private
|
46
67
|
|
47
|
-
def sendmsg(
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
warn "Sparoid error: #{e.message}"
|
54
|
-
end
|
68
|
+
def sendmsg(addrs, data)
|
69
|
+
socket = Socket.new Socket::AF_INET, Socket::SOCK_DGRAM
|
70
|
+
addrs.each do |addr|
|
71
|
+
socket.sendmsg data, 0, addr
|
72
|
+
rescue StandardError => e
|
73
|
+
warn "Sparoid error: #{e.message}"
|
55
74
|
end
|
75
|
+
ensure
|
76
|
+
socket.close
|
56
77
|
end
|
57
78
|
|
58
79
|
def encrypt(key, data)
|
@@ -131,6 +152,8 @@ module Sparoid
|
|
131
152
|
|
132
153
|
class Error < StandardError; end
|
133
154
|
|
155
|
+
class ResolvError < Error; end
|
156
|
+
|
134
157
|
# Instance of SPAroid that only resolved public_ip once
|
135
158
|
class Instance
|
136
159
|
include Sparoid
|
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.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carl Hörberg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -54,6 +54,7 @@ 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
|
+
rubygems_mfa_required: 'true'
|
57
58
|
post_install_message:
|
58
59
|
rdoc_options: []
|
59
60
|
require_paths:
|
@@ -69,7 +70,7 @@ 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
|
+
rubygems_version: 3.3.7
|
73
74
|
signing_key:
|
74
75
|
specification_version: 4
|
75
76
|
summary: Single Packet Authorisation client
|