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 +4 -4
- data/CHANGELOG.md +8 -1
- data/lib/sparoid.rb +43 -30
- data/lib/sparoid/cli.rb +9 -3
- data/lib/sparoid/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9949f3421911f8f9d588b87ba8955407b68ac62bae5ad7f53ef5b707077ef60
|
4
|
+
data.tar.gz: 06b115e1db22eb0222dd9f7a439024e18d8579255324aaff1bb1c935e35c10f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6ef1abb4e1c01d435f771ffbf779aeced9a04a2384a309c623fef0546d8cf8adae7ab76a86ba60b485c49ddbd386e545ecc9ce7c62efdcec465732c23cd1f59
|
7
|
+
data.tar.gz: f616bb367217c07aa36865be2c1eaeeecce685c260911aaf6a97f1e8cb80f8652d906944edca1954d1f161a123bcf333945947992c40ea289be0911e40be7c29
|
data/CHANGELOG.md
CHANGED
data/lib/sparoid.rb
CHANGED
@@ -7,20 +7,41 @@ require "resolv"
|
|
7
7
|
|
8
8
|
# Single Packet Authorisation client
|
9
9
|
module Sparoid
|
10
|
-
|
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
|
-
|
16
|
+
sendmsg(host, port, data)
|
14
17
|
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
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
|
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
|
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
|
73
|
+
def public_ip
|
53
74
|
Resolv::DNS.open(nameserver: ["resolver1.opendns.com"]) do |dns|
|
54
|
-
dns.
|
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
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
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 "
|
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
|
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.
|
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
|
data/lib/sparoid/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2021-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|