4 # Extent IPAddr with a private/public address space checks
7 IPAddr.new("10.0.0.0/8"),
8 IPAddr.new("172.16.0.0/12"),
9 IPAddr.new("192.168.0.0/16"),
10 IPAddr.new("255.255.255.255/32")
14 IPAddr.new("fc00::/7"), # private
19 PrivateIPv4Ranges.each do |ipr|
20 return true if ipr.include?(self)
24 PrivateIPv6Ranges.each do |ipr|
25 return true if ipr.include?(self)
36 class FirewallLeakCheck
37 attr_reader :ipv4_tcp_leaks, :ipv4_nontcp_leaks, :ipv6_leaks, :nonip_leaks
39 def initialize(pcap_file, tor_relays)
40 packets = PacketFu::PcapFile.new.file_to_array(:filename => pcap_file)
41 @tor_relays = tor_relays
43 ipv4_nontcp_packets = []
47 if PacketFu::TCPPacket.can_parse?(p)
48 ipv4_tcp_packets << PacketFu::TCPPacket.parse(p)
49 elsif PacketFu::IPPacket.can_parse?(p)
50 ipv4_nontcp_packets << PacketFu::IPPacket.parse(p)
51 elsif PacketFu::IPv6Packet.can_parse?(p)
52 ipv6_packets << PacketFu::IPv6Packet.parse(p)
53 elsif PacketFu::Packet.can_parse?(p)
54 nonip_packets << PacketFu::Packet.parse(p)
57 raise "Found something in the pcap file that cannot be parsed"
60 ipv4_tcp_hosts = get_public_hosts_from_ippackets ipv4_tcp_packets
61 tor_nodes = Set.new(get_all_tor_contacts)
62 @ipv4_tcp_leaks = ipv4_tcp_hosts.select{|host| !tor_nodes.member?(host)}
63 @ipv4_nontcp_leaks = get_public_hosts_from_ippackets ipv4_nontcp_packets
64 @ipv6_leaks = get_public_hosts_from_ippackets ipv6_packets
65 @nonip_leaks = nonip_packets
68 # Returns a list of all unique non-LAN destination IP addresses
70 def get_public_hosts_from_ippackets(packets)
74 if p.kind_of?(PacketFu::IPPacket)
75 candidate = p.ip_daddr
76 elsif p.kind_of?(PacketFu::IPv6Packet)
77 candidate = p.ipv6_header.ipv6_daddr
80 raise "Expected an IP{v4,v6} packet, but got something else:\n" +
83 if candidate != nil and IPAddr.new(candidate).public?
90 # Returns an array of all Tor relays and authorities, i.e. all
91 # Internet hosts Tails ever should contact.
92 def get_all_tor_contacts
93 @tor_relays + $tor_authorities
97 @ipv4_tcp_leaks.empty? and @ipv4_nontcp_leaks.empty? and @ipv6_leaks.empty? and @nonip_leaks.empty?