sparoid 1.0.17 → 1.0.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8747bc66fcbc1b4f3e31d7246d2608298a882df7d5661aef6d51c7f7b99f406c
4
- data.tar.gz: 99e0f9044333f8d17e022f406e519abcd9977c420a86003fb4d69d891ba92475
3
+ metadata.gz: 9d3f9a0d1d95953662422a99f8d0170ce0db8df6ec82042e7f7d6d32e1721853
4
+ data.tar.gz: b2f702533aa2d6e1a96aed917a8cc77f8aa8916395944174c74644379392d7b8
5
5
  SHA512:
6
- metadata.gz: 16095424a1dce5589c2922191ce96a380dd0e973dcc77c1715ec0fe9af376b4caf3127645808c2d87a161797d7d929135fa80d32be8fd06e7ef14a86cefad72f
7
- data.tar.gz: 2a56181b6d57bc511ea35e10128f9536ad4bc480fb8fae007facd5e2ee7feb8cee3a7b4aeae910b1c03c5670b20de35f7f470e495d1b5a57dd3b5a422f0cc288
6
+ metadata.gz: c1803bdedaca58f7e172516864f502693e2478e43b7d9d5b8a0b5f306bb6284d4d19066e23235e9825c5f87ba0567f71388f19df52148cbce2637a17b8afd6d3
7
+ data.tar.gz: beb7813a740aa8d52d2689ee26c65872a45f991a9c2d2b937a46ba9451926471a064ca6635056441609a7bc8dfade4ef97aed2de130615b23d269e4ef308469e
@@ -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.18"
5
5
  end
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
- 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,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(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)
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(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
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)
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.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: 2021-11-15 00:00:00.000000000 Z
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.1.4
73
+ rubygems_version: 3.3.7
73
74
  signing_key:
74
75
  specification_version: 4
75
76
  summary: Single Packet Authorisation client