summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/vpn/service.py
blob: bbde1044135a950fd83dda9acea9690b8ced2078 (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# service.py
# Copyright (C) 2015-2017 LEAP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
EIP service declaration.
"""

import os

from twisted.internet import defer

from leap.bitmask.hooks import HookableService
from leap.bitmask.vpn.eip import EIPManager
from leap.bitmask.vpn._checks import is_service_ready, get_eip_cert_path
from leap.bitmask.vpn._config import get_bitmask_helper_path
from leap.bitmask.vpn._config import get_bitmask_polkit_policy_path
from leap.bitmask.vpn import privilege
from leap.common.config import get_path_prefix
from leap.common.files import check_and_fix_urw_only


class EIPService(HookableService):

    name = 'eip'

    def __init__(self, basepath=None):
        """
        Initialize EIP service
        """
        super(EIPService, self).__init__()

        self._started = False
        self._eip = None

        if basepath is None:
            self._basepath = get_path_prefix()
        else:
            self._basepath = basepath

    def startService(self):
        print "Starting EIP Service..."
        # TODO this could trigger a check for validity of the certificates,
        # etc.
        super(EIPService, self).startService()

    def stopService(self):
        print "Stopping EIP Service..."
        super(EIPService, self).stopService()

    def start_vpn(self, domain):
        self._setup(domain)
        self._eip.start()
        self._started = True
        return {'result': 'started'}

    def stop_vpn(self):
        if self._started:
            self._eip.stop()
            self._started = False
            return {'result': 'stopped'}

    def do_status(self):
        if self._eip:
            status = self._eip.get_status()
        else:
            status = {'EIP': 'OFF'}
        return status

    def do_check(self):
        """Check whether the EIP Service is properly configured,
        and can be started"""
        # TODO either pass a provider, or set a given provider
        _ready = is_service_ready('demo.bitmask.net')
        if _ready:
            result = 'ok'
        else:
            result = 'no'
        return {'eip_ready': result}

    @defer.inlineCallbacks
    def do_get_cert(self, provider):
        # fetch vpn cert and store
        bonafide = self.parent.getServiceNamed("bonafide")
        _, cert_str = yield bonafide.do_get_vpn_cert()

        cert_path = get_eip_cert_path(provider)
        cert_dir = os.path.dirname(cert_path)
        if not os.path.exists(cert_dir):
            os.makedirs(cert_dir, mode=0700)
        with open(cert_path, 'w') as outf:
            outf.write(cert_str)
        check_and_fix_urw_only(cert_path)
        defer.returnValue({'get_cert': 'ok'})

    def do_install(self):
        ask = privilege.install_helpers()
        return {'install': 'ok'}

    def do_uninstall(self):
        ask = privilege.uninstall_helpers()
        return {'uninstall': 'ok'}

    def _setup(self, provider):
        """Set up EIPManager for a specified provider.

        :param provider: the provider to use, e.g. 'demo.bitmask.net'
        :type provider: str"""

        # FIXME ---------------------------------------------------------
        # XXX picked manually from eip-service.json
        remotes = (
            ("198.252.153.84", "1194"),
            ("46.165.242.169", "1194"),
        )

        prefix = os.path.join(self._basepath,
                              "leap/providers/{0}/keys".format(provider))
        cert_path = key_path = prefix + "/client/openvpn.pem"
        ca_path = prefix + "/ca/cacert.pem"

        # FIXME
        # XXX picked manually from eip-service.json
        extra_flags = {
            "auth": "SHA1",
            "cipher": "AES-128-CBC",
            "keepalive": "10 30",
            "tls-cipher": "DHE-RSA-AES128-SHA",
        }

        self._eip = EIPManager(remotes, cert_path, key_path, ca_path,
                               extra_flags)