summaryrefslogtreecommitdiffstats
path: root/features/step_definitions/usb.rb
diff options
context:
space:
mode:
Diffstat (limited to 'features/step_definitions/usb.rb')
-rw-r--r--features/step_definitions/usb.rb552
1 files changed, 328 insertions, 224 deletions
diff --git a/features/step_definitions/usb.rb b/features/step_definitions/usb.rb
index f9f17ea2..76f94d2f 100644
--- a/features/step_definitions/usb.rb
+++ b/features/step_definitions/usb.rb
@@ -1,103 +1,131 @@
-def persistent_mounts
- {
- "cups-configuration" => "/etc/cups",
- "nm-system-connections" => "/etc/NetworkManager/system-connections",
- "claws-mail" => "/home/#{$live_user}/.claws-mail",
- "gnome-keyrings" => "/home/#{$live_user}/.gnome2/keyrings",
- "gnupg" => "/home/#{$live_user}/.gnupg",
- "bookmarks" => "/home/#{$live_user}/.mozilla/firefox/bookmarks",
- "pidgin" => "/home/#{$live_user}/.purple",
- "openssh-client" => "/home/#{$live_user}/.ssh",
- "Persistent" => "/home/#{$live_user}/Persistent",
- "apt/cache" => "/var/cache/apt/archives",
- "apt/lists" => "/var/lib/apt/lists",
+# Returns a hash that for each preset the running Tails is aware of
+# maps the source to the destination.
+def get_persistence_presets(skip_links = false)
+ # Perl script that prints all persistence presets (one per line) on
+ # the form: <mount_point>:<comma-separated-list-of-options>
+ script = <<-EOF
+ use strict;
+ use warnings FATAL => "all";
+ use Tails::Persistence::Configuration::Presets;
+ foreach my $preset (Tails::Persistence::Configuration::Presets->new()->all) {
+ say $preset->destination, ":", join(",", @{$preset->options});
}
+EOF
+ # VMCommand:s cannot handle newlines, and they're irrelevant in the
+ # above perl script any way
+ script.delete!("\n")
+ presets = $vm.execute_successfully("perl -E '#{script}'").stdout.chomp.split("\n")
+ assert presets.size >= 10, "Got #{presets.size} persistence presets, " +
+ "which is too few"
+ persistence_mapping = Hash.new
+ for line in presets
+ destination, options_str = line.split(":")
+ options = options_str.split(",")
+ is_link = options.include? "link"
+ next if is_link and skip_links
+ source_str = options.find { |option| /^source=/.match option }
+ # If no source is given as an option, live-boot's persistence
+ # feature defaults to the destination minus the initial "/".
+ if source_str.nil?
+ source = destination.partition("/").last
+ else
+ source = source_str.split("=")[1]
+ end
+ persistence_mapping[source] = destination
+ end
+ return persistence_mapping
end
-def persistent_volumes_mountpoints
- @vm.execute("ls -1 -d /live/persistence/*_unlocked/").stdout.chomp.split
+def persistent_dirs
+ get_persistence_presets
end
-Given /^I create a new (\d+) ([[:alpha:]]+) USB drive named "([^"]+)"$/ do |size, unit, name|
- next if @skip_steps_while_restoring_background
- @vm.storage.create_new_disk(name, {:size => size, :unit => unit})
+def persistent_mounts
+ get_persistence_presets(true)
+end
+
+def persistent_volumes_mountpoints
+ $vm.execute("ls -1 -d /live/persistence/*_unlocked/").stdout.chomp.split
end
Given /^I clone USB drive "([^"]+)" to a new USB drive "([^"]+)"$/ do |from, to|
- next if @skip_steps_while_restoring_background
- @vm.storage.clone_to_new_disk(from, to)
+ $vm.storage.clone_to_new_disk(from, to)
end
Given /^I unplug USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- @vm.unplug_drive(name)
+ $vm.unplug_drive(name)
end
Given /^the computer is set to boot from the old Tails DVD$/ do
- next if @skip_steps_while_restoring_background
- @vm.set_cdrom_boot($old_tails_iso)
+ $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')
+ $vm.set_os_loader('UEFI')
@os_loader = 'UEFI'
end
-class ISOHybridUpgradeNotSupported < StandardError
+class UpgradeNotSupported < StandardError
end
def usb_install_helper(name)
- @screen.wait('USBCreateLiveUSB.png', 10)
-
- # Here we'd like to select USB drive using #{name}, but Sikuli's
- # OCR seems to be too unreliable.
-# @screen.wait('USBTargetDevice.png', 10)
-# match = @screen.find('USBTargetDevice.png')
-# region_x = match.x
-# region_y = match.y + match.h
-# region_w = match.w*3
-# region_h = match.h*2
-# ocr = Sikuli::Region.new(region_x, region_y, region_w, region_h).text
-# STDERR.puts ocr
-# # Unfortunately this results in almost garbage, like "|]dev/sdm"
-# # when it should be /dev/sda1
-
- @screen.wait_and_click('USBCreateLiveUSB.png', 10)
- if @screen.exists("USBSuggestsInstall.png")
- raise ISOHybridUpgradeNotSupported
+ @screen.wait('USBTailsLogo.png', 10)
+ if @screen.exists("USBCannotUpgrade.png")
+ raise UpgradeNotSupported
end
+ @screen.wait_and_click('USBCreateLiveUSB.png', 10)
@screen.wait('USBCreateLiveUSBConfirmWindow.png', 10)
@screen.wait_and_click('USBCreateLiveUSBConfirmYes.png', 10)
- @screen.wait('USBInstallationComplete.png', 60*60)
+ @screen.wait('USBInstallationComplete.png', 30*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)
+ step 'I start "TailsInstaller" via the GNOME "Tails" applications menu'
+ @screen.wait('USBCloneAndInstall.png', 30)
+end
+
+When /^I start Tails Installer in "([^"]+)" mode$/ do |mode|
+ step 'I start Tails Installer'
+ case mode
+ when 'Clone & Install'
+ @screen.wait_and_click('USBCloneAndInstall.png', 10)
+ when 'Clone & Upgrade'
+ @screen.wait_and_click('USBCloneAndUpgrade.png', 10)
+ when 'Upgrade from ISO'
+ @screen.wait_and_click('USBUpgradeFromISO.png', 10)
+ else
+ raise "Unsupported mode '#{mode}'"
+ end
+end
+
+Then /^Tails Installer detects that a device is too small$/ do
+ @screen.wait('TailsInstallerTooSmallDevice.png', 10)
end
When /^I "Clone & Install" Tails to USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- step "I start Tails Installer"
- @screen.wait_and_click('USBCloneAndInstall.png', 30)
+ step 'I start Tails Installer in "Clone & Install" mode'
usb_install_helper(name)
end
When /^I "Clone & Upgrade" Tails to USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- step "I start Tails Installer"
- @screen.wait_and_click('USBCloneAndUpgrade.png', 30)
+ step 'I start Tails Installer in "Clone & Upgrade" mode'
usb_install_helper(name)
end
When /^I try a "Clone & Upgrade" Tails to USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
begin
step "I \"Clone & Upgrade\" Tails to USB drive \"#{name}\""
- rescue ISOHybridUpgradeNotSupported
+ rescue UpgradeNotSupported
+ # this is what we expect
+ else
+ raise "The USB installer should not succeed"
+ end
+end
+
+When /^I try to "Upgrade from ISO" USB drive "([^"]+)"$/ do |name|
+ begin
+ step "I do a \"Upgrade from ISO\" on USB drive \"#{name}\""
+ rescue UpgradeNotSupported
# this is what we expect
else
raise "The USB installer should not succeed"
@@ -105,140 +133,151 @@ When /^I try a "Clone & Upgrade" Tails to USB drive "([^"]+)"$/ do |name|
end
When /^I am suggested to do a "Clone & Install"$/ do
- next if @skip_steps_while_restoring_background
- @screen.find("USBSuggestsInstall.png")
+ @screen.find("USBCannotUpgrade.png")
end
-def shared_iso_dir_on_guest
- "/tmp/shared_iso_dir"
+When /^I am told that the destination device cannot be upgraded$/ do
+ @screen.find("USBCannotUpgrade.png")
end
Given /^I setup a filesystem share containing the Tails ISO$/ do
- next if @skip_steps_while_restoring_background
- @vm.add_share(File.dirname($tails_iso), shared_iso_dir_on_guest)
+ shared_iso_dir_on_host = "#{$config["TMPDIR"]}/shared_iso_dir"
+ @shared_iso_dir_on_guest = "/tmp/shared_iso_dir"
+ FileUtils.mkdir_p(shared_iso_dir_on_host)
+ FileUtils.cp(TAILS_ISO, shared_iso_dir_on_host)
+ add_after_scenario_hook { FileUtils.rm_r(shared_iso_dir_on_host) }
+ $vm.add_share(shared_iso_dir_on_host, @shared_iso_dir_on_guest)
end
When /^I do a "Upgrade from ISO" on USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- step "I start Tails Installer"
- @screen.wait_and_click('USBUpgradeFromISO.png', 10)
+ step 'I start Tails Installer in "Upgrade from ISO" mode'
@screen.wait('USBUseLiveSystemISO.png', 10)
match = @screen.find('USBUseLiveSystemISO.png')
@screen.click(match.getCenter.offset(0, match.h*2))
@screen.wait('USBSelectISO.png', 10)
- @screen.wait_and_click('GnomeFileDiagTypeFilename.png', 10)
- iso = "#{shared_iso_dir_on_guest}/#{File.basename($tails_iso)}"
- @screen.type(iso + Sikuli::Key.ENTER)
+ @screen.wait_and_click('GnomeFileDiagHome.png', 10)
+ @screen.type("l", Sikuli::KeyModifier.CTRL)
+ @screen.wait('GnomeFileDiagTypeFilename.png', 10)
+ iso = "#{@shared_iso_dir_on_guest}/#{File.basename(TAILS_ISO)}"
+ @screen.type(iso)
+ @screen.wait_and_click('GnomeFileDiagOpenButton.png', 10)
usb_install_helper(name)
end
Given /^I enable all persistence presets$/ do
- next if @skip_steps_while_restoring_background
@screen.wait('PersistenceWizardPresets.png', 20)
- # Mark first non-default persistence preset
- @screen.type(Sikuli::Key.TAB*2)
- # Check all non-default persistence presets
- 12.times do
- @screen.type(Sikuli::Key.SPACE + Sikuli::Key.TAB)
+ # Select the "Persistent" folder preset, which is checked by default.
+ @screen.type(Sikuli::Key.TAB)
+ # Check all non-default persistence presets, i.e. all *after* the
+ # "Persistent" folder, which are unchecked by default.
+ (persistent_dirs.size - 1).times do
+ @screen.type(Sikuli::Key.TAB + Sikuli::Key.SPACE)
end
@screen.wait_and_click('PersistenceWizardSave.png', 10)
- @screen.wait('PersistenceWizardDone.png', 20)
+ @screen.wait('PersistenceWizardDone.png', 30)
@screen.type(Sikuli::Key.F4, Sikuli::KeyModifier.ALT)
end
-Given /^I create a persistent partition with password "([^"]+)"$/ do |pwd|
- 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("GnomeApplicationsConfigurePersistentVolume.png", 20)
- @screen.wait('PersistenceWizardWindow.png', 40)
+Given /^I create a persistent partition$/ do
+ step 'I start "ConfigurePersistentVolume" via the GNOME "Tails" applications menu'
@screen.wait('PersistenceWizardStart.png', 20)
- @screen.type(pwd + "\t" + pwd + Sikuli::Key.ENTER)
+ @screen.type(@persistence_password + "\t" + @persistence_password + Sikuli::Key.ENTER)
@screen.wait('PersistenceWizardPresets.png', 300)
step "I enable all persistence presets"
end
-def check_part_integrity(name, dev, usage, type, scheme, label)
- info = @vm.execute("udisks --show-info #{dev}").stdout
- info_split = info.split("\n partition:\n")
+def check_disk_integrity(name, dev, scheme)
+ info = $vm.execute("udisksctl info --block-device '#{dev}'").stdout
+ info_split = info.split("\n org\.freedesktop\.UDisks2\.PartitionTable:\n")
+ dev_info = info_split[0]
+ part_table_info = info_split[1]
+ assert(part_table_info.match("^ Type: +#{scheme}$"),
+ "Unexpected partition scheme on USB drive '#{name}', '#{dev}'")
+end
+
+def check_part_integrity(name, dev, usage, fs_type, part_label, part_type = nil)
+ info = $vm.execute("udisksctl info --block-device '#{dev}'").stdout
+ info_split = info.split("\n org\.freedesktop\.UDisks2\.Partition:\n")
dev_info = info_split[0]
part_info = info_split[1]
- assert(dev_info.match("^ usage: +#{usage}$"),
+ assert(dev_info.match("^ IdUsage: +#{usage}$"),
"Unexpected device field 'usage' on USB drive '#{name}', '#{dev}'")
- assert(dev_info.match("^ type: +#{type}$"),
- "Unexpected device field 'type' on USB drive '#{name}', '#{dev}'")
- assert(part_info.match("^ scheme: +#{scheme}$"),
- "Unexpected partition scheme on USB drive '#{name}', '#{dev}'")
- assert(part_info.match("^ label: +#{label}$"),
+ assert(dev_info.match("^ IdType: +#{fs_type}$"),
+ "Unexpected device field 'IdType' on USB drive '#{name}', '#{dev}'")
+ assert(part_info.match("^ Name: +#{part_label}$"),
"Unexpected partition label on USB drive '#{name}', '#{dev}'")
+ if part_type
+ assert(part_info.match("^ Type: +#{part_type}$"),
+ "Unexpected partition type on USB drive '#{name}', '#{dev}'")
+ end
end
def tails_is_installed_helper(name, tails_root, loader)
- dev = @vm.disk_dev(name) + "1"
- check_part_integrity(name, dev, "filesystem", "vfat", "gpt", "Tails")
+ disk_dev = $vm.disk_dev(name)
+ part_dev = disk_dev + "1"
+ check_disk_integrity(name, disk_dev, "gpt")
+ check_part_integrity(name, part_dev, "filesystem", "vfat", "Tails",
+ # EFI System Partition
+ 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b')
target_root = "/mnt/new"
- @vm.execute("mkdir -p #{target_root}")
- @vm.execute("mount #{dev} #{target_root}")
+ $vm.execute("mkdir -p #{target_root}")
+ $vm.execute("mount #{part_dev} #{target_root}")
- c = @vm.execute("diff -qr '#{tails_root}/live' '#{target_root}/live'")
+ c = $vm.execute("diff -qr '#{tails_root}/live' '#{target_root}/live'")
assert(c.success?,
- "USB drive '#{name}' has differences in /live:\n#{c.stdout}")
+ "USB drive '#{name}' has differences in /live:\n#{c.stdout}\n#{c.stderr}")
- syslinux_files = @vm.execute("ls -1 #{target_root}/syslinux").stdout.chomp.split
+ syslinux_files = $vm.execute("ls -1 #{target_root}/syslinux").stdout.chomp.split
# We deal with these files separately
- ignores = ["syslinux.cfg", "exithelp.cfg", "ldlinux.sys"]
+ ignores = ["syslinux.cfg", "exithelp.cfg", "ldlinux.c32", "ldlinux.sys"]
for f in syslinux_files - ignores do
- c = @vm.execute("diff -q '#{tails_root}/#{loader}/#{f}' " +
+ c = $vm.execute("diff -q '#{tails_root}/#{loader}/#{f}' " +
"'#{target_root}/syslinux/#{f}'")
assert(c.success?, "USB drive '#{name}' has differences in " +
"'/syslinux/#{f}'")
end
# The main .cfg is named differently vs isolinux
- c = @vm.execute("diff -q '#{tails_root}/#{loader}/#{loader}.cfg' " +
+ c = $vm.execute("diff -q '#{tails_root}/#{loader}/#{loader}.cfg' " +
"'#{target_root}/syslinux/syslinux.cfg'")
assert(c.success?, "USB drive '#{name}' has differences in " +
"'/syslinux/syslinux.cfg'")
- @vm.execute("umount #{target_root}")
- @vm.execute("sync")
+ $vm.execute("umount #{target_root}")
+ $vm.execute("sync")
end
Then /^the running Tails is installed on USB drive "([^"]+)"$/ do |target_name|
- next if @skip_steps_while_restoring_background
loader = boot_device_type == "usb" ? "syslinux" : "isolinux"
tails_is_installed_helper(target_name, "/lib/live/mount/medium", loader)
end
Then /^the ISO's Tails is installed on USB drive "([^"]+)"$/ do |target_name|
- next if @skip_steps_while_restoring_background
- iso = "#{shared_iso_dir_on_guest}/#{File.basename($tails_iso)}"
+ iso = "#{@shared_iso_dir_on_guest}/#{File.basename(TAILS_ISO)}"
iso_root = "/mnt/iso"
- @vm.execute("mkdir -p #{iso_root}")
- @vm.execute("mount -o loop #{iso} #{iso_root}")
+ $vm.execute("mkdir -p #{iso_root}")
+ $vm.execute("mount -o loop #{iso} #{iso_root}")
tails_is_installed_helper(target_name, iso_root, "isolinux")
- @vm.execute("umount #{iso_root}")
+ $vm.execute("umount #{iso_root}")
end
Then /^there is no persistence partition on USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- data_part_dev = @vm.disk_dev(name) + "2"
- assert(!@vm.execute("test -b #{data_part_dev}").success?,
+ data_part_dev = $vm.disk_dev(name) + "2"
+ assert(!$vm.execute("test -b #{data_part_dev}").success?,
"USB drive #{name} has a partition '#{data_part_dev}'")
end
-Then /^a Tails persistence partition with password "([^"]+)" exists on USB drive "([^"]+)"$/ do |pwd, name|
- next if @skip_steps_while_restoring_background
- dev = @vm.disk_dev(name) + "2"
- check_part_integrity(name, dev, "crypto", "crypto_LUKS", "gpt", "TailsData")
+Then /^a Tails persistence partition exists on USB drive "([^"]+)"$/ do |name|
+ dev = $vm.disk_dev(name) + "2"
+ check_part_integrity(name, dev, "crypto", "crypto_LUKS", "TailsData")
# The LUKS container may already be opened, e.g. by udisks after
# we've run tails-persistence-setup.
- c = @vm.execute("ls -1 /dev/mapper/")
+ c = $vm.execute("ls -1 /dev/mapper/")
if c.success?
for candidate in c.stdout.split("\n")
- luks_info = @vm.execute("cryptsetup status #{candidate}")
+ luks_info = $vm.execute("cryptsetup status #{candidate}")
if luks_info.success? and luks_info.stdout.match("^\s+device:\s+#{dev}$")
luks_dev = "/dev/mapper/#{candidate}"
break
@@ -246,122 +285,133 @@ Then /^a Tails persistence partition with password "([^"]+)" exists on USB drive
end
end
if luks_dev.nil?
- c = @vm.execute("echo #{pwd} | cryptsetup luksOpen #{dev} #{name}")
+ c = $vm.execute("echo #{@persistence_password} | " +
+ "cryptsetup luksOpen #{dev} #{name}")
assert(c.success?, "Couldn't open LUKS device '#{dev}' on drive '#{name}'")
luks_dev = "/dev/mapper/#{name}"
end
# Adapting check_part_integrity() seems like a bad idea so here goes
- info = @vm.execute("udisks --show-info #{luks_dev}").stdout
- assert info.match("^ cleartext luks device:$")
- assert info.match("^ usage: +filesystem$")
- assert info.match("^ type: +ext[34]$")
- assert info.match("^ label: +TailsData$")
+ info = $vm.execute("udisksctl info --block-device '#{luks_dev}'").stdout
+ assert info.match("^ CryptoBackingDevice: +'/[a-zA-Z0-9_/]+'$")
+ assert info.match("^ IdUsage: +filesystem$")
+ assert info.match("^ IdType: +ext[34]$")
+ assert info.match("^ IdLabel: +TailsData$")
mount_dir = "/mnt/#{name}"
- @vm.execute("mkdir -p #{mount_dir}")
- c = @vm.execute("mount #{luks_dev} #{mount_dir}")
+ $vm.execute("mkdir -p #{mount_dir}")
+ c = $vm.execute("mount #{luks_dev} #{mount_dir}")
assert(c.success?,
"Couldn't mount opened LUKS device '#{dev}' on drive '#{name}'")
- @vm.execute("umount #{mount_dir}")
- @vm.execute("sync")
- @vm.execute("cryptsetup luksClose #{name}")
+ $vm.execute("umount #{mount_dir}")
+ $vm.execute("sync")
+ $vm.execute("cryptsetup luksClose #{name}")
end
-Given /^I enable persistence with password "([^"]+)"$/ do |pwd|
- next if @skip_steps_while_restoring_background
+Given /^I enable persistence$/ do
@screen.wait('TailsGreeterPersistence.png', 10)
@screen.type(Sikuli::Key.SPACE)
@screen.wait('TailsGreeterPersistencePassphrase.png', 10)
match = @screen.find('TailsGreeterPersistencePassphrase.png')
@screen.click(match.getCenter.offset(match.w*2, match.h/2))
- @screen.type(pwd)
+ @screen.type(@persistence_password)
end
def tails_persistence_enabled?
persistence_state_file = "/var/lib/live/config/tails.persistence"
- return @vm.execute("test -e '#{persistence_state_file}'").success? &&
- @vm.execute('. #{persistence_state_file} && ' +
+ return $vm.execute("test -e '#{persistence_state_file}'").success? &&
+ $vm.execute(". '#{persistence_state_file}' && " +
'test "$TAILS_PERSISTENCE_ENABLED" = true').success?
end
-Given /^persistence is enabled$/ do
- next if @skip_steps_while_restoring_background
+Given /^all persistence presets(| from the old Tails version) are enabled$/ do |old_tails|
try_for(120, :msg => "Persistence is disabled") do
tails_persistence_enabled?
end
# Check that all persistent directories are mounted
- mount = @vm.execute("mount").stdout.chomp
- for _, dir in persistent_mounts do
+ if old_tails.empty?
+ expected_mounts = persistent_mounts
+ else
+ assert_not_nil($remembered_persistence_mounts)
+ expected_mounts = $remembered_persistence_mounts
+ end
+ mount = $vm.execute("mount").stdout.chomp
+ for _, dir in expected_mounts do
assert(mount.include?("on #{dir} "),
"Persistent directory '#{dir}' is not mounted")
end
end
Given /^persistence is disabled$/ do
- next if @skip_steps_while_restoring_background
assert(!tails_persistence_enabled?, "Persistence is enabled")
end
-Given /^I enable read-only persistence with password "([^"]+)"$/ do |pwd|
- step "I enable persistence with password \"#{pwd}\""
- next if @skip_steps_while_restoring_background
+Given /^I enable read-only persistence$/ do
+ step "I enable persistence"
@screen.wait_and_click('TailsGreeterPersistenceReadOnly.png', 10)
end
def boot_device
# Approach borrowed from
# config/chroot_local_includes/lib/live/config/998-permissions
- boot_dev_id = @vm.execute("udevadm info --device-id-of-file=/lib/live/mount/medium").stdout.chomp
- boot_dev = @vm.execute("readlink -f /dev/block/'#{boot_dev_id}'").stdout.chomp
+ boot_dev_id = $vm.execute("udevadm info --device-id-of-file=/lib/live/mount/medium").stdout.chomp
+ boot_dev = $vm.execute("readlink -f /dev/block/'#{boot_dev_id}'").stdout.chomp
return boot_dev
end
-def boot_device_type
+def device_info(dev)
# Approach borrowed from
# config/chroot_local_includes/lib/live/config/998-permissions
- boot_dev_info = @vm.execute("udevadm info --query=property --name='#{boot_device}'").stdout.chomp
- boot_dev_type = (boot_dev_info.split("\n").select { |x| x.start_with? "ID_BUS=" })[0].split("=")[1]
- return boot_dev_type
+ info = $vm.execute("udevadm info --query=property --name='#{dev}'").stdout.chomp
+ info.split("\n").map { |e| e.split('=') } .to_h
end
-Then /^Tails is running from USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- assert_equal("usb", boot_device_type)
+def boot_device_type
+ device_info(boot_device)['ID_BUS']
+end
+
+Then /^Tails is running from (.*) drive "([^"]+)"$/ do |bus, name|
+ bus = bus.downcase
+ case bus
+ when "ide"
+ expected_bus = "ata"
+ else
+ expected_bus = bus
+ end
+ assert_equal(expected_bus, boot_device_type)
actual_dev = boot_device
# The boot partition differs between a "normal" install using the
# USB installer and isohybrid installations
- expected_dev_normal = @vm.disk_dev(name) + "1"
- expected_dev_isohybrid = @vm.disk_dev(name) + "4"
+ expected_dev_normal = $vm.disk_dev(name) + "1"
+ expected_dev_isohybrid = $vm.disk_dev(name) + "4"
assert(actual_dev == expected_dev_normal ||
actual_dev == expected_dev_isohybrid,
- "We are running from device #{actual_dev}, but for USB drive " +
+ "We are running from device #{actual_dev}, but for #{bus} drive " +
"'#{name}' we expected to run from either device " +
"#{expected_dev_normal} (when installed via the USB installer) " +
- "or #{expected_dev_normal} (when installed from an isohybrid)")
+ "or #{expected_dev_isohybrid} (when installed from an isohybrid)")
end
Then /^the boot device has safe access rights$/ do
- next if @skip_steps_while_restoring_background
super_boot_dev = boot_device.sub(/[[:digit:]]+$/, "")
- devs = @vm.execute("ls -1 #{super_boot_dev}*").stdout.chomp.split
+ devs = $vm.execute("ls -1 #{super_boot_dev}*").stdout.chomp.split
assert(devs.size > 0, "Could not determine boot device")
- all_users = @vm.execute("cut -d':' -f1 /etc/passwd").stdout.chomp.split
+ all_users = $vm.execute("cut -d':' -f1 /etc/passwd").stdout.chomp.split
all_users_with_groups = all_users.collect do |user|
- groups = @vm.execute("groups #{user}").stdout.chomp.sub(/^#{user} : /, "").split(" ")
+ groups = $vm.execute("groups #{user}").stdout.chomp.sub(/^#{user} : /, "").split(" ")
[user, groups]
end
for dev in devs 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
+ 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_equal("root", dev_owner)
assert(dev_group == "disk" || dev_group == "root",
"Boot device '#{dev}' owned by group '#{dev_group}', expected " +
"'disk' or 'root'.")
- assert_equal("1660", dev_perms)
+ assert_equal("660", dev_perms)
for user, groups in all_users_with_groups do
next if user == "root"
assert(!(groups.include?(dev_group)),
@@ -370,34 +420,34 @@ Then /^the boot device has safe access rights$/ do
end
end
- info = @vm.execute("udisks --show-info #{super_boot_dev}").stdout
- assert(info.match("^ system internal: +1$"),
+ info = $vm.execute("udisksctl info --block-device '#{super_boot_dev}'").stdout
+ assert(info.match("^ HintSystem: +true$"),
"Boot device '#{super_boot_dev}' is not system internal for udisks")
end
-Then /^persistent filesystems have safe access rights$/ do
+Then /^all persistent filesystems have safe access rights$/ do
persistent_volumes_mountpoints.each do |mountpoint|
- 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
+ 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_equal("root", fs_owner)
assert_equal("root", fs_group)
assert_equal('775', fs_perms)
end
end
-Then /^persistence configuration files have safe access rights$/ do
+Then /^all persistence configuration files have safe access rights$/ do
persistent_volumes_mountpoints.each do |mountpoint|
- assert(@vm.execute("test -e #{mountpoint}/persistence.conf").success?,
+ assert($vm.execute("test -e #{mountpoint}/persistence.conf").success?,
"#{mountpoint}/persistence.conf does not exist, while it should")
- assert(@vm.execute("test ! -e #{mountpoint}/live-persistence.conf").success?,
+ assert($vm.execute("test ! -e #{mountpoint}/live-persistence.conf").success?,
"#{mountpoint}/live-persistence.conf does exist, while it should not")
- @vm.execute(
+ $vm.execute(
"ls -1 #{mountpoint}/persistence.conf #{mountpoint}/live-*.conf"
).stdout.chomp.split.each do |f|
- 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
+ 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_equal("tails-persistence-setup", file_owner)
assert_equal("tails-persistence-setup", file_group)
assert_equal("600", file_perms)
@@ -405,88 +455,142 @@ Then /^persistence configuration files have safe access rights$/ do
end
end
-Then /^persistent directories have safe access rights$/ do
- next if @skip_steps_while_restoring_background
- expected_perms = "700"
+Then /^all persistent directories(| from the old Tails version) have safe access rights$/ do |old_tails|
+ if old_tails.empty?
+ expected_dirs = persistent_dirs
+ else
+ assert_not_nil($remembered_persistence_dirs)
+ expected_dirs = $remembered_persistence_dirs
+ end
persistent_volumes_mountpoints.each do |mountpoint|
- # We also want to check that dotfiles' source has safe permissions
- all_persistent_dirs = persistent_mounts.clone
- all_persistent_dirs["dotfiles"] = "/home/#{$live_user}/"
- persistent_mounts.each do |src, dest|
- next unless dest.start_with?("/home/#{$live_user}/")
- f = "#{mountpoint}/#{src}"
- next unless @vm.execute("test -d #{f}").success?
- file_perms = @vm.execute("stat -c %a '#{f}'").stdout.chomp
- assert_equal(expected_perms, file_perms)
+ expected_dirs.each do |src, dest|
+ full_src = "#{mountpoint}/#{src}"
+ assert_vmcommand_success $vm.execute("test -d #{full_src}")
+ dir_perms = $vm.execute_successfully("stat -c %a '#{full_src}'").stdout.chomp
+ dir_owner = $vm.execute_successfully("stat -c %U '#{full_src}'").stdout.chomp
+ if dest.start_with?("/home/#{LIVE_USER}")
+ expected_perms = "700"
+ expected_owner = LIVE_USER
+ else
+ expected_perms = "755"
+ expected_owner = "root"
+ end
+ assert_equal(expected_perms, dir_perms,
+ "Persistent source #{full_src} has permission " \
+ "#{dir_perms}, expected #{expected_perms}")
+ assert_equal(expected_owner, dir_owner,
+ "Persistent source #{full_src} has owner " \
+ "#{dir_owner}, expected #{expected_owner}")
end
end
end
When /^I write some files expected to persist$/ do
- next if @skip_steps_while_restoring_background
persistent_mounts.each do |_, dir|
- owner = @vm.execute("stat -c %U #{dir}").stdout.chomp
- assert(@vm.execute("touch #{dir}/XXX_persist", user=owner).success?,
+ owner = $vm.execute("stat -c %U #{dir}").stdout.chomp
+ assert($vm.execute("touch #{dir}/XXX_persist", :user => owner).success?,
"Could not create file in persistent directory #{dir}")
end
end
When /^I remove some files expected to persist$/ do
- next if @skip_steps_while_restoring_background
persistent_mounts.each do |_, dir|
- owner = @vm.execute("stat -c %U #{dir}").stdout.chomp
- assert(@vm.execute("rm #{dir}/XXX_persist", user=owner).success?,
+ owner = $vm.execute("stat -c %U #{dir}").stdout.chomp
+ assert($vm.execute("rm #{dir}/XXX_persist", :user => owner).success?,
"Could not remove file in persistent directory #{dir}")
end
end
When /^I write some files not expected to persist$/ do
- next if @skip_steps_while_restoring_background
persistent_mounts.each do |_, dir|
- owner = @vm.execute("stat -c %U #{dir}").stdout.chomp
- assert(@vm.execute("touch #{dir}/XXX_gone", user=owner).success?,
+ owner = $vm.execute("stat -c %U #{dir}").stdout.chomp
+ assert($vm.execute("touch #{dir}/XXX_gone", :user => owner).success?,
"Could not create file in persistent directory #{dir}")
end
end
-Then /^the expected persistent files are present in the filesystem$/ do
- next if @skip_steps_while_restoring_background
- persistent_mounts.each do |_, dir|
- assert(@vm.execute("test -e #{dir}/XXX_persist").success?,
+When /^I take note of which persistence presets are available$/ do
+ $remembered_persistence_mounts = persistent_mounts
+ $remembered_persistence_dirs = persistent_dirs
+end
+
+Then /^the expected persistent files(| created with the old Tails version) are present in the filesystem$/ do |old_tails|
+ if old_tails.empty?
+ expected_mounts = persistent_mounts
+ else
+ assert_not_nil($remembered_persistence_mounts)
+ expected_mounts = $remembered_persistence_mounts
+ end
+ expected_mounts.each do |_, dir|
+ assert($vm.execute("test -e #{dir}/XXX_persist").success?,
"Could not find expected file in persistent directory #{dir}")
- assert(!@vm.execute("test -e #{dir}/XXX_gone").success?,
+ assert(!$vm.execute("test -e #{dir}/XXX_gone").success?,
"Found file that should not have persisted in persistent directory #{dir}")
end
end
-Then /^only the expected files should persist on USB drive "([^"]+)"$/ do |name|
- next if @skip_steps_while_restoring_background
- step "a computer"
- step "the computer is set to boot from USB drive \"#{name}\""
- step "the network is unplugged"
- step "I start the computer"
- step "the computer boots Tails"
- step "I enable read-only persistence with password \"asdf\""
- step "I log in to a new session"
- step "persistence is enabled"
- step "GNOME has started"
- step "all notifications have disappeared"
- step "the expected persistent files are present in the filesystem"
- step "I shutdown Tails and wait for the computer to power off"
+Then /^only the expected files are present on the persistence partition on USB drive "([^"]+)"$/ do |name|
+ assert(!$vm.is_running?)
+ disk = {
+ :path => $vm.storage.disk_path(name),
+ :opts => {
+ :format => $vm.storage.disk_format(name),
+ :readonly => true
+ }
+ }
+ $vm.storage.guestfs_disk_helper(disk) do |g, disk_handle|
+ partitions = g.part_list(disk_handle).map do |part_desc|
+ disk_handle + part_desc["part_num"].to_s
+ end
+ partition = partitions.find do |part|
+ g.blkid(part)["PART_ENTRY_NAME"] == "TailsData"
+ end
+ assert_not_nil(partition, "Could not find the 'TailsData' partition " \
+ "on disk '#{disk_handle}'")
+ luks_mapping = File.basename(partition) + "_unlocked"
+ g.luks_open(partition, @persistence_password, luks_mapping)
+ luks_dev = "/dev/mapper/#{luks_mapping}"
+ mount_point = "/"
+ g.mount(luks_dev, mount_point)
+ assert_not_nil($remembered_persistence_mounts)
+ $remembered_persistence_mounts.each do |dir, _|
+ # Guestfs::exists may have a bug; if the file exists, 1 is
+ # returned, but if it doesn't exist false is returned. It seems
+ # the translation of C types into Ruby types is glitchy.
+ assert(g.exists("/#{dir}/XXX_persist") == 1,
+ "Could not find expected file in persistent directory #{dir}")
+ assert(g.exists("/#{dir}/XXX_gone") != 1,
+ "Found file that should not have persisted in persistent directory #{dir}")
+ end
+ g.umount(mount_point)
+ g.luks_close(luks_dev)
+ end
end
When /^I delete the persistent partition$/ 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("GnomeApplicationsDeletePersistentVolume.png", 20)
- @screen.wait("PersistenceWizardWindow.png", 40)
+ step 'I start "DeletePersistentVolume" via the GNOME "Tails" applications menu'
@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?,
+ assert($vm.execute("test -d /sys/firmware/efi").success?,
"/sys/firmware/efi does not exist")
end
+
+Given /^I create a ([[:alpha:]]+) label on disk "([^"]+)"$/ do |type, name|
+ $vm.storage.disk_mklabel(name, type)
+end
+
+Then /^a suitable USB device is (?:still )?not found$/ do
+ @screen.wait("TailsInstallerNoQEMUHardDisk.png", 30)
+end
+
+Then /^the "(?:[^"]+)" USB drive is selected$/ do
+ @screen.wait("TailsInstallerQEMUHardDisk.png", 30)
+end
+
+Then /^no USB drive is selected$/ do
+ @screen.wait("TailsInstallerNoQEMUHardDisk.png", 30)
+end