sparoid 1.0.0 → 1.0.5

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: 97ffed008109eb32f070fc300c536cd29f000c6ff943b67bff64658c218f70ce
4
- data.tar.gz: 87fcc661eb04ee0a79b9d9cbd4ef12b5f80c8a4c1856569076f1eac57a37c41b
3
+ metadata.gz: 10aba94e127e9bfb74963c3e88276ef11879e16db16cb6e44fd8e01476c747b7
4
+ data.tar.gz: 4b64175b2dbc751bd409624f48b11fb2629268f1b42d81df8cf1b410bf579507
5
5
  SHA512:
6
- metadata.gz: ded717258409725cbf49b97fd9c704dbbe550a024f4ce09b484640306079f67ccfd43f64d063326c787ed700cef4db09179b6facb98c7403304dad0a861216ea
7
- data.tar.gz: 180a6a9ae33549e198130f73e3e4bd5e9ce4e63727668e6ea2124e22ade18b4e7324efb15abf00053fc22b0728a05d17f49cff353a6f68cdf6b3bf9709b5fab4
6
+ metadata.gz: 3218c0a291f09ac0b66ca26c0fe5f7d5675d6aacc7dab69e72e3a645ebfea828eacadd62ce477634ebb3be245ddd23b05955a439ea637af32e45ec3c5adb89f2
7
+ data.tar.gz: e6e7c9f967abce41da45a20066e448351279720f231af9cfb49b62e46090360093411f84537b25a5329e3792447f4a8e0305d450bc8ab210441421521bcbba0b
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,23 @@
1
- ## [Unreleased]
1
+ ## [1.0.5] - 2021-04-12
2
+
3
+ - Prefix all logging with `Sparoid: `
4
+
5
+ ## [1.0.4] - 2021-03-25
6
+
7
+ - Only warn if config is missing when connecting with CLI
8
+
9
+ ## [1.0.3] - 2021-03-17
10
+
11
+ - Nicer error handling in CLI, remove --fdpass option
12
+
13
+ ## [1.0.2] - 2021-03-15
14
+
15
+ - `sparoid send` renamed to `sparoid auth`
16
+ - `sparoid connect [host] [port]` added for automatic fd passing
17
+
18
+ ## [1.0.1] - 2021-03-12
19
+
20
+ - --fdpass option to send
2
21
 
3
22
  ## [1.0.0] - 2021-03-11
4
23
 
data/README.md CHANGED
@@ -20,7 +20,15 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- TODO: Write usage instructions here
23
+ ...
24
+
25
+ Can be used with OpenSSH's ProxyCommand/ProxyUseFdpass to send the packet before connecting, open the TCP connection and that pass that connection back to the SSH client.
26
+
27
+ ```
28
+ Host *.example.com
29
+ ProxyCommand sparoid send %h --passfd %p
30
+ ProxyUseFdpass yes
31
+ ```
24
32
 
25
33
  ## Development
26
34
 
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)
17
+ end
18
+
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)
14
33
  end
15
34
 
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
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,31 +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
73
+ def public_ip
53
74
  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"
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
70
-
71
79
  class Error < StandardError; end
80
+
81
+ # Instance of SPAroid that only resolved public_ip once
82
+ class Instance
83
+ include Sparoid
84
+
85
+ private
86
+
87
+ def public_ip
88
+ @public_ip ||= super
89
+ end
90
+ end
72
91
  end
data/lib/sparoid/cli.rb CHANGED
@@ -6,13 +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, default: "~/.sparoid.ini"
11
- def send(host, port = 8484)
12
- abort "Config not found" unless File.exist? options[: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
13
18
 
14
- key, hmac_key = get_keys(parse_ini(options[:config]))
15
- Sparoid.send(key, hmac_key, host, port.to_i)
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}"
16
30
  end
17
31
 
18
32
  desc "keygen", "Generate an encryption key and a HMAC key"
@@ -26,8 +40,13 @@ module Sparoid
26
40
 
27
41
  private
28
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
+
29
48
  def parse_ini(path)
30
- 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
31
50
  end
32
51
 
33
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.0"
4
+ VERSION = "1.0.5"
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.0
4
+ version: 1.0.5
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-11 00:00:00.000000000 Z
11
+ date: 2021-04-12 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