summaryrefslogtreecommitdiffstats
path: root/features/support/helpers/firewall_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'features/support/helpers/firewall_helper.rb')
-rw-r--r--features/support/helpers/firewall_helper.rb87
1 files changed, 54 insertions, 33 deletions
diff --git a/features/support/helpers/firewall_helper.rb b/features/support/helpers/firewall_helper.rb
index 400965a5..fce363c5 100644
--- a/features/support/helpers/firewall_helper.rb
+++ b/features/support/helpers/firewall_helper.rb
@@ -11,21 +11,12 @@ class IPAddr
]
PrivateIPv6Ranges = [
- IPAddr.new("fc00::/7"), # private
+ IPAddr.new("fc00::/7")
]
def private?
- if self.ipv4?
- PrivateIPv4Ranges.each do |ipr|
- return true if ipr.include?(self)
- end
- return false
- else
- PrivateIPv6Ranges.each do |ipr|
- return true if ipr.include?(self)
- end
- return false
- end
+ private_ranges = self.ipv4? ? PrivateIPv4Ranges : PrivateIPv6Ranges
+ private_ranges.any? { |range| range.include?(self) }
end
def public?
@@ -34,16 +25,25 @@ class IPAddr
end
class FirewallLeakCheck
- attr_reader :ipv4_tcp_leaks, :ipv4_nontcp_leaks, :ipv6_leaks, :nonip_leaks
+ attr_reader :ipv4_tcp_leaks, :ipv4_nontcp_leaks, :ipv6_leaks, :nonip_leaks, :mac_leaks
- def initialize(pcap_file, tor_relays)
- packets = PacketFu::PcapFile.new.file_to_array(:filename => pcap_file)
- @tor_relays = tor_relays
+ def initialize(pcap_file, options = {})
+ options[:accepted_hosts] ||= []
+ options[:ignore_lan] ||= true
+ @pcap_file = pcap_file
+ packets = PacketFu::PcapFile.new.file_to_array(:filename => @pcap_file)
+ mac_leaks = Set.new
ipv4_tcp_packets = []
ipv4_nontcp_packets = []
ipv6_packets = []
nonip_packets = []
packets.each do |p|
+ if PacketFu::EthPacket.can_parse?(p)
+ packet = PacketFu::EthPacket.parse(p)
+ mac_leaks << packet.eth_saddr
+ mac_leaks << packet.eth_daddr
+ end
+
if PacketFu::TCPPacket.can_parse?(p)
ipv4_tcp_packets << PacketFu::TCPPacket.parse(p)
elsif PacketFu::IPPacket.can_parse?(p)
@@ -57,17 +57,25 @@ class FirewallLeakCheck
raise "Found something in the pcap file that cannot be parsed"
end
end
- ipv4_tcp_hosts = get_public_hosts_from_ippackets ipv4_tcp_packets
- tor_nodes = Set.new(get_all_tor_contacts)
- @ipv4_tcp_leaks = ipv4_tcp_hosts.select{|host| !tor_nodes.member?(host)}
- @ipv4_nontcp_leaks = get_public_hosts_from_ippackets ipv4_nontcp_packets
- @ipv6_leaks = get_public_hosts_from_ippackets ipv6_packets
+ ipv4_tcp_hosts = filter_hosts_from_ippackets(ipv4_tcp_packets,
+ options[:ignore_lan])
+ accepted = Set.new(options[:accepted_hosts])
+ @mac_leaks = mac_leaks
+ @ipv4_tcp_leaks = ipv4_tcp_hosts.select { |host| !accepted.member?(host) }
+ @ipv4_nontcp_leaks = filter_hosts_from_ippackets(ipv4_nontcp_packets,
+ options[:ignore_lan])
+ @ipv6_leaks = filter_hosts_from_ippackets(ipv6_packets,
+ options[:ignore_lan])
@nonip_leaks = nonip_packets
end
- # Returns a list of all unique non-LAN destination IP addresses
- # found in `packets`.
- def get_public_hosts_from_ippackets(packets)
+ def save_pcap_file
+ save_failure_artifact("Network capture", @pcap_file)
+ end
+
+ # Returns a list of all unique destination IP addresses found in
+ # `packets`. Exclude LAN hosts if ignore_lan is set.
+ def filter_hosts_from_ippackets(packets, ignore_lan)
hosts = []
packets.each do |p|
candidate = nil
@@ -80,21 +88,34 @@ class FirewallLeakCheck
raise "Expected an IP{v4,v6} packet, but got something else:\n" +
p.peek_format
end
- if candidate != nil and IPAddr.new(candidate).public?
+ if candidate != nil and (not(ignore_lan) or IPAddr.new(candidate).public?)
hosts << candidate
end
end
hosts.uniq
end
- # Returns an array of all Tor relays and authorities, i.e. all
- # Internet hosts Tails ever should contact.
- def get_all_tor_contacts
- @tor_relays + $tor_authorities
- end
-
- def empty?
- @ipv4_tcp_leaks.empty? and @ipv4_nontcp_leaks.empty? and @ipv6_leaks.empty? and @nonip_leaks.empty?
+ def assert_no_leaks
+ err = ""
+ if !@ipv4_tcp_leaks.empty?
+ err += "The following IPv4 TCP non-Tor Internet hosts were " +
+ "contacted:\n" + ipv4_tcp_leaks.join("\n")
+ end
+ if !@ipv4_nontcp_leaks.empty?
+ err += "The following IPv4 non-TCP Internet hosts were contacted:\n" +
+ ipv4_nontcp_leaks.join("\n")
+ end
+ if !@ipv6_leaks.empty?
+ err += "The following IPv6 Internet hosts were contacted:\n" +
+ ipv6_leaks.join("\n")
+ end
+ if !@nonip_leaks.empty?
+ err += "Some non-IP packets were sent\n"
+ end
+ if !err.empty?
+ save_pcap_file
+ raise err
+ end
end
end