2014-06-04 18:01:09 +00:00
|
|
|
require 'active_model'
|
|
|
|
|
|
|
|
module Metasploit
|
|
|
|
module Framework
|
|
|
|
# This class provides an in-memory representation of a conceptual Credential
|
|
|
|
#
|
|
|
|
# It contains the public, private, and realm if any.
|
|
|
|
class Credential
|
|
|
|
include ActiveModel::Validations
|
|
|
|
|
|
|
|
# @!attribute paired
|
|
|
|
# @return [Boolean] Whether BOTH a public and private are required
|
|
|
|
# (defaults to `true`)
|
|
|
|
attr_accessor :paired
|
2014-07-29 16:20:52 +00:00
|
|
|
# @!attribute parent
|
|
|
|
# @return [Object] the parent object that had .to_credential called on it to create this object
|
|
|
|
attr_accessor :parent
|
2014-06-04 18:01:09 +00:00
|
|
|
# @!attribute private
|
|
|
|
# The private credential component (e.g. username)
|
|
|
|
#
|
|
|
|
# @return [String] if {#paired} is `true` or {#private} is `nil`
|
|
|
|
# @return [String, nil] if {#paired} is `false` or {#private} is not `nil`.
|
|
|
|
attr_accessor :private
|
2014-07-07 18:07:28 +00:00
|
|
|
# @!attribute private_type
|
|
|
|
# The type of private credential this object represents, e.g. a
|
|
|
|
# password or an NTLM hash.
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
attr_accessor :private_type
|
2014-06-04 18:01:09 +00:00
|
|
|
# @!attribute public
|
|
|
|
# The public credential component (e.g. password)
|
|
|
|
#
|
|
|
|
# @return [String] if {#paired} is `true` or {#public} is `nil`
|
|
|
|
# @return [String, nil] if {#paired} is `false` or {#public} is not `nil`.
|
|
|
|
attr_accessor :public
|
|
|
|
# @!attribute realm
|
|
|
|
# @return [String,nil] The realm credential component (e.g domain name)
|
|
|
|
attr_accessor :realm
|
2014-07-07 18:07:28 +00:00
|
|
|
# @!attribute realm
|
|
|
|
# @return [String,nil] The type of {#realm}
|
|
|
|
attr_accessor :realm_key
|
2014-06-04 18:01:09 +00:00
|
|
|
|
|
|
|
validates :paired,
|
|
|
|
inclusion: { in: [true, false] }
|
|
|
|
|
|
|
|
# If we have no public we MUST have a private (e.g. SNMP Community String)
|
|
|
|
validates :private,
|
|
|
|
exclusion: { in: [nil] },
|
|
|
|
if: "public.nil? or paired"
|
|
|
|
|
2014-07-07 18:07:28 +00:00
|
|
|
# These values should be #demodularized from subclasses of
|
|
|
|
# `Metasploit::Credential::Private`
|
|
|
|
validates :private_type,
|
2014-07-07 20:40:52 +00:00
|
|
|
inclusion: { in: [ :password, :ntlm_hash, :ssh_key ] },
|
|
|
|
if: "private_type.present?"
|
2014-07-07 18:07:28 +00:00
|
|
|
|
2014-06-04 18:01:09 +00:00
|
|
|
# If we have no private we MUST have a public
|
|
|
|
validates :public,
|
|
|
|
presence: true,
|
|
|
|
if: "private.nil? or paired"
|
|
|
|
|
|
|
|
# @param attributes [Hash{Symbol => String,nil}]
|
|
|
|
def initialize(attributes={})
|
|
|
|
attributes.each do |attribute, value|
|
|
|
|
public_send("#{attribute}=", value)
|
|
|
|
end
|
|
|
|
|
|
|
|
self.paired = true if self.paired.nil?
|
|
|
|
end
|
|
|
|
|
|
|
|
def inspect
|
2014-06-04 22:03:52 +00:00
|
|
|
"#<#{self.class} \"#{self}\" >"
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_s
|
2014-07-10 19:31:42 +00:00
|
|
|
if realm && realm_key == Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN
|
|
|
|
"#{self.realm}\\#{self.public}:#{self.private}"
|
|
|
|
else
|
|
|
|
"#{self.public}:#{self.private}#{at_realm}"
|
|
|
|
end
|
2014-06-04 18:01:09 +00:00
|
|
|
end
|
2014-06-05 16:37:48 +00:00
|
|
|
|
|
|
|
def ==(other)
|
2014-07-23 21:17:09 +00:00
|
|
|
other.respond_to?(:public) && other.public == self.public &&
|
|
|
|
other.respond_to?(:private) && other.private == self.private &&
|
|
|
|
other.respond_to?(:realm) && other.realm == self.realm
|
2014-06-05 16:37:48 +00:00
|
|
|
end
|
2014-07-07 18:07:28 +00:00
|
|
|
|
2014-06-26 16:05:59 +00:00
|
|
|
def to_credential
|
|
|
|
self
|
|
|
|
end
|
2014-07-07 18:07:28 +00:00
|
|
|
|
2014-06-10 16:07:15 +00:00
|
|
|
private
|
|
|
|
|
|
|
|
def at_realm
|
|
|
|
if self.realm.present?
|
|
|
|
"@#{self.realm}"
|
|
|
|
else
|
|
|
|
""
|
|
|
|
end
|
|
|
|
end
|
2014-06-04 18:01:09 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|