class Wonk::PolicyValidators::AwsEC2Validator

Constants

AWS_GOVCLOUD_CERTIFICATE
AWS_PUBLIC_CERTIFICATE
RULES_MAP

Attributes

rules[R]

Public Class Methods

new(parameters) click to toggle source
# File lib/wonk/policy_validators/aws_ec2_validator.rb, line 58
def initialize(parameters)
  raise "Wonk.aws_region must be set to use AwsEC2Validator." if Wonk.aws_region.nil?

  @identity_cert =
    case Wonk.aws_region
    when 'us-gov-west-1'
      AWS_GOVCLOUD_CERTIFICATE
    else
      AWS_PUBLIC_CERTIFICATE
    end

  @ec2_rsrc = Aws::EC2::Resource.new(region: Wonk.aws_region)
  @iam_rsrc = Aws::IAM::Resource.new(region: Wonk.aws_region)

  @rules =
    (parameters[:rules] || []).map do |rule_definition|
      rule_class = RULES_MAP[rule_definition[:type]]

      raise "no rule class for type '#{rule_definition[:type]}'" if rule_class.nil?

      rule_class.new(rule_definition[:parameters] || {})
    end.freeze
end

Public Instance Methods

do_authenticate(submission) click to toggle source
# File lib/wonk/policy_validators/aws_ec2_validator.rb, line 86
      def do_authenticate(submission)
        env = { captures: {} }

        success =
          [ :document, :signature ].each do |n|
            raise ValidatorError, "'#{n}' is required." unless submission.key?(n)
          end

          pemmed_signature = <<-PKCS.strip_heredoc
-----BEGIN PKCS7-----
#{submission[:signature]}
-----END PKCS7-----
          PKCS

          Dir.mktmpdir do |dir|
            cert_path = "#{dir}/cert.pem"
            signature_path = "#{dir}/signature.pem"
            data_path = "#{dir}/data.json"

            IO.write(cert_path, @identity_cert)
            IO.write(signature_path, pemmed_signature)
            IO.write(data_path, submission[:document])

            `openssl smime -verify -inform PEM -in '#{signature_path}' -content '#{data_path}' -certfile '#{cert_path}' -noverify > /dev/null 2>&1`

            if $?.success?
              instance_identity = JSON.parse(submission[:document]).deep_symbolize_keys

              instance_id = instance_identity[:instanceId]

              env[:instance_id] = instance_identity[:instanceId]
              env[:account_id] = instance_identity[:accountId]

              instance = @ec2_rsrc.instance(instance_id)

              rule_result =
                begin
                  @rules.map { |rule| rule.try_match(instance, instance_identity) }.find(&:success?)
                rescue Aws::Errors::MissingCredentialsError => err
                  Wonk.logger.error "No AWS credentials found!"
                  raise err
                end

              if !rule_result.nil?
                env[:captures].merge!(rule_result.captures)

                true
              else
                false
              end
            else
              false
            end
          end

        ValidatorResult.new(successful: success, environment: env)
      end
validator_name() click to toggle source
# File lib/wonk/policy_validators/aws_ec2_validator.rb, line 82
def validator_name
  'aws-ec2'
end