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.
Files changed (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +113 -0
  4. data/lib/right_agent.rb +59 -0
  5. data/lib/right_agent/actor.rb +182 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +232 -0
  8. data/lib/right_agent/agent.rb +1149 -0
  9. data/lib/right_agent/agent_config.rb +480 -0
  10. data/lib/right_agent/agent_identity.rb +210 -0
  11. data/lib/right_agent/agent_tag_manager.rb +237 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/clients.rb +31 -0
  14. data/lib/right_agent/clients/api_client.rb +383 -0
  15. data/lib/right_agent/clients/auth_client.rb +247 -0
  16. data/lib/right_agent/clients/balanced_http_client.rb +369 -0
  17. data/lib/right_agent/clients/base_retry_client.rb +495 -0
  18. data/lib/right_agent/clients/right_http_client.rb +279 -0
  19. data/lib/right_agent/clients/router_client.rb +493 -0
  20. data/lib/right_agent/command.rb +30 -0
  21. data/lib/right_agent/command/agent_manager_commands.rb +150 -0
  22. data/lib/right_agent/command/command_client.rb +136 -0
  23. data/lib/right_agent/command/command_constants.rb +33 -0
  24. data/lib/right_agent/command/command_io.rb +126 -0
  25. data/lib/right_agent/command/command_parser.rb +87 -0
  26. data/lib/right_agent/command/command_runner.rb +118 -0
  27. data/lib/right_agent/command/command_serializer.rb +63 -0
  28. data/lib/right_agent/connectivity_checker.rb +179 -0
  29. data/lib/right_agent/console.rb +65 -0
  30. data/lib/right_agent/core_payload_types.rb +44 -0
  31. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  32. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  33. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  34. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  35. data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
  36. data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
  37. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  38. data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
  39. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  40. data/lib/right_agent/core_payload_types/login_user.rb +79 -0
  41. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  42. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
  43. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  44. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  45. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
  46. data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
  47. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  48. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  49. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  50. data/lib/right_agent/daemonize.rb +35 -0
  51. data/lib/right_agent/dispatched_cache.rb +109 -0
  52. data/lib/right_agent/dispatcher.rb +272 -0
  53. data/lib/right_agent/enrollment_result.rb +221 -0
  54. data/lib/right_agent/exceptions.rb +87 -0
  55. data/lib/right_agent/history.rb +145 -0
  56. data/lib/right_agent/log.rb +460 -0
  57. data/lib/right_agent/minimal.rb +46 -0
  58. data/lib/right_agent/monkey_patches.rb +30 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  64. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  65. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  66. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
  67. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  68. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  69. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  70. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  71. data/lib/right_agent/multiplexer.rb +102 -0
  72. data/lib/right_agent/offline_handler.rb +270 -0
  73. data/lib/right_agent/operation_result.rb +300 -0
  74. data/lib/right_agent/packets.rb +673 -0
  75. data/lib/right_agent/payload_formatter.rb +104 -0
  76. data/lib/right_agent/pending_requests.rb +128 -0
  77. data/lib/right_agent/pid_file.rb +159 -0
  78. data/lib/right_agent/platform.rb +770 -0
  79. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  80. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  81. data/lib/right_agent/platform/unix/platform.rb +226 -0
  82. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  83. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  84. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  85. data/lib/right_agent/protocol_version_mixin.rb +69 -0
  86. data/lib/right_agent/retryable_request.rb +195 -0
  87. data/lib/right_agent/scripts/agent_controller.rb +543 -0
  88. data/lib/right_agent/scripts/agent_deployer.rb +400 -0
  89. data/lib/right_agent/scripts/common_parser.rb +160 -0
  90. data/lib/right_agent/scripts/log_level_manager.rb +192 -0
  91. data/lib/right_agent/scripts/stats_manager.rb +268 -0
  92. data/lib/right_agent/scripts/usage.rb +58 -0
  93. data/lib/right_agent/secure_identity.rb +92 -0
  94. data/lib/right_agent/security.rb +32 -0
  95. data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
  96. data/lib/right_agent/security/certificate.rb +102 -0
  97. data/lib/right_agent/security/certificate_cache.rb +89 -0
  98. data/lib/right_agent/security/distinguished_name.rb +56 -0
  99. data/lib/right_agent/security/encrypted_document.rb +83 -0
  100. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  101. data/lib/right_agent/security/signature.rb +86 -0
  102. data/lib/right_agent/security/static_certificate_store.rb +85 -0
  103. data/lib/right_agent/sender.rb +792 -0
  104. data/lib/right_agent/serialize.rb +29 -0
  105. data/lib/right_agent/serialize/message_pack.rb +107 -0
  106. data/lib/right_agent/serialize/secure_serializer.rb +151 -0
  107. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  108. data/lib/right_agent/serialize/serializable.rb +151 -0
  109. data/lib/right_agent/serialize/serializer.rb +159 -0
  110. data/lib/right_agent/subprocess.rb +38 -0
  111. data/lib/right_agent/tracer.rb +124 -0
  112. data/right_agent.gemspec +101 -0
  113. data/spec/actor_registry_spec.rb +80 -0
  114. data/spec/actor_spec.rb +162 -0
  115. data/spec/agent_config_spec.rb +235 -0
  116. data/spec/agent_identity_spec.rb +78 -0
  117. data/spec/agent_spec.rb +734 -0
  118. data/spec/agent_tag_manager_spec.rb +319 -0
  119. data/spec/clients/api_client_spec.rb +423 -0
  120. data/spec/clients/auth_client_spec.rb +272 -0
  121. data/spec/clients/balanced_http_client_spec.rb +576 -0
  122. data/spec/clients/base_retry_client_spec.rb +635 -0
  123. data/spec/clients/router_client_spec.rb +594 -0
  124. data/spec/clients/spec_helper.rb +111 -0
  125. data/spec/command/agent_manager_commands_spec.rb +51 -0
  126. data/spec/command/command_io_spec.rb +93 -0
  127. data/spec/command/command_parser_spec.rb +79 -0
  128. data/spec/command/command_runner_spec.rb +107 -0
  129. data/spec/command/command_serializer_spec.rb +51 -0
  130. data/spec/connectivity_checker_spec.rb +83 -0
  131. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  132. data/spec/core_payload_types/dev_repository_spec.rb +33 -0
  133. data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
  134. data/spec/core_payload_types/login_user_spec.rb +102 -0
  135. data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
  136. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  137. data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
  138. data/spec/core_payload_types/spec_helper.rb +23 -0
  139. data/spec/dispatched_cache_spec.rb +136 -0
  140. data/spec/dispatcher_spec.rb +324 -0
  141. data/spec/enrollment_result_spec.rb +53 -0
  142. data/spec/history_spec.rb +246 -0
  143. data/spec/log_spec.rb +192 -0
  144. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  145. data/spec/multiplexer_spec.rb +48 -0
  146. data/spec/offline_handler_spec.rb +340 -0
  147. data/spec/operation_result_spec.rb +208 -0
  148. data/spec/packets_spec.rb +461 -0
  149. data/spec/pending_requests_spec.rb +136 -0
  150. data/spec/platform/spec_helper.rb +216 -0
  151. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  152. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  153. data/spec/platform/unix/spec_helper.rb +149 -0
  154. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  155. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  156. data/spec/platform/windows/spec_helper.rb +720 -0
  157. data/spec/retryable_request_spec.rb +306 -0
  158. data/spec/secure_identity_spec.rb +50 -0
  159. data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
  160. data/spec/security/certificate_cache_spec.rb +71 -0
  161. data/spec/security/certificate_spec.rb +49 -0
  162. data/spec/security/distinguished_name_spec.rb +46 -0
  163. data/spec/security/encrypted_document_spec.rb +55 -0
  164. data/spec/security/rsa_key_pair_spec.rb +55 -0
  165. data/spec/security/signature_spec.rb +66 -0
  166. data/spec/security/static_certificate_store_spec.rb +58 -0
  167. data/spec/sender_spec.rb +1045 -0
  168. data/spec/serialize/message_pack_spec.rb +131 -0
  169. data/spec/serialize/secure_serializer_spec.rb +132 -0
  170. data/spec/serialize/serializable_spec.rb +90 -0
  171. data/spec/serialize/serializer_spec.rb +197 -0
  172. data/spec/spec.opts +2 -0
  173. data/spec/spec.win32.opts +1 -0
  174. data/spec/spec_helper.rb +130 -0
  175. data/spec/tracer_spec.rb +114 -0
  176. 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