Class: Rex::Proto::DNS::StaticHostnames
- Inherits:
-
Object
- Object
- Rex::Proto::DNS::StaticHostnames
- Extended by:
- Forwardable
- Defined in:
- lib/rex/proto/dns/static_hostnames.rb
Overview
This class manages statically defined hostnames for DNS resolution where each name is a mapping to an IPv4 and or an IPv6 address. A single hostname can only map to one address of each family.
Class Method Summary collapse
Instance Method Summary collapse
-
#add(hostname, ip_address) ⇒ Object
Add an IP address for the specified hostname.
-
#delete(hostname, ip_address) ⇒ Object
Delete an IP address for the specified hostname.
-
#flush ⇒ Object
Delete all hostname to IP address definitions.
-
#get(hostname, type = Dnsruby::Types::A) ⇒ Object
Get all IP addresses of the specified type for the hostname.
-
#get1(hostname, type = Dnsruby::Types::A) ⇒ Object
Get an IP address of the specified type for the hostname.
-
#initialize(hostnames: nil) ⇒ StaticHostnames
constructor
A new instance of StaticHostnames.
-
#parse_hosts_file ⇒ Object
Locate and parse a hosts file on the system.
Constructor Details
#initialize(hostnames: nil) ⇒ StaticHostnames
Returns a new instance of StaticHostnames.
19 20 21 22 23 24 25 26 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 19 def initialize(hostnames: nil) @hostnames = {} if hostnames hostnames.each do |hostname, ip_address| add(hostname, ip_address) end end end |
Class Method Details
.is_valid_hostname?(name) ⇒ Boolean
139 140 141 142 143 144 145 146 147 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 139 def self.is_valid_hostname?(name) # check if it appears to be a fully qualified domain name, e.g. www.metasploit.com return true if Rex::Socket.is_name?(name) # check if it appears to at least be a valid hostname, e.g. localhost return true if (name =~ /^([a-z0-9][a-z0-9\-]{0,61})?[a-z0-9]$/i) && (name =~ /\s/).nil? false end |
Instance Method Details
#add(hostname, ip_address) ⇒ Object
Add an IP address for the specified hostname.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 80 def add(hostname, ip_address) unless self.class.is_valid_hostname?(hostname) # it is important to validate the hostname because assumptions about what characters it may contain are made # when saving and loading it from the configuration raise ::ArgumentError.new("Invalid hostname: #{hostname}") end ip_address = IPAddr.new(ip_address) if ip_address.is_a?(String) && Rex::Socket.is_ip_addr?(ip_address) hostname = hostname.downcase.delete_suffix('.') this_host = @hostnames.fetch(hostname, {}) if ip_address.family == ::Socket::AF_INET type = Dnsruby::Types::A else type = Dnsruby::Types::AAAA end this_type = this_host.fetch(type, []) this_type << ip_address unless this_type.include?(ip_address) this_host[type] = this_type @hostnames[hostname] = this_host nil end |
#delete(hostname, ip_address) ⇒ Object
Delete an IP address for the specified hostname.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 108 def delete(hostname, ip_address) ip_address = IPAddr.new(ip_address) if ip_address.is_a?(String) && Rex::Socket.is_ip_addr?(ip_address) if ip_address.family == ::Socket::AF_INET type = Dnsruby::Types::A else type = Dnsruby::Types::AAAA end hostname = hostname.downcase this_host = @hostnames.fetch(hostname, {}) this_type = this_host.fetch(type, []) this_type.delete(ip_address) if this_type.empty? this_host.delete(type) else this_host[type] = this_type end if this_host.empty? @hostnames.delete(hostname) else @hostnames[hostname] = this_host end nil end |
#flush ⇒ Object
Delete all hostname to IP address definitions.
135 136 137 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 135 def flush @hostnames.clear end |
#get(hostname, type = Dnsruby::Types::A) ⇒ Object
Get all IP addresses of the specified type for the hostname.
70 71 72 73 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 70 def get(hostname, type = Dnsruby::Types::A) hostname = hostname.downcase @hostnames.fetch(hostname, {}).fetch(type, []).dup end |
#get1(hostname, type = Dnsruby::Types::A) ⇒ Object
Get an IP address of the specified type for the hostname. Only the first address is returned in cases where multiple addresses are defined.
60 61 62 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 60 def get1(hostname, type = Dnsruby::Types::A) get(hostname, type).first end |
#parse_hosts_file ⇒ Object
Locate and parse a hosts file on the system. Only the first hostname to IP address definition is used which replicates the behavior of /etc/hosts on Linux. Loaded definitions are merged with existing definitions.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rex/proto/dns/static_hostnames.rb', line 30 def parse_hosts_file path = %w[ %WINDIR%\system32\drivers\etc\hosts /etc/hosts /data/data/com.termux/files/usr/etc/hosts ].find do |path| path = File.(path) File.file?(path) && File.readable?(path) end return unless path path = File.(path) ::IO.foreach(path) do |line| words = line.split next unless words.length > 1 && Rex::Socket.is_ip_addr?(words.first) ip_address = IPAddr.new(words.shift) words.each do |hostname| add(hostname, ip_address) end end end |