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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8747bc66fcbc1b4f3e31d7246d2608298a882df7d5661aef6d51c7f7b99f406c
4
- data.tar.gz: 99e0f9044333f8d17e022f406e519abcd9977c420a86003fb4d69d891ba92475
3
+ metadata.gz: aa860bf3df506199abf0f4abb417458de5758c1f87d2c7226688ed57f8f7a089
4
+ data.tar.gz: 46d9e5756c5eaaf85cd5cd51ebcf67aadc48929cb161d11a15236b24ddf02086
5
5
  SHA512:
6
- metadata.gz: 16095424a1dce5589c2922191ce96a380dd0e973dcc77c1715ec0fe9af376b4caf3127645808c2d87a161797d7d929135fa80d32be8fd06e7ef14a86cefad72f
7
- data.tar.gz: 2a56181b6d57bc511ea35e10128f9536ad4bc480fb8fae007facd5e2ee7feb8cee3a7b4aeae910b1c03c5670b20de35f7f470e495d1b5a57dd3b5a422f0cc288
6
+ metadata.gz: 6601f26feedc978e69aee6c10b573fb7a0cf0304da6a083f7236ccfaa4b12ea0586b263845a65bcb7bde7ba217bae299f3c941eaa8592e16291851a3395b82f8
7
+ data.tar.gz: 6e71a0ee6ab5627e589808f753aed3d6dc39c6c04ada839fccbc85138d6bf46c391b7cb0565a738179d143b9e17a9cde8c37b6fbe28d525b734346690ba09434
@@ -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@v2
10
- - name: Set up Ruby
11
- uses: ruby/setup-ruby@v1
13
+ - uses: actions/checkout@v3
14
+ - uses: ruby/setup-ruby@v1
12
15
  with:
13
- ruby-version: 2.7.2
14
- - name: Run the default task
15
- run: |
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
@@ -1,6 +1,7 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.5
3
3
  NewCops: enable
4
+ SuggestExtensions: false
4
5
 
5
6
  Style/StringLiterals:
6
7
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
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
+
1
7
  ## [1.0.17] - 2021-11-15
2
8
 
3
9
  - Raise more specific error when failing to resolv hostname
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
- begin
25
- send_auth(host, spa_port, options[:config])
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["SPAROID_KEY"],
60
- "hmac-key" => ENV["SPAROID_HMAC_KEY"]
55
+ "key" => ENV.fetch("SPAROID_KEY", nil),
56
+ "hmac-key" => ENV.fetch("SPAROID_HMAC_KEY", nil)
61
57
  }
62
58
  end
63
59
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sparoid
4
- VERSION = "1.0.17"
4
+ VERSION = "1.0.19"
5
5
  end
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
- ips = Resolv.getaddresses(host)
17
- raise(ResolvError, "Sparoid failed to resolv #{host}") if ips.empty?
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(ips, port, data)
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(host, port, connect_timeout: 20)
40
- tcp = Socket.tcp host, port, connect_timeout: connect_timeout
41
- parent = Socket.for_fd(1)
42
- parent.sendmsg "\0", 0, nil, Socket::AncillaryData.unix_rights(tcp)
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(ips, port, data)
48
- UDPSocket.open do |socket|
49
- ips.each do |ip|
50
- socket.connect ip, port
51
- socket.sendmsg data, 0
52
- rescue StandardError => e
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 e.message =~ /cannot interpret as IPv4 address/
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
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
 
29
29
  spec.add_dependency "thor"
30
+ spec.metadata["rubygems_mfa_required"] = "true"
30
31
  end
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.17
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: 2021-11-15 00:00:00.000000000 Z
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
- post_install_message:
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.1.4
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: []