right_agent 2.0.7-x86-mingw32
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.
- data/LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +113 -0
- data/lib/right_agent.rb +59 -0
- data/lib/right_agent/actor.rb +182 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +232 -0
- data/lib/right_agent/agent.rb +1149 -0
- data/lib/right_agent/agent_config.rb +480 -0
- data/lib/right_agent/agent_identity.rb +210 -0
- data/lib/right_agent/agent_tag_manager.rb +237 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/clients.rb +31 -0
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +150 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +33 -0
- data/lib/right_agent/command/command_io.rb +126 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +118 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +44 -0
- data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
- data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
- data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
- data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
- data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
- data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +79 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
- data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
- data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
- data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
- data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
- data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
- data/lib/right_agent/daemonize.rb +35 -0
- data/lib/right_agent/dispatched_cache.rb +109 -0
- data/lib/right_agent/dispatcher.rb +272 -0
- data/lib/right_agent/enrollment_result.rb +221 -0
- data/lib/right_agent/exceptions.rb +87 -0
- data/lib/right_agent/history.rb +145 -0
- data/lib/right_agent/log.rb +460 -0
- data/lib/right_agent/minimal.rb +46 -0
- data/lib/right_agent/monkey_patches.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
- data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
- data/lib/right_agent/multiplexer.rb +102 -0
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/operation_result.rb +300 -0
- data/lib/right_agent/packets.rb +673 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +770 -0
- data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
- data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
- data/lib/right_agent/platform/unix/platform.rb +226 -0
- data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
- data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
- data/lib/right_agent/platform/windows/platform.rb +1808 -0
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/retryable_request.rb +195 -0
- data/lib/right_agent/scripts/agent_controller.rb +543 -0
- data/lib/right_agent/scripts/agent_deployer.rb +400 -0
- data/lib/right_agent/scripts/common_parser.rb +160 -0
- data/lib/right_agent/scripts/log_level_manager.rb +192 -0
- data/lib/right_agent/scripts/stats_manager.rb +268 -0
- data/lib/right_agent/scripts/usage.rb +58 -0
- data/lib/right_agent/secure_identity.rb +92 -0
- data/lib/right_agent/security.rb +32 -0
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
- data/lib/right_agent/security/certificate.rb +102 -0
- data/lib/right_agent/security/certificate_cache.rb +89 -0
- data/lib/right_agent/security/distinguished_name.rb +56 -0
- data/lib/right_agent/security/encrypted_document.rb +83 -0
- data/lib/right_agent/security/rsa_key_pair.rb +76 -0
- data/lib/right_agent/security/signature.rb +86 -0
- data/lib/right_agent/security/static_certificate_store.rb +85 -0
- data/lib/right_agent/sender.rb +792 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +107 -0
- data/lib/right_agent/serialize/secure_serializer.rb +151 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +151 -0
- data/lib/right_agent/serialize/serializer.rb +159 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +101 -0
- data/spec/actor_registry_spec.rb +80 -0
- data/spec/actor_spec.rb +162 -0
- data/spec/agent_config_spec.rb +235 -0
- data/spec/agent_identity_spec.rb +78 -0
- data/spec/agent_spec.rb +734 -0
- data/spec/agent_tag_manager_spec.rb +319 -0
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/agent_manager_commands_spec.rb +51 -0
- data/spec/command/command_io_spec.rb +93 -0
- data/spec/command/command_parser_spec.rb +79 -0
- data/spec/command/command_runner_spec.rb +107 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/dev_repository_spec.rb +33 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
- data/spec/core_payload_types/login_user_spec.rb +102 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatched_cache_spec.rb +136 -0
- data/spec/dispatcher_spec.rb +324 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/history_spec.rb +246 -0
- data/spec/log_spec.rb +192 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/operation_result_spec.rb +208 -0
- data/spec/packets_spec.rb +461 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/platform/spec_helper.rb +216 -0
- data/spec/platform/unix/darwin/platform_spec.rb +181 -0
- data/spec/platform/unix/linux/platform_spec.rb +540 -0
- data/spec/platform/unix/spec_helper.rb +149 -0
- data/spec/platform/windows/mingw/platform_spec.rb +222 -0
- data/spec/platform/windows/mswin/platform_spec.rb +259 -0
- data/spec/platform/windows/spec_helper.rb +720 -0
- data/spec/retryable_request_spec.rb +306 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
- data/spec/security/certificate_cache_spec.rb +71 -0
- data/spec/security/certificate_spec.rb +49 -0
- data/spec/security/distinguished_name_spec.rb +46 -0
- data/spec/security/encrypted_document_spec.rb +55 -0
- data/spec/security/rsa_key_pair_spec.rb +55 -0
- data/spec/security/signature_spec.rb +66 -0
- data/spec/security/static_certificate_store_spec.rb +58 -0
- data/spec/sender_spec.rb +1045 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +132 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +197 -0
- data/spec/spec.opts +2 -0
- data/spec/spec.win32.opts +1 -0
- data/spec/spec_helper.rb +130 -0
- data/spec/tracer_spec.rb +114 -0
- metadata +447 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
SERIALIZE_BASE_DIR = File.join(File.dirname(__FILE__), 'serialize')
|
24
|
+
|
25
|
+
require File.normalize_path(File.join(SERIALIZE_BASE_DIR, 'message_pack'))
|
26
|
+
require File.normalize_path(File.join(SERIALIZE_BASE_DIR, 'secure_serializer'))
|
27
|
+
require File.normalize_path(File.join(SERIALIZE_BASE_DIR, 'secure_serializer_initializer'))
|
28
|
+
require File.normalize_path(File.join(SERIALIZE_BASE_DIR, 'serializable'))
|
29
|
+
require File.normalize_path(File.join(SERIALIZE_BASE_DIR, 'serializer'))
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'rubygems'
|
24
|
+
require 'msgpack'
|
25
|
+
|
26
|
+
# Extend MessagePack to conform to load/dump interface of other serializers like JSON
|
27
|
+
# and to create internal class objects when they are encountered when unserializing
|
28
|
+
module MessagePack
|
29
|
+
|
30
|
+
# Unserialize data and generate any msgpack_class objects within
|
31
|
+
#
|
32
|
+
# === Parameters
|
33
|
+
# data(String):: MessagePack string to unserialize
|
34
|
+
#
|
35
|
+
# === Return
|
36
|
+
# obj(Object):: Unserialized object
|
37
|
+
def self.load(data)
|
38
|
+
if data.respond_to?(:force_encoding)
|
39
|
+
# For Ruby 1.9 need to ensure that MessagePack receives ASCII-8BIT data
|
40
|
+
create(unpack(data.force_encoding("ASCII-8BIT")))
|
41
|
+
else
|
42
|
+
create(unpack(data))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Create any msgpack_class objects nested within the unserialized data by calling
|
47
|
+
# their associated msgpack_create method
|
48
|
+
#
|
49
|
+
# === Parameters
|
50
|
+
# object(Object):: Unserialized object that may contain other objects that need to be created
|
51
|
+
#
|
52
|
+
# === Return
|
53
|
+
# object(Object):: Fully unserialized object
|
54
|
+
#
|
55
|
+
# === Raises
|
56
|
+
# ArgumentError:: If object to be created does not have a msgpack_create method
|
57
|
+
def self.create(object)
|
58
|
+
if object.is_a?(Hash)
|
59
|
+
object.each { |k, v| object[k] = create(v) if v.is_a?(Hash) || v.is_a?(Array) }
|
60
|
+
if klass_name = object['msgpack_class']
|
61
|
+
klass = deep_const_get(klass_name)
|
62
|
+
raise ArgumentError, "#{klass_name} missing msgpack_create method" unless klass.respond_to?(:msgpack_create)
|
63
|
+
object = klass.msgpack_create(object)
|
64
|
+
end
|
65
|
+
elsif object.is_a?(Array)
|
66
|
+
object = object.map { |v| v.is_a?(Hash) || v.is_a?(Array) ? create(v) : v }
|
67
|
+
end
|
68
|
+
object
|
69
|
+
end
|
70
|
+
|
71
|
+
# Serialize object
|
72
|
+
# Any non-standard objects must have an associated to_msgpack instance method
|
73
|
+
#
|
74
|
+
# === Parameters
|
75
|
+
# object(Object):: Object to be serialized
|
76
|
+
#
|
77
|
+
# === Return
|
78
|
+
# (String):: Serialized object
|
79
|
+
def self.dump(object)
|
80
|
+
pack(object)
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
# Return the constant located at the specified path
|
86
|
+
#
|
87
|
+
# === Parameters
|
88
|
+
# path(String):: Absolute namespace path that is of the form ::A::B::C or A::B::C,
|
89
|
+
# with A always being at the top level
|
90
|
+
#
|
91
|
+
# === Return
|
92
|
+
# (Object):: Constant at the end of the path
|
93
|
+
#
|
94
|
+
# === Raises
|
95
|
+
# ArgumentError:: If there is no constant at the given path
|
96
|
+
def self.deep_const_get(path)
|
97
|
+
path = path.to_s
|
98
|
+
path.split(/::/).inject(Object) do |p, c|
|
99
|
+
case
|
100
|
+
when c.empty? then p
|
101
|
+
when p.const_defined?(c) then p.const_get(c)
|
102
|
+
else raise ArgumentError, "Cannot find const #{path}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end # MessagePack
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2013 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightScale
|
24
|
+
|
25
|
+
# Serializer implementation which secures messages by using
|
26
|
+
# X.509 certificate signing
|
27
|
+
class SecureSerializer
|
28
|
+
|
29
|
+
include ProtocolVersionMixin
|
30
|
+
|
31
|
+
class MissingPrivateKey < Exception; end
|
32
|
+
class MissingCertificate < Exception; end
|
33
|
+
class InvalidSignature < Exception; end
|
34
|
+
|
35
|
+
# Create the one and only SecureSerializer
|
36
|
+
def self.init(serializer, identity, store, encrypt = true)
|
37
|
+
@serializer = SecureSerializer.new(serializer, identity, store, encrypt)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
# Was serializer initialized?
|
42
|
+
def self.initialized?
|
43
|
+
!@serializer.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
# See SecureSerializer#dump
|
47
|
+
def self.dump(obj, encrypt = nil)
|
48
|
+
raise "Secure serializer not initialized" unless initialized?
|
49
|
+
@serializer.dump(obj, encrypt)
|
50
|
+
end
|
51
|
+
|
52
|
+
# See SecureSerializer#load
|
53
|
+
def self.load(msg, id = nil)
|
54
|
+
raise "Secure serializer not initialized" unless initialized?
|
55
|
+
@serializer.load(msg, id)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Initialize serializer, must be called prior to using it
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
# serializer(Serializer):: Object serializer
|
62
|
+
# identity(String):: Serialized identity associated with serialized messages
|
63
|
+
# store(Object):: Credentials store exposing certificates used for
|
64
|
+
# encryption (:get_target), signature validation (:get_signer), and
|
65
|
+
# certificate(s)/key(s) used for decryption (:get_receiver)
|
66
|
+
# encrypt(Boolean):: true if data should be signed and encrypted, otherwise
|
67
|
+
# just signed, true by default
|
68
|
+
def initialize(serializer, identity, store, encrypt = true)
|
69
|
+
@identity = identity
|
70
|
+
raise "Missing local agent identity" unless @identity
|
71
|
+
@store = store
|
72
|
+
raise "Missing credentials store" unless @store
|
73
|
+
@cert, @key = @store.get_receiver(@identity)
|
74
|
+
raise "Missing local agent public certificate" unless @cert
|
75
|
+
raise "Missing local agent private key" unless @key
|
76
|
+
@encrypt = encrypt
|
77
|
+
@serializer = serializer
|
78
|
+
end
|
79
|
+
|
80
|
+
# Serialize, sign, and encrypt message
|
81
|
+
# Sign and encrypt using X.509 certificate
|
82
|
+
#
|
83
|
+
# === Parameters
|
84
|
+
# obj(Object):: Object to be serialized and encrypted
|
85
|
+
# encrypt(Boolean|nil):: true if object should be signed and encrypted,
|
86
|
+
# false if just signed, nil means use class setting
|
87
|
+
#
|
88
|
+
# === Return
|
89
|
+
# (String):: MessagePack serialized and optionally encrypted object
|
90
|
+
#
|
91
|
+
# === Raise
|
92
|
+
# Exception:: If certificate identity, certificate store, certificate, or private key missing
|
93
|
+
def dump(obj, encrypt = nil)
|
94
|
+
must_encrypt = encrypt || @encrypt
|
95
|
+
serialize_format = if obj.respond_to?(:send_version) && can_handle_msgpack_result?(obj.send_version)
|
96
|
+
@serializer.format
|
97
|
+
else
|
98
|
+
:json
|
99
|
+
end
|
100
|
+
encode_format = serialize_format == :json ? :pem : :der
|
101
|
+
msg = @serializer.dump(obj, serialize_format)
|
102
|
+
if must_encrypt
|
103
|
+
certs = @store.get_target(obj)
|
104
|
+
if certs
|
105
|
+
msg = EncryptedDocument.new(msg, certs).encrypted_data(encode_format)
|
106
|
+
else
|
107
|
+
target = obj.target_for_encryption if obj.respond_to?(:target_for_encryption)
|
108
|
+
Log.error("No certs available for object #{obj.class} being sent to #{target.inspect}\n") if target
|
109
|
+
end
|
110
|
+
end
|
111
|
+
sig = Signature.new(msg, @cert, @key).data(encode_format)
|
112
|
+
@serializer.dump({'id' => @identity, 'data' => msg, 'signature' => sig, 'encrypted' => !certs.nil?}, serialize_format)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Decrypt, authorize signature, and unserialize message
|
116
|
+
# Use x.509 certificate store for decrypting and validating signature
|
117
|
+
#
|
118
|
+
# === Parameters
|
119
|
+
# msg(String):: Serialized and optionally encrypted object using MessagePack or JSON
|
120
|
+
# id(String|nil):: Optional identifier of source of data for use
|
121
|
+
# in determining who is the receiver
|
122
|
+
#
|
123
|
+
# === Return
|
124
|
+
# (Object):: Unserialized object
|
125
|
+
#
|
126
|
+
# === Raise
|
127
|
+
# Exception:: If certificate store, certificate, or private key missing
|
128
|
+
# MissingCertificate:: If could not find certificate for message signer
|
129
|
+
# InvalidSignature:: If message signature check failed for message
|
130
|
+
def load(msg, id = nil)
|
131
|
+
msg = @serializer.load(msg)
|
132
|
+
sig = Signature.from_data(msg['signature'])
|
133
|
+
certs = @store.get_signer(msg['id'])
|
134
|
+
raise MissingCertificate.new("Could not find a certificate for signer #{msg['id']}") unless certs
|
135
|
+
|
136
|
+
certs = [ certs ] unless certs.respond_to?(:any?)
|
137
|
+
raise InvalidSignature.new("Failed signature check for signer #{msg['id']}") unless certs.any? { |c| sig.match?(c) }
|
138
|
+
|
139
|
+
data = msg['data']
|
140
|
+
if data && msg['encrypted']
|
141
|
+
cert, key = @store.get_receiver(id)
|
142
|
+
raise MissingCertificate.new("Could not find a certificate for #{id.inspect}") unless cert
|
143
|
+
raise MissingPrivateKey.new("Could not find a private key for #{id.inspect}") unless key
|
144
|
+
data = EncryptedDocument.from_data(data).decrypted_data(key, cert)
|
145
|
+
end
|
146
|
+
@serializer.load(data) if data
|
147
|
+
end
|
148
|
+
|
149
|
+
end # SecureSerializer
|
150
|
+
|
151
|
+
end # RightScale
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2013 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightScale
|
24
|
+
|
25
|
+
# Helper class used to initialize secure serializer for agents
|
26
|
+
class SecureSerializerInitializer
|
27
|
+
|
28
|
+
# Initialize serializer
|
29
|
+
#
|
30
|
+
# === Parameters
|
31
|
+
# agent_type(String):: Agent type used to build filename of certificate and key
|
32
|
+
# agent_id(String):: Serialized agent identity
|
33
|
+
#
|
34
|
+
# === Return
|
35
|
+
# true:: Always return true
|
36
|
+
def self.init(agent_type, agent_id)
|
37
|
+
cert = Certificate.load(AgentConfig.certs_file("#{agent_type}.cert"))
|
38
|
+
key = RsaKeyPair.load(AgentConfig.certs_file("#{agent_type}.key"))
|
39
|
+
router_cert = Certificate.load(AgentConfig.certs_file("router.cert"))
|
40
|
+
store = StaticCertificateStore.new(cert, key, router_cert, router_cert)
|
41
|
+
SecureSerializer.init(Serializer.new, agent_id, store)
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#
|
23
|
+
|
24
|
+
module RightScale
|
25
|
+
|
26
|
+
# MessagePack and JSON serializable types that are sent to and from agents
|
27
|
+
module Serializable
|
28
|
+
|
29
|
+
@check_active_support = true
|
30
|
+
|
31
|
+
def self.included(base)
|
32
|
+
if @check_active_support
|
33
|
+
if require_succeeds?("active_support") && (v = Gem.loaded_specs['activesupport'].version.to_s) != "2.3.5"
|
34
|
+
raise Exception.new("Some versions of the activesupport gem modify json in ways that are incompatible with this " +
|
35
|
+
"RightScale::Serializable module. Version #{v} used here is not allowed, use 2.3.5 instead.")
|
36
|
+
else
|
37
|
+
@check_active_support = false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
base.extend ClassMethods
|
42
|
+
base.send(:include, InstanceMethods)
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
|
47
|
+
# Called when deserializing MessagePack to create object
|
48
|
+
#
|
49
|
+
# === Parameters
|
50
|
+
# o(Hash):: Unserialized object data
|
51
|
+
#
|
52
|
+
# === Return
|
53
|
+
# (Object):: Unserialized object
|
54
|
+
def msgpack_create(o)
|
55
|
+
new(*o['data'])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Called by JSON serializer to create object
|
59
|
+
#
|
60
|
+
# === Parameters
|
61
|
+
# o(Hash):: Unserialized object data
|
62
|
+
#
|
63
|
+
# === Return
|
64
|
+
# (Object):: Unserialized object
|
65
|
+
def json_create(o)
|
66
|
+
new(*o['data'])
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
module InstanceMethods
|
72
|
+
|
73
|
+
# Called by MessagePack serializer to serialise object's members
|
74
|
+
#
|
75
|
+
# === Parameters
|
76
|
+
# *a(Array):: Pass-through to Hash's 'to_msgpack' method
|
77
|
+
#
|
78
|
+
# === Return
|
79
|
+
# (String):: MessagePack representation
|
80
|
+
def to_msgpack(*a)
|
81
|
+
{
|
82
|
+
'msgpack_class' => self.class.name,
|
83
|
+
'data' => serialized_members
|
84
|
+
}.to_msgpack(*a).to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
# Called by JSON serializer to serialise object's members
|
88
|
+
#
|
89
|
+
# === Parameters
|
90
|
+
# *a(Array):: Pass-through to Hash's 'to_json' method
|
91
|
+
#
|
92
|
+
# === Return
|
93
|
+
# (String):: JSON representation
|
94
|
+
def to_json(*a)
|
95
|
+
{
|
96
|
+
'json_class' => self.class.name,
|
97
|
+
'data' => serialized_members
|
98
|
+
}.to_json(*a)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Implement in serializable class and return array of fields
|
102
|
+
# that should be given to constructor when deserializing
|
103
|
+
#
|
104
|
+
# === Raise
|
105
|
+
# RuntimeError:: Always raised. Override in heir.
|
106
|
+
def serialized_members
|
107
|
+
raise NotImplemented.new("Must be implemented by #{self.class.name}")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Use serialized members to compare two serializable instances
|
111
|
+
#
|
112
|
+
# === Parameters
|
113
|
+
# other(Serializable):: Other instance to compare self to
|
114
|
+
#
|
115
|
+
# === Return
|
116
|
+
# true:: If both serializable have identical serialized fields
|
117
|
+
# false:: Otherwise
|
118
|
+
def ==(other)
|
119
|
+
return false unless other.respond_to?(:serialized_members)
|
120
|
+
self.serialized_members == other.serialized_members
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
class SerializationHelper
|
128
|
+
|
129
|
+
# Symbolize keys of hash, use when retrieving hashes that use symbols
|
130
|
+
# for keys as JSON and MessagePack serialization will produce strings instead
|
131
|
+
# Simply return any object that is not a hash as is
|
132
|
+
#
|
133
|
+
# === Parameters
|
134
|
+
# hash(Hash):: Hash whose keys are to be symbolized
|
135
|
+
#
|
136
|
+
# === Return
|
137
|
+
# (Hash):: Hash with same values but symbol keys
|
138
|
+
def self.symbolize_keys(hash)
|
139
|
+
if hash.is_a?(Hash)
|
140
|
+
hash.inject({}) do |h, (key, value)|
|
141
|
+
h[(key.to_sym rescue key) || key] = value
|
142
|
+
h
|
143
|
+
end
|
144
|
+
else
|
145
|
+
hash
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end # Serializable
|
150
|
+
|
151
|
+
end # RightScale
|