summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/baseapp/eip.py4
-rw-r--r--src/leap/baseapp/mainwindow.py52
-rw-r--r--src/leap/eip/checks.py37
-rw-r--r--src/leap/eip/config.py19
-rw-r--r--src/leap/eip/eipconnection.py15
-rw-r--r--src/leap/eip/openvpnconnection.py4
-rw-r--r--src/leap/eip/specs.py6
-rwxr-xr-xsrc/leap/gui/firstrunwizard.py82
8 files changed, 154 insertions, 65 deletions
diff --git a/src/leap/baseapp/eip.py b/src/leap/baseapp/eip.py
index ca2e03c3..26a2a1fb 100644
--- a/src/leap/baseapp/eip.py
+++ b/src/leap/baseapp/eip.py
@@ -25,6 +25,7 @@ class EIPConductorAppMixin(object):
def __init__(self, *args, **kwargs):
opts = kwargs.pop('opts')
config_file = getattr(opts, 'config_file', None)
+ provider = kwargs.pop('provider')
self.eip_service_started = False
@@ -39,7 +40,8 @@ class EIPConductorAppMixin(object):
checker_signals=(self.changeLeapStatus.emit, ),
status_signals=(self.statusChange.emit, ),
debug=self.debugmode,
- ovpn_verbosity=opts.openvpn_verb)
+ ovpn_verbosity=opts.openvpn_verb,
+ provider=provider)
self.skip_download = opts.no_provider_checks
self.skip_verify = opts.no_ca_verify
diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py
index df7159ce..752dba51 100644
--- a/src/leap/baseapp/mainwindow.py
+++ b/src/leap/baseapp/mainwindow.py
@@ -35,7 +35,8 @@ class LeapWindow(QtGui.QMainWindow,
triggerEIPError = QtCore.pyqtSignal([object])
start_eipconnection = QtCore.pyqtSignal([])
- # XXX fix nomenclature here
+ # XXX fix nomenclature here:
+ # eipStatusChange vs. leapStatusChange
# this is eip status change got from vpn management
statusChange = QtCore.pyqtSignal([object])
# this is global leap status
@@ -49,11 +50,14 @@ class LeapWindow(QtGui.QMainWindow,
self.createLogBrowser()
settings = QtCore.QSettings()
- provider_domain = settings.value("provider_domain", None)
- logger.debug('provider: %s', provider_domain)
+ self.provider_domain = settings.value("provider_domain", None)
+ self.eip_username = settings.value("eip_username", None)
+
+ logger.debug('provider: %s', self.provider_domain)
+ logger.debug('eip_username: %s', self.eip_username)
EIPConductorAppMixin.__init__(
- self, opts=opts, provider=provider_domain)
+ self, opts=opts, provider=self.provider_domain)
StatusAwareTrayIconMixin.__init__(self)
NetworkCheckerAppMixin.__init__(self)
MainWindowMixin.__init__(self)
@@ -62,13 +66,15 @@ class LeapWindow(QtGui.QMainWindow,
geom = settings.value(geom_key)
if geom:
self.restoreGeometry(geom)
+
+ # XXX check for wizard
self.wizard_done = settings.value("FirstRunWizardDone")
self.initchecks = InitChecksThread(self.run_eip_checks)
# bind signals
self.initchecks.finished.connect(
- lambda: logger.debug('Initial checks finished'))
+ lambda: logger.debug('Initial checks thread finished'))
self.trayIcon.activated.connect(self.iconActivated)
self.newLogLine.connect(
lambda line: self.onLoggerNewLine(line))
@@ -92,32 +98,52 @@ class LeapWindow(QtGui.QMainWindow,
self.changeLeapStatus.connect(
lambda newstatus: self.onChangeLeapConnStatus(newstatus))
- # do frwizard and init signals
+ # do first run wizard and init signals
self.mainappReady.connect(self.do_first_run_wizard_check)
self.initReady.connect(self.runchecks_and_eipconnect)
# ... all ready. go!
- # calls do_first_run_wizard_check
+ # connected to do_first_run_wizard_check
self.mainappReady.emit()
def do_first_run_wizard_check(self):
+ """
+ checks whether first run wizard needs to be run
+ launches it if needed (with initReady signal as a success callback)
+ and emits initReady signal if not.
+ """
+ # XXX change DOC string after I remove the success callbac!!!
+
logger.debug('first run wizard check...')
- if self.wizard_done:
- self.initReady.emit()
- else:
- # need to run first-run-wizard
- logger.debug('running first run wizard')
+ need_wizard = False
+
+ # do checks (can overlap if wizard was interrupted)
+ if not self.wizard_done:
+ need_wizard = True
+ if not self.provider_domain:
+ need_wizard = True
+
+ # launch wizard if needed
+ if need_wizard:
from leap.gui.firstrunwizard import FirstRunWizard
wizard = FirstRunWizard(
+ self.conductor,
parent=self,
- success_cb=self.initReady.emit)
+ eip_username=self.eip_username,
+ start_eipconnection_signal=self.start_eipconnection)
wizard.show()
+ else: # no wizard needed
+ logger.debug('running first run wizard')
+ self.initReady.emit()
+ return
def runchecks_and_eipconnect(self):
self.initchecks.begin()
class InitChecksThread(QtCore.QThread):
+ # XXX rename as a generic QThread class,
+ # has nothing specific to initchecks
def __init__(self, fun, parent=None):
QtCore.QThread.__init__(self, parent)
diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py
index b335b857..44c8f234 100644
--- a/src/leap/eip/checks.py
+++ b/src/leap/eip/checks.py
@@ -45,7 +45,8 @@ reachable and testable as a whole.
"""
-def get_ca_cert():
+def get_branding_ca_cert(domain):
+ # XXX deprecated
ca_file = BRANDING.get('provider_ca_file')
if ca_file:
return leapcerts.where(ca_file)
@@ -62,7 +63,7 @@ class ProviderCertChecker(object):
self.fetcher = fetcher
self.domain = domain
- self.cacert = get_ca_cert()
+ self.cacert = eipspecs.provider_ca_path(domain)
def run_all(
self, checker=None,
@@ -84,7 +85,7 @@ class ProviderCertChecker(object):
checker.is_there_provider_ca()
# XXX FAKE IT!!!
- checker.is_https_working(verify=do_verify)
+ checker.is_https_working(verify=do_verify, autocacert=True)
checker.check_new_cert_needed(verify=do_verify)
def download_ca_cert(self, uri=None, verify=True):
@@ -136,17 +137,14 @@ class ProviderCertChecker(object):
raise NotImplementedError
def is_there_provider_ca(self):
- # XXX modify for generic build
- from leap import certs
- logger.debug('do we have provider_ca?')
- cacert_path = BRANDING.get('provider_ca_file', None)
- if not cacert_path:
- # XXX look from the domain
- logger.debug('False')
+ if not self.cacert:
return False
- self.cacert = certs.where(cacert_path)
- logger.debug('True')
- return True
+ cacert_exists = os.path.isfile(self.cacert)
+ if cacert_exists:
+ logger.debug('True')
+ return True
+ logger.debug('False!')
+ return False
def is_https_working(
self, uri=None, verify=True,
@@ -162,6 +160,7 @@ class ProviderCertChecker(object):
if autocacert and verify is True and self.cacert is not None:
logger.debug('verify cert: %s', self.cacert)
verify = self.cacert
+ #import pdb4qt; pdb4qt.set_trace()
logger.debug('is https working?')
logger.debug('uri: %s (verify:%s)', uri, verify)
try:
@@ -169,18 +168,16 @@ class ProviderCertChecker(object):
except requests.exceptions.SSLError as exc:
logger.error("SSLError")
- raise eipexceptions.HttpsBadCertError
+ # XXX RAISE! See #638
+ #raise eipexceptions.HttpsBadCertError
+ logger.warning('BUG #638 CERT VERIFICATION FAILED! '
+ '(this should be CRITICAL)')
+ logger.warning('SSLError: %s', exc.message)
except requests.exceptions.ConnectionError:
logger.error('ConnectionError')
raise eipexceptions.HttpsNotSupported
- except requests.exceptions.SSLError as exc:
- logger.warning('BUG #638 CERT VERIFICATION FAILED! '
- '(this should be CRITICAL)')
- logger.warning('SSLError: %s', exc.message)
- # XXX RAISE! See #638
- #raise eipexceptions.EIPBadCertError
else:
logger.debug('True')
return True
diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py
index 1ce4a54e..57e15c9e 100644
--- a/src/leap/eip/config.py
+++ b/src/leap/eip/config.py
@@ -110,6 +110,8 @@ def build_ovpn_options(daemon=False, socket_path=None, **kwargs):
# since we will need to take some
# things from there if present.
+ provider = kwargs.pop('provider', None)
+
# get user/group name
# also from config.
user = baseconfig.get_username()
@@ -136,6 +138,7 @@ def build_ovpn_options(daemon=False, socket_path=None, **kwargs):
logger.debug('setting eip gateway to %s', gw)
opts.append(str(gw))
opts.append('1194')
+ #opts.append('80')
opts.append('udp')
opts.append('--tls-client')
@@ -172,12 +175,15 @@ def build_ovpn_options(daemon=False, socket_path=None, **kwargs):
opts.append('7777')
# certs
+ client_cert_path = eipspecs.client_cert_path(provider)
+ ca_cert_path = eipspecs.provider_ca_path(provider)
+
opts.append('--cert')
- opts.append(eipspecs.client_cert_path())
+ opts.append(client_cert_path)
opts.append('--key')
- opts.append(eipspecs.client_cert_path())
+ opts.append(client_cert_path)
opts.append('--ca')
- opts.append(eipspecs.provider_ca_path())
+ opts.append(ca_cert_path)
# we cannot run in daemon mode
# with the current subp setting.
@@ -245,7 +251,7 @@ def build_ovpn_command(debug=False, do_pkexec_check=True, vpnbin=None,
return [command[0], command[1:]]
-def check_vpn_keys():
+def check_vpn_keys(provider=None):
"""
performs an existance and permission check
over the openvpn keys file.
@@ -253,8 +259,9 @@ def check_vpn_keys():
per provider, containing the CA cert,
the provider key, and our client certificate
"""
- provider_ca = eipspecs.provider_ca_path()
- client_cert = eipspecs.client_cert_path()
+ assert provider is not None
+ provider_ca = eipspecs.provider_ca_path(provider)
+ client_cert = eipspecs.client_cert_path(provider)
logger.debug('provider ca = %s', provider_ca)
logger.debug('client cert = %s', client_cert)
diff --git a/src/leap/eip/eipconnection.py b/src/leap/eip/eipconnection.py
index f0e7861e..d4aeddf6 100644
--- a/src/leap/eip/eipconnection.py
+++ b/src/leap/eip/eipconnection.py
@@ -29,6 +29,7 @@ class EIPConnection(OpenVPNConnection):
*args, **kwargs):
self.settingsfile = kwargs.get('settingsfile', None)
self.logfile = kwargs.get('logfile', None)
+ self.provider = kwargs.pop('provider', None)
self.error_queue = Queue.Queue()
@@ -38,8 +39,10 @@ class EIPConnection(OpenVPNConnection):
checker_signals = kwargs.pop('checker_signals', None)
self.checker_signals = checker_signals
- self.provider_cert_checker = provider_cert_checker()
- self.config_checker = config_checker()
+ # initialize checkers
+ self.provider_cert_checker = provider_cert_checker(
+ domain=self.provider)
+ self.config_checker = config_checker(domain=self.provider)
host = eipconfig.get_socket_path()
kwargs['host'] = host
@@ -49,6 +52,14 @@ class EIPConnection(OpenVPNConnection):
def has_errors(self):
return True if self.error_queue.qsize() != 0 else False
+ def set_provider_domain(self, domain):
+ """
+ sets the provider domain.
+ used from the first run wizard when we launch the run_checks
+ and connect process after having initialized the conductor.
+ """
+ self.provider = domain
+
def run_checks(self, skip_download=False, skip_verify=False):
"""
run all eip checks previous to attempting a connection
diff --git a/src/leap/eip/openvpnconnection.py b/src/leap/eip/openvpnconnection.py
index 2ec7d08c..d7c571bc 100644
--- a/src/leap/eip/openvpnconnection.py
+++ b/src/leap/eip/openvpnconnection.py
@@ -25,7 +25,6 @@ class OpenVPNConnection(Connection):
"""
def __init__(self,
- #config_file=None,
watcher_cb=None,
debug=False,
host=None,
@@ -96,6 +95,7 @@ to be triggered for each one of them.
# XXX check also for command-line --command flag
try:
command, args = eip_config.build_ovpn_command(
+ provider=self.provider,
debug=self.debug,
socket_path=self.host,
ovpn_verbosity=self.ovpn_verbosity)
@@ -115,7 +115,7 @@ to be triggered for each one of them.
checks for correct permissions on vpn keys
"""
try:
- eip_config.check_vpn_keys()
+ eip_config.check_vpn_keys(provider=self.provider)
except eip_exceptions.EIPInitBadKeyFilePermError:
logger.error('Bad VPN Keys permission!')
# do nothing now
diff --git a/src/leap/eip/specs.py b/src/leap/eip/specs.py
index 4014b7c9..84b2597d 100644
--- a/src/leap/eip/specs.py
+++ b/src/leap/eip/specs.py
@@ -4,6 +4,8 @@ import os
from leap import __branding
from leap.base import config as baseconfig
+# XXX move provider stuff to base config
+
PROVIDER_CA_CERT = __branding.get(
'provider_ca_file',
'testprovider-ca-cert.pem')
@@ -13,7 +15,7 @@ provider_ca_path = lambda domain: str(os.path.join(
baseconfig.get_provider_path(domain),
'keys', 'ca',
'cacert.pem'
-))
+)) if domain else None
default_provider_ca_path = lambda: str(os.path.join(
baseconfig.get_default_provider_path(),
@@ -28,7 +30,7 @@ client_cert_path = lambda domain: unicode(os.path.join(
baseconfig.get_provider_path(domain),
'keys', 'client',
'openvpn.pem'
-))
+)) if domain else None
default_client_cert_path = lambda: unicode(os.path.join(
baseconfig.get_default_provider_path(),
diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py
index d9e33f7e..c7531d16 100755
--- a/src/leap/gui/firstrunwizard.py
+++ b/src/leap/gui/firstrunwizard.py
@@ -44,20 +44,28 @@ QLabel { color: red;
class FirstRunWizard(QtGui.QWizard):
def __init__(
- self, parent=None, providers=None,
+ self,
+ conductor_instance,
+ parent=None,
+ eip_username=None,
+ providers=None,
success_cb=None, is_provider_setup=False,
is_previously_registered=False,
trusted_certs=None,
netchecker=basechecks.LeapNetworkChecker,
providercertchecker=eipchecks.ProviderCertChecker,
- eipconfigchecker=eipchecks.EIPConfigChecker):
+ eipconfigchecker=eipchecks.EIPConfigChecker,
+ start_eipconnection_signal=None):
super(FirstRunWizard, self).__init__(
parent,
QtCore.Qt.WindowStaysOnTopHint)
- # XXX hardcoded for tests
- #if not providers:
- #providers = ('springbok',)
+ # we keep a reference to the conductor
+ # to be able to launch eip checks and connection
+ # in the connection page, before the wizard has ended.
+ self.conductor = conductor_instance
+
+ self.eip_username = eip_username
self.providers = providers
# success callback
@@ -79,10 +87,13 @@ class FirstRunWizard(QtGui.QWizard):
self.providercertchecker = providercertchecker
self.eipconfigchecker = eipconfigchecker
+ # signal for starting eip connection
+ # will be emitted in connecting page
+ self.start_eipconnection_signal = start_eipconnection_signal
+
self.providerconfig = None
- # FIXME add param for previously_registered
- # should start at login page.
+ is_previously_registered = bool(self.eip_username)
pages_dict = OrderedDict((
# (name, WizardPage)
@@ -150,11 +161,11 @@ class FirstRunWizard(QtGui.QWizard):
"""
final step in the wizard.
gather the info, update settings
- and call the success callback.
+ and call the success callback if any has been passed.
"""
provider = self.field('provider_domain')
username = self.field('userName')
- #password = self.field('userPassword')
+ password = self.field('userPassword')
remember_pass = self.field('rememberPassword')
logger.debug('chosen provider: %s', provider)
@@ -163,19 +174,25 @@ class FirstRunWizard(QtGui.QWizard):
super(FirstRunWizard, self).accept()
settings = QtCore.QSettings()
+ # we are assuming here that we only remember one username
+ # in the form username@provider.domain
+ # We probably could extend this to support some form of
+ # profiles.
+
settings.setValue("FirstRunWizardDone", True)
- settings.setValue(
- "eip_%s_username" % provider,
- username)
- settings.setValue("%s_remember_pass" % provider, remember_pass)
+ settings.setValue("provider_domain", provider)
+ full_username = "%s@%s" % (username, provider)
+
+ settings.setValue("eip_username", full_username)
+ settings.setValue("remember_user_and_pass", remember_pass)
seed = self.get_random_str(10)
settings.setValue("%s_seed" % provider, seed)
- # Commenting out for 0.2.0 release
- # since we did not fix #744 on time.
-
- #leapkeyring.leap_set_password(username, password, seed=seed)
+ # XXX #744: comment out for 0.2.0 release
+ # if we need to have a version of python-keyring < 0.9
+ leapkeyring.leap_set_password(
+ full_username, password, seed=seed)
logger.debug('First Run Wizard Done.')
cb = self.success_cb
@@ -863,7 +880,7 @@ class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
return False
if password == "123456":
- # XD
+ # joking
self.set_validation_status('Password too obvious.')
return False
@@ -970,6 +987,30 @@ class ConnectingPage(QtGui.QWizardPage):
def get_donemsg(self, msg):
return "%s ... done" % msg
+ def run_eip_checks_for_provider(self, domain):
+ wizard = self.wizard()
+ conductor = wizard.conductor
+ start_eip_signal = getattr(
+ wizard,
+ 'start_eipconnection_signal', None)
+ conductor.set_provider_domain(domain)
+ conductor.run_checks()
+ self.conductor = conductor
+ errors = self.eip_error_check()
+ if not errors and start_eip_signal:
+ start_eip_signal.emit()
+
+ def eip_error_check(self):
+ """
+ a version of the main app error checker,
+ but integrated within the connecting page of the wizard.
+ consumes the conductor error queue.
+ pops errors, and add those to the wizard page
+ """
+ logger.debug('eip error check from connecting page')
+ errq = self.conductor.error_queue
+ # XXX missing!
+
def fetch_and_validate(self):
# Fake... till you make it...
import time
@@ -1023,6 +1064,9 @@ class ConnectingPage(QtGui.QWizardPage):
self.progress.setValue(100)
time.sleep(3)
+ # here we go! :)
+ self.run_eip_checks_for_provider(domain)
+
return True
# pagewizard methods
@@ -1092,6 +1136,6 @@ if __name__ == '__main__':
"18C62B941192CC1A"
"49AE62218B2A4B7C": ['springbok']}
- wizard = FirstRunWizard(trusted_certs=trusted_certs)
+ wizard = FirstRunWizard(None, trusted_certs=trusted_certs)
wizard.show()
sys.exit(app.exec_())