admin.py 1.91 KB
Newer Older
segfault's avatar
segfault committed
1
2
3
import os
import os.path
import logging
4
import shlex
5
import subprocess
segfault's avatar
segfault committed
6
7

import tailsgreeter.config
8
from tailsgreeter.settings import SettingNotFoundError
9
from tailsgreeter.settings.utils import read_settings, write_settings
segfault's avatar
segfault committed
10
11
12
13
14


class AdminSetting(object):
    """Setting controlling the sudo password"""

15
16
17
18
    settings_file = tailsgreeter.config.admin_password_path

    def save(self, password: str):
        proc = subprocess.run(
segfault's avatar
segfault committed
19
20
21
            # mkpasswd generates a salt if none is provided (even though the
            # man page doesn't explicitly state this).
            ["mkpasswd", "--stdin", "--method=sha512crypt"],
22
            input=password.encode(),
23
24
25
26
27
28
            capture_output=True,
            check=True,
        )
        hashed_and_salted_pw = proc.stdout.decode().strip()

        write_settings(self.settings_file, {
29
            'TAILS_USER_PASSWORD': hashed_and_salted_pw,
30
            'TAILS_PASSWORD_HASH_FUNCTION': 'SHA512',
31
32
33
34
        })
        logging.debug('password written to %s', self.settings_file)

    def delete(self):
segfault's avatar
segfault committed
35
36
        # Try to remove the password file
        try:
37
38
            os.unlink(self.settings_file)
            logging.debug('removed %s', self.settings_file)
segfault's avatar
segfault committed
39
40
        except OSError:
            # It's bad if the file exists and couldn't be removed, so we
41
            # we raise the exception in that case
42
            if os.path.exists(self.settings_file):
segfault's avatar
segfault committed
43
                raise
44

45
46
47
    def load(self):
        # We don't return the stored value, because the UI can't do
        # anything with it since it's hashed.
48
49
50
        try:
            settings = read_settings(self.settings_file)
        except FileNotFoundError:
51
            raise SettingNotFoundError("No persistent admin settings file found (path: %s)" % self.settings_file)
52

53
        if settings.get('TAILS_USER_PASSWORD') is None:
54
            raise SettingNotFoundError("No admin password setting found in settings file (path: %s)" % self.settings_file)