@@ -0,0 +1,92 @@
1+#!@PYTHON@
2+
3+import json
4+import os
5+import re
6+import shlex
7+import sqlite3
8+import subprocess
9+import sys
10+
11+
12+DB_PATH = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.sqlite')
13+DB_COPY = os.path.join(os.environ['HOME'], '.config/Signal/sql/db.tmp')
14+CONFIG_PATH = os.path.join(os.environ['HOME'], '.config/Signal/config.json')
15+
16+
17+def zenity_askyesno(title, text):
18+ args = [
19+ '@ZENITY@',
20+ '--question',
21+ '--title',
22+ shlex.quote(title),
23+ '--text',
24+ shlex.quote(text)
25+ ]
26+ return subprocess.run(args).returncode == 0
27+
28+
29+def start_signal():
30+ os.execvp('@SIGNAL-DESKTOP@', ['@SIGNAL-DESKTOP@'] + sys.argv[1:])
31+
32+
33+def copy_pragma(name):
34+ result = subprocess.run([
35+ '@SQLCIPHER@',
36+ DB_PATH,
37+ f"PRAGMA {name};"
38+ ], check=True, capture_output=True).stdout
39+ result = re.search(r'[0-9]+', result.decode()).group(0)
40+ subprocess.run([
41+ '@SQLCIPHER@',
42+ DB_COPY,
43+ f"PRAGMA key = \"x'{key}'\"; PRAGMA {name} = {result};"
44+ ], check=True, capture_output=True)
45+
46+
47+try:
48+ # Test if DB is encrypted:
49+ con = sqlite3.connect(f'file:{DB_PATH}?mode=ro', uri=True)
50+ cursor = con.cursor()
51+ cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
52+ con.close()
53+except:
54+ # DB is encrypted, everything ok:
55+ start_signal()
56+
57+
58+# DB is unencrypted!
59+answer = zenity_askyesno(
60+ "Error: Signal-Desktop database is not encrypted",
61+ "Should we try to fix this automatically?"
62+ + "You likely want to backup ~/.config/Signal/ first."
63+)
64+if not answer:
65+ answer = zenity_askyesno(
66+ "Launch Signal-Desktop",
67+ "DB is unencrypted, should we still launch Signal-Desktop?"
68+ + "Warning: This could result in data loss!"
69+ )
70+ if not answer:
71+ print('Aborted')
72+ sys.exit(0)
73+ start_signal()
74+
75+# Re-encrypt the DB:
76+with open(CONFIG_PATH) as json_file:
77+ key = json.load(json_file)['key']
78+result = subprocess.run([
79+ '@SQLCIPHER@',
80+ DB_PATH,
81+ f" ATTACH DATABASE '{DB_COPY}' AS signal_db KEY \"x'{key}'\";"
82+ + " SELECT sqlcipher_export('signal_db');"
83+ + " DETACH DATABASE signal_db;"
84+]).returncode
85+if result != 0:
86+ print('DB encryption failed')
87+ sys.exit(1)
88+# Need to copy user_version and schema_version manually:
89+copy_pragma('user_version')
90+copy_pragma('schema_version')
91+os.rename(DB_COPY, DB_PATH)
92+start_signal()