summaryrefslogtreecommitdiffstats
path: root/features/step_definitions
diff options
context:
space:
mode:
Diffstat (limited to 'features/step_definitions')
-rw-r--r--features/step_definitions/apt.rb11
-rw-r--r--features/step_definitions/checks.rb29
-rw-r--r--features/step_definitions/common_steps.rb326
-rw-r--r--features/step_definitions/dhcp.rb20
-rw-r--r--features/step_definitions/encryption.rb4
-rw-r--r--features/step_definitions/erase_memory.rb6
-rw-r--r--features/step_definitions/evince.rb20
-rw-r--r--features/step_definitions/i2p.rb60
-rw-r--r--features/step_definitions/pidgin.rb188
-rw-r--r--features/step_definitions/root_access_control.rb18
-rw-r--r--features/step_definitions/torified_browsing.rb11
-rw-r--r--features/step_definitions/torified_gnupg.rb10
-rw-r--r--features/step_definitions/totem.rb50
-rw-r--r--features/step_definitions/unsafe_browser.rb44
-rw-r--r--features/step_definitions/usb.rb77
15 files changed, 742 insertions, 132 deletions
diff --git a/features/step_definitions/apt.rb b/features/step_definitions/apt.rb
index 1a5421e..a549205 100644
--- a/features/step_definitions/apt.rb
+++ b/features/step_definitions/apt.rb
@@ -3,7 +3,7 @@ require 'uri'
Given /^the only hosts in APT sources are "([^"]*)"$/ do |hosts_str|
next if @skip_steps_while_restoring_background
hosts = hosts_str.split(',')
- @vm.execute("cat /etc/apt/sources.list /etc/apt/sources.list.d/*").stdout.chomp.each_line { |line|
+ @vm.file_content("/etc/apt/sources.list /etc/apt/sources.list.d/*").chomp.each_line { |line|
next if ! line.start_with? "deb"
source_host = URI(line.split[1]).host
if !hosts.include?(source_host)
@@ -69,3 +69,12 @@ Then /^I should be able to install a package using Synaptic$/ do
@screen.wait('SynapticChangesAppliedPrompt.png', 120)
step "package \"#{package}\" is installed"
end
+
+When /^I start Synaptic$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsSystem.png", 10)
+ @screen.wait_and_click("GnomeApplicationsAdministration.png", 10)
+ @screen.wait_and_click("GnomeApplicationsSynaptic.png", 20)
+ deal_with_polkit_prompt('SynapticPolicyKitAuthPrompt.png', @sudo_password)
+end
diff --git a/features/step_definitions/checks.rb b/features/step_definitions/checks.rb
index b05486d..76cfe67 100644
--- a/features/step_definitions/checks.rb
+++ b/features/step_definitions/checks.rb
@@ -14,7 +14,7 @@ Then /^the shipped Tails signing key is not outdated$/ do
"--list-key #{sig_key_fingerprint}", $live_user).stdout
shipped_sig_key_info = @vm.execute("gpg --batch --list-key #{sig_key_fingerprint}",
$live_user).stdout
- assert(shipped_sig_key_info == fresh_sig_key_info,
+ assert_equal(fresh_sig_key_info, shipped_sig_key_info,
"The Tails signing key shipped inside Tails is outdated:\n" +
"Shipped key:\n" +
shipped_sig_key_info +
@@ -28,8 +28,7 @@ Then /^the live user has been setup by live\-boot$/ do
"live-boot failed its user-setup")
actual_username = @vm.execute(". /etc/live/config/username.conf; " +
"echo $LIVE_USERNAME").stdout.chomp
- assert(actual_username == $live_user,
- "The live username is '#{actual_username}', not '#{$live_user}'")
+ assert_equal($live_user, actual_username)
end
Then /^the live user is a member of only its own group and "(.*?)"$/ do |groups|
@@ -38,9 +37,9 @@ Then /^the live user is a member of only its own group and "(.*?)"$/ do |groups|
actual_groups = @vm.execute("groups #{$live_user}").stdout.chomp.sub(/^#{$live_user} : /, "").split(" ")
unexpected = actual_groups - expected_groups
missing = expected_groups - actual_groups
- assert(unexpected.size == 0,
+ assert_equal(0, unexpected.size,
"live user in unexpected groups #{unexpected}")
- assert(missing.size == 0,
+ assert_equal(0, missing.size,
"live user not in expected groups #{missing}")
end
@@ -51,10 +50,8 @@ Then /^the live user owns its home dir and it has normal permissions$/ do
"The live user's home doesn't exist or is not a directory")
owner = @vm.execute("stat -c %U:%G #{home}").stdout.chomp
perms = @vm.execute("stat -c %a #{home}").stdout.chomp
- assert(owner == "#{$live_user}:#{$live_user}",
- "The live user's home has unexpected ownership '#{owner}'")
- assert(perms == "700",
- "The live user's home has unexpected permissions '#{perms}'")
+ assert_equal("#{$live_user}:#{$live_user}", owner)
+ assert_equal("700", perms)
end
Given /^I wait between (\d+) and (\d+) seconds$/ do |min, max|
@@ -106,7 +103,7 @@ Then /^the VirtualBox guest modules are available$/ do
end
def shared_pdf_dir_on_guest
- "/tmp/shared_dir"
+ "/tmp/shared_pdf_dir"
end
Given /^I setup a filesystem share containing a sample PDF$/ do
@@ -119,8 +116,7 @@ Then /^MAT can clean some sample PDF file$/ do
for pdf_on_host in Dir.glob("#{$misc_files_dir}/*.pdf") do
pdf_name = File.basename(pdf_on_host)
pdf_on_guest = "/home/#{$live_user}/#{pdf_name}"
- @vm.execute("cp #{shared_pdf_dir_on_guest}/#{pdf_name} #{pdf_on_guest}",
- $live_user)
+ step "I copy \"#{shared_pdf_dir_on_guest}/#{pdf_name}\" to \"#{pdf_on_guest}\" as user \"#{$live_user}\""
@vm.execute("mat --display '#{pdf_on_guest}'",
$live_user).stdout
check_before = @vm.execute("mat --check '#{pdf_on_guest}'",
@@ -136,3 +132,12 @@ Then /^MAT can clean some sample PDF file$/ do
"MAT failed to clean '#{pdf_on_host}'")
end
end
+
+Then /^AppArmor is enabled$/ do
+ assert(@vm.execute("aa-status").success?, "AppArmor is not enabled")
+end
+
+Then /^some AppArmor profiles are enforced$/ do
+ assert(@vm.execute("aa-status --enforced").stdout.chomp.to_i > 0,
+ "No AppArmor profile is enforced")
+end
diff --git a/features/step_definitions/common_steps.rb b/features/step_definitions/common_steps.rb
index 8843bbd..66ccd6d 100644
--- a/features/step_definitions/common_steps.rb
+++ b/features/step_definitions/common_steps.rb
@@ -51,6 +51,7 @@ def restore_background
if @vm.has_network?
if @vm.execute("service tor status").success?
@vm.execute("service tor stop")
+ @vm.execute("rm -f /var/log/tor/log")
@vm.execute("killall vidalia")
@vm.host_to_guest_time_sync
@vm.execute("service tor start")
@@ -60,15 +61,6 @@ def restore_background
end
end
-def run_dialog_picture
- case @theme
- when "windows"
- return 'WindowsRunDialog.png'
- else
- return 'GnomeRunDialog.png'
- end
-end
-
Given /^a computer$/ do
@vm.destroy if @vm
@vm = VM.new($vm_xml_path, $x_display)
@@ -140,6 +132,58 @@ When /^I start the computer$/ do
post_vm_start_hook
end
+Given /^I start Tails from DVD(| with network unplugged) and I login$/ do |network_unplugged|
+ # we don't @skip_steps_while_restoring_background as we're only running
+ # other steps, that are taking care of it *if* they have to
+ step "the computer is set to boot from the Tails DVD"
+ if network_unplugged.empty?
+ step "the network is plugged"
+ else
+ step "the network is unplugged"
+ end
+ step "I start the computer"
+ step "the computer boots Tails"
+ step "I log in to a new session"
+ step "Tails seems to have booted normally"
+ if network_unplugged.empty?
+ step "Tor is ready"
+ step "all notifications have disappeared"
+ step "available upgrades have been checked"
+ else
+ step "all notifications have disappeared"
+ end
+end
+
+Given /^I start Tails from (.+?) drive "(.+?)"(| with network unplugged) and I login(| with(| read-only) persistence password "([^"]+)")$/ do |drive_type, drive_name, network_unplugged, persistence_on, persistence_ro, persistence_pwd|
+ # we don't @skip_steps_while_restoring_background as we're only running
+ # other steps, that are taking care of it *if* they have to
+ step "the computer is set to boot from #{drive_type} drive \"#{drive_name}\""
+ if network_unplugged.empty?
+ step "the network is plugged"
+ else
+ step "the network is unplugged"
+ end
+ step "I start the computer"
+ step "the computer boots Tails"
+ if ! persistence_on.empty?
+ assert(! persistence_pwd.empty?, "A password must be provided when enabling persistence")
+ if persistence_ro.empty?
+ step "I enable persistence with password \"#{persistence_pwd}\""
+ else
+ step "I enable read-only persistence with password \"#{persistence_pwd}\""
+ end
+ end
+ step "I log in to a new session"
+ step "Tails seems to have booted normally"
+ if network_unplugged.empty?
+ step "Tor is ready"
+ step "all notifications have disappeared"
+ step "available upgrades have been checked"
+ else
+ step "all notifications have disappeared"
+ end
+end
+
When /^I power off the computer$/ do
next if @skip_steps_while_restoring_background
assert(@vm.is_running?,
@@ -158,12 +202,32 @@ When /^I destroy the computer$/ do
@vm.destroy
end
-Given /^the computer boots Tails$/ do
+Given /^the computer (re)?boots Tails$/ do |reboot|
next if @skip_steps_while_restoring_background
- @screen.wait('TailsBootSplash.png', 30)
- @screen.wait('TailsBootSplashTabMsg.png', 10)
+
+ case @os_loader
+ when "UEFI"
+ assert(!reboot, "Testing of reboot with UEFI enabled is not implemented")
+ bootsplash = 'TailsBootSplashUEFI.png'
+ bootsplash_tab_msg = 'TailsBootSplashTabMsgUEFI.png'
+ boot_timeout = 30
+ else
+ if reboot
+ bootsplash = 'TailsBootSplashPostReset.png'
+ bootsplash_tab_msg = 'TailsBootSplashTabMsgPostReset.png'
+ boot_timeout = 120
+ else
+ bootsplash = 'TailsBootSplash.png'
+ bootsplash_tab_msg = 'TailsBootSplashTabMsg.png'
+ boot_timeout = 30
+ end
+ end
+
+ @screen.wait(bootsplash, boot_timeout)
+ @screen.wait(bootsplash_tab_msg, 10)
@screen.type(Sikuli::Key.TAB)
- @screen.waitVanish('TailsBootSplashTabMsg.png', 1)
+ @screen.waitVanish(bootsplash_tab_msg, 1)
+
@screen.type(" autotest_never_use_this_option #{@boot_options}" +
Sikuli::Key.ENTER)
@screen.wait('TailsGreeter.png', 30*60)
@@ -249,21 +313,43 @@ Given /^available upgrades have been checked$/ do
}
end
-Given /^Iceweasel has started and is not loading a web page$/ do
+Given /^the Tor Browser has started$/ do
next if @skip_steps_while_restoring_background
case @theme
when "windows"
- iceweasel_picture = "WindowsIceweaselWindow.png"
+ tor_browser_picture = "WindowsTorBrowserWindow.png"
else
- iceweasel_picture = "IceweaselWindow.png"
+ tor_browser_picture = "TorBrowserWindow.png"
end
- # Stop iceweasel to load its home page. We do this to prevent Tor
- # from getting confused in case we save and restore a snapshot in
- # the middle of loading a page.
- @screen.wait_and_click(iceweasel_picture, 120)
- @screen.type("l", Sikuli::KeyModifier.CTRL)
- @screen.type("about:blank" + Sikuli::Key.ENTER)
+ @screen.wait(tor_browser_picture, 60)
+end
+
+Given /^the Tor Browser has started and loaded the startup page$/ do
+ next if @skip_steps_while_restoring_background
+ step "the Tor Browser has started"
+ @screen.wait("TorBrowserStartupPage.png", 120)
+end
+
+Given /^the Tor Browser has started in offline mode$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait("TorBrowserOffline.png", 60)
+end
+
+Given /^I add a bookmark to eff.org in the Tor Browser$/ do
+ next if @skip_steps_while_restoring_background
+ url = "https://www.eff.org"
+ step "I open the address \"#{url}\" in the Tor Browser"
+ @screen.wait("TorBrowserOffline.png", 5)
+ @screen.type("d", Sikuli::KeyModifier.CTRL)
+ @screen.wait("TorBrowserBookmarkPrompt.png", 10)
+ @screen.type(url + Sikuli::Key.ENTER)
+end
+
+Given /^the Tor Browser has a bookmark to eff.org$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.type("b", Sikuli::KeyModifier.ALT)
+ @screen.wait("TorBrowserEFFBookmark.png", 10)
end
Given /^all notifications have disappeared$/ do
@@ -336,20 +422,6 @@ Then /^all Internet traffic has only flowed through Tor$/ do
end
end
-When /^I open the GNOME run dialog$/ do
- next if @skip_steps_while_restoring_background
- @screen.type(Sikuli::Key.F2, Sikuli::KeyModifier.ALT)
- @screen.wait(run_dialog_picture, 10)
-end
-
-When /^I run "([^"]*)"$/ do |program|
- next if @skip_steps_while_restoring_background
- step "I open the GNOME run dialog"
- @screen.type(program)
- sleep 0.5
- @screen.type(Sikuli::Key.ENTER)
-end
-
Given /^I enter the sudo password in the gksu prompt$/ do
next if @skip_steps_while_restoring_background
@screen.wait('GksuAuthPrompt.png', 60)
@@ -359,18 +431,22 @@ Given /^I enter the sudo password in the gksu prompt$/ do
@screen.waitVanish('GksuAuthPrompt.png', 10)
end
-Given /^I enter the sudo password in the PolicyKit prompt$/ do
+Given /^I enter the sudo password in the pkexec prompt$/ do
next if @skip_steps_while_restoring_background
- step "I enter the \"#{@sudo_password}\" password in the PolicyKit prompt"
+ step "I enter the \"#{@sudo_password}\" password in the pkexec prompt"
end
-Given /^I enter the "([^"]*)" password in the PolicyKit prompt$/ do |password|
- next if @skip_steps_while_restoring_background
- @screen.wait('PolicyKitAuthPrompt.png', 60)
+def deal_with_polkit_prompt (image, password)
+ @screen.wait(image, 60)
sleep 1 # wait for weird fade-in to unblock the "Ok" button
@screen.type(password)
@screen.type(Sikuli::Key.ENTER)
- @screen.waitVanish('PolicyKitAuthPrompt.png', 10)
+ @screen.waitVanish(image, 10)
+end
+
+Given /^I enter the "([^"]*)" password in the pkexec prompt$/ do |password|
+ next if @skip_steps_while_restoring_background
+ deal_with_polkit_prompt('PolicyKitAuthPrompt.png', password)
end
Given /^process "([^"]+)" is running$/ do |process|
@@ -430,6 +506,11 @@ When /^I request a shutdown using the emergency shutdown applet$/ do
@screen.wait_and_click('TailsEmergencyShutdownHalt.png', 10)
end
+When /^I warm reboot the computer$/ do
+ next if @skip_steps_while_restoring_background
+ @vm.execute("reboot")
+end
+
When /^I request a reboot using the emergency shutdown applet$/ do
next if @skip_steps_while_restoring_background
@screen.hide_cursor
@@ -443,3 +524,164 @@ Given /^package "([^"]+)" is installed$/ do |package|
assert(@vm.execute("dpkg -s '#{package}' 2>/dev/null | grep -qs '^Status:.*installed$'").success?,
"Package '#{package}' is not installed")
end
+
+When /^I start the Tor Browser$/ do
+ next if @skip_steps_while_restoring_background
+ case @theme
+ when "windows"
+ step 'I click the start menu'
+ @screen.wait_and_click("WindowsApplicationsInternet.png", 10)
+ @screen.wait_and_click("WindowsApplicationsTorBrowser.png", 10)
+ else
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsInternet.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTorBrowser.png", 10)
+ end
+end
+
+When /^I start the Tor Browser in offline mode$/ do
+ next if @skip_steps_while_restoring_background
+ step "I start the Tor Browser"
+ case @theme
+ when "windows"
+ @screen.wait_and_click("WindowsTorBrowserOfflinePrompt.png", 10)
+ @screen.click("WindowsTorBrowserOfflinePromptStart.png")
+ else
+ @screen.wait_and_click("TorBrowserOfflinePrompt.png", 10)
+ @screen.click("TorBrowserOfflinePromptStart.png")
+ end
+end
+
+def xul_app_shared_lib_check(pid, chroot)
+ expected_absent_tbb_libs = ['libnssdbm3.so']
+ absent_tbb_libs = []
+ unwanted_native_libs = []
+ tbb_libs = @vm.execute_successfully(
+ ". /usr/local/lib/tails-shell-library/tor-browser.sh; " +
+ "ls -1 #{chroot}${TBB_INSTALL}/*.so"
+ ).stdout.split
+ firefox_pmap_info = @vm.execute("pmap #{pid}").stdout
+ for lib in tbb_libs do
+ lib_name = File.basename lib
+ if not /\W#{lib}$/.match firefox_pmap_info
+ absent_tbb_libs << lib_name
+ end
+ native_libs = @vm.execute_successfully(
+ "find /usr/lib /lib -name \"#{lib_name}\""
+ ).stdout.split
+ for native_lib in native_libs do
+ if /\W#{native_lib}$"/.match firefox_pmap_info
+ unwanted_native_libs << lib_name
+ end
+ end
+ end
+ absent_tbb_libs -= expected_absent_tbb_libs
+ assert(absent_tbb_libs.empty? && unwanted_native_libs.empty?,
+ "The loaded shared libraries for the firefox process are not the " +
+ "way we expect them.\n" +
+ "Expected TBB libs that are absent: #{absent_tbb_libs}\n" +
+ "Native libs that we don't want: #{unwanted_native_libs}")
+end
+
+Then /^(.*) uses all expected TBB shared libraries$/ do |application|
+ next if @skip_steps_while_restoring_background
+ binary = @vm.execute_successfully(
+ '. /usr/local/lib/tails-shell-library/tor-browser.sh; ' +
+ 'echo ${TBB_INSTALL}/firefox'
+ ).stdout.chomp
+ case application
+ when "the Tor Browser"
+ user = $live_user
+ cmd_regex = "#{binary} .* -profile /home/#{user}/\.tor-browser/profile\.default"
+ chroot = ""
+ when "the Unsafe Browser"
+ user = "clearnet"
+ cmd_regex = "#{binary} .* -profile /home/#{user}/\.tor-browser/profile\.default"
+ chroot = "/var/lib/unsafe-browser/chroot"
+ when "Tor Launcher"
+ user = "tor-launcher"
+ cmd_regex = "#{binary} -app /home/#{user}/\.tor-launcher/tor-launcher-standalone/application\.ini"
+ chroot = ""
+ else
+ raise "Invalid browser or XUL application: #{application}"
+ end
+ pid = @vm.execute_successfully("pgrep --uid #{user} --full --exact '#{cmd_regex}'").stdout.chomp
+ assert(/\A\d+\z/.match(pid), "It seems like #{application} is not running")
+ xul_app_shared_lib_check(pid, chroot)
+end
+
+Given /^I add a wired DHCP NetworkManager connection called "([^"]+)"$/ do |con_name|
+ next if @skip_steps_while_restoring_background
+ con_content = <<EOF
+[802-3-ethernet]
+duplex=full
+
+[connection]
+id=#{con_name}
+uuid=bbc60668-1be0-11e4-a9c6-2f1ce0e75bf1
+type=802-3-ethernet
+timestamp=1395406011
+
+[ipv6]
+method=auto
+
+[ipv4]
+method=auto
+EOF
+ con_content.split("\n").each do |line|
+ @vm.execute("echo '#{line}' >> /tmp/NM.#{con_name}")
+ end
+ @vm.execute("install -m 0600 '/tmp/NM.#{con_name}' '/etc/NetworkManager/system-connections/#{con_name}'")
+ try_for(10) {
+ nm_con_list = @vm.execute("nmcli --terse --fields NAME con list").stdout
+ nm_con_list.split("\n").include? "#{con_name}"
+ }
+end
+
+Given /^I switch to the "([^"]+)" NetworkManager connection$/ do |con_name|
+ next if @skip_steps_while_restoring_background
+ @vm.execute("nmcli con up id #{con_name}")
+ try_for(60) {
+ @vm.execute("nmcli --terse --fields NAME,STATE con status").stdout.chomp == "#{con_name}:activated"
+ }
+end
+
+When /^I start and focus GNOME Terminal$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsAccessories.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTerminal.png", 20)
+ @screen.wait_and_click('GnomeTerminalWindow.png', 20)
+end
+
+When /^I run "([^"]+)" in GNOME Terminal$/ do |command|
+ next if @skip_steps_while_restoring_background
+ step "I start and focus GNOME Terminal"
+ @screen.type(command + Sikuli::Key.ENTER)
+end
+
+When /^the file "([^"]+)" exists$/ do |file|
+ next if @skip_steps_while_restoring_background
+ assert(@vm.file_exist?(file))
+end
+
+When /^I copy "([^"]+)" to "([^"]+)" as user "([^"]+)"$/ do |source, destination, user|
+ next if @skip_steps_while_restoring_background
+ c = @vm.execute("cp \"#{source}\" \"#{destination}\"", $live_user)
+ assert(c.success?, "Failed to copy file:\n#{c.stdout}\n#{c.stderr}")
+end
+
+Given /^the USB drive "([^"]+)" contains Tails with persistence configured and password "([^"]+)"$/ do |drive, password|
+ step "a computer"
+ step "I start Tails from DVD with network unplugged and I login"
+ step "I create a new 4 GiB USB drive named \"#{drive}\""
+ step "I plug USB drive \"#{drive}\""
+ step "I \"Clone & Install\" Tails to USB drive \"#{drive}\""
+ step "there is no persistence partition on USB drive \"#{drive}\""
+ step "I shutdown Tails and wait for the computer to power off"
+ step "a computer"
+ step "I start Tails from USB drive \"#{drive}\" with network unplugged and I login"
+ step "I create a persistent partition with password \"#{password}\""
+ step "a Tails persistence partition with password \"#{password}\" exists on USB drive \"#{drive}\""
+ step "I shutdown Tails and wait for the computer to power off"
+end
diff --git a/features/step_definitions/dhcp.rb b/features/step_definitions/dhcp.rb
new file mode 100644
index 0000000..78ee8f2
--- /dev/null
+++ b/features/step_definitions/dhcp.rb
@@ -0,0 +1,20 @@
+Then /^the hostname should not have been leaked on the network$/ do
+ next if @skip_steps_while_restoring_background
+ hostname = @vm.execute("hostname").stdout.chomp
+ packets = PacketFu::PcapFile.new.file_to_array(:filename => @sniffer.pcap_file)
+ packets.each do |p|
+ # if PacketFu::TCPPacket.can_parse?(p)
+ # ipv4_tcp_packets << PacketFu::TCPPacket.parse(p)
+ if PacketFu::IPPacket.can_parse?(p)
+ payload = PacketFu::IPPacket.parse(p).payload
+ elsif PacketFu::IPv6Packet.can_parse?(p)
+ payload = PacketFu::IPv6Packet.parse(p).payload
+ else
+ save_pcap_file
+ raise "Found something in the pcap file that either is non-IP, or cannot be parsed"
+ end
+ if payload.match(hostname)
+ raise "Hostname leak detected"
+ end
+ end
+end
diff --git a/features/step_definitions/encryption.rb b/features/step_definitions/encryption.rb
index d1310d9..404890a 100644
--- a/features/step_definitions/encryption.rb
+++ b/features/step_definitions/encryption.rb
@@ -23,7 +23,9 @@ end
When /^I type a message into gedit$/ do
next if @skip_steps_while_restoring_background
- step 'I run "gedit"'
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsAccessories.png", 10)
+ @screen.wait_and_click("GnomeApplicationsGedit.png", 20)
@screen.wait_and_click("GeditWindow.png", 10)
sleep 0.5
@screen.type("ATTACK AT DAWN")
diff --git a/features/step_definitions/erase_memory.rb b/features/step_definitions/erase_memory.rb
index 41666fb..171f997 100644
--- a/features/step_definitions/erase_memory.rb
+++ b/features/step_definitions/erase_memory.rb
@@ -24,15 +24,13 @@ end
Given /^the PAE kernel is running$/ do
next if @skip_steps_while_restoring_background
kernel = which_kernel
- assert(kernel == "vmlinuz2",
- "Kernel #{kernel} is running, expected 'vmlinuz2' (PAE)")
+ assert_equal("vmlinuz2", kernel)
end
Given /^the non-PAE kernel is running$/ do
next if @skip_steps_while_restoring_background
kernel = which_kernel
- assert(kernel == "vmlinuz",
- "Kernel #{kernel} is running, expected 'vmlinuz' (non-PAE)")
+ assert_equal("vmlinuz", kernel)
end
def used_ram_in_MiB
diff --git a/features/step_definitions/evince.rb b/features/step_definitions/evince.rb
new file mode 100644
index 0000000..d9bb42c
--- /dev/null
+++ b/features/step_definitions/evince.rb
@@ -0,0 +1,20 @@
+When /^I(?:| try to) open "([^"]+)" with Evince$/ do |filename|
+ next if @skip_steps_while_restoring_background
+ step "I run \"evince #{filename}\" in GNOME Terminal"
+end
+
+Then /^I can print the current document to "([^"]+)"$/ do |output_file|
+ next if @skip_steps_while_restoring_background
+ @screen.type("p", Sikuli::KeyModifier.CTRL)
+ @screen.wait("EvincePrintDialog.png", 10)
+ @screen.wait_and_click("EvincePrintToFile.png", 10)
+ @screen.wait_and_double_click("EvincePrintOutputFile.png", 10)
+ @screen.hide_cursor
+ @screen.wait("EvincePrintOutputFileSelected.png", 10)
+ # Only the file's basename is selected by double-clicking,
+ # so we type only the desired file's basename to replace it
+ @screen.type(output_file.sub(/[.]pdf$/, '') + Sikuli::Key.ENTER)
+ try_for(10, :msg => "The document was not printed to #{output_file}") {
+ @vm.file_exist?(output_file)
+ }
+end
diff --git a/features/step_definitions/i2p.rb b/features/step_definitions/i2p.rb
new file mode 100644
index 0000000..0b8a8d3
--- /dev/null
+++ b/features/step_definitions/i2p.rb
@@ -0,0 +1,60 @@
+Given /^I2P is running$/ do
+ next if @skip_steps_while_restoring_background
+ try_for(30) do
+ @vm.execute('service i2p status').success?
+ end
+end
+
+Given /^the I2P router console is ready$/ do
+ next if @skip_steps_while_restoring_background
+ try_for(60) do
+ @vm.execute('. /usr/local/lib/tails-shell-library/i2p.sh; ' +
+ 'i2p_router_console_is_ready').success?
+ end
+end
+
+When /^I start the I2P Browser through the GNOME menu$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsInternet.png", 10)
+ @screen.wait_and_click("GnomeApplicationsI2PBrowser.png", 20)
+end
+
+Then /^the I2P Browser desktop file is (|not )present$/ do |mode|
+ next if @skip_steps_while_restoring_background
+ file = '/usr/share/applications/i2p-browser.desktop'
+ if mode == ''
+ assert(@vm.execute("test -e #{file}").success?)
+ elsif mode == 'not '
+ assert(@vm.execute("! test -e #{file}").success?)
+ else
+ raise "Unsupported mode passed: '#{mode}'"
+ end
+end
+
+Then /^the I2P Browser sudo rules are (enabled|not present)$/ do |mode|
+ next if @skip_steps_while_restoring_background
+ file = '/etc/sudoers.d/zzz_i2pbrowser'
+ if mode == 'enabled'
+ assert(@vm.execute("test -e #{file}").success?)
+ elsif mode == 'not present'
+ assert(@vm.execute("! test -e #{file}").success?)
+ else
+ raise "Unsupported mode passed: '#{mode}'"
+ end
+end
+
+Then /^the I2P firewall rules are (enabled|disabled)$/ do |mode|
+ next if @skip_steps_while_restoring_background
+ i2p_username = 'i2psvc'
+ i2p_uid = @vm.execute("getent passwd #{i2p_username} | awk -F ':' '{print $3}'").stdout.chomp
+ accept_rules = @vm.execute("iptables -L -n -v | grep -E '^\s+[0-9]+\s+[0-9]+\s+ACCEPT.*owner UID match #{i2p_uid}$'").stdout
+ accept_rules_count = accept_rules.lines.count
+ if mode == 'enabled'
+ assert_equal(13, accept_rules_count)
+ elsif mode == 'disabled'
+ assert_equal(0, accept_rules_count)
+ else
+ raise "Unsupported mode passed: '#{mode}'"
+ end
+end
diff --git a/features/step_definitions/pidgin.rb b/features/step_definitions/pidgin.rb
new file mode 100644
index 0000000..23b48e2
--- /dev/null
+++ b/features/step_definitions/pidgin.rb
@@ -0,0 +1,188 @@
+def configured_pidgin_accounts
+ accounts = []
+ xml = REXML::Document.new(@vm.file_content('$HOME/.purple/accounts.xml',
+ $live_user))
+ xml.elements.each("account/account") do |e|
+ account = e.elements["name"].text
+ account_name, network = account.split("@")
+ protocol = e.elements["protocol"].text
+ port = e.elements["settings/setting[@name='port']"].text
+ nickname = e.elements["settings/setting[@name='username']"].text
+ real_name = e.elements["settings/setting[@name='realname']"].text
+ accounts.push({
+ 'name' => account_name,
+ 'network' => network,
+ 'protocol' => protocol,
+ 'port' => port,
+ 'nickname' => nickname,
+ 'real_name' => real_name,
+ })
+ end
+
+ return accounts
+end
+
+def chan_image (account, channel, image)
+ images = {
+ 'irc.oftc.net' => {
+ '#tails' => {
+ 'roaster' => 'PidginTailsChannelEntry',
+ 'conversation_tab' => 'PidginTailsConversationTab',
+ 'welcome' => 'PidginTailsChannelWelcome',
+ }
+ }
+ }
+ return images[account][channel][image] + ".png"
+end
+
+def default_chan (account)
+ chans = {
+ 'irc.oftc.net' => '#tails',
+ }
+ return chans[account]
+end
+
+def pidgin_otr_keys
+ return @vm.file_content('$HOME/.purple/otr.private_key', $live_user)
+end
+
+Given /^Pidgin has the expected accounts configured with random nicknames$/ do
+ next if @skip_steps_while_restoring_background
+ expected = [
+ ["irc.oftc.net", "prpl-irc", "6697"],
+ ["127.0.0.1", "prpl-irc", "6668"],
+ ]
+ configured_pidgin_accounts.each() do |account|
+ assert(account['nickname'] != "XXX_NICK_XXX", "Nickname was no randomised")
+ assert_equal(account['nickname'], account['real_name'],
+ "Nickname and real name are not identical: " +
+ account['nickname'] + " vs. " + account['real_name'])
+ assert_equal(account['name'], account['nickname'],
+ "Account name and nickname are not identical: " +
+ account['name'] + " vs. " + account['nickname'])
+ candidate = [account['network'], account['protocol'], account['port']]
+ assert(expected.include?(candidate), "Unexpected account: #{candidate}")
+ expected.delete(candidate)
+ end
+ assert(expected.empty?, "These Pidgin accounts are not configured: " +
+ "#{expected}")
+end
+
+When /^I start Pidgin through the GNOME menu$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsInternet.png", 10)
+ @screen.wait_and_click("GnomeApplicationsPidgin.png", 20)
+end
+
+When /^I open Pidgin's account manager window$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.type("a", Sikuli::KeyModifier.CTRL) # shortcut for "manage accounts"
+ step "I see Pidgin's account manager window"
+end
+
+When /^I see Pidgin's account manager window$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait("PidginAccountWindow.png", 20)
+end
+
+When /^I close Pidgin's account manager window$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("PidginAccountManagerCloseButton.png", 10)
+end
+
+When /^I activate the "([^"]+)" Pidgin account$/ do |account|
+ next if @skip_steps_while_restoring_background
+ @screen.click("PidginAccount_#{account}.png")
+ @screen.type(Sikuli::Key.LEFT + Sikuli::Key.SPACE)
+ # wait for the Pidgin to be connecting, otherwise sometimes the step
+ # that closes the account management dialog happens before the account
+ # is actually enabled
+ @screen.wait("PidginConnecting.png", 5)
+end
+
+Then /^Pidgin successfully connects to the "([^"]+)" account$/ do |account|
+ next if @skip_steps_while_restoring_background
+ expected_channel_entry = chan_image(account, default_chan(account), 'roaster')
+ @screen.wait(expected_channel_entry, 60)
+end
+
+Then /^I can join the "([^"]+)" channel on "([^"]+)"$/ do |channel, account|
+ next if @skip_steps_while_restoring_background
+ @screen.doubleClick( chan_image(account, channel, 'roaster'))
+ @screen.wait_and_click(chan_image(account, channel, 'conversation_tab'), 10)
+ @screen.wait( chan_image(account, channel, 'welcome'), 10)
+end
+
+Then /^I take note of the configured Pidgin accounts$/ do
+ next if @skip_steps_while_restoring_background
+ @persistent_pidgin_accounts = configured_pidgin_accounts
+end
+
+Then /^I take note of the OTR key for Pidgin's "([^"]+)" account$/ do |account_name|
+ next if @skip_steps_while_restoring_background
+ @persistent_pidgin_otr_keys = pidgin_otr_keys
+end
+
+Then /^Pidgin has the expected persistent accounts configured$/ do
+ next if @skip_steps_while_restoring_background
+ current_accounts = configured_pidgin_accounts
+ assert(current_accounts <=> @persistent_pidgin_accounts,
+ "Currently configured Pidgin accounts do not match the persistent ones:\n" +
+ "Current:\n#{current_accounts}\n" +
+ "Persistent:\n#{@persistent_pidgin_accounts}"
+ )
+end
+
+Then /^Pidgin has the expected persistent OTR keys$/ do
+ next if @skip_steps_while_restoring_background
+ assert_equal(pidgin_otr_keys, @persistent_pidgin_otr_keys)
+end
+
+def pidgin_add_certificate_from (cert_file)
+ # Here, we need a certificate that is not already in the NSS database
+ step "I copy \"/usr/share/ca-certificates/spi-inc.org/spi-cacert-2008.crt\" to \"#{cert_file}\" as user \"amnesia\""
+
+ @screen.wait_and_click('PidginToolsMenu.png', 10)
+ @screen.wait_and_click('PidginCertificatesMenuItem.png', 10)
+ @screen.wait('PidginCertificateManagerDialog.png', 10)
+ @screen.wait_and_click('PidginCertificateAddButton.png', 10)
+ begin
+ @screen.wait_and_click('GtkFileChooserDesktopButton.png', 10)
+ rescue FindFailed
+ # The first time we're run, the file chooser opens in the Recent
+ # view, so we have to browse a directory before we can use the
+ # "Type file name" button. But on subsequent runs, the file
+ # chooser is already in the Desktop directory, so we don't need to
+ # do anything. Hence, this noop exception handler.
+ end
+ @screen.wait_and_click('GtkFileTypeFileNameButton.png', 10)
+ @screen.type("l", Sikuli::KeyModifier.ALT) # "Location" field
+ @screen.type(cert_file + Sikuli::Key.ENTER)
+end
+
+Then /^I can add a certificate from the "([^"]+)" directory to Pidgin$/ do |cert_dir|
+ next if @skip_steps_while_restoring_background
+ pidgin_add_certificate_from("#{cert_dir}/test.crt")
+ @screen.wait('PidginCertificateAddHostnameDialog.png', 10)
+ @screen.type("XXX test XXX" + Sikuli::Key.ENTER)
+ @screen.wait('PidginCertificateTestItem.png', 10)
+end
+
+Then /^I cannot add a certificate from the "([^"]+)" directory to Pidgin$/ do |cert_dir|
+ next if @skip_steps_while_restoring_background
+ pidgin_add_certificate_from("#{cert_dir}/test.crt")
+ @screen.wait('PidginCertificateImportFailed.png', 10)
+end
+
+When /^I close Pidgin's certificate manager$/ do
+ @screen.type(Sikuli::Key.ESC)
+ # @screen.wait_and_click('PidginCertificateManagerClose.png', 10)
+ @screen.waitVanish('PidginCertificateManagerDialog.png', 10)
+end
+
+When /^I close Pidgin's certificate import failure dialog$/ do
+ @screen.type(Sikuli::Key.ESC)
+ # @screen.wait_and_click('PidginCertificateManagerClose.png', 10)
+ @screen.waitVanish('PidginCertificateImportFailed.png', 10)
+end
diff --git a/features/step_definitions/root_access_control.rb b/features/step_definitions/root_access_control.rb
index 0a4788c..aaebb0d 100644
--- a/features/step_definitions/root_access_control.rb
+++ b/features/step_definitions/root_access_control.rb
@@ -1,8 +1,8 @@
Then /^I should be able to run administration commands as the live user$/ do
next if @skip_steps_while_restoring_background
stdout = @vm.execute("echo #{@sudo_password} | sudo -S whoami", $live_user).stdout
- assert(stdout.sub(/^\[sudo\] password for #{$live_user}: /, "") == "root\n",
- "Could not use sudo")
+ actual_user = stdout.sub(/^\[sudo\] password for #{$live_user}: /, "").chomp
+ assert_equal("root", actual_user, "Could not use sudo")
end
Then /^I should not be able to run administration commands as the live user with the "([^"]*)" password$/ do |password|
@@ -26,10 +26,8 @@ end
Then /^I should be able to run a command as root with pkexec$/ do
next if @skip_steps_while_restoring_background
- step 'I run "gnome-terminal"'
- @screen.wait_and_click('GnomeTerminalWindow.png', 20)
- @screen.type('pkexec touch /root/pkexec-test' + Sikuli::Key.ENTER)
- step 'I enter the sudo password in the PolicyKit prompt'
+ step "I run \"pkexec touch /root/pkexec-test\" in GNOME Terminal"
+ step 'I enter the sudo password in the pkexec prompt'
try_for(10, :msg => 'The /root/pkexec-test file was not created.') {
@vm.execute('ls /root/pkexec-test').success?
}
@@ -37,13 +35,11 @@ end
Then /^I should not be able to run a command as root with pkexec and the standard passwords$/ do
next if @skip_steps_while_restoring_background
- step 'I run "gnome-terminal"'
- @screen.wait_and_click('GnomeTerminalWindow.png', 20)
- @screen.type('pkexec touch /root/pkexec-test' + Sikuli::Key.ENTER)
+ step "I run \"pkexec touch /root/pkexec-test\" in GNOME Terminal"
['', 'live'].each do |password|
- step "I enter the \"#{password}\" password in the PolicyKit prompt"
+ step "I enter the \"#{password}\" password in the pkexec prompt"
@screen.wait('PolicyKitAuthFailure.png', 20)
end
- step "I enter the \"amnesia\" password in the PolicyKit prompt"
+ step "I enter the \"amnesia\" password in the pkexec prompt"
@screen.wait('PolicyKitAuthCompleteFailure.png', 20)
end
diff --git a/features/step_definitions/torified_browsing.rb b/features/step_definitions/torified_browsing.rb
index afc4eaf..770fda5 100644
--- a/features/step_definitions/torified_browsing.rb
+++ b/features/step_definitions/torified_browsing.rb
@@ -1,13 +1,12 @@
-When /^I open a new tab in Iceweasel$/ do
+When /^I open a new tab in the Tor Browser$/ do
next if @skip_steps_while_restoring_background
- @screen.wait_and_click("IceweaselWindow.png", 10)
- @screen.type("t", Sikuli::KeyModifier.CTRL)
+ @screen.click("TorBrowserNewTabButton.png")
end
-When /^I open the address "([^"]*)" in Iceweasel$/ do |address|
+When /^I open the address "([^"]*)" in the Tor Browser$/ do |address|
next if @skip_steps_while_restoring_background
- step "I open a new tab in Iceweasel"
- @screen.type("l", Sikuli::KeyModifier.CTRL)
+ step "I open a new tab in the Tor Browser"
+ @screen.click("TorBrowserAddressBar.png")
sleep 0.5
@screen.type(address + Sikuli::Key.ENTER)
end
diff --git a/features/step_definitions/torified_gnupg.rb b/features/step_definitions/torified_gnupg.rb
index ba5d913..5a1462c 100644
--- a/features/step_definitions/torified_gnupg.rb
+++ b/features/step_definitions/torified_gnupg.rb
@@ -30,9 +30,17 @@ When /^the "([^"]*)" key is in the live user's public keyring after at most (\d+
}
end
+When /^I start Seahorse$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsSystem.png", 10)
+ @screen.wait_and_click("GnomeApplicationsPreferences.png", 10)
+ @screen.wait_and_click("GnomeApplicationsSeahorse.png", 10)
+end
+
When /^I fetch the "([^"]*)" OpenPGP key using Seahorse$/ do |keyid|
next if @skip_steps_while_restoring_background
- step "I run \"torsocks seahorse\""
+ step "I start Seahorse"
@screen.wait("SeahorseWindow.png", 10)
@screen.type("r", Sikuli::KeyModifier.ALT) # Menu: "Remote" ->
@screen.type("f") # "Find Remote Keys...".
diff --git a/features/step_definitions/totem.rb b/features/step_definitions/totem.rb
new file mode 100644
index 0000000..d125f4e
--- /dev/null
+++ b/features/step_definitions/totem.rb
@@ -0,0 +1,50 @@
+def shared_video_dir_on_guest
+ "/tmp/shared_video_dir"
+end
+
+Given /^I create sample videos$/ do
+ next if @skip_steps_while_restoring_background
+ fatal_system("ffmpeg -loop 1 -t 30 -f image2 " +
+ "-i 'features/images/TailsBootSplash.png' " +
+ "-an -vcodec libx264 -y " +
+ "'#{$misc_files_dir}/video.mp4' >/dev/null 2>&1")
+end
+
+Given /^I setup a filesystem share containing sample videos$/ do
+ next if @skip_steps_while_restoring_background
+ @vm.add_share($misc_files_dir, shared_video_dir_on_guest)
+end
+
+Given /^I copy the sample videos to "([^"]+)" as user "([^"]+)"$/ do |destination, user|
+ next if @skip_steps_while_restoring_background
+ for video_on_host in Dir.glob("#{$misc_files_dir}/*.mp4") do
+ video_name = File.basename(video_on_host)
+ src_on_guest = "#{shared_video_dir_on_guest}/#{video_name}"
+ dst_on_guest = "#{destination}/#{video_name}"
+ step "I copy \"#{src_on_guest}\" to \"#{dst_on_guest}\" as user \"amnesia\""
+ end
+end
+
+When /^I start Totem through the GNOME menu$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsSoundVideo.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTotem.png", 20)
+ @screen.wait_and_click("TotemMainWindow.png", 20)
+end
+
+When /^I load the "([^"]+)" URL in Totem$/ do |url|
+ next if @skip_steps_while_restoring_background
+ @screen.type("l", Sikuli::KeyModifier.CTRL)
+ @screen.wait("TotemOpenUrlDialog.png", 10)
+ @screen.type(url + Sikuli::Key.ENTER)
+end
+
+When /^I(?:| try to) open "([^"]+)" with Totem$/ do |filename|
+ next if @skip_steps_while_restoring_background
+ step "I run \"totem #{filename}\" in GNOME Terminal"
+end
+
+When /^I close Totem$/ do
+ step 'I kill the process "totem"'
+end
diff --git a/features/step_definitions/unsafe_browser.rb b/features/step_definitions/unsafe_browser.rb
index a3cc222..86f1c16 100644
--- a/features/step_definitions/unsafe_browser.rb
+++ b/features/step_definitions/unsafe_browser.rb
@@ -27,15 +27,17 @@ end
When /^I start the Unsafe Browser$/ do
next if @skip_steps_while_restoring_background
- unsafe_browser_cmd = nil
- @vm.execute("cat /usr/share/applications/unsafe-browser.desktop").stdout.chomp.each_line { |line|
- next if ! line.start_with? "Exec="
- unsafe_browser_cmd = line[/^Exec=(.*)/,1]
- }
- assert(!unsafe_browser_cmd.nil?, "failed to extract the unsafe browser command")
- step "I run \"#{unsafe_browser_cmd}\""
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsInternet.png", 10)
+ @screen.wait_and_click("GnomeApplicationsUnsafeBrowser.png", 20)
+end
+
+When /^I successfully start the Unsafe Browser$/ do
+ next if @skip_steps_while_restoring_background
+ step "I start the Unsafe Browser"
step "I see and accept the Unsafe Browser start verification"
step "I see the Unsafe Browser start notification and wait for it to close"
+ step "the Unsafe Browser has started"
end
Then /^I see a warning about another instance already running$/ do
@@ -73,15 +75,24 @@ When /^I open the address "([^"]*)" in the Unsafe Browser$/ do |address|
@screen.type(address + Sikuli::Key.ENTER)
end
+# Workaround until the TBB shows the menu bar by default
+# https://lists.torproject.org/pipermail/tor-qa/2014-October/000478.html
+def show_unsafe_browser_menu_bar
+ try_for(15, :msg => "Failed to show the menu bar") do
+ @screen.type("h", Sikuli::KeyModifier.ALT)
+ @screen.find('UnsafeBrowserEditMenu.png')
+ end
+end
+
Then /^I cannot configure the Unsafe Browser to use any local proxies$/ do
next if @skip_steps_while_restoring_background
@screen.wait_and_click("UnsafeBrowserWindow.png", 10)
- sleep 0.5
# First we open the proxy settings page to prepare it with the
# correct open tabs for the loop below.
- @screen.type("e", Sikuli::KeyModifier.ALT)
- @screen.type("n")
- @screen.wait('UnsafeBrowserPreferences.png', 10)
+ show_unsafe_browser_menu_bar
+ @screen.hover('UnsafeBrowserEditMenu.png')
+ @screen.wait_and_click('UnsafeBrowserEditPreferences.png', 10)
+ @screen.wait('UnsafeBrowserPreferencesWindow.png', 10)
@screen.wait_and_click('UnsafeBrowserAdvancedSettings.png', 10)
@screen.wait_and_click('UnsafeBrowserNetworkTab.png', 10)
sleep 0.5
@@ -99,7 +110,7 @@ Then /^I cannot configure the Unsafe Browser to use any local proxies$/ do
proxies = [[socks_proxy, 9050],
[socks_proxy, 9061],
[socks_proxy, 9062],
- [socks_proxy, 9151],
+ [socks_proxy, 9150],
[http_proxy, 8118],
[no_proxy, 0]]
@@ -107,10 +118,13 @@ Then /^I cannot configure the Unsafe Browser to use any local proxies$/ do
proxy_type = proxy[0]
proxy_port = proxy[1]
+ @screen.hide_cursor
+
# Open proxy settings and select manual proxy configuration
- @screen.type("e", Sikuli::KeyModifier.ALT)
- @screen.type("n")
- @screen.wait('UnsafeBrowserPreferences.png', 10)
+ show_unsafe_browser_menu_bar
+ @screen.hover('UnsafeBrowserEditMenu.png')
+ @screen.wait_and_click('UnsafeBrowserEditPreferences.png', 10)
+ @screen.wait('UnsafeBrowserPreferencesWindow.png', 10)
@screen.type("e", Sikuli::KeyModifier.ALT)
@screen.wait('UnsafeBrowserProxySettings.png', 10)
@screen.type("m", Sikuli::KeyModifier.ALT)
diff --git a/features/step_definitions/usb.rb b/features/step_definitions/usb.rb
index e80c93d..f9f17ea 100644
--- a/features/step_definitions/usb.rb
+++ b/features/step_definitions/usb.rb
@@ -38,6 +38,12 @@ Given /^the computer is set to boot from the old Tails DVD$/ do
@vm.set_cdrom_boot($old_tails_iso)
end
+Given /^the computer is set to boot in UEFI mode$/ do
+ next if @skip_steps_while_restoring_background
+ @vm.set_os_loader('UEFI')
+ @os_loader = 'UEFI'
+end
+
class ISOHybridUpgradeNotSupported < StandardError
end
@@ -66,16 +72,23 @@ def usb_install_helper(name)
@screen.wait('USBInstallationComplete.png', 60*60)
end
+When /^I start Tails Installer$/ do
+ next if @skip_steps_while_restoring_background
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTails.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTailsInstaller.png", 20)
+end
+
When /^I "Clone & Install" Tails to USB drive "([^"]+)"$/ do |name|
next if @skip_steps_while_restoring_background
- step "I run \"liveusb-creator-launcher\""
+ step "I start Tails Installer"
@screen.wait_and_click('USBCloneAndInstall.png', 30)
usb_install_helper(name)
end
When /^I "Clone & Upgrade" Tails to USB drive "([^"]+)"$/ do |name|
next if @skip_steps_while_restoring_background
- step "I run \"liveusb-creator-launcher\""
+ step "I start Tails Installer"
@screen.wait_and_click('USBCloneAndUpgrade.png', 30)
usb_install_helper(name)
end
@@ -97,7 +110,7 @@ When /^I am suggested to do a "Clone & Install"$/ do
end
def shared_iso_dir_on_guest
- "/tmp/shared_dir"
+ "/tmp/shared_iso_dir"
end
Given /^I setup a filesystem share containing the Tails ISO$/ do
@@ -107,7 +120,7 @@ end
When /^I do a "Upgrade from ISO" on USB drive "([^"]+)"$/ do |name|
next if @skip_steps_while_restoring_background
- step "I run \"liveusb-creator-launcher\""
+ step "I start Tails Installer"
@screen.wait_and_click('USBUpgradeFromISO.png', 10)
@screen.wait('USBUseLiveSystemISO.png', 10)
match = @screen.find('USBUseLiveSystemISO.png')
@@ -135,9 +148,9 @@ end
Given /^I create a persistent partition with password "([^"]+)"$/ do |pwd|
next if @skip_steps_while_restoring_background
- step 'I run "gnome-terminal"'
- @screen.wait_and_click('GnomeTerminalWindow.png', 20)
- @screen.type('/usr/local/bin/tails-persistence-setup' + Sikuli::Key.ENTER)
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTails.png", 10)
+ @screen.wait_and_click("GnomeApplicationsConfigurePersistentVolume.png", 20)
@screen.wait('PersistenceWizardWindow.png', 40)
@screen.wait('PersistenceWizardStart.png', 20)
@screen.type(pwd + "\t" + pwd + Sikuli::Key.ENTER)
@@ -188,15 +201,6 @@ def tails_is_installed_helper(name, tails_root, loader)
assert(c.success?, "USB drive '#{name}' has differences in " +
"'/syslinux/syslinux.cfg'")
- # We have to account for the different path vs isolinux
- old_exithelp = @vm.execute("cat '#{tails_root}/#{loader}/exithelp.cfg'").stdout
- new_exithelp = @vm.execute("cat '#{target_root}/syslinux/exithelp.cfg'").stdout
- new_exithelp_undiffed = new_exithelp.sub("kernel /syslinux/vesamenu.c32",
- "kernel /#{loader}/vesamenu.c32")
- assert(new_exithelp_undiffed == old_exithelp,
- "USB drive '#{name}' has unexpected differences in " +
- "'/syslinux/exithelp.cfg'")
-
@vm.execute("umount #{target_root}")
@vm.execute("sync")
end
@@ -324,8 +328,7 @@ end
Then /^Tails is running from USB drive "([^"]+)"$/ do |name|
next if @skip_steps_while_restoring_background
- assert(boot_device_type == "usb",
- "Got device type '#{boot_device_type}' while expecting 'usb'")
+ assert_equal("usb", boot_device_type)
actual_dev = boot_device
# The boot partition differs between a "normal" install using the
# USB installer and isohybrid installations
@@ -354,13 +357,11 @@ Then /^the boot device has safe access rights$/ do
dev_owner = @vm.execute("stat -c %U #{dev}").stdout.chomp
dev_group = @vm.execute("stat -c %G #{dev}").stdout.chomp
dev_perms = @vm.execute("stat -c %a #{dev}").stdout.chomp
- assert(dev_owner == "root",
- "Boot device '#{dev}' owned by user '#{dev_owner}', expected 'root'")
+ assert_equal("root", dev_owner)
assert(dev_group == "disk" || dev_group == "root",
"Boot device '#{dev}' owned by group '#{dev_group}', expected " +
"'disk' or 'root'.")
- assert(dev_perms == "1660",
- "Boot device '#{dev}' has permissions '#{dev_perms}', expected '660'")
+ assert_equal("1660", dev_perms)
for user, groups in all_users_with_groups do
next if user == "root"
assert(!(groups.include?(dev_group)),
@@ -379,12 +380,9 @@ Then /^persistent filesystems have safe access rights$/ do
fs_owner = @vm.execute("stat -c %U #{mountpoint}").stdout.chomp
fs_group = @vm.execute("stat -c %G #{mountpoint}").stdout.chomp
fs_perms = @vm.execute("stat -c %a #{mountpoint}").stdout.chomp
- assert(fs_owner == "root",
- "Persistent filesystem '#{mountpoint}' owned by user '#{fs_owner}', expected 'root'")
- assert(fs_group == "root",
- "Persistent filesystem '#{mountpoint}' owned by group '#{fs_group}', expected 'root'")
- assert(fs_perms == '775',
- "Persistent filesystem '#{mountpoint}' has permissions '#{fs_perms}', expected '775'")
+ assert_equal("root", fs_owner)
+ assert_equal("root", fs_group)
+ assert_equal('775', fs_perms)
end
end
@@ -400,12 +398,9 @@ Then /^persistence configuration files have safe access rights$/ do
file_owner = @vm.execute("stat -c %U '#{f}'").stdout.chomp
file_group = @vm.execute("stat -c %G '#{f}'").stdout.chomp
file_perms = @vm.execute("stat -c %a '#{f}'").stdout.chomp
- assert(file_owner == "tails-persistence-setup",
- "'#{f}' is owned by user '#{file_owner}', expected 'tails-persistence-setup'")
- assert(file_group == "tails-persistence-setup",
- "'#{f}' is owned by group '#{file_group}', expected 'tails-persistence-setup'")
- assert(file_perms == "600",
- "'#{f}' has permissions '#{file_perms}', expected '600'")
+ assert_equal("tails-persistence-setup", file_owner)
+ assert_equal("tails-persistence-setup", file_group)
+ assert_equal("600", file_perms)
end
end
end
@@ -422,8 +417,7 @@ Then /^persistent directories have safe access rights$/ do
f = "#{mountpoint}/#{src}"
next unless @vm.execute("test -d #{f}").success?
file_perms = @vm.execute("stat -c %a '#{f}'").stdout.chomp
- assert(file_perms == expected_perms,
- "'#{f}' has permissions '#{file_perms}', expected '#{expected_perms}'")
+ assert_equal(expected_perms, file_perms)
end
end
end
@@ -483,11 +477,16 @@ end
When /^I delete the persistent partition$/ do
next if @skip_steps_while_restoring_background
- step 'I run "gnome-terminal"'
- @screen.wait_and_click('GnomeTerminalWindow.png', 20)
- @screen.type('/usr/local/bin/tails-delete-persistent-volume' + Sikuli::Key.ENTER)
+ @screen.wait_and_click("GnomeApplicationsMenu.png", 10)
+ @screen.wait_and_click("GnomeApplicationsTails.png", 10)
+ @screen.wait_and_click("GnomeApplicationsDeletePersistentVolume.png", 20)
@screen.wait("PersistenceWizardWindow.png", 40)
@screen.wait("PersistenceWizardDeletionStart.png", 20)
@screen.type(" ")
@screen.wait("PersistenceWizardDone.png", 120)
end
+
+Then /^Tails has started in UEFI mode$/ do
+ assert(@vm.execute("test -d /sys/firmware/efi").success?,
+ "/sys/firmware/efi does not exist")
+ end