sparoid 1.0.1 → 1.0.2

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: f9949f3421911f8f9d588b87ba8955407b68ac62bae5ad7f53ef5b707077ef60
4
+ data.tar.gz: 06b115e1db22eb0222dd9f7a439024e18d8579255324aaff1bb1c935e35c10f4
5
5
  SHA512:
6
- metadata.gz: c361191ea89d2c980dc89a639c11cdf77575006526560f00ae4a200e79b9ba5a66b282d1f2b9b750af5135652316cbffc87476100af6799dc904e8aa8b5f2ffb
7
- data.tar.gz: 3b6df9484af0ee540bedff510f9643642151da0558767d9a20de4dfb7d8217df5ff25623802ccba00c5855ba3e002c22743eac0bbfff9322480b86d2ce4e2c3d
6
+ metadata.gz: d6ef1abb4e1c01d435f771ffbf779aeced9a04a2384a309c623fef0546d8cf8adae7ab76a86ba60b485c49ddbd386e545ecc9ce7c62efdcec465732c23cd1f59
7
+ data.tar.gz: f616bb367217c07aa36865be2c1eaeeecce685c260911aaf6a97f1e8cb80f8652d906944edca1954d1f161a123bcf333945947992c40ea289be0911e40be7c29
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
- ## [Unreleased]
1
+ ## [1.0.2] - 2021-03-15
2
+
3
+ - `sparoid send` renamed to `sparoid auth`
4
+ - `sparoid connect [host] [port]` added for automatic fd passing
5
+
6
+ ## [1.0.1] - 2021-03-12
7
+
8
+ - --fdpass option to send
2
9
 
3
10
  ## [1.0.0] - 2021-03-11
4
11
 
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
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
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,21 +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"
9
+ desc "auth HOST [PORT]", "Send a authorization packet"
10
10
  method_option :config, desc: "Path to a config file, INI format, with key and hmac-key"
11
11
  method_option :fdpass,
12
12
  type: :numeric,
13
13
  desc: "After sending, open a TCP connection and pass the FD back to the calling process. \
14
14
  For use with OpenSSH ProxyCommand and ProxyUseFdpass"
15
- def send(host, port = 8484)
15
+ def auth(host, port = 8484)
16
16
  config = File.expand_path(options[:config] || "~/.sparoid.ini")
17
17
  abort "Config '#{config}' not found" unless File.exist? config
18
18
 
19
19
  key, hmac_key = get_keys(parse_ini(config))
20
- Sparoid.send(key, hmac_key, host, port.to_i)
20
+ Sparoid.auth(key, hmac_key, host, port.to_i)
21
21
  Sparoid.fdpass(host, options[:fdpass]) if options[:fdpass]
22
22
  end
23
23
 
24
+ desc "connect", "Send a SPA, TCP connect, and then pass the FD back to the parent"
25
+ def connect(host, port, spa_port = 8484)
26
+ auth(host, spa_port)
27
+ Sparoid.fdpass(host, port)
28
+ end
29
+
24
30
  desc "keygen", "Generate an encryption key and a HMAC key"
25
31
  def keygen
26
32
  Sparoid.keygen
@@ -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.2"
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.2
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-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor