import time from PyQt4 import QtCore from leap.baseapp.dialogs import ErrorDialog from leap.eip import exceptions as eip_exceptions from leap.eip.eipconnection import EIPConnection class EIPConductorApp(object): def __init__(self, *args, **kwargs): # # conductor is in charge of all # vpn-related configuration / monitoring. # we pass a tuple of signals that will be # triggered when status changes. # opts = kwargs.pop('opts') config_file = getattr(opts, 'config_file', None) self.eip_service_started = False self.conductor = EIPConnection( watcher_cb=self.newLogLine.emit, config_file=config_file, status_signals=(self.statusChange.emit, ), debug=self.debugmode) # XXX remove skip download when sample service is ready self.conductor.run_checks(skip_download=True) self.error_check() # XXX should receive "ready" signal #if self.conductor.autostart: #self.start_or_stopVPN() # move to eipconductor init? if self.debugmode: self.startStopButton.clicked.connect( lambda: self.start_or_stopVPN()) def error_check(self): ####### error checking ################ # # bunch of self checks. # XXX move somewhere else alltogether. # if self.conductor.missing_definition is True: dialog = ErrorDialog() dialog.criticalMessage( 'The default ' 'definition.json file cannot be found', 'error') if self.conductor.missing_provider is True: dialog = ErrorDialog() dialog.criticalMessage( 'Missing provider. Add a remote_ip entry ' 'under section [provider] in eip.cfg', 'error') if self.conductor.missing_vpn_keyfile is True: dialog = ErrorDialog() dialog.criticalMessage( 'Could not find the vpn keys file', 'error') # ... btw, review pending. # os.kill of subprocess fails if we have # some of this errors. if self.conductor.bad_provider is True: dialog = ErrorDialog() dialog.criticalMessage( 'Bad provider entry. Check that remote_ip entry ' 'has an IP under section [provider] in eip.cfg', 'error') if self.conductor.bad_keyfile_perms is True: dialog = ErrorDialog() dialog.criticalMessage( 'The vpn keys file has bad permissions', 'error') if self.conductor.missing_auth_agent is True: dialog = ErrorDialog() dialog.warningMessage( 'We could not find any authentication ' 'agent in your system.
' 'Make sure you have ' 'polkit-gnome-authentication-agent-1 ' 'running and try again.', 'error') if self.conductor.missing_pkexec is True: dialog = ErrorDialog() dialog.warningMessage( 'We could not find pkexec in your ' 'system.
Do you want to try ' 'setuid workaround? ' '(DOES NOTHING YET)', 'error') @QtCore.pyqtSlot() def statusUpdate(self): """ called on timer tick polls status and updates ui with real time info about transferred bytes / connection state. """ # XXX it's too expensive to poll # continously. move to signal events instead. if not self.eip_service_started: return # XXX remove all access to manager layer # from here. if self.conductor.with_errors: #XXX how to wait on pkexec??? #something better that this workaround, plz!! time.sleep(5) print('errors. disconnect.') self.start_or_stopVPN() # is stop state = self.conductor.poll_connection_state() if not state: return ts, con_status, ok, ip, remote = state self.set_statusbarMessage(con_status) self.setIconToolTip() ts = time.strftime("%a %b %d %X", ts) if self.debugmode: self.updateTS.setText(ts) self.status_label.setText(con_status) self.ip_label.setText(ip) self.remote_label.setText(remote) # status i/o status = self.conductor.get_status_io() if status and self.debugmode: #XXX move this to systray menu indicators ts, (tun_read, tun_write, tcp_read, tcp_write, auth_read) = status ts = time.strftime("%a %b %d %X", ts) self.updateTS.setText(ts) self.tun_read_bytes.setText(tun_read) self.tun_write_bytes.setText(tun_write) @QtCore.pyqtSlot() def start_or_stopVPN(self): """ stub for running child process with vpn """ if self.eip_service_started is False: try: self.conductor.connect() # XXX move this to error queue except eip_exceptions.EIPNoCommandError: dialog = ErrorDialog() dialog.warningMessage( 'No suitable openvpn command found. ' '
(Might be a permissions problem)', 'error') if self.debugmode: self.startStopButton.setText('&Disconnect') self.eip_service_started = True # XXX what is optimum polling interval? # too little is overkill, too much # will miss transition states.. self.timer.start(250.0) return if self.eip_service_started is True: self.conductor.disconnect() if self.debugmode: self.startStopButton.setText('&Connect') self.eip_service_started = False self.timer.stop() return