Commit 39592c9e authored by sajolida's avatar sajolida
Browse files

Merge remote-tracking branch 'origin/devel' into doc/15825-remove-mac-dvd

parents 4c9d48f3 e375ad3a
......@@ -53,6 +53,7 @@
/config/chroot_local-includes/usr/share/applications/unlock-veracrypt-volumes.desktop
/config/chroot_local-includes/usr/share/desktop-directories/Tails.directory
/config/chroot_local-includes/usr/share/polkit-1/actions/org.boum.tails.root-terminal.policy
/config/chroot_local-includes/usr/share/polkit-1/actions/org.boum.tails.additional-software.policy
/config/chroot_local-includes/usr/share/unlock-veracrypt-volumes/ui/*.ui
/tmp/
......
......@@ -142,7 +142,8 @@ def _notify_failure(summary, details=None):
log.
"""
if details:
# Translators: Don't translate {details}, it's a placeholder and will be replaced.
# Translators: Don't translate {details}, it's a placeholder and will
# be replaced.
details = _("{details} Please check your list of additional "
"software or read the system log to "
"understand the problem.").format(details=details)
......@@ -216,7 +217,8 @@ def _format_iterable(iterable):
if len(iterable) == 1:
return iterable[0]
elif len(iterable) > 1:
# Translators: Don't translate {beginning} or {last}, they are placeholders and will be replaced.
# Translators: Don't translate {beginning} or {last}, they are
# placeholders and will be replaced.
return _("{beginning} and {last}").format(
beginning=_(", ").join(iterable[:-1]), last=iterable[-1])
else:
......@@ -282,7 +284,8 @@ def handle_installed_packages(packages):
"""
logging.info("New packages manually installed: %s" % packages)
if has_unlocked_persistence(search_new_persistence=True):
# Translators: Don't translate {packages}, it's a placeholder and will be replaced.
# Translators: Don't translate {packages}, it's a placeholder and will
# be replaced.
if _notify(_("Add {packages} to your additional software?").format(
packages=_format_iterable(packages)),
_("To install it automatically from your persistent "
......@@ -311,7 +314,8 @@ def handle_installed_packages(packages):
logging.warning("Warning: persistence storage is locked, can't add "
"additional software.")
elif is_tails_media_writable():
# Translators: Don't translate {packages}, it's a placeholder and will be replaced.
# Translators: Don't translate {packages}, it's a placeholder and will
# be replaced.
if _notify(_("Add {packages} to your additional software?").format(
packages=_format_iterable(packages)),
_("To install it automatically when starting Tails, you "
......@@ -332,7 +336,8 @@ def handle_installed_packages(packages):
logging.warning("Cannot create persistent storage on this media.")
if not os.path.isfile(ASP_STATE_INSTALLER_ASKED):
open(ASP_STATE_INSTALLER_ASKED, 'a').close()
# Translators: Don't translate {packages}, it's a placeholder and will be replaced.
# Translators: Don't translate {packages}, it's a placeholder and
# will be replaced.
_notify(_("You could install {packages} automatically when "
"starting Tails").format(
packages=_format_iterable(packages)),
......@@ -349,10 +354,12 @@ def handle_removed_packages(packages):
actually remove them if requested.
"""
logging.info("Additional packages removed: %s" % packages)
# Translators: Don't translate {packages}, it's a placeholder and will be replaced.
# Translators: Don't translate {packages}, it's a placeholder and will be
# replaced.
if _notify(_("Remove {packages} from your additional software?").format(
packages=_format_iterable(packages)),
# Translators: Don't translate {packages}, it's a placeholder and will be replaced.
# Translators: Don't translate {packages}, it's a placeholder
# and will be replaced.
_("This will stop installing {packages} automatically.").format(
packages=_format_iterable(packages)),
_("Remove"),
......@@ -473,15 +480,17 @@ def apt_hook_post():
os.remove(ASP_STATE_PACKAGES)
additional_packages_names = {
filter_package_details(pkg) for pkg in get_additional_packages(search_new_persistence=True)
filter_package_details(pkg) for pkg in
get_additional_packages(search_new_persistence=True)
}
apt_cache = apt.cache.Cache()
# Filter automatically installed packages and packages already configured
# as additional software
new_manually_installed_packages = {
pkg for pkg in packages["installed"] if not apt_cache[pkg].is_auto_installed and
pkg not in additional_packages_names
pkg for pkg in packages["installed"] if (
not apt_cache[pkg].is_auto_installed and
pkg not in additional_packages_names)
}
if new_manually_installed_packages:
......@@ -493,6 +502,7 @@ def apt_hook_post():
if additional_packages_removed:
handle_removed_packages(additional_packages_removed)
def install_additional_packages(upgrade_mode=False):
"""Subcommand which activates and installs all additional packages.
......
......@@ -8,8 +8,6 @@ whisperback
python3-pyinotify
# contains mkpasswd, needed in chroot_local-hooks/01-password
whois
# needed by getTorBrowserUserAgent
unzip
# needed in chroot_local-includes/etc/NetworkManager/dispatcher.d/50-htp.sh
bind9-host
# needed by tails-security-check
......
--- a/usr/share/xul-ext/torbirdy/install.rdf 2018-08-07 10:48:50.000000000 +0000
+++ b/usr/share/xul-ext/torbirdy/install.rdf 2018-10-22 15:27:09.132000000 +0000
@@ -14,7 +14,7 @@
<Description>
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>52.0</em:minVersion>
- <em:maxVersion>60.0</em:maxVersion>
+ <em:maxVersion>60.*</em:maxVersion>
</Description>
</em:targetApplication>
......@@ -13,10 +13,10 @@ doesn't seem sufficient, even though strace confirms it's being read.
--- a/usr/share/xul-ext/torbirdy/defaults/preferences/prefs.js
+++ b/usr/share/xul-ext/torbirdy/defaults/preferences/prefs.js
@@ -9,6 +9,6 @@
@@ -8,6 +8,6 @@
pref("extensions.torbirdy.gpg_already_torified", false);
pref("extensions.torbirdy.timezone", true);
pref("extensions.torbirdy.whonix_run", true);
pref("extensions.torbirdy.info_run", false);
-pref("extensions.torbirdy.emailwizard", false);
+pref("extensions.torbirdy.emailwizard", true);
pref("extensions.torbirdy.fetchall", false);
......
......@@ -24,4 +24,4 @@ box.
+pref("extensions.torbirdy.gpg_already_torified", true);
pref("extensions.torbirdy.timezone", true);
pref("extensions.torbirdy.whonix_run", true);
pref("extensions.torbirdy.info_run", false);
pref("extensions.torbirdy.emailwizard", true);
......@@ -56,14 +56,16 @@ Given /^the computer is set to boot from (.+?) drive "(.+?)"$/ do |type, name|
$vm.set_disk_boot(name, type.downcase)
end
Given /^I (temporarily )?create an? (\d+) ([[:alpha:]]+) disk named "([^"]+)"$/ do |temporary, size, unit, name|
Given /^I (temporarily )?create an? (\d+) ([[:alpha:]]+) (?:([[:alpha:]]+) )?disk named "([^"]+)"$/ do |temporary, size, unit, type, name|
type ||= "qcow2"
$vm.storage.create_new_disk(name, {:size => size, :unit => unit,
:type => "qcow2"})
:type => type})
add_after_scenario_hook { $vm.storage.delete_volume(name) } if temporary
end
Given /^I plug (.+) drive "([^"]+)"$/ do |bus, name|
$vm.plug_drive(name, bus.downcase)
sleep 1
if $vm.is_running?
step "drive \"#{name}\" is detected by Tails"
end
......@@ -71,7 +73,7 @@ end
Then /^drive "([^"]+)" is detected by Tails$/ do |name|
raise "Tails is not running" unless $vm.is_running?
try_for(10, :msg => "Drive '#{name}' is not detected by Tails") do
try_for(20, :msg => "Drive '#{name}' is not detected by Tails") do
$vm.disk_detected?(name)
end
end
......@@ -673,7 +675,13 @@ Given /^I start "([^"]+)" via GNOME Activities Overview$/ do |app_name|
@screen.wait('GnomeApplicationsMenu.png', 10)
$vm.execute_successfully('xdotool key Super', user: LIVE_USER)
@screen.wait('GnomeActivitiesOverview.png', 10)
@screen.type(app_name)
# Trigger startup of search providers
@screen.type(app_name[0])
# Give search providers some time to start (#13469#note-5) otherwise
# our search sometimes returns no results at all.
sleep 1
# Type the rest of the search query
@screen.type(app_name[1..-1])
@screen.type(Sikuli::Key.ENTER, Sikuli::KeyModifier.CTRL)
end
......@@ -927,8 +935,8 @@ def share_host_files(files)
files = [files] if files.class == String
assert_equal(Array, files.class)
disk_size = files.map { |f| File.new(f).size } .inject(0, :+)
# Let's add some extra space for filesysten overhead etc.
disk_size += [convert_to_bytes(1, 'MiB'), (disk_size * 0.10).ceil].max
# Let's add some extra space for filesystem overhead etc.
disk_size += [convert_to_bytes(1, 'MiB'), (disk_size * 0.15).ceil].max
disk = random_alpha_string(10)
step "I temporarily create an #{disk_size} bytes disk named \"#{disk}\""
step "I create a gpt partition labeled \"#{disk}\" with an ext4 " +
......
# coding: utf-8
require 'expect'
require 'pty'
require 'tempfile'
$veracrypt_passphrase = 'asdf'
$veracrypt_hidden_passphrase = 'fdsa'
$veracrypt_volume_name = 'veracrypt'
def veracrypt_volume_size_in_GNOME(is_hidden)
is_hidden ? '52 MB' : '105 MB'
end
def create_veracrypt_keyfile()
keyfile = Tempfile.new('veracrypt-keyfile', $config["TMPDIR"])
keyfile << 'asdf'
keyfile.close
return keyfile.path
end
def reply_prompt(r_f, w_f, prompt_re, answer)
r_f.expect(prompt_re) do
debug_log "got prompt, typing #{answer}"
sleep 1 # tcplay takes some time before it's ready to read our input
w_f.puts "#{answer}"
end
end
def create_veracrypt_volume(type, with_keyfile)
@veracrypt_is_hidden = (type == 'hidden')
@veracrypt_needs_keyfile = with_keyfile
step "I temporarily create a 100 MiB raw disk named \"#{$veracrypt_volume_name}\""
disk_path = $vm.storage.disk_path($veracrypt_volume_name)
keyfile = create_veracrypt_keyfile()
fatal_system "losetup -f '#{disk_path}'"
loop_dev = `losetup -j '#{disk_path}'`.split(':').first
tcplay_create_cmd = "tcplay --create --device='#{loop_dev}'" \
+ " --weak-keys --insecure-erase"
tcplay_create_cmd += " --hidden" if @veracrypt_is_hidden
tcplay_create_cmd += " --keyfile='#{keyfile}'" if @veracrypt_needs_keyfile
debug_log "tcplay create command: #{tcplay_create_cmd}"
PTY.spawn(tcplay_create_cmd) do |r_f, w_f, pid|
begin
w_f.sync = true
reply_prompt(r_f, w_f, /^Passphrase:\s/, $veracrypt_passphrase)
reply_prompt(r_f, w_f, /^Repeat passphrase:\s/, $veracrypt_passphrase)
if @veracrypt_is_hidden
reply_prompt(r_f, w_f, /^Passphrase for hidden volume:\s/,
$veracrypt_hidden_passphrase)
reply_prompt(r_f, w_f, /^Repeat passphrase:\s/,
$veracrypt_hidden_passphrase)
reply_prompt(r_f, w_f, /^Size of hidden volume.*:\s/, '50M')
end
reply_prompt(r_f, w_f, /^\s*Are you sure you want to proceed/, 'y')
r_f.expect(/^All done!/)
rescue Errno::EIO
ensure
Process.wait pid
end
$?.exitstatus == 0 or raise "#{tcplay_create_cmd} exited with #{$?.exitstatus}"
end
tcplay_map_cmd = "tcplay --map=veracrypt --device='#{loop_dev}'"
tcplay_map_cmd += " --keyfile='#{keyfile}'" if @veracrypt_needs_keyfile
debug_log "tcplay map command: #{tcplay_map_cmd}"
PTY.spawn(tcplay_map_cmd) do |r_f, w_f, pid|
begin
w_f.sync = true
reply_prompt(r_f, w_f, /^Passphrase:\s/,
@veracrypt_is_hidden ? $veracrypt_hidden_passphrase : $veracrypt_passphrase)
r_f.expect(/^All ok!/)
rescue Errno::EIO
ensure
Process.wait pid
end
$?.exitstatus == 0 or raise "#{tcplay_map_cmd} exited with #{$?.exitstatus}"
end
fatal_system "mkfs.vfat '/dev/mapper/veracrypt' >/dev/null"
Dir.mktmpdir('veracrypt-mountpoint', $config["TMPDIR"]) { |mountpoint|
fatal_system "mount -t vfat '/dev/mapper/veracrypt' '#{mountpoint}'"
# must match SecretFileOnVeraCryptVolume.png when displayed in GNOME Files
FileUtils.cp('/usr/share/common-licenses/GPL-3', "#{mountpoint}/SecretFile")
fatal_system "umount '#{mountpoint}'"
}
fatal_system "tcplay --unmap=veracrypt"
fatal_system "losetup -d '#{loop_dev}'"
File.delete(keyfile)
end
When /^I plug a USB drive containing a (.+) VeraCrypt volume( with a keyfile)?$/ do |type, with_keyfile|
create_veracrypt_volume(type, with_keyfile)
step "I plug USB drive \"#{$veracrypt_volume_name}\""
end
When /^I plug and mount a USB drive containing a (.+) VeraCrypt file container( with a keyfile)?$/ do |type, with_keyfile|
create_veracrypt_volume(type, with_keyfile)
@veracrypt_shared_dir_in_guest = share_host_files($vm.storage.disk_path($veracrypt_volume_name))
$vm.execute_successfully(
"chown #{LIVE_USER}:#{LIVE_USER} '#{@veracrypt_shared_dir_in_guest}/#{$veracrypt_volume_name}'"
)
end
When /^I unlock and mount this VeraCrypt (volume|file container) with Unlock VeraCrypt Volumes$/ do |support|
step 'I start "Unlock VeraCrypt Volumes" via GNOME Activities Overview'
case support
when 'volume'
@screen.wait_and_click('Gtk3UnlockButton.png', 10)
when 'file container'
@screen.wait_and_click('UnlockVeraCryptVolumesAddButton.png', 10)
@screen.wait('Gtk3FileChooserDesktopButton.png', 10)
@screen.type(@veracrypt_shared_dir_in_guest + '/' + $veracrypt_volume_name + Sikuli::Key.ENTER)
end
@screen.wait('VeraCryptUnlockDialog.png', 10)
@screen.type(
@veracrypt_is_hidden ? $veracrypt_hidden_passphrase : $veracrypt_passphrase
)
@screen.click('VeraCryptUnlockDialogHiddenVolumeLabel.png') if @veracrypt_is_hidden
@screen.type(Sikuli::Key.ENTER)
@screen.waitVanish('VeraCryptUnlockDialog.png', 10)
try_for(30) do
$vm.execute_successfully('ls /media/amnesia/*/SecretFile')
end
end
When /^I unlock and mount this VeraCrypt (volume|file container) with GNOME Disks$/ do |support|
step 'I start "Disks" via GNOME Activities Overview'
disks = Dogtail::Application.new('gnome-disks')
case support
when 'volume'
disks.children(roleName: 'table cell').find { |row|
/^105 MB Drive/.match(row.name)
}.grabFocus
when 'file container'
gnome_shell = Dogtail::Application.new('gnome-shell')
menu = gnome_shell.menu('Disks')
menu.click()
@screen.wait_and_click('GnomeDisksAttachDiskImageMenuEntry.png', 10)
# Once we use a more recent Dogtail that can deal with UTF-8 (#12185),
# we can instead do:
# gnome_shell.child('Attach Disk Image…', roleName: 'label').click
# Otherwise Disks is sometimes minimized, for some reason I don't understand
sleep 2
attach_dialog = disks.child('Select Disk Image to Attach', roleName: 'file chooser', showingOnly: true)
attach_dialog.child('Set up read-only loop device', roleName: 'check box').click
filter = attach_dialog.child('Disk Images (*.img, *.iso)', roleName: 'combo box')
filter.click
try_for(5) do
begin
filter.child('All Files', roleName: 'menu item').click
true
rescue RuntimeError
# we probably clicked too early, which triggered an "Attempting
# to generate a mouse event at negative coordinates" Dogtail error
false
end
end
@screen.type(@veracrypt_shared_dir_in_guest + '/' + $veracrypt_volume_name)
sleep 2 # avoid ENTER being eaten by the auto-completion system
@screen.type(Sikuli::Key.ENTER)
try_for(15) do
begin
disks.children(roleName: 'table cell').find { |row|
/^105 MB Loop Device/.match(row.name)
}.grabFocus
true
rescue NoMethodError
false
end
end
end
disks.child('', roleName: 'panel', description: 'Unlock selected encrypted partition').click
unlock_dialog = disks.dialog('Set options to unlock')
passphrase_field = unlock_dialog.child('', roleName: 'password text')
passphrase_field.grabFocus()
passphrase_field.typeText(
@veracrypt_is_hidden ? $veracrypt_hidden_passphrase : $veracrypt_passphrase
)
if @veracrypt_needs_keyfile
# not accessible and unreachable with the keyboard (#15952)
@screen.click('GnomeDisksUnlockDialogKeyfileComboBox.png')
@screen.wait('Gtk3FileChooserDesktopButton.png', 10)
$vm.file_overwrite('/tmp/keyfile', 'asdf')
@screen.type('/tmp/keyfile' + Sikuli::Key.ENTER)
@screen.waitVanish('Gtk3FileChooserDesktopButton.png', 10)
end
@screen.wait_and_click('GnomeDisksUnlockDialogHiddenVolumeLabel.png', 10) if @veracrypt_is_hidden
# Clicking is robust neither with Dogtail (no visible effect) nor with Sikuli
# (that sometimes clicks just a little bit outside of the button)
@screen.wait('Gtk3UnlockButton.png', 10)
@screen.type('u', Sikuli::KeyModifier.ALT) # "Unlock" button
try_for(10, :msg => "Failed to mount the unlocked volume") do
begin
unlocked_volume = disks.child('105 MB VeraCrypt/TrueCrypt', roleName: 'panel', showingOnly: true)
unlocked_volume.click
# Move the focus down to the "Filesystem\n107 MB FAT" item (that Dogtail
# is not able to find) using the 'Down' arrow, in order to display
# the "Mount selected partition" button.
unlocked_volume.grabFocus()
sleep 0.5 # otherwise the following key press is sometimes lost
disks.pressKey('Down')
disks.child('', roleName: 'panel', description: 'Mount selected partition', showingOnly: true).click
true
rescue RuntimeError
# we probably did something too early, which triggered a Dogtail error
# such as "Attempting to generate a mouse event at negative coordinates"
false
end
end
try_for(10, :msg => "/media/amnesia/*/SecretFile does not exist") do
$vm.execute_successfully('ls /media/amnesia/*/SecretFile')
end
end
When /^I open this VeraCrypt volume in GNOME Files$/ do
$vm.spawn('nautilus /media/amnesia/*', user: LIVE_USER)
Dogtail::Application.new('nautilus').window(
veracrypt_volume_size_in_GNOME(@veracrypt_is_hidden) + ' Volume'
)
end
When /^I lock the currently opened VeraCrypt (volume|file container)$/ do |support|
$vm.execute_successfully(
'udisksctl unmount --block-device /dev/mapper/tcrypt-*',
:user => LIVE_USER
)
device = support == 'volume' ? '/dev/sda' : '/dev/loop1'
$vm.execute_successfully(
"udisksctl lock --block-device #{device}",
:user => LIVE_USER
)
end
Then /^the VeraCrypt (volume|file container) has been unmounted and locked$/ do |support|
assert(! $vm.execute('ls /media/amnesia/*/SecretFile').success?)
assert(! $vm.execute('ls /dev/mapper/tcrypt-*').success?)
end
......@@ -13,6 +13,7 @@ module Dogtail
:dialog,
:menu,
:menuItem,
:panel,
:tab,
:textentry,
]
......@@ -61,6 +62,7 @@ module Dogtail
"import dogtail.config",
"import dogtail.tree",
"import dogtail.predicate",
"import dogtail.rawinput",
"dogtail.config.logDebugToFile = False",
"dogtail.config.logDebugToStdOut = False",
"dogtail.config.blinkOnActions = True",
......@@ -186,6 +188,16 @@ module Dogtail
get_field('roleName')
end
# Note: this is a global Dogtail action, which should probably live
# elsewhere than in our Application class, but currently we lack
# the infrastructure to do that: the Ruby plumbing that generates
# and runs Python code lives in the Application class.
def pressKey(key)
# Dogtail will prefix the value of key with 'KEY_'
# and the result must be a valid Gdk key symbol such as Gdk.KEY_Down
run("dogtail.rawinput.pressKey('#{key}')")
end
TREE_API_APP_SEARCHES.each do |method|
define_method(method) do |*args|
args_str = self.class.args_to_s(args)
......
......@@ -156,6 +156,7 @@ def sikuli_screen_proxy.new(*args)
begin
return findfailed_hook(self, orig_method, args)
rescue FindFailedHookFailure
debug_log("FindFailedHookFailure was raised, re-running the failing Sikuli method.")
# Due to bugs in rjb we cannot re-throw Java exceptions,
# which is what we want now. Instead we have to resort to
# a hack: let's re-run the failing Sikuli method to
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment