From 8c8b404cc966e970446cb7ff8e686d1c856b9224 Mon Sep 17 00:00:00 2001 From: Eric Shamow Date: Tue, 28 Sep 2010 14:54:40 -0400 Subject: [PATCH] Added alternate psk which passes gid --- .../psk_alternatives/psk_gid.rb | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 simplerpc_authorization/psk_alternatives/psk_gid.rb diff --git a/simplerpc_authorization/psk_alternatives/psk_gid.rb b/simplerpc_authorization/psk_alternatives/psk_gid.rb new file mode 100644 index 0000000..058ea97 --- /dev/null +++ b/simplerpc_authorization/psk_alternatives/psk_gid.rb @@ -0,0 +1,99 @@ +module MCollective + module Security + # Impliments message authentication using digests and shared keys + # + # You should configure a psk in the configuration file and all requests + # will be validated for authenticity with this. + # + # Serialization uses Marshal, this is the default security module that is + # supported out of the box. + # + # Validation is as default and is provided by MCollective::Security::Base + class Psk < Base + # Returns a unique ID for the caller's group + def callerid + "gid=#{Process.gid}" + end + + # Decodes a message by unserializing all the bits etc, it also validates + # it as valid using the psk etc + def decodemsg(msg) + body = Marshal.load(msg.payload) + + if validrequest?(body) + body[:body] = Marshal.load(body[:body]) + return body + else + nil + end + end + + # Encodes a reply + def encodereply(sender, target, msg, requestid, filter={}) + serialized = Marshal.dump(msg) + digest = makehash(serialized) + + @log.debug("Encoded a message with hash #{digest} for request #{requestid}") + + Marshal.dump({:senderid => @config.identity, + :requestid => requestid, + :senderagent => sender, + :msgtarget => target, + :msgtime => Time.now.to_i, + :hash => digest, + :body => serialized}) + end + + # Encodes a request msg + def encoderequest(sender, target, msg, requestid, filter={}) + serialized = Marshal.dump(msg) + digest = makehash(serialized) + + @log.debug("Encoding a request for '#{target}' with request id #{requestid}") + request = {:body => serialized, + :hash => digest, + :senderid => @config.identity, + :requestid => requestid, + :msgtarget => target, + :filter => filter, + :msgtime => Time.now.to_i} + + # if we're in use by a client add the callerid to the main client hashes + request[:callerid] = callerid if @initiated_by == :client + + Marshal.dump(request) + end + + # Checks the md5 hash in the request body against our psk, the request sent for validation + # should not have been deserialized already + def validrequest?(req) + digest = makehash(req[:body]) + + if digest == req[:hash] + @stats.validated + + return true + else + @stats.unvalidated + + raise("Received an invalid signature in message") + end + end + + private + # Retrieves the value of plugin.psk and builds a hash with it and the passed body + def makehash(body) + if ENV.include?("MCOLLECTIVE_PSK") + psk = ENV["MCOLLECTIVE_PSK"] + else + raise("No plugin.psk configuration option specified") unless @config.pluginconf.include?("psk") + psk = @config.pluginconf["psk"] + end + + Digest::MD5.hexdigest(body.to_s + psk) + end + + end + end +end +# vi:tabstop=4:expandtab:ai