Class | MCollective::Security::Base |
In: |
lib/mcollective/security/base.rb
|
Parent: | Object |
This is a base class the other security modules should inherit from it handles statistics and validation of messages that should in most cases apply to all security models.
To create your own security plugin you should provide a plugin that inherits from this and provides the following methods:
decodemsg - Decodes a message that was received from the middleware encodereply - Encodes a reply message to a previous request message encoderequest - Encodes a new request message validrequest? - Validates a request received from the middleware
Optionally if you are identifying users by some other means like certificate name you can provide your own callerid method that can provide the rest of the system with an id, and you would see this id being usable in SimpleRPC authorization methods
The @initiated_by variable will be set to either :client or :node depending on who is using this plugin. This is to help security providers that operate in an asymetric mode like public/private key based systems.
Specifics of each of these are a bit fluid and the interfaces for this is not set in stone yet, specifically the encode methods will be provided with a helper that takes care of encoding the core requirements. The best place to see how security works is by looking at the provided MCollective::Security::PSK plugin.
initiated_by | [RW] | |
stats | [R] |
Register plugins that inherits base
# File lib/mcollective/security/base.rb, line 32 32: def self.inherited(klass) 33: PluginManager << {:type => "security_plugin", :class => klass.to_s} 34: end
Initializes configuration and logging as well as prepare a zero‘d hash of stats various security methods and filter validators should increment stats, see MCollective::Security::Psk for a sample
# File lib/mcollective/security/base.rb, line 38 38: def initialize 39: @config = Config.instance 40: @log = Log.instance 41: 42: @stats = PluginManager["global_stats"] 43: end
Returns a unique id for the caller, by default we just use the unix user id, security plugins can provide their own means of doing ids.
# File lib/mcollective/security/base.rb, line 128 128: def callerid 129: "uid=#{Process.uid}" 130: end
Security providers should provide this, see MCollective::Security::Psk
# File lib/mcollective/security/base.rb, line 148 148: def decodemsg(msg) 149: @log.error("decodemsg is not implimented in #{this.class}") 150: end
Security providers should provide this, see MCollective::Security::Psk
# File lib/mcollective/security/base.rb, line 143 143: def encodereply(sender, target, msg, filter={}) 144: @log.error("encodereply is not implimented in #{this.class}") 145: end
Security providers should provide this, see MCollective::Security::Psk
# File lib/mcollective/security/base.rb, line 138 138: def encoderequest(sender, target, msg, filter={}) 139: @log.error("encoderequest is not implimented in #{this.class}") 140: end
Takes a Hash with a filter in it and validates it against host information.
At present this supports filter matches against the following criteria:
the file configured with classesfile
TODO: Support REGEX and/or multiple filter keys to be AND‘d
# File lib/mcollective/security/base.rb, line 56 56: def validate_filter?(filter) 57: failed = 0 58: passed = 0 59: 60: passed = 1 if Util.empty_filter?(filter) 61: 62: filter.keys.each do |key| 63: case key 64: when /puppet_class|cf_class/ 65: filter[key].each do |f| 66: @log.debug("Checking for class #{f}") 67: if Util.has_cf_class?(f) then 68: @log.debug("Passing based on configuration management class #{f}") 69: passed += 1 70: else 71: @log.debug("Failing based on configuration management class #{f}") 72: failed += 1 73: end 74: end 75: 76: when "agent" 77: filter[key].each do |f| 78: if Util.has_agent?(f) || f == "mcollective" 79: @log.debug("Passing based on agent #{f}") 80: passed += 1 81: else 82: @log.debug("Failing based on agent #{f}") 83: failed += 1 84: end 85: end 86: 87: when "fact" 88: filter[key].each do |f| 89: if Util.has_fact?(f[:fact], f[:value]) 90: @log.debug("Passing based on fact #{f[:fact]} = #{f[:value]}") 91: passed += 1 92: else 93: @log.debug("Failing based on fact #{f[:fact]} = #{f[:value]}") 94: failed += 1 95: end 96: end 97: 98: when "identity" 99: filter[key].each do |f| 100: if Util.has_identity?(f) 101: @log.debug("Passing based on identity = #{f}") 102: passed += 1 103: else 104: @log.debug("Failed based on identity = #{f}") 105: failed += 1 106: end 107: end 108: end 109: end 110: 111: if failed == 0 && passed > 0 112: @log.debug("Message passed the filter checks") 113: 114: @stats.passed 115: 116: return true 117: else 118: @log.debug("Message failed the filter checks") 119: 120: @stats.filtered 121: 122: return false 123: end 124: end
Security providers should provide this, see MCollective::Security::Psk
# File lib/mcollective/security/base.rb, line 133 133: def validrequest?(req) 134: @log.error("validrequest? is not implimented in #{this.class}") 135: end