Commit a728286b authored by intrigeri's avatar intrigeri
Browse files

Merge remote-tracking branch 'origin/stable' into test/9897-unsafe-browser-langs

parents 552c4196 4fd56700
This diff is collapsed.
......@@ -5,11 +5,29 @@ set -e
echo "Configuring I2P"
# This must be set in order for the i2p init script to work
sed -i 's/^RUN_DAEMON=.*$/RUN_DAEMON="true"/' /etc/default/i2p
# Remove the "i2prouter" script, its man page, and its apparmor profile
# since these are not used by Tails:
rm /etc/apparmor.d/usr.bin.i2prouter /usr/share/man/man1/i2prouter.1.gz
# Install custom i2prouter stub scripts
for script in ${I2PROUTER} ${I2PROUTER}-nowrapper; do
echo "Removing $script"
dpkg-divert --rename --add "${script}"
cat > "$script" << EOF
echo "This script is not used by Tails."
echo "See for more information."
exit 0
chmod 755 "$script"
# Remove the outproxy from the tunnel on port 4444
# This will remove the following lines:
# tunnel.0.proxyList=false.i2p
......@@ -48,3 +66,7 @@ EOF
cat > "$I2P/susimail.config" << EOF
# enforce apparmor
echo Setting the I2P apparmor profile to enforce mode
sed -i -re 's|flags=\(complain\)||' /etc/apparmor.d/system_i2p
......@@ -33,7 +33,7 @@ install_torbrowser_AppArmor_profile() {
tmpdir="$(mktemp -d)"
cd "$tmpdir"
apt-get source torbrowser-launcher/testing
apt-get source torbrowser-launcher/sid
install -m 0644 \
torbrowser-launcher-*/apparmor/torbrowser.Browser.firefox \
......@@ -93,3 +93,7 @@ pref("browser.newtabpage.introShown", true);
// add-on localizes search-engines in an incompatible but equivalent
// way.
pref("", false);
// Without setting this, the Download Management page will not update
// the progress being made.
pref("", true);
......@@ -41,24 +41,6 @@ tor_has_bootstrapped() {
sudo -n -u debian-tor /usr/local/sbin/tor-has-bootstrapped
# Workaround bug #8036 by copying any localized search plugins into
# the profile.
enable_localized_searchplugins() {
local locale plugin
locale=$(cat "${PROFILE}"/preferences/0000locale.js | \
sed 's@^pref("general\.useragent\.locale", "\([^"]*\)");$@\1@')
if [ "${locale}" = en-US ] || [ -e "${PROFILE}"/searchplugins ]; then
# Fallback to a similar locale if there is no exact match
plugin="$(ls -1 "${TBB_INSTALL}"/distribution/searchplugins/locale/ | grep -m1 "^${locale}\(-[A-Z]\+\)\?$" || true)"
if [ -n "${plugin}" ]; then
mkdir -p "${PROFILE}"/searchplugins
# The plugins do not load if they are symlinks
cp --dereference "${TBB_INSTALL}"/distribution/searchplugins/locale/"${plugin}"/* "${PROFILE}"/searchplugins
start_browser() {
if [ ! -d "${PROFILE}" ]; then
......@@ -68,11 +50,11 @@ start_browser() {
mkdir --mode=0700 -p "$TMPDIR"
export TMPDIR
# We need to set general.useragent.locale properly to get
# localized search plugins (and perhaps other things too). It is
# not enough to simply set intl.locale.matchOS to true.
configure_best_tor_browser_locale "${PROFILE}"
# Workaround bug #8036
if [ -z "$XAUTHORITY" ]; then
......@@ -41,13 +41,13 @@ wait_until_i2p_router_console_is_ready() {
notify_router_console_success() {
/usr/local/sbin/tails-notify-user \
"`gettext \"I2P's router console is ready\"`" \
"`gettext \"You can now access I2P's router console on\"`"
"`gettext \"You can now access I2P's router console in the I2P Browser.\"`"
bootstrap_failure() {
/usr/local/sbin/tails-notify-user \
"`gettext \"I2P is not ready\"`" \
"`gettext \"Eepsite tunnel not built within six minutes. Check the router console at or the logs in /var/log/i2p for more information. Reconnect to the network to try again.\"`"
"`gettext \"Eepsite tunnel not built within six minutes. Check the router console in the I2P Browser or the logs in /var/log/i2p for more information. Reconnect to the network to try again.\"`"
exit 1
......@@ -61,9 +61,15 @@ while(my $sl = $parser->next) {
# The beginning of *all* (not only wireless) new
# connections. We drop any previous state so it won't
# interfere.
$state{$1} = undef;
} elsif ($text =~ /\(([^)]+)\): supplicant connection state:.*-> (.*)$/) {
# Wireless connection state transition.
$state{$1} = "";
} elsif ($text =~ /\(([^)]+)\): supplicant (?:connection|interface) state: \S+ -> (\S+)/ ||
$text =~ /\(([^)]+)\): device state change: \S+ -> (\S+)/) {
# NetworkManager logs state transitions with the above
# messages, but the really important part is that we
# accurately log the state changes *to* and *from*
# "associating" (for the next case). Hence the safest bet
# seems to be to deal with all observed types of transitions
# that NetworkManager logs.
$state{$1} = $2;
} elsif ($text =~ /Activation \(([^)]+)\/[^)]*\): association took too long/) {
# Wireless connection failure. If it happens during
......@@ -14,6 +14,14 @@ set -e
disable_networking() {
service network-manager stop || :
for f in /etc/init.d/network-manager /usr/sbin/NetworkManager; do
[ -e "${f}" ] && mv "${f}" "${f}.disabled"
log "Networking disabled"
show_notification() {
# We must wait until all the facilities necessary for showing the
# notification to the Live user is available to prevent it from
......@@ -63,8 +71,8 @@ mac_spoof_panic() {
echo "blacklist ${module}" >> /etc/modprobe.d/"${module}"-blacklist.conf
unload_module_and_rev_deps "${module}" || :
if nic_exists "${nic}"; then
log "Failed to unload module ${module} of NIC ${nic}. Stopping NetworkManager."
service network-manager stop
log "Failed to unload module ${module} of NIC ${nic}"
notify_panic_failure "${nic}" "${nic_name}" &
log "Successfully unloaded module ${module} of NIC ${nic}."
......@@ -130,8 +138,8 @@ then
# If mac_spoof_panic() fails we're quite screwed, so we kill
# NetworkManager without notification to do our best to
# prevent a MAC address leak.
log "Panic mode failed for NIC ${NIC}. Killing NetworkManager."
service network-manager stop
log "Panic mode failed for NIC ${NIC}"
exit 1
......@@ -19,4 +19,10 @@ rm -f "${BLACKLIST}"
# if NM wins, the udev trigger's run of tails-spoof-mac will fail.
/sbin/udevadm settle
service network-manager start
# If tails-spoof-mac goes into panic mode but fails to disable the
# problematic device, networking will be disabled by having these
# removed.
if [ -e "/etc/init.d/network-manager" ] && \
[ -e "/usr/sbin/NetworkManager" ]; then
service network-manager start
......@@ -22,3 +22,10 @@ pref("", "");
pref("", "");
// ... and disable the explanation shown the first time
pref("browser.newtabpage.introShown", true);
// Without setting this, the Download Management page will not update
// the progress being made.
pref("", true);
// Never add 'www' or '.com' to hostnames in I2P Browser.
pref("browser.fixup.alternate.enabled", false);
675fd2c364c2fae7bcd10d5e814b63fb539674019053fc2e003f7c3fdc4c967a tor-browser-linux32-5.0.2_ar.tar.xz
7812523197fee6f1b10057d49f670df1d6a15a7a3eee52ebe47f7d6741e27567 tor-browser-linux32-5.0.2_de.tar.xz
e683f839c2e4b001403347200c786e8115e17a521936644455454b3e24023cb1 tor-browser-linux32-5.0.2_en-US.tar.xz
bad8efb9272b82e296fee1a400207b521be39a39229d5b69d7fc023ffb3d95c9 tor-browser-linux32-5.0.2_es-ES.tar.xz
9e9d67541b6a92edca0e304baba1859402e4c485a0d4f3601f3280167f0c4dd8 tor-browser-linux32-5.0.2_fa.tar.xz
7537dc1f14f2ac141d2f98d64d6138c6316ba6a3c3b6aaf3823393582af088a8 tor-browser-linux32-5.0.2_fr.tar.xz
ca8f95a0991af6381d1b14cbd65fa8dd86a04c722e7a4b361c489cef5f38e224 tor-browser-linux32-5.0.2_it.tar.xz
aff6ad9c2758a182d46425c287fd3a34f13c879cf58aa13d28b3b7867f36f7fd tor-browser-linux32-5.0.2_ko.tar.xz
0e86be84432a278f2fec7d24b5d796bada28860c1b9ca8bbd074e29db7b5699a tor-browser-linux32-5.0.2_nl.tar.xz
594b9280a9f9f72c6ddce2d9823e0a37dd6cb35ffbb24990b7c3e778f0eed707 tor-browser-linux32-5.0.2_pl.tar.xz
0efdd680b2ae3dc7703440e8d9c2f31d91f02dcf12441a8abb8fb01cf745b437 tor-browser-linux32-5.0.2_pt-PT.tar.xz
733b8005cd8d4d658e7aaffea523908ed081fe899b24fe8eb3a1771942235297 tor-browser-linux32-5.0.2_ru.tar.xz
db737ed3339a87142d6d5e2725038c9140017443d0c51e8562557e599adfaaac tor-browser-linux32-5.0.2_tr.tar.xz
f4a692f82ead892f61fa3e4da1b514fe9bbd390a154090d432060f750306f6ef tor-browser-linux32-5.0.2_vi.tar.xz
545037f2567e1c38530b87b588092c48bffd37f79dc735dd6c6cf646e8efce7b tor-browser-linux32-5.0.2_zh-CN.tar.xz
42169e9c727e10b3e376ba260a3a143a6309c7316ec667e69fa74d401d4d7c4c tor-browser-linux32-5.0.3_ar.tar.xz
b5f56d37ea5a93a8c5f45f85d610da23cb768e8ccd2f0562b0f65a00e0937379 tor-browser-linux32-5.0.3_de.tar.xz
0e94498cb83a07895bf8becf76d3c3b071d8cfadd50048971f701819f80a56aa tor-browser-linux32-5.0.3_en-US.tar.xz
e6382d5b2cbf8db45fb02388a85e953f236b486bf4146396d6521e9f5ed20a13 tor-browser-linux32-5.0.3_es-ES.tar.xz
5666669aaeb695045a9263775d108a9fbe04899d3ef70aa27906a58245d713f4 tor-browser-linux32-5.0.3_fa.tar.xz
e8d667bd356185ee1a4a51ad14f75a2a338ca49a2e56697a8f3f74f7bb8ac04c tor-browser-linux32-5.0.3_fr.tar.xz
1cc8f0488c2b2f851eb7d7a5412a7ade130e2a9db769b87f5889146673034d6d tor-browser-linux32-5.0.3_it.tar.xz
fccf7493864ef2eba80368f8c98e6463be2f97b36392a84c29609c8be174ecfa tor-browser-linux32-5.0.3_ko.tar.xz
dc577b97aeba0b095a2d49df23893bdfdf0f8b8f36207ab97d4e59103b67728b tor-browser-linux32-5.0.3_nl.tar.xz
a022dd5e3d0aebba1f4f67e327e292b72d042a102806943c9693adf0692f63f8 tor-browser-linux32-5.0.3_pl.tar.xz
34c278bfd818a8d29f36bfcebbd1a77276ef61918f107540ce5b9caf4712cd0f tor-browser-linux32-5.0.3_pt-PT.tar.xz
c1391ded41dc3c59adb6fb0286c5262b962ccb12a062c2300d1da5fdea103b46 tor-browser-linux32-5.0.3_ru.tar.xz
44bdcd53aaefc894f8556258b42fadc5fd10458db01f568734a47a9f6d070e5c tor-browser-linux32-5.0.3_tr.tar.xz
87e08f755d3551e9ef3086695d0a976e0ea9be0ff5c88833e5bedb057f64280e tor-browser-linux32-5.0.3_vi.tar.xz
f1d5a0084d06e838a5acfe4352995c40c54ac4488006acb014ab7cf81360f62e tor-browser-linux32-5.0.3_zh-CN.tar.xz
......@@ -32,3 +32,7 @@ pref("browser.newtabpage.introShown", true);
// add-on localizes search-engines in an incompatible but equivalent
// way.
pref("", false);
// Without setting this, the Download Management page will not update
// the progress being made.
pref("", true);
tails (1.6) UNRELEASED; urgency=medium
tails (1.6) unstable; urgency=medium
* Dummy changelog entry.
* Security fixes
- Upgrade Tor Browser to 5.0.3. (Closes: #10223)
- Upgrade bind9-based packages to 1:9.8.4.dfsg.P1-6+nmu2+deb7u7.
- Upgrade liblcms1 to 1.19.dfsg2-1.2+deb7u1.
- Upgrade libldap-2.4-2 to 2.4.31-2+deb7u1.
- Upgrade libslp1 to 1.2.1-9+deb7u1.
- Upgrade ssl-cert to 1.0.32+deb7u1.
* Bugfixes
- Fix a corner case for the MAC spoofing panic mode. If panic mode
failed to disable the specific device that couldn't be spoofed
(by unloading the module) we disable networking. Previously we
only stopped NetworkManager. The problem is that NM isn't even
started at this time, but will specifically be started when
we're done with MAC spoofing. Therefore, let's completely
disable NetworkManager so it cannot possibly be
started. (Closes: #10160)
- Avoid use of uninitialized value in restricted-network-detector.
If NetworkManager decides that a wireless connection has timed
out before "supplicant connection state" has occued, our idea of
the state is `undef`, so it cannot be used in a string
comparison. Hence, let's initialize the state to the empty
string instead of `undef`. Also fix the state
recording. Apparently NetworkManager can say a few different
things when it logs the device state transitions. (Closes:
-- anonym <> Fri, 28 Aug 2015 13:32:45 +0200
* Minor improvements
- Remove workaround for localizing search engine plugins. The
workaround has recently become unnecessary, possibly due to the
changes made for the seach bar after the Tor Browser was rebased
on Firefox 38esr. (Closes: #9146)
- Refer to the I2P Browser in the I2P notifications. Instead of
some obscure links that won't work in the Tor Browser, where
users likely will try them, and which I believe will open them
by default. (Closes: #10182)
- Upgrade I2P to 0.9.22. Also set the I2P apparmor profile to
enforce mode. (Closes: #9830)
* Test suite
- Test that udev-watchdog is monitoring the correct device when
booted from USB. (Closes: #9890)
- Remove unused 'gksu' step. This causes a false-positive to be
found for #5330. (Closes: #9877)
- Make --capture capture individual videos for failed scenarios
only, and --capture-all to capture videos for all scenarios.
(Closes: #10148)
- Use the more efficient x264 encoding when capturing videos using
the --capture* options. (Closes: #10001)
- Make --old-iso default to --iso if omitted. Using the same ISO
for the USB upgrade tests most often still does what we want,
e.g. test that the current version of Tails being tested has a
working Tails installer. Hence this seems like a reasonable
default. (Closes: #10147)
- Avoid nested FindFailed exceptions in waitAny()/findAny(), and
throw a new dedicated FindAnyFailed exception if these fail
instead. Rjb::throw doesn't block Ruby's execution until the
Java exception has been received by Ruby, so strange things can
happen and we must avoid it. (Closes: #9633)
- Fix the Download Management page in our browsers. Without the pref set, the progress being made
will not update until after the browser has been restarted.
(Closes: #8159)
- Add a 'pretty_debug' (with an alias: 'debug') Cucumber formatter
that deals with debugging instead of printing it to STDERR via
the `--debug` option (which now has been removed). This gives us
the full flexibility of Cucumber's formatter system, e.g. one
easy-to-read formatter can print to the terminal, while we get
the full debug log printed to a file. (Closes: #9491)
- Import logging module in Our does not use
logging but the jabberbot library makes logging calls, causing a
one-off message “No handlers could be found for logger
"jabberbot"” to be printed to the console. This commit
effectively prevents logging/outputting anything to the terminal
which is at a level lower than CRITICAL. (Closes: 9375)
- Force new Tor circuit and reload web site on browser
timeouts. (Closes: #10116)
- Focus Pidgin's buddy list before trying to access the tools
menu. (Closes: #10217)
- Optimize IRC test using waitAny. If connecting to IRC fails,
such as when OFTC is blocking Tor, waiting 60 seconds to connect
while a a Reconnect button is visible is sub-optimal. It would
be better to try forcing a new Tor circuit and clicking the
reconnect button. (Closes: #9653)
- Wait for (and focus if necessary) Pidgin's Certificate windows.
(Closes: #10222)
-- Tails developers <> Sun, 20 Sep 2015 17:47:26 +0000
tails (1.5.1) unstable; urgency=medium
DEBUG: false
CAPTURE: false
......@@ -3,6 +3,7 @@ import sys
import jabberbot
import xmpp
import potr
import logging
from argparse import ArgumentParser
class OtrContext(potr.context.Context):
......@@ -51,9 +52,11 @@ class OtrBot(jabberbot.JabberBot):
def __init__(self, account, password, otr_key_path, connect_server = None):
def __init__(self, account, password, otr_key_path,
connect_server = None, log_file = None):
self.__connect_server = connect_server
self.__password = password
self.__log_file = log_file
super(OtrBot, self).__init__(account, password)
self.__otr_manager = OtrContextManager(account, otr_key_path)
self.send_raw_message_fn = super(OtrBot, self).send_message
......@@ -71,6 +74,8 @@ class OtrBot(jabberbot.JabberBot):
# completely (copy-paste mostly) in order to add support for using
# an XMPP "Connect Server".
def connect(self):
logging.basicConfig(filename = self.__log_file,
level = logging.DEBUG)
if not self.conn:
conn = xmpp.Client(self.jid.getDomain(), debug=[])
if self.__connect_server:
......@@ -185,10 +190,14 @@ if __name__ == '__main__':
"(port defaults to 5222)")
parser.add_argument("-j", "--auto-join", nargs = '+', metavar = 'ROOMS',
help = "auto-join multi-user chatrooms on start")
parser.add_argument("-l", "--log-file", metavar = 'LOGFILE',
help = "Log to file instead of stderr")
args = parser.parse_args()
otr_bot_opt_args = dict()
if args.connect_server:
otr_bot_opt_args["connect_server"] = args.connect_server
if args.log_file:
otr_bot_opt_args["log_file"] = args.log_file
otr_bot = OtrBot(args.account, args.password, args.otr_key_path,
if args.auto_join:
......@@ -7,7 +7,8 @@ rescue LoadError => e
raise "This script must be run from within Tails' Git directory."
$config =
$config["DEBUG"] = false
def debug_log(*args) ; end
class FakeVM
def get_remote_shell_port
......@@ -110,13 +110,9 @@ end
Then /^drive "([^"]+)" is detected by Tails$/ do |name|
next if @skip_steps_while_restoring_background
if @vm.is_running?
try_for(10, :msg => "Drive '#{name}' is not detected by Tails") {
STDERR.puts "Cannot tell if drive '#{name}' is detected by Tails: " +
"Tails is not running"
raise "Tails is not running" unless @vm.is_running?
try_for(10, :msg => "Drive '#{name}' is not detected by Tails") do
......@@ -643,9 +639,22 @@ When /^I open the address "([^"]*)" in the (.*)$/ do |address, browser|
next if @skip_steps_while_restoring_background
step "I open a new tab in the #{browser}"
info = xul_application_info(browser)[:address_bar_image])
sleep 0.5
@screen.type(address + Sikuli::Key.ENTER)
open_address = do[:address_bar_image])
sleep 0.5
@screen.type(address + Sikuli::Key.ENTER)
if browser == "Tor Browser"
recovery_on_failure = do
@screen.waitVanish('BrowserReloadButton.png', 3)
retry_tor(recovery_on_failure) do
@screen.wait('BrowserReloadButton.png', 120)
Then /^the (.*) has no plugins installed$/ do |browser|
......@@ -1065,16 +1074,13 @@ When /^I open a page on the LAN web server in the (.*)$/ do |browser|
def force_new_tor_circuit(with_vidalia=nil)
assert(!@new_circuit_tries.nil? && @new_circuit_tries >= 0,
'@new_circuit_tries was not initialized before it was used')
@new_circuit_tries += 1
STDERR.puts "Forcing new Tor circuit... (attempt ##{@new_circuit_tries})" if $config["DEBUG"]
debug_log("Forcing new Tor circuit...")
if with_vidalia
assert_equal('gnome', @theme, "Vidalia is not available in the #{@theme} theme.")
step 'process "vidalia" is running'
rescue Test::Unit::AssertionFailedError
STDERR.puts "Vidalia was not running. Attempting to start Vidalia..." if $config["DEBUG"]
debug_log("Vidalia was not running. Attempting to start Vidalia...")
step 'process "vidalia" is running within 15 seconds'
......@@ -1151,6 +1157,5 @@ end
Then /^I force Tor to use a new circuit( in Vidalia)?$/ do |with_vidalia|
next if @skip_steps_while_restoring_background
@new_circuit_tries = 1 if @new_circuit_tries.nil?
......@@ -140,18 +140,19 @@ Given /^I fill the guest's memory with a known pattern(| without verifying)$/ do
@vm.pidof("fillram").each do |pid|
@vm.execute_successfully("echo 15 > /proc/#{pid}/oom_adj")
STDERR.print "Memory fill progress: "
ram_usage = ""
remove_chars = 0
prev_used_ram_ratio = -1
# ... and that it finishes
try_for(instances*2*60, { :msg => "fillram didn't complete, probably the VM crashed" }) do
used_ram = used_ram_in_MiB
remove_chars = ram_usage.size
ram_usage = "%3d%% " % ((used_ram.to_f/@detected_ram_m)*100)
STDERR.print "\b"*remove_chars + ram_usage
used_ram_ratio = (used_ram_in_MiB.to_f/@detected_ram_m)*100
# Round down to closest multiple of 10 to limit the logging a bit.
used_ram_ratio = (used_ram_ratio/10).round*10
if used_ram_ratio - prev_used_ram_ratio >= 10
debug_log("Memory fill progress: %3d%%" % used_ram_ratio)
prev_used_ram_ratio = used_ram_ratio
! @vm.has_process?("fillram")
STDERR.print "\b"*remove_chars + "finished.\n"
debug_log("Memory fill progress: finished")
if verify
coverage = pattern_coverage_in_guest_ram()
# Let's aim for having the pattern cover at least 80% of the free RAM.
......@@ -18,19 +18,20 @@ EOF
return account
def wait_and_focus(img, time = 10, window)
@screen.wait(img, time)
rescue FindFailed
@screen.wait(img, time)
def focus_pidgin_irc_conversation_window(account)
account = account.sub(/^irc\./, '')
def close_pidgin_conversation_window(account)
@screen.type(Sikuli::Key.F4, Sikuli::KeyModifier.ALT)
if @screen.exists('PidginConfirmationIcon.png')'GnomeCloseButton.png')
When /^I create my XMPP account$/ do
next if @skip_steps_while_restoring_background
account = xmpp_account("Tails_account")
......@@ -296,9 +297,11 @@ 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), 'roster')
@new_circuit_tries = 0
until @new_circuit_tries == $config["MAX_NEW_TOR_CIRCUIT_RETRIES"] do
# Sometimes the OFTC welcome notice window pops up over the buddy list one...
reconnect_button = 'PidginReconnect.png'
recovery_on_failure = do
@screen.wait_and_click(reconnect_button, 20)
retry_tor(recovery_on_failure) do
@vm.focus_window('Buddy List')
rescue ExecutionFailedInVM
......@@ -307,17 +310,11 @@ Then /^Pidgin successfully connects to the "([^"]+)" account$/ do |account|
# conversation window. At worst, the test will still fail...
# FIXME This should be modified to use waitAny once #9633 is addressed
@screen.wait(expected_channel_entry, 60)
rescue FindFailed
@screen.wait_and_click('PidginReconnect.png', 20)
on_screen, _ = @screen.waitAny([expected_channel_entry, reconnect_button], 60)
unless on_screen == expected_channel_entry
raise "Connecting to account #{account} failed."
@screen.wait(expected_channel_entry, 10)
Then /^the "([^"]*)" account only responds to PING and VERSION CTCP requests$/ do |irc_server|
......@@ -385,6 +382,7 @@ 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/\" to \"#{cert_file}\" as user \"amnesia\""
@vm.focus_window('Buddy List')
@screen.wait_and_click('PidginToolsMenu.png', 10)
@screen.wait_and_click('PidginCertificatesMenuItem.png', 10)
@screen.wait('PidginCertificateManagerDialog.png', 10)