sparoid 1.0.1 → 1.0.6

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: 6069344b10804fda4024554fc6bfb9490c52ef0ef197dfcb598724cb760f587d
4
- data.tar.gz: 35cc6eec43bb0b03fd2938166628618936c9659768b5454d880d96b942da04d1
3
+ metadata.gz: a9c9e31643c35e5466c71be88339a2c7999e401d893b6c7364597380def920cf
4
+ data.tar.gz: 237a5a03c2b3a306b25ad947754ce92acb866dcf2985650e27720773edc1f39e
5
5
  SHA512:
6
- metadata.gz: c361191ea89d2c980dc89a639c11cdf77575006526560f00ae4a200e79b9ba5a66b282d1f2b9b750af5135652316cbffc87476100af6799dc904e8aa8b5f2ffb
7
- data.tar.gz: 3b6df9484af0ee540bedff510f9643642151da0558767d9a20de4dfb7d8217df5ff25623802ccba00c5855ba3e002c22743eac0bbfff9322480b86d2ce4e2c3d
6
+ metadata.gz: a417c0b53950536d98a43f417690952e2b4bf41b3bcb72b13e8bd52e367f9a0a814b7e10ce9072b57098b48cd8ee36c41166f354f6eb6b0782430e4a945e7bf3
7
+ data.tar.gz: fc30ef678295a18379cd770840f702c2c328047fcbe9bbaa6fd65514c95105a29b88fd946a0c7bcf0cf93703dba2a6cd547a81ec6dc9c31e73f7bf06626e9c45
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -1,4 +1,27 @@
1
- ## [Unreleased]
1
+ ## [1.0.6] - 2021-04-13
2
+
3
+ - Use static IP for opendns resolver, saves one DNS lookup
4
+
5
+ ## [1.0.5] - 2021-04-12
6
+
7
+ - Prefix all logging with `Sparoid: `
8
+
9
+ ## [1.0.4] - 2021-03-25
10
+
11
+ - Only warn if config is missing when connecting with CLI
12
+
13
+ ## [1.0.3] - 2021-03-17
14
+
15
+ - Nicer error handling in CLI, remove --fdpass option
16
+
17
+ ## [1.0.2] - 2021-03-15
18
+
19
+ - `sparoid send` renamed to `sparoid auth`
20
+ - `sparoid connect [host] [port]` added for automatic fd passing
21
+
22
+ ## [1.0.1] - 2021-03-12
23
+
24
+ - --fdpass option to send
2
25
 
3
26
  ## [1.0.0] - 2021-03-11
4
27
 
data/lib/sparoid.rb CHANGED
@@ -7,20 +7,41 @@ require "resolv"
7
7
 
8
8
  # Single Packet Authorisation client
9
9
  module Sparoid
10
- def self.send(key, hmac_key, host, port)
10
+ extend self
11
+
12
+ # Send an authorization packet
13
+ def auth(key, hmac_key, host, port)
11
14
  msg = message(public_ip)
12
15
  data = prefix_hmac(hmac_key, encrypt(key, msg))
13
- udp_send(host, port, data)
16
+ sendmsg(host, port, data)
14
17
  end
15
18
 
16
- def self.udp_send(host, port, data)
17
- socket = UDPSocket.new
18
- socket.connect host, port
19
- socket.send data, 0
20
- socket.close
19
+ # Generate new aes and hmac keys, print to stdout
20
+ def keygen
21
+ cipher = OpenSSL::Cipher.new("aes-256-cbc")
22
+ key = cipher.random_key.unpack1("H*")
23
+ hmac_key = OpenSSL::Random.random_bytes(32).unpack1("H*")
24
+ puts "key = #{key}"
25
+ puts "hmac-key = #{hmac_key}"
26
+ end
27
+
28
+ # Connect to a TCP server and pass the FD to the parent
29
+ def fdpass(host, port, connect_timeout: 20)
30
+ tcp = Socket.tcp host, port, connect_timeout: connect_timeout
31
+ parent = Socket.for_fd(1)
32
+ parent.sendmsg "\0", 0, nil, Socket::AncillaryData.unix_rights(tcp)
33
+ end
34
+
35
+ private
36
+
37
+ def sendmsg(host, port, data)
38
+ UDPSocket.open do |socket|
39
+ socket.connect host, port
40
+ socket.sendmsg data, 0
41
+ end
21
42
  end
22
43
 
23
- def self.encrypt(key, data)
44
+ def encrypt(key, data)
24
45
  key = [key].pack("H*") # hexstring to bytes
25
46
  raise ArgumentError, "Key must be 32 bytes hex encoded" if key.bytesize != 32
26
47
 
@@ -34,7 +55,7 @@ module Sparoid
34
55
  output << cipher.final
35
56
  end
36
57
 
37
- def self.prefix_hmac(hmac_key, data)
58
+ def prefix_hmac(hmac_key, data)
38
59
  hmac_key = [hmac_key].pack("H*") # hexstring to bytes
39
60
  raise ArgumentError, "HMAC key must be 32 bytes hex encoded" if hmac_key.bytesize != 32
40
61
 
@@ -42,37 +63,29 @@ module Sparoid
42
63
  hmac + data
43
64
  end
44
65
 
45
- def self.message(ip)
66
+ def message(ip)
46
67
  version = 1
47
68
  ts = (Time.now.utc.to_f * 1000).floor
48
69
  nounce = OpenSSL::Random.random_bytes(16)
49
70
  [version, ts, nounce, ip.address].pack("Nq>a16a4")
50
71
  end
51
72
 
52
- def self.public_ip
53
- Resolv::DNS.open(nameserver: ["resolver1.opendns.com"]) do |dns|
54
- dns.each_address("myip.opendns.com") do |resolv|
55
- case resolv
56
- when Resolv::IPv4 then return resolv
57
- end
58
- end
59
- raise Error, "No public IPv4 address found"
73
+ def public_ip
74
+ Resolv::DNS.open(nameserver: ["208.67.222.222", "208.67.220.220"]) do |dns|
75
+ dns.getresource("myip.opendns.com", Resolv::DNS::Resource::IN::A).address
60
76
  end
61
77
  end
62
78
 
63
- def self.keygen
64
- cipher = OpenSSL::Cipher.new("aes-256-cbc")
65
- key = cipher.random_key.unpack1("H*")
66
- hmac_key = OpenSSL::Random.random_bytes(32).unpack1("H*")
67
- puts "key = #{key}"
68
- puts "hmac-key = #{hmac_key}"
69
- end
79
+ class Error < StandardError; end
70
80
 
71
- def self.fdpass(host, port)
72
- ssh = Socket.tcp host, port
73
- parent = Socket.for_fd(1)
74
- parent.sendmsg "\0", 0, nil, Socket::AncillaryData.unix_rights(ssh)
75
- end
81
+ # Instance of SPAroid that only resolved public_ip once
82
+ class Instance
83
+ include Sparoid
76
84
 
77
- class Error < StandardError; end
85
+ private
86
+
87
+ def public_ip
88
+ @public_ip ||= super
89
+ end
90
+ end
78
91
  end
data/lib/sparoid/cli.rb CHANGED
@@ -6,19 +6,27 @@ require_relative "../sparoid"
6
6
  module Sparoid
7
7
  # CLI
8
8
  class CLI < Thor
9
- desc "send HOST [PORT]", "Send a packet"
10
- method_option :config, desc: "Path to a config file, INI format, with key and hmac-key"
11
- method_option :fdpass,
12
- type: :numeric,
13
- desc: "After sending, open a TCP connection and pass the FD back to the calling process. \
14
- For use with OpenSSH ProxyCommand and ProxyUseFdpass"
15
- def send(host, port = 8484)
16
- config = File.expand_path(options[:config] || "~/.sparoid.ini")
17
- abort "Config '#{config}' not found" unless File.exist? config
9
+ desc "auth HOST [PORT]", "Send a authorization packet"
10
+ method_option :config, desc: "Path to a config file, INI format, with key and hmac-key", default: "~/.sparoid.ini"
11
+ def auth(host, port = 8484)
12
+ send_auth(host, port, options[:config])
13
+ rescue Errno::ENOENT
14
+ abort "Sparoid: Config not found"
15
+ rescue StandardError => e
16
+ abort "Sparoid: #{e.message}"
17
+ end
18
18
 
19
- key, hmac_key = get_keys(parse_ini(config))
20
- Sparoid.send(key, hmac_key, host, port.to_i)
21
- Sparoid.fdpass(host, options[:fdpass]) if options[:fdpass]
19
+ desc "connect HOST PORT [SPA-PORT]", "Send a SPA, TCP connect, and then pass the FD back to the parent"
20
+ method_option :config, desc: "Path to a config file, INI format, with key and hmac-key", default: "~/.sparoid.ini"
21
+ 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)
28
+ rescue StandardError => e
29
+ abort "Sparoid: #{e.message}"
22
30
  end
23
31
 
24
32
  desc "keygen", "Generate an encryption key and a HMAC key"
@@ -32,8 +40,13 @@ module Sparoid
32
40
 
33
41
  private
34
42
 
43
+ def send_auth(host, port, config)
44
+ key, hmac_key = get_keys(parse_ini(config))
45
+ Sparoid.auth(key, hmac_key, host, port.to_i)
46
+ end
47
+
35
48
  def parse_ini(path)
36
- File.readlines(path).map! { |l| l.split("=", 2).map!(&:strip) }.to_h
49
+ File.readlines(File.expand_path(path)).map! { |line| line.split("=", 2).map!(&:strip) }.to_h
37
50
  end
38
51
 
39
52
  def get_keys(config)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sparoid
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.6"
5
5
  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.1
4
+ version: 1.0.6
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-03-12 00:00:00.000000000 Z
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -69,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubygems_version: 3.1.4
72
+ rubygems_version: 3.2.3
73
73
  signing_key:
74
74
  specification_version: 4
75
75
  summary: Single Packet Authorisation client