Skip to content

Instantly share code, notes, and snippets.

@rocodes
Created September 22, 2021 22:57
Show Gist options
  • Save rocodes/b9d26b0405473090137b7249512d504d to your computer and use it in GitHub Desktop.
Save rocodes/b9d26b0405473090137b7249512d504d to your computer and use it in GitHub Desktop.
Repair auto-updates on Tails < 4.19 by downloading missing cert
import grp
import os
import io
import sys
import subprocess
import pwd
from shutil import copyfileobj
# Check TailsOS version and remediate auto-update failures if version < 4.19
# See https://tails.boum.org/news/version_4.18/
# Must be run as root, but we will operate as amnesia user for all but updating
# the certificate chain
if os.geteuid() != 0:
sys.exit('You need to run this as root')
amnesia_gid = grp.getgrnam('amnesia').gr_gid
amnesia_uid = pwd.getpwnam('amnesia').pw_uid
os.setresgid(amnesia_gid, amnesia_gid, -1)
os.setresuid(amnesia_uid, amnesia_uid, -1)
env = os.environ.copy()
env['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/run/user/{}/bus'.format(
amnesia_uid)
path_tails_version = '/etc/amnesia/version'
tails_min_version = [4, 19]
needs_update = False
try:
cmd = 'cat /etc/os-release | grep VERSION | cut -f2 -d\\"'
# Using shell=True because contents of /etc/os-release are trusted
tails_current_version = subprocess.check_output(cmd, shell=True,
universal_newlines=True, env=env).strip().split(".")
try:
needs_update = (len(tails_current_version) >= len(tails_min_version) and
(int(tails_current_version[0]) < tails_min_version[0]
or int(tails_current_version[1]) < tails_min_version[1]))
except (TypeError, ValueError):
sys.exit('Error checking Tails version. Please visit tails.boum.org ' +
'to ensure your version of Tails is up to date.')
if needs_update:
cert_name = 'isrg-root-x1-cross-signed.pem'
pem_file = open('/tmp/' + cert_name, 'w+')
pem_download_proc = subprocess.call(['torsocks',
'curl',
'--silent',
'https://tails.boum.org/' + cert_name],
stdout=pem_file, env=env)
verify_proc = subprocess.check_output(['openssl', 'verify',
'/tmp/' + cert_name], universal_newlines=True, env=env)
if 'OK' in verify_proc: # More verification work is needed here
# Updating the cert chain requires sudo privileges
os.setresgid(0, 0, -1)
os.setresuid(0, 0, -1)
with open('/usr/local/etc/ssl/certs/tails.boum.org-CA.pem', 'a') as chain:
pem_file.seek(0)
copyfileobj(pem_file, chain)
chain.close()
# As amnesia user, start updater GUI
os.setresgid(amnesia_gid, amnesia_gid, -1)
os.setresuid(amnesia_uid, amnesia_uid, -1)
restart_proc = subprocess.call(['systemctl',
'--user',
'restart',
'tails-upgrade-frontend'], env=env)
# clean up
pem_file.close()
except subprocess.CalledProcessError:
sys.exit('Error checking Tails version. Please visit tails.boum.org ' +
'to ensure your version of Tails is up to date.')
@rocodes
Copy link
Author

rocodes commented Sep 22, 2021

Testing instructions: on a Tails workstation running Tails < 4.19, establish a Tor network connection, download this script, and run sudo python3 fix_tails_autoupdate.py. Within about 15-30 seconds, the update GUI should appear.

@zenmonkeykstop
Copy link

This looks like a solid approach to me, particularly digging that there is some cert verification going on. I'd say we're good to get stuck in on a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment