HEX
Server: Apache
System: Linux vpshost0650.publiccloud.com.br 4.4.79-grsec-1.lc.x86_64 #1 SMP Wed Aug 2 14:18:21 -03 2017 x86_64
User: bandeirantesbomb3 (10068)
PHP: 8.0.7
Disabled: apache_child_terminate,dl,escapeshellarg,escapeshellcmd,exec,link,mail,openlog,passthru,pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_wait,pcntl_waitpid,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,php_check_syntax,php_strip_whitespace,popen,proc_close,proc_open,shell_exec,symlink,system
Upload Files
File: //proc/thread-self/root/opt/puppetlabs/puppet/lib/ruby/vendor_ruby/mcollective/security/psk.rb
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
    #
    # You can configure the caller id being created, this can adjust how you
    # create authorization plugins.  For example you can use a unix group instead
    # of uid to do authorization.
    class Psk < Base
      require 'etc'

      # 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)

        should_process_msg?(msg, body[:requestid])

        if validrequest?(body)
          body[:body] = Marshal.load(body[:body])
          return body
        else
          nil
        end
      end

      # Encodes a reply
      def encodereply(sender, msg, requestid, requestcallerid=nil)
        serialized  = Marshal.dump(msg)
        digest = makehash(serialized)

        req = create_reply(requestid, sender, serialized)
        req[:hash] = digest

        Marshal.dump(req)
      end

      # Encodes a request msg
      def encoderequest(sender, msg, requestid, filter, target_agent, target_collective, ttl=60)
        serialized = Marshal.dump(msg)
        digest = makehash(serialized)

        req = create_request(requestid, filter, serialized, @initiated_by, target_agent, target_collective, ttl)
        req[:hash] = digest

        Marshal.dump(req)
      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(SecurityValidationFailed, "Received an invalid signature in message")
        end
      end

      def callerid
        if @config.pluginconf.include?("psk.callertype")
          callertype = @config.pluginconf["psk.callertype"].to_sym if @config.pluginconf.include?("psk.callertype")
        else
          callertype = :uid
        end

        case callertype
          when :gid
            id  = "gid=#{Process.gid}"

          when :group
            raise "Cannot use the 'group' callertype for the PSK security plugin on the Windows platform" if Util.windows?

            id = "group=#{Etc.getgrgid(Process.gid).name}"

          when :user
            id = "user=#{Etc.getlogin}"

          when :identity
            id = "identity=#{@config.identity}"

          else
            id ="uid=#{Process.uid}"
        end

        Log.debug("Setting callerid to #{id} based on callertype=#{callertype}")

        id
      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