1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
require 'date'
require 'timeout'
require 'test/unit'
# Make all the assert_* methods easily accessible in any context.
include Test::Unit::Assertions
def assert_vmcommand_success(p, msg = nil)
assert(p.success?, msg.nil? ? "Command failed: #{p.cmd}\n" + \
"error code: #{p.returncode}\n" \
"stderr: #{p.stderr}" : \
msg)
end
# Call block (ignoring any exceptions it may throw) repeatedly with one
# second breaks until it returns true, or until `t` seconds have
# passed when we throw Timeout::Error. As a precondition, the code
# block cannot throw Timeout::Error.
def try_for(t, options = {})
options[:delay] ||= 1
begin
Timeout::timeout(t) do
loop do
begin
return true if yield
rescue Timeout::Error => e
if options[:msg]
raise RuntimeError, options[:msg], caller
else
raise e
end
rescue Exception
# noop
end
sleep options[:delay]
end
end
rescue Timeout::Error => e
if options[:msg]
raise RuntimeError, options[:msg], caller
else
raise e
end
end
end
def wait_until_tor_is_working
try_for(240) { @vm.execute(
'. /usr/local/lib/tails-shell-library/tor.sh; tor_is_working').success? }
end
def convert_bytes_mod(unit)
case unit
when "bytes", "b" then mod = 1
when "KB" then mod = 10**3
when "k", "KiB" then mod = 2**10
when "MB" then mod = 10**6
when "M", "MiB" then mod = 2**20
when "GB" then mod = 10**9
when "G", "GiB" then mod = 2**30
when "TB" then mod = 10**12
when "T", "TiB" then mod = 2**40
else
raise "invalid memory unit '#{unit}'"
end
return mod
end
def convert_to_bytes(size, unit)
return (size*convert_bytes_mod(unit)).to_i
end
def convert_to_MiB(size, unit)
return (size*convert_bytes_mod(unit) / (2**20)).to_i
end
def convert_from_bytes(size, unit)
return size.to_f/convert_bytes_mod(unit).to_f
end
def cmd_helper(cmd)
IO.popen(cmd + " 2>&1") do |p|
out = p.readlines.join("\n")
p.close
ret = $?
assert_equal(0, ret, "Command failed (returned #{ret}): #{cmd}:\n#{out}")
return out
end
end
def tails_iso_creation_date(path)
label = cmd_helper("/sbin/blkid -p -s LABEL -o value #{path}")
assert(label[/^TAILS \d+(\.\d+)+(~rc\d+)? - \d+$/],
"Got invalid label '#{label}' from Tails image '#{path}'")
return label[/\d+$/]
end
def sort_isos_by_creation_date
Dir.glob("#{Dir.pwd}/*.iso").sort_by {|f| tails_iso_creation_date(f)}
end
def get_newest_iso
return sort_isos_by_creation_date.last
end
def get_oldest_iso
return sort_isos_by_creation_date.first
end
# This command will grab all router IP addresses from the Tor
# consensus in the VM.
def get_tor_relays
cmd = 'awk "/^r/ { print \$6 }" /var/lib/tor/cached-microdesc-consensus'
@vm.execute(cmd).stdout.chomp.split("\n")
end
def save_pcap_file
pcap_copy = "#{$tmp_dir}/pcap_with_leaks-#{DateTime.now}"
FileUtils.cp(@sniffer.pcap_file, pcap_copy)
puts "Full network capture available at: #{pcap_copy}"
end
|