3 # Impliments message authentication using digests and shared keys
5 # You should configure a psk in the configuration file and all requests
6 # will be validated for authenticity with this.
8 # Serialization uses Marshal, this is the default security module that is
9 # supported out of the box.
11 # Validation is as default and is provided by MCollective::Security::Base
13 # You can configure the caller id being created, this can adjust how you
14 # create authorization plugins. For example you can use a unix group instead
15 # of uid to do authorization.
19 # Decodes a message by unserializing all the bits etc, it also validates
20 # it as valid using the psk etc
22 body = Marshal.load(msg.payload)
24 should_process_msg?(msg, body[:requestid])
26 if validrequest?(body)
27 body[:body] = Marshal.load(body[:body])
35 def encodereply(sender, msg, requestid, requestcallerid=nil)
36 serialized = Marshal.dump(msg)
37 digest = makehash(serialized)
39 req = create_reply(requestid, sender, serialized)
45 # Encodes a request msg
46 def encoderequest(sender, msg, requestid, filter, target_agent, target_collective, ttl=60)
47 serialized = Marshal.dump(msg)
48 digest = makehash(serialized)
50 req = create_request(requestid, filter, serialized, @initiated_by, target_agent, target_collective, ttl)
56 # Checks the md5 hash in the request body against our psk, the request sent for validation
57 # should not have been deserialized already
58 def validrequest?(req)
59 digest = makehash(req[:body])
61 if digest == req[:hash]
68 raise(SecurityValidationFailed, "Received an invalid signature in message")
73 if @config.pluginconf.include?("psk.callertype")
74 callertype = @config.pluginconf["psk.callertype"].to_sym if @config.pluginconf.include?("psk.callertype")
81 id = "gid=#{Process.gid}"
84 raise "Cannot use the 'group' callertype for the PSK security plugin on the Windows platform" if Util.windows?
86 id = "group=#{Etc.getgrgid(Process.gid).name}"
89 id = "user=#{Etc.getlogin}"
92 id = "identity=#{@config.identity}"
95 id ="uid=#{Process.uid}"
98 Log.debug("Setting callerid to #{id} based on callertype=#{callertype}")
104 # Retrieves the value of plugin.psk and builds a hash with it and the passed body
106 if ENV.include?("MCOLLECTIVE_PSK")
107 psk = ENV["MCOLLECTIVE_PSK"]
109 raise("No plugin.psk configuration option specified") unless @config.pluginconf.include?("psk")
110 psk = @config.pluginconf["psk"]
113 Digest::MD5.hexdigest(body.to_s + psk)