summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/vpn/helpers/__init__.py
blob: 631ad78513680df4d8682a7cb3086fbe2a3a62b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from os import remove, chmod, access, R_OK
from shutil import copyfile
from hashlib import sha512
import os.path
import sys

from leap.bitmask.vpn.constants import IS_LINUX, IS_MAC
from leap.bitmask.vpn import _config

from leap.bitmask.util import STANDALONE

if IS_LINUX:

    from leap.bitmask.vpn.constants import BITMASK_ROOT_SYSTEM
    from leap.bitmask.vpn.constants import BITMASK_ROOT_LOCAL
    from leap.bitmask.vpn.constants import OPENVPN_SYSTEM, OPENVPN_LOCAL
    from leap.bitmask.vpn.constants import POLKIT_SYSTEM, POLKIT_LOCAL
    from leap.bitmask.vpn.privilege import is_pkexec_in_system
    from leap.bitmask.vpn.privilege import LinuxPolicyChecker

    def install():
        helper_from = _config.get_bitmask_helper_path()
        polkit_from = _config.get_bitmask_polkit_policy_path()
        openvpn_from = _config.get_bitmask_openvpn_path()

        sbin = '/usr/local/sbin'
        if not os.path.isdir(sbin):
            os.makedirs(sbin)

        copyfile(helper_from, BITMASK_ROOT_LOCAL)
        chmod(BITMASK_ROOT_LOCAL, 0744)

        copyfile(polkit_from, POLKIT_LOCAL)

        if STANDALONE:
            copyfile(openvpn_from, OPENVPN_LOCAL)
            chmod(OPENVPN_LOCAL, 0744)

    def uninstall():
        remove(BITMASK_ROOT_LOCAL)
        remove(POLKIT_LOCAL)
        remove(OPENVPN_LOCAL)

    def privcheck(timeout=5):
        has_pkexec = is_pkexec_in_system()
        running = LinuxPolicyChecker.is_up()
        if not running:
            try:
                LinuxPolicyChecker.get_usable_pkexec(timeout=timeout)
                running = LinuxPolicyChecker.is_up()
            except Exception:
                running = False
        return has_pkexec and running

    def check():
        return (
            is_pkexec_in_system() and
            _check_helper() and
            _check_polkit() and
            _check_openvpn())

    def _check_helper():
        helper_path = _config.get_bitmask_helper_path()
        if not access(helper_path, R_OK):
            return True

        helper_path_digest = digest(helper_path)
        if (access(BITMASK_ROOT_SYSTEM, R_OK) and
                helper_path_digest == digest(BITMASK_ROOT_SYSTEM)):
                return True
        if (access(BITMASK_ROOT_LOCAL, R_OK) and
                helper_path_digest == digest(BITMASK_ROOT_LOCAL)):
                return True

        return False

    def _check_openvpn():
        if os.path.exists(OPENVPN_SYSTEM):
            return True

        openvpn_path = _config.get_bitmask_openvpn_path()
        if openvpn_path is None:
            return True

        openvpn_path_digest = digest(openvpn_path)
        if (access(OPENVPN_LOCAL, R_OK) and
                openvpn_path_digest == digest(OPENVPN_LOCAL)):
                return True

        return False

    def _check_polkit():
        # XXX: we are just checking if there is any policy file installed not
        # if it's valid or if it's the correct one that will be used.
        # (if LOCAL is used if /usr/local/sbin/bitmask-root is used and SYSTEM
        # if /usr/sbin/bitmask-root)
        return (os.path.exists(POLKIT_LOCAL) or
                os.path.exists(POLKIT_SYSTEM))


elif IS_MAC:

    def check():
        # XXX check if bitmask-helper is running
        return True

    def privcheck():
        return True


def digest(path):
    with open(path, 'r') as f:
        s = f.read()
    return sha512(s).digest()


def main():
    if sys.argv[-1] == 'install':
        install()
    if sys.argv[-1] == 'uninstall':
        uninstall()


if __name__ == "__main__":
    main()