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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11677eb6c66244eed7b68e11a2d543db02020701b990a3fdec1c6e230df7f883
4
- data.tar.gz: 3a3c8c05b72ae568bf7edb0ff95e37fa60cb9173380283e626f07455d24e9064
3
+ metadata.gz: 9d3f9a0d1d95953662422a99f8d0170ce0db8df6ec82042e7f7d6d32e1721853
4
+ data.tar.gz: b2f702533aa2d6e1a96aed917a8cc77f8aa8916395944174c74644379392d7b8
5
5
  SHA512:
6
- metadata.gz: bc14a72d7d060bad1b0bb813987a66c9464e89cb8e8dcd58cff28a91130560d91e3a5d5c49182be4465f0a8d3499f7d87e564a78b1abcf2576c4aa0bc3610550
7
- data.tar.gz: b9dffb39f58ae71e43a54aa1417c0a1f69e25f398c6354497243b01a2f5604c26023624dffc33c3b55b7f8065c29789ef34f252298feb3f883d44ac5cc58f19a
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,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
- begin
23
- send_auth(host, spa_port, options[:config])
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["SPAROID_KEY"],
53
- "hmac-key" => ENV["SPAROID_HMAC_KEY"]
55
+ "key" => ENV.fetch("SPAROID_KEY", nil),
56
+ "hmac-key" => ENV.fetch("SPAROID_HMAC_KEY", nil)
54
57
  }
55
58
  end
56
59
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sparoid
4
- VERSION = "1.0.16"
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(Error, "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)
@@ -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
@@ -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.16
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-08-23 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.2.15
73
+ rubygems_version: 3.3.7
73
74
  signing_key:
74
75
  specification_version: 4
75
76
  summary: Single Packet Authorisation client