forked from mirrors/nixpkgs
45bd7b39a4
This is super hacky... :o But then again it should at least prevent data loss. Note: At least this isn't required for NixOS 21.05.
93 lines
2.3 KiB
Python
Executable file
93 lines
2.3 KiB
Python
Executable file
#!@PYTHON@
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import shlex
|
|
import sqlite3
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
DB_PATH = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.sqlite')
|
|
DB_COPY = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.tmp')
|
|
CONFIG_PATH = os.path.join(os.environ['HOME'], '.config/Signal/config.json')
|
|
|
|
|
|
def zenity_askyesno(title, text):
|
|
args = [
|
|
'@ZENITY@',
|
|
'--question',
|
|
'--title',
|
|
shlex.quote(title),
|
|
'--text',
|
|
shlex.quote(text)
|
|
]
|
|
return subprocess.run(args).returncode == 0
|
|
|
|
|
|
def start_signal():
|
|
os.execvp('@SIGNAL-DESKTOP@', ['@SIGNAL-DESKTOP@'] + sys.argv[1:])
|
|
|
|
|
|
def copy_pragma(name):
|
|
result = subprocess.run([
|
|
'@SQLCIPHER@',
|
|
DB_PATH,
|
|
f"PRAGMA {name};"
|
|
], check=True, capture_output=True).stdout
|
|
result = re.search(r'[0-9]+', result.decode()).group(0)
|
|
subprocess.run([
|
|
'@SQLCIPHER@',
|
|
DB_COPY,
|
|
f"PRAGMA key = \"x'{key}'\"; PRAGMA {name} = {result};"
|
|
], check=True, capture_output=True)
|
|
|
|
|
|
try:
|
|
# Test if DB is encrypted:
|
|
con = sqlite3.connect(f'file:{DB_PATH}?mode=ro', uri=True)
|
|
cursor = con.cursor()
|
|
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
|
con.close()
|
|
except:
|
|
# DB is encrypted, everything ok:
|
|
start_signal()
|
|
|
|
|
|
# DB is unencrypted!
|
|
answer = zenity_askyesno(
|
|
"Error: Signal-Desktop database is not encrypted",
|
|
"Should we try to fix this automatically?"
|
|
+ "You likely want to backup ~/.config/Signal/ first."
|
|
)
|
|
if not answer:
|
|
answer = zenity_askyesno(
|
|
"Launch Signal-Desktop",
|
|
"DB is unencrypted, should we still launch Signal-Desktop?"
|
|
+ "Warning: This could result in data loss!"
|
|
)
|
|
if not answer:
|
|
print('Aborted')
|
|
sys.exit(0)
|
|
start_signal()
|
|
|
|
# Re-encrypt the DB:
|
|
with open(CONFIG_PATH) as json_file:
|
|
key = json.load(json_file)['key']
|
|
result = subprocess.run([
|
|
'@SQLCIPHER@',
|
|
DB_PATH,
|
|
f" ATTACH DATABASE '{DB_COPY}' AS signal_db KEY \"x'{key}'\";"
|
|
+ " SELECT sqlcipher_export('signal_db');"
|
|
+ " DETACH DATABASE signal_db;"
|
|
]).returncode
|
|
if result != 0:
|
|
print('DB encryption failed')
|
|
sys.exit(1)
|
|
# Need to copy user_version and schema_version manually:
|
|
copy_pragma('user_version')
|
|
copy_pragma('schema_version')
|
|
os.rename(DB_COPY, DB_PATH)
|
|
start_signal()
|