From da080c472fc415b0ce918f4dd4a1ab143bb1bca4 Mon Sep 17 00:00:00 2001 From: Philip Hands Date: Mon, 14 Mar 2016 15:36:16 +0100 Subject: rough attempt to grab the good cucumber bits from recent tails --- features/support/helpers/firewall_helper.rb | 87 ++++++++++++++++++----------- 1 file changed, 54 insertions(+), 33 deletions(-) (limited to 'features/support/helpers/firewall_helper.rb') 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 -- cgit v1.2.3-70-g09d2