nova 0.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 +7 -0
- data/LICENSE +19 -0
- data/README.md +29 -0
- data/bin/nova +8 -0
- data/lib/generator/template/new_install/galaxy/some_star.rb +3 -0
- data/lib/generator/template/new_install/supernova.yml +16 -0
- data/lib/nova.rb +49 -0
- data/lib/nova/cli.rb +62 -0
- data/lib/nova/commands/server.rb +71 -0
- data/lib/nova/common.rb +17 -0
- data/lib/nova/common/event_handler.rb +165 -0
- data/lib/nova/common/event_handler/event.rb +147 -0
- data/lib/nova/common/features.rb +93 -0
- data/lib/nova/common/features/feature.rb +65 -0
- data/lib/nova/common/metadata.rb +65 -0
- data/lib/nova/common/metadata/data.rb +171 -0
- data/lib/nova/common/star_management.rb +164 -0
- data/lib/nova/constructor.rb +84 -0
- data/lib/nova/exceptions.rb +16 -0
- data/lib/nova/project.rb +199 -0
- data/lib/nova/remote.rb +10 -0
- data/lib/nova/remote/fake.rb +51 -0
- data/lib/nova/remote/fake/commands.rb +44 -0
- data/lib/nova/remote/fake/file_system.rb +76 -0
- data/lib/nova/remote/fake/operating_system.rb +52 -0
- data/lib/nova/remote/fake/platform.rb +89 -0
- data/lib/nova/star.rb +25 -0
- data/lib/nova/starbound.rb +14 -0
- data/lib/nova/starbound/client.rb +59 -0
- data/lib/nova/starbound/encryptor.rb +134 -0
- data/lib/nova/starbound/encryptors.rb +13 -0
- data/lib/nova/starbound/encryptors/openssl.rb +122 -0
- data/lib/nova/starbound/encryptors/plaintext.rb +64 -0
- data/lib/nova/starbound/encryptors/rbnacl.rb +67 -0
- data/lib/nova/starbound/protocol.rb +81 -0
- data/lib/nova/starbound/protocol/encryption.rb +48 -0
- data/lib/nova/starbound/protocol/exceptions.rb +38 -0
- data/lib/nova/starbound/protocol/messages.rb +116 -0
- data/lib/nova/starbound/protocol/packet.rb +267 -0
- data/lib/nova/starbound/protocol/socket.rb +231 -0
- data/lib/nova/starbound/server.rb +182 -0
- data/lib/nova/version.rb +5 -0
- data/spec/constructor_spec.rb +20 -0
- data/spec/local_spec.rb +26 -0
- data/spec/nova_spec.rb +7 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/star/some_type.rb +27 -0
- data/spec/star_spec.rb +107 -0
- data/spec/starbound/encryptor_spec.rb +33 -0
- data/spec/starbound/openssl_encryptor_spec.rb +80 -0
- data/spec/starbound/packet_spec.rb +61 -0
- data/spec/starbound/plaintext_encryptor_spec.rb +27 -0
- data/spec/starbound/protocol_spec.rb +163 -0
- data/spec/starbound/rbnacl_encryptor_spec.rb +70 -0
- metadata +166 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'nova/starbound/encryptors/plaintext'
|
2
|
+
require 'nova/starbound/encryptors/openssl'
|
3
|
+
require 'nova/starbound/encryptors/rbnacl'
|
4
|
+
|
5
|
+
module Nova
|
6
|
+
module Starbound
|
7
|
+
|
8
|
+
# A module containing the encryptors that come with starbound.
|
9
|
+
module Encryptors
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
|
3
|
+
module Nova
|
4
|
+
module Starbound
|
5
|
+
module Encryptors
|
6
|
+
|
7
|
+
# Handles encryption using the OpenSSL library. Shares the
|
8
|
+
# shared secret using RSA public key encryption, creates a
|
9
|
+
# HMAC digest of the body using the shared secret as a key, and
|
10
|
+
# encrypts the body using AES-256-CBC encryption.
|
11
|
+
class OpenSSL < Encryptor
|
12
|
+
|
13
|
+
# The RSA key size for the key exchange.
|
14
|
+
RSA_KEY_SIZE = 4096
|
15
|
+
|
16
|
+
# The shared secret size, in bytes. If RSA_KEY_SIZE is 4096,
|
17
|
+
# this is 256.
|
18
|
+
SECRET_SIZE = RSA_KEY_SIZE / 16
|
19
|
+
|
20
|
+
encryptor_name "openssl/rsa-#{RSA_KEY_SIZE}/aes-256-cbc"
|
21
|
+
register! 1
|
22
|
+
|
23
|
+
# see Encryptor.available?
|
24
|
+
def self.available?
|
25
|
+
@_available ||= begin
|
26
|
+
require 'openssl'
|
27
|
+
true
|
28
|
+
rescue LoadError
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# (see Encryptor#encrypt)
|
34
|
+
def encrypt(packet)
|
35
|
+
packet = packet.clone
|
36
|
+
cipher = ::OpenSSL::Cipher::AES256.new(:CBC)
|
37
|
+
cipher.encrypt
|
38
|
+
cipher.key = options[:shared_secret]
|
39
|
+
|
40
|
+
# we have to fit the packet's nonce size.
|
41
|
+
packet[:nonce] = cipher.iv = ::OpenSSL::Random.random_bytes(24)
|
42
|
+
|
43
|
+
encrypted = cipher.update(packet[:body]) + cipher.final
|
44
|
+
|
45
|
+
packet.body = hmac_digest(encrypted) + encrypted
|
46
|
+
packet
|
47
|
+
end
|
48
|
+
|
49
|
+
# (see Encryptor#decrypt)
|
50
|
+
def decrypt(packet)
|
51
|
+
packet = packet.clone
|
52
|
+
decipher = ::OpenSSL::Cipher::AES256.new(:CBC)
|
53
|
+
decipher.decrypt
|
54
|
+
decipher.key = options[:shared_secret]
|
55
|
+
decipher.iv = packet[:nonce]
|
56
|
+
|
57
|
+
digest = packet[:body][0..63]
|
58
|
+
actual_body = packet[:body][64..-1]
|
59
|
+
|
60
|
+
if hmac_digest(actual_body) != digest
|
61
|
+
raise EncryptorError, "Digest doesn't match the body."
|
62
|
+
end
|
63
|
+
|
64
|
+
packet.body = decipher.update(actual_body) +
|
65
|
+
decipher.final
|
66
|
+
packet
|
67
|
+
end
|
68
|
+
|
69
|
+
# (see Encryptor#private_key!)
|
70
|
+
def private_key!
|
71
|
+
options[:private] = ::OpenSSL::PKey::RSA.new(RSA_KEY_SIZE)
|
72
|
+
end
|
73
|
+
|
74
|
+
# If we have already recieved the other public key, we'll
|
75
|
+
# generate the secret here, and return the encrypted version
|
76
|
+
# of that secret here. Otherwise, we'll generate our private
|
77
|
+
# key and return that in DER format.
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
def public_key
|
81
|
+
if options[:other_public]
|
82
|
+
options[:shared_secret] =
|
83
|
+
::OpenSSL::Random.random_bytes(SECRET_SIZE)
|
84
|
+
options[:other_public].public_encrypt(
|
85
|
+
options[:shared_secret])
|
86
|
+
else
|
87
|
+
options[:public] ||= options[:private].public_key.to_der
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# If we already have a public key, that means that the value
|
92
|
+
# that's passed to this method is the shared secret.
|
93
|
+
# Otherwise, it really is the public key of the other remote.
|
94
|
+
# If the passed value is a shared secret, it's decrypted with
|
95
|
+
# our private key and stored. If it's the other public key,
|
96
|
+
# it's instantized to a openssl RSA key, and stored.
|
97
|
+
#
|
98
|
+
# @return [void]
|
99
|
+
def other_public_key=(public_key)
|
100
|
+
if options[:public]
|
101
|
+
options[:shared_secret] =
|
102
|
+
options[:private].private_decrypt(public_key)
|
103
|
+
else
|
104
|
+
options[:other_public] =
|
105
|
+
::OpenSSL::PKey::RSA.new(public_key)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Provides a digest of the data, using HMAC.
|
112
|
+
#
|
113
|
+
# @return [String]
|
114
|
+
def hmac_digest(body)
|
115
|
+
::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA512.new,
|
116
|
+
options[:shared_secret], body.to_s)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Nova
|
2
|
+
module Starbound
|
3
|
+
module Encryptors
|
4
|
+
|
5
|
+
# The plaintext encryptor.
|
6
|
+
class Plaintext < Encryptor
|
7
|
+
|
8
|
+
encryptor_name "plaintext"
|
9
|
+
register! 0
|
10
|
+
|
11
|
+
# The random provider for this clas.
|
12
|
+
RANDOM = Random.new
|
13
|
+
|
14
|
+
# Whether or not this encryptor is available. Since it's
|
15
|
+
# plaintext, it's always available.
|
16
|
+
#
|
17
|
+
# @return [true]
|
18
|
+
def self.available?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
# Whether or not this encryptor is plaintext. It is. This
|
23
|
+
# will always return true for this class.
|
24
|
+
#
|
25
|
+
# @return [true]
|
26
|
+
def self.plaintext?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
# (see Encryptor#encrypt)
|
31
|
+
def encrypt(packet)
|
32
|
+
packet = packet.clone
|
33
|
+
|
34
|
+
packet[:nonce] = RANDOM.bytes(24)
|
35
|
+
packet
|
36
|
+
end
|
37
|
+
|
38
|
+
# (see Encryptor#decrypt)
|
39
|
+
def decrypt(packet)
|
40
|
+
packet = packet.clone
|
41
|
+
|
42
|
+
packet
|
43
|
+
end
|
44
|
+
|
45
|
+
# Does nothing.
|
46
|
+
#
|
47
|
+
# @return [nil]
|
48
|
+
def private_key!; end
|
49
|
+
|
50
|
+
# Does nothing.
|
51
|
+
#
|
52
|
+
# @return [String] an empty string.
|
53
|
+
def public_key; ""; end
|
54
|
+
|
55
|
+
# Does nothing.
|
56
|
+
#
|
57
|
+
# @param _ [String] the other "public" key.
|
58
|
+
# @return [nil]
|
59
|
+
def other_public_key=(_); end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Nova
|
2
|
+
module Starbound
|
3
|
+
module Encryptors
|
4
|
+
|
5
|
+
# Provides encryption using RbNaCl.
|
6
|
+
class RbNaCl < Encryptor
|
7
|
+
|
8
|
+
encryptor_name "rbnacl/1.0.0"
|
9
|
+
register! 2
|
10
|
+
|
11
|
+
# (see Encryptor.available?)
|
12
|
+
def self.available?
|
13
|
+
@_available ||= begin
|
14
|
+
require 'rbnacl'
|
15
|
+
true
|
16
|
+
rescue LoadError
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# (see Encryptor#encrypt)
|
22
|
+
def encrypt(packet)
|
23
|
+
packet = packet.clone
|
24
|
+
packet[:nonce] = Crypto::Random.random_bytes(24)
|
25
|
+
box = Crypto::Box.new(options[:public_key], options[:private_key])
|
26
|
+
enc = box.encrypt(packet[:nonce], packet[:body])
|
27
|
+
|
28
|
+
packet.body = enc
|
29
|
+
packet
|
30
|
+
end
|
31
|
+
|
32
|
+
# (see Encryptor#decrypt)
|
33
|
+
def decrypt(packet)
|
34
|
+
packet = packet.clone
|
35
|
+
box = Crypto::Box.new(options[:public_key], options[:private_key])
|
36
|
+
packet.body = box.decrypt(packet[:nonce], packet[:body])
|
37
|
+
|
38
|
+
packet
|
39
|
+
rescue Crypto::CryptoError => e
|
40
|
+
raise EncryptorError, e
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generates a private key.
|
44
|
+
#
|
45
|
+
# @return [void]
|
46
|
+
def private_key!
|
47
|
+
options[:private_key] = Crypto::PrivateKey.generate
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the public key for this remote.
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def public_key
|
54
|
+
options[:private_key].public_key.to_bytes
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sets the other public key to the given value.
|
58
|
+
#
|
59
|
+
# @return [void]
|
60
|
+
def other_public_key=(public_key)
|
61
|
+
options[:public_key] = Crypto::PublicKey.new(public_key)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'nova/starbound/protocol/exceptions'
|
2
|
+
require 'nova/starbound/protocol/encryption'
|
3
|
+
require 'nova/starbound/protocol/messages'
|
4
|
+
require 'nova/starbound/protocol/packet'
|
5
|
+
require 'nova/starbound/protocol/socket'
|
6
|
+
|
7
|
+
module Nova
|
8
|
+
module Starbound
|
9
|
+
|
10
|
+
# The basic Starbound protocol.
|
11
|
+
#
|
12
|
+
# @todo More testing.
|
13
|
+
class Protocol
|
14
|
+
|
15
|
+
include Protocol::Socket
|
16
|
+
include Protocol::Encryption
|
17
|
+
include Protocol::Messages
|
18
|
+
|
19
|
+
# The options that was passed to this protocol on
|
20
|
+
# initialization.
|
21
|
+
#
|
22
|
+
# @return [Hash<Symbol, Object>]
|
23
|
+
attr_reader :options
|
24
|
+
|
25
|
+
# The current state of the protocol. Known values:
|
26
|
+
# +:offline+ (default), +:handshake+, +:online+, +:closing+.
|
27
|
+
#
|
28
|
+
# @return [Symbol]
|
29
|
+
attr_reader :state
|
30
|
+
|
31
|
+
# Perform a handshake with the server. First sets the state to
|
32
|
+
# +:handshake+.
|
33
|
+
#
|
34
|
+
# @return [void]
|
35
|
+
def handshake
|
36
|
+
@state = :handshake
|
37
|
+
thread
|
38
|
+
|
39
|
+
if options[:type] == :client
|
40
|
+
message = send :protocol_version, Nova::VERSION
|
41
|
+
response = response_to message
|
42
|
+
check_versions response
|
43
|
+
handle_encryption
|
44
|
+
else
|
45
|
+
|
46
|
+
wait_for_protocol_version
|
47
|
+
handle_server_encryption
|
48
|
+
end
|
49
|
+
|
50
|
+
@state = :online
|
51
|
+
end
|
52
|
+
|
53
|
+
# Initialize the protocol.
|
54
|
+
#
|
55
|
+
# @param options [Hash] the options to initialize the protocol
|
56
|
+
# with.
|
57
|
+
def initialize(options = {})
|
58
|
+
@options = options
|
59
|
+
@state = :offline
|
60
|
+
|
61
|
+
super()
|
62
|
+
end
|
63
|
+
|
64
|
+
# Closes the connection.
|
65
|
+
#
|
66
|
+
# @return [void]
|
67
|
+
def close(code = :none)
|
68
|
+
@state = :closing
|
69
|
+
|
70
|
+
if code
|
71
|
+
send :close, Packet::CloseReasons[code].to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
super()
|
75
|
+
|
76
|
+
@state = :offline
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Nova
|
2
|
+
module Starbound
|
3
|
+
class Protocol
|
4
|
+
|
5
|
+
# The encryption used in the protocol.
|
6
|
+
module Encryption
|
7
|
+
|
8
|
+
# The provider used to encrypt the body.
|
9
|
+
#
|
10
|
+
# @return [Encryptor]
|
11
|
+
attr_writer :encryption_provider
|
12
|
+
|
13
|
+
# Initialize the encryption.
|
14
|
+
def initialize
|
15
|
+
@encryption_provider = Encryptors::Plaintext.new
|
16
|
+
|
17
|
+
super()
|
18
|
+
end
|
19
|
+
|
20
|
+
# Gets the encryption provider.
|
21
|
+
#
|
22
|
+
# @raise [NoEncryptionError] if {#state} isn't handshake,
|
23
|
+
# the encryption provider returns true on
|
24
|
+
# {Encryptor.plaintext?}, and +:allow_plaintext+ is false.
|
25
|
+
# @return [Encryptor]
|
26
|
+
def encryption_provider
|
27
|
+
raise NoEncryptionError if
|
28
|
+
@encryption_provider.class.plaintext? &&
|
29
|
+
!should_allow_plaintext?
|
30
|
+
|
31
|
+
@encryption_provider
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Whether or not plaintext is acceptable. Checks the state to
|
37
|
+
# see if it's +:handshake+ and the +:allow_plaintext+ option
|
38
|
+
# to return true or false.
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
def should_allow_plaintext?
|
42
|
+
state == :handshake || options.fetch(:allow_plaintext, false)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Nova
|
2
|
+
module Starbound
|
3
|
+
# Any error that is related to the protocol should inherit this
|
4
|
+
# class.
|
5
|
+
class ProtocolError < StandardError; end
|
6
|
+
|
7
|
+
# When the protocol needs to exit from a connection, this is
|
8
|
+
# raised. Meant to be raised by a third party; not raised by this
|
9
|
+
# library.
|
10
|
+
class ExitError < StandardError; end
|
11
|
+
|
12
|
+
# Raised when the socket isn't using encryption, and we've
|
13
|
+
# already finished with the handshake, and if the
|
14
|
+
# +:allow_plaintext+ option isn't true. Used in
|
15
|
+
# {Protocol::Socket}.
|
16
|
+
class NoEncryptionError < ProtocolError; end
|
17
|
+
|
18
|
+
# Raised when the major version of the remote does not match the
|
19
|
+
# major version of this library. Used in {Protocol::Messages}.
|
20
|
+
class IncompatibleRemoteError < ProtocolError; end
|
21
|
+
|
22
|
+
# The remote closed the connection. Used in {Protocol::Socket}.
|
23
|
+
class RemoteClosedError < ProtocolError; end
|
24
|
+
|
25
|
+
# Raised when a string is unpacked but it doesn't match any
|
26
|
+
# struct defined here. Used in {Protocol::Packet}.
|
27
|
+
class NoStructError < ProtocolError; end
|
28
|
+
|
29
|
+
# Raised when a packet is sent when another packet was
|
30
|
+
# expected. Used in {Protocol::Packet}.
|
31
|
+
class UnacceptablePacketError < ProtocolError; end
|
32
|
+
|
33
|
+
# Raised if the encryptor runs into an error with encrypting
|
34
|
+
# or decrypting the packet. Used in {Encryptors::OpenSSL} and
|
35
|
+
# {Encryptors::RbNaCl}.
|
36
|
+
class EncryptorError < StandardError; end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Nova
|
2
|
+
module Starbound
|
3
|
+
class Protocol
|
4
|
+
|
5
|
+
# Handles messages.
|
6
|
+
module Messages
|
7
|
+
|
8
|
+
# Checks the versions of the remote and us. If the major
|
9
|
+
# versions don't match, raise an error.
|
10
|
+
#
|
11
|
+
# @raise [IncompatibleRemoteError] if the major versions don't
|
12
|
+
# match.
|
13
|
+
# @return [void]
|
14
|
+
def check_versions(other_packet)
|
15
|
+
other_packet.expect(:protocol_version)
|
16
|
+
our_major = Nova::VERSION.split('.').first
|
17
|
+
their_major = other_packet.body.split('.').first
|
18
|
+
|
19
|
+
if our_major != their_major
|
20
|
+
raise IncompatibleRemoteError,
|
21
|
+
"Major versions do not match (our: #{our_major}, " +
|
22
|
+
"theirs: #{their_major})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Waits for the remote to send their protocol version, and
|
27
|
+
# then checks their version against ours, making sure the
|
28
|
+
# versions match.
|
29
|
+
#
|
30
|
+
# @raise [IncompatibleRemoteError] if the major versions don't
|
31
|
+
# match.
|
32
|
+
# @return [void]
|
33
|
+
def wait_for_protocol_version
|
34
|
+
pack = read
|
35
|
+
|
36
|
+
check_versions(pack)
|
37
|
+
|
38
|
+
respond_to pack, :protocol_version, Nova::VERSION
|
39
|
+
end
|
40
|
+
|
41
|
+
# Handles setting up encryption with the server. Sends the
|
42
|
+
# server the list of options we have, and waits for a
|
43
|
+
# response. The first 4 bytes of the public key correspond
|
44
|
+
# to the index of the encryptor, and the rest is the actual
|
45
|
+
# public key. It then sends our public key back, but doesn't
|
46
|
+
# wait for a response.
|
47
|
+
#
|
48
|
+
# @return [void]
|
49
|
+
def handle_encryption
|
50
|
+
sent = send :encryption_options,
|
51
|
+
Encryptor.sorted_encryptors.map(&:encryptor_name).join("\n")
|
52
|
+
|
53
|
+
response = response_to sent
|
54
|
+
response.expect(:public_key)
|
55
|
+
|
56
|
+
encryptor = matching_encryptor *response.body.split("\n", 2)
|
57
|
+
|
58
|
+
respond_to response, :public_key, encryptor.public_key
|
59
|
+
self.encryption_provider = encryptor
|
60
|
+
end
|
61
|
+
|
62
|
+
# Handles the server encryption. Reads a packet, splits the
|
63
|
+
# body by new lines, and searches our encryptors for a
|
64
|
+
# matching encryptor. Initializes it, and sends back data
|
65
|
+
# to the client containing which encryptor was used and our
|
66
|
+
# public key; waits for a response containing the client's
|
67
|
+
# public key, and then sets the encryption provider.
|
68
|
+
#
|
69
|
+
# @return [void]
|
70
|
+
def handle_server_encryption
|
71
|
+
enc_options = read
|
72
|
+
enc_options.expect(:encryption_options)
|
73
|
+
lines = enc_options.body.split("\n")
|
74
|
+
|
75
|
+
encs = Encryptor.sorted_encryptors.select do |e|
|
76
|
+
lines.include?(e.encryptor_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
preferred = encs.first
|
80
|
+
index = lines.index(preferred.encryptor_name)
|
81
|
+
encryptor = preferred.new
|
82
|
+
encryptor.private_key!
|
83
|
+
|
84
|
+
data = preferred.encryptor_name + "\n"
|
85
|
+
|
86
|
+
out = respond_to enc_options, :public_key, data +
|
87
|
+
encryptor.public_key
|
88
|
+
|
89
|
+
pub_key = response_to out
|
90
|
+
pub_key.expect(:public_key)
|
91
|
+
|
92
|
+
encryptor.other_public_key = pub_key.body
|
93
|
+
|
94
|
+
self.encryption_provider = encryptor
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# Handles selecting and setting up the encryption for this
|
100
|
+
# protocol, given the name from the remote.
|
101
|
+
#
|
102
|
+
# @return [Encryptor]
|
103
|
+
def matching_encryptor(name, body)
|
104
|
+
enc = Encryptor.encryptors.select { |e|
|
105
|
+
e.encryptor_name == name
|
106
|
+
}.first.new
|
107
|
+
enc.private_key!
|
108
|
+
enc.other_public_key = body
|
109
|
+
|
110
|
+
enc
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|