diff --git a/lib/metasploit/framework/credential_collection.rb b/lib/metasploit/framework/credential_collection.rb index cdd63fe3d9..c6666d117d 100644 --- a/lib/metasploit/framework/credential_collection.rb +++ b/lib/metasploit/framework/credential_collection.rb @@ -2,127 +2,127 @@ require 'metasploit/framework/credential' module Metasploit::Framework - class PrivateCredentialCollection - # @!attribute additional_privates - # Additional privates to be combined - # - # @return [Array] - attr_accessor :additional_privates + class PrivateCredentialCollection + # @!attribute additional_privates + # Additional privates to be combined + # + # @return [Array] + attr_accessor :additional_privates - # @!attribute blank_passwords - # Whether each username should be tried with a blank password - # @return [Boolean] - attr_accessor :blank_passwords + # @!attribute blank_passwords + # Whether each username should be tried with a blank password + # @return [Boolean] + attr_accessor :blank_passwords - # @!attribute pass_file - # Path to a file containing passwords, one per line - # @return [String] - attr_accessor :pass_file + # @!attribute pass_file + # Path to a file containing passwords, one per line + # @return [String] + attr_accessor :pass_file - # @!attribute password - # @return [String] - attr_accessor :password + # @!attribute password + # @return [String] + attr_accessor :password - # @!attribute prepended_creds - # List of credentials to be tried before any others - # - # @see #prepend_cred - # @return [Array] - attr_accessor :prepended_creds + # @!attribute prepended_creds + # List of credentials to be tried before any others + # + # @see #prepend_cred + # @return [Array] + attr_accessor :prepended_creds - # @!attribute realm - # @return [String] - attr_accessor :realm + # @!attribute realm + # @return [String] + attr_accessor :realm - # @option opts [Boolean] :blank_passwords See {#blank_passwords} - # @option opts [String] :pass_file See {#pass_file} - # @option opts [String] :password See {#password} - # @option opts [Array] :prepended_creds ([]) See {#prepended_creds} - # @option opts [Boolean] :user_as_pass See {#user_as_pass} - # @option opts [String] :user_file See {#user_file} - # @option opts [String] :username See {#username} - # @option opts [String] :userpass_file See {#userpass_file} - def initialize(opts = {}) - opts.each do |attribute, value| - public_send("#{attribute}=", value) - end - self.prepended_creds ||= [] - self.additional_privates ||= [] + # @option opts [Boolean] :blank_passwords See {#blank_passwords} + # @option opts [String] :pass_file See {#pass_file} + # @option opts [String] :password See {#password} + # @option opts [Array] :prepended_creds ([]) See {#prepended_creds} + # @option opts [Boolean] :user_as_pass See {#user_as_pass} + # @option opts [String] :user_file See {#user_file} + # @option opts [String] :username See {#username} + # @option opts [String] :userpass_file See {#userpass_file} + def initialize(opts = {}) + opts.each do |attribute, value| + public_send("#{attribute}=", value) + end + self.prepended_creds ||= [] + self.additional_privates ||= [] + end + + # Adds a string as an addition private credential + # to be combined in the collection. + # + # @param [String] private_str the string to use as a private + # @return [void] + def add_private(private_str='') + additional_privates << private_str + end + + # Add {Credential credentials} that will be yielded by {#each} + # + # @see prepended_creds + # @param cred [Credential] + # @return [self] + def prepend_cred(cred) + prepended_creds.unshift cred + self + end + + # Combines all the provided credential sources into a stream of {Credential} + # objects, yielding them one at a time + # + # @yieldparam credential [Metasploit::Framework::Credential] + # @return [void] + def each + if pass_file.present? + pass_fd = File.open(pass_file, 'r:binary') end - # Adds a string as an addition private credential - # to be combined in the collection. - # - # @param [String] private_str the string to use as a private - # @return [void] - def add_private(private_str='') - additional_privates << private_str + prepended_creds.each { |c| yield c } + + if password.present? + yield Metasploit::Framework::Credential.new(private: password, realm: realm, private_type: private_type(password)) + end + if blank_passwords + yield Metasploit::Framework::Credential.new(private: "", realm: realm, private_type: :password) + end + if pass_fd + pass_fd.each_line do |pass_from_file| + pass_from_file.chomp! + yield Metasploit::Framework::Credential.new(private: pass_from_file, realm: realm, private_type: private_type(pass_from_file)) + end + pass_fd.seek(0) + end + additional_privates.each do |add_private| + yield Metasploit::Framework::Credential.new(private: add_private, realm: realm, private_type: private_type(add_private)) end - # Add {Credential credentials} that will be yielded by {#each} - # - # @see prepended_creds - # @param cred [Credential] - # @return [self] - def prepend_cred(cred) - prepended_creds.unshift cred - self - end + ensure + pass_fd.close if pass_fd && !pass_fd.closed? + end - # Combines all the provided credential sources into a stream of {Credential} - # objects, yielding them one at a time - # - # @yieldparam credential [Metasploit::Framework::Credential] - # @return [void] - def each - if pass_file.present? - pass_fd = File.open(pass_file, 'r:binary') - end + # Returns true when #each will have no results to iterate + def empty? + prepended_creds.empty? && !has_privates? + end - prepended_creds.each { |c| yield c } + def has_privates? + password.present? || pass_file.present? || !additional_privates.empty? || blank_passwords + end - if password.present? - yield Metasploit::Framework::Credential.new(private: password, realm: realm, private_type: private_type(password)) - end - if blank_passwords - yield Metasploit::Framework::Credential.new(private: "", realm: realm, private_type: :password) - end - if pass_fd - pass_fd.each_line do |pass_from_file| - pass_from_file.chomp! - yield Metasploit::Framework::Credential.new(private: pass_from_file, realm: realm, private_type: private_type(pass_from_file)) - end - pass_fd.seek(0) - end - additional_privates.each do |add_private| - yield Metasploit::Framework::Credential.new(private: add_private, realm: realm, private_type: private_type(add_private)) - end + protected - ensure - pass_fd.close if pass_fd && !pass_fd.closed? - end - - # Returns true when #each will have no results to iterate - def empty? - prepended_creds.empty? && !has_privates? - end - - def has_privates? - password.present? || pass_file.present? || !additional_privates.empty? || blank_passwords - end - - protected - - def private_type(private) - if private =~ /[0-9a-f]{32}:[0-9a-f]{32}/ - :ntlm_hash - elsif private =~ /^md5([a-f0-9]{32})$/ - :postgres_md5 - else - :password - end + def private_type(private) + if private =~ /[0-9a-f]{32}:[0-9a-f]{32}/ + :ntlm_hash + elsif private =~ /^md5([a-f0-9]{32})$/ + :postgres_md5 + else + :password end end + end class CredentialCollection < PrivateCredentialCollection