diff options
-rw-r--r-- | src/leap/bitmask/vpn/_management.py | 131 | ||||
-rw-r--r-- | src/leap/bitmask/vpn/process.py | 2 |
2 files changed, 60 insertions, 73 deletions
diff --git a/src/leap/bitmask/vpn/_management.py b/src/leap/bitmask/vpn/_management.py index 18e52ed7..16bb86fe 100644 --- a/src/leap/bitmask/vpn/_management.py +++ b/src/leap/bitmask/vpn/_management.py @@ -28,6 +28,10 @@ class AlienOpenVPNAlreadyRunning(Exception): "not be stopped because it was not launched by LEAP.") +class ImproperlyConfigured(Exception): + pass + + class VPNManagement(object): """ This is a mixin that we use in the VPNProcess class. @@ -46,6 +50,12 @@ class VPNManagement(object): def __init__(self): self._tn = None self.aborted = False + self._host = None + self._port = None + + self._last_state = None + self._last_status = None + self._status = None def set_connection(self, host, port): """ @@ -58,6 +68,50 @@ class VPNManagement(object): self._host = host self._port = port + def is_connected(self): + return bool(self._tn) + + def connect(self): + if not self._host or not self._port: + raise ImproperlyConfigured('Connection is not configured') + + if self.is_connected(): + self._close_management_socket() + try: + self._tn = UDSTelnet(self._host, self._port) + self._tn.read_eager() + + except Exception as e: + self.log.warn('Could not connect to OpenVPN yet: %r' % (e,)) + self._tn = None + + if self._tn: + return True + else: + self.log.error('Error while connecting to management!') + return False + + def connect_retry(self, retry=0, max_retries=None): + """ + Attempts to connect to a management interface, and retries + after CONNECTION_RETRY_TIME if not successful. + + :param retry: number of the retry + :type retry: int + """ + if max_retries and retry > max_retries: + self.log.warn( + 'Max retries reached while attempting to connect ' + 'to management. Aborting.') + self.aborted = True + return + + if not self.aborted and not self.is_connected(): + self.connect() + reactor.callLater( + self.CONNECTION_RETRY_TIME, + self.connect_retry, retry + 1) + def _seek_to_eof(self): """ Read as much as available. Position seek pointer to end of stream @@ -100,7 +154,7 @@ class VPNManagement(object): self.log.warn('Socket error (command was: "%s")' % (command,)) self._close_management_socket(announce=False) self.log.debug('Trying to connect to management again') - self.try_to_connect_to_management(max_retries=5) + self.connect_retry(max_retries=5) return [] except Exception as e: @@ -118,75 +172,6 @@ class VPNManagement(object): self._tn.get_socket().close() self._tn = None - def connect_to_management(self): - """ - Connects to the management interface. - - :type socket_port: str - """ - if self.is_connected(): - self._close_management_socket() - - try: - self._tn = UDSTelnet(self._host, self._port) - - # XXX make password optional - # specially for win. we should generate - # the pass on the fly when invoking manager - # from conductor - - # self.tn.read_until('ENTER PASSWORD:', 2) - # self.tn.write(self.password + '\n') - # self.tn.read_until('SUCCESS:', 2) - if self._tn: - self._tn.read_eager() - - except Exception as e: - print "ERROR", e - self.log.warn('Could not connect to OpenVPN yet: %r' % (e,)) - self._tn = None - - if self._tn: - return True - else: - print "ERROR!" - #self.log.failure('Error while connecting to management!') - return False - - def is_connected(self): - """ - Returns the status of the management interface. - - :returns: True if connected, False otherwise - :rtype: bool - """ - return True if self._tn else False - - def try_to_connect_to_management(self, retry=0, max_retries=None): - """ - Attempts to connect to a management interface, and retries - after CONNECTION_RETRY_TIME if not successful. - - :param retry: number of the retry - :type retry: int - """ - if max_retries and retry > max_retries: - self.log.warn( - 'Max retries reached while attempting to connect ' - 'to management. Aborting.') - self.aborted = True - return - - # _alive flag is set in the VPNProcess class. - if not self._alive: - self.log.debug('Tried to connect to management but process is ' - 'not alive.') - return - if not self.aborted and not self.is_connected(): - self.connect_to_management() - reactor.callLater( - self.CONNECTION_RETRY_TIME, - self.try_to_connect_to_management, retry + 1) def _parse_state_and_notify(self, output): """ @@ -198,6 +183,7 @@ class VPNManagement(object): :type output: list """ for line in output: + print "PARSING", line stripped = line.strip() if stripped == "END": continue @@ -227,11 +213,13 @@ class VPNManagement(object): as its output :type output: list """ + print "PARSING STATUS", output tun_tap_read = "" tun_tap_write = "" for line in output: stripped = line.strip() + print "LINE", stripped if stripped.endswith("STATISTICS") or stripped == "END": continue parts = stripped.split(",") @@ -295,7 +283,6 @@ class VPNManagement(object): under normal circumstances, we should be able to delete. """ if self._socket_port == "unix": - self.log.debug('Cleaning socket file temp folder') tempfolder = _first(os.path.split(self._host)) if tempfolder and os.path.isdir(tempfolder): try: @@ -377,7 +364,7 @@ class VPNManagement(object): port = cmdline[index + 2] self.log.debug("Trying to connect to %s:%s" % (host, port)) - self.connect_to_management() + self.connect() # XXX this has a problem with connections to different # remotes. So the reconnection will only work when we are diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py index d6e6129b..34548bff 100644 --- a/src/leap/bitmask/vpn/process.py +++ b/src/leap/bitmask/vpn/process.py @@ -120,7 +120,7 @@ class _VPNProcess(protocol.ProcessProtocol, _management.VPNManagement): """ self._alive = True self.aborted = False - self.try_to_connect_to_management(max_retries=10) + self.connect_retry(max_retries=10) def outReceived(self, data): """ |