From f38e0eaf6aa23d06e7418bbb88a639f67888dc17 Mon Sep 17 00:00:00 2001 From: antialias Date: Fri, 12 Oct 2012 14:10:13 -0400 Subject: ping_gateway now uses the provider gateway defined in config file. --- src/leap/base/checks.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 84f9dd46..7285e74f 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -16,13 +16,9 @@ class LeapNetworkChecker(object): """ all network related checks """ - # #718 - # XXX get provider gateway as a parameter - # for constructor. - # def __init__(self, *args, **kwargs): - # ... - # provider_gw = kwargs.pop('provider_gw', None) - # self.provider_gateway = provider_gw + def __init__(self, *args, **kwargs): + provider_gw = kwargs.pop('provider_gw', None) + self.provider_gateway = provider_gw def run_all(self, checker=None): if not checker: @@ -34,15 +30,8 @@ class LeapNetworkChecker(object): checker.check_internet_connection() checker.is_internet_up() - # XXX We are pinging the default gateway for our connection right? - # kali: 2012-10-05 20:59 -- I think we should get - # also the default gateway and ping it instead. - checker.ping_gateway() - - # something like: ? - # see __init__ above - # if self.provider_gateway: - # checker.ping_gateway(self.provider_gateway) + if self.provider_gateway: + checker.ping_gateway(self.provider_gateway) def check_internet_connection(self): try: @@ -65,7 +54,7 @@ class LeapNetworkChecker(object): def is_internet_up(self): iface, gateway = self.get_default_interface_gateway() - self.ping_gateway(self) + self.ping_gateway(self.provider_gateway) def check_tunnel_default_interface(self): """ -- cgit v1.2.3 From e1dbfc454180a77ebb38ecae6244ac4abe6d0ac5 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 18 Oct 2012 09:30:53 +0900 Subject: catch cert verification errors and ask user for trust with a little helper function using gnutls --- src/leap/base/checks.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 7285e74f..23446f4a 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import logging import platform +import socket import netifaces import ping @@ -23,7 +24,7 @@ class LeapNetworkChecker(object): def run_all(self, checker=None): if not checker: checker = self - self.error = None # ? + #self.error = None # ? # for MVS checker.check_tunnel_default_interface() @@ -118,11 +119,9 @@ class LeapNetworkChecker(object): if packet_loss > constants.MAX_ICMP_PACKET_LOSS: raise exceptions.NoConnectionToGateway - # XXX check for name resolution servers - # dunno what's the best way to do this... - # check for etc/resolv entries or similar? - # just try to resolve? - # is there something in psutil? - - # def check_name_resolution(self): - # pass + def check_name_resolution(self, domain_name): + try: + socket.gethostbyname(domain_name) + return True + except socket.gaierror: + raise exceptions.CannotResolveDomainError -- cgit v1.2.3 From 79dc31303f1e2a5449a03b1a6a4bdf291cae52e7 Mon Sep 17 00:00:00 2001 From: antialias Date: Fri, 30 Nov 2012 16:28:07 -0500 Subject: in leap.base.checks.check_internet_connection modified the order in which errors are checked and improved test coverage. --- src/leap/base/checks.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 23446f4a..dc2602c2 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -39,9 +39,6 @@ class LeapNetworkChecker(object): # XXX remove this hardcoded random ip # ping leap.se or eip provider instead...? requests.get('http://216.172.161.165') - - except (requests.HTTPError, requests.RequestException) as e: - raise exceptions.NoInternetConnection(e.message) except requests.ConnectionError as e: error = "Unidentified Connection Error" if e.message == "[Errno 113] No route to host": @@ -51,11 +48,17 @@ class LeapNetworkChecker(object): error = "Provider server appears to be down." logger.error(error) raise exceptions.NoInternetConnection(error) + except (requests.HTTPError, requests.RequestException) as e: + raise exceptions.NoInternetConnection(e.message) logger.debug('Network appears to be up.') def is_internet_up(self): iface, gateway = self.get_default_interface_gateway() - self.ping_gateway(self.provider_gateway) + try: + self.ping_gateway(self.provider_gateway) + except exceptions.NoConnectionToGateway: + return False + return True def check_tunnel_default_interface(self): """ -- cgit v1.2.3 From 1e116fe9453a9010338820394ace05a4f0bcc648 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 9 Jan 2013 05:40:12 +0900 Subject: dont shut down when conn lost --- src/leap/base/checks.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index dc2602c2..c7839548 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -68,6 +68,8 @@ class LeapNetworkChecker(object): if not platform.system() == "Linux": raise NotImplementedError + # XXX GET DARWIN IMPLEMENTATION + f = open("/proc/net/route") route_table = f.readlines() f.close() -- cgit v1.2.3 From f90f9df1d09e12ba64e9401530684d5a36220ad3 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 15 Jan 2013 22:17:56 +0900 Subject: todo about ping_gateway function --- src/leap/base/checks.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index c7839548..4d4a5d8b 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -120,6 +120,12 @@ class LeapNetworkChecker(object): # -- is it a valid ip? (there's something in util) # -- is it a domain? # -- can we resolve? -- raise NoDNSError if not. + + # XXX -- needs review! + # We cannout use this ping implementation; it needs root. + # We need to look for another, poors-man implementation + # or wrap around system traceroute (using sh module, fi) + # -- kali packet_loss = ping.quiet_ping(gateway)[0] if packet_loss > constants.MAX_ICMP_PACKET_LOSS: raise exceptions.NoConnectionToGateway -- cgit v1.2.3 From 14f433c16de60753d122d5946df68e8e82285ca3 Mon Sep 17 00:00:00 2001 From: antialias Date: Mon, 19 Nov 2012 16:16:01 -0800 Subject: implemented abstracted layer with matching and passed callback. tests as well. --- src/leap/base/checks.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 4d4a5d8b..587012fb 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -12,6 +12,9 @@ from leap.base import exceptions logger = logging.getLogger(name=__name__) +#EVENTS OF NOTE +EVENT_CONNECT_REFUSED = "[ECONNREFUSED]: Connection refused (code=111)" + class LeapNetworkChecker(object): """ @@ -34,6 +37,8 @@ class LeapNetworkChecker(object): if self.provider_gateway: checker.ping_gateway(self.provider_gateway) + checker.parse_log_and_react([], ()) + def check_internet_connection(self): try: # XXX remove this hardcoded random ip @@ -136,3 +141,19 @@ class LeapNetworkChecker(object): return True except socket.gaierror: raise exceptions.CannotResolveDomainError + + def parse_log_and_react(self, log, error_matrix=None): + """ + compares the recent openvpn status log to + strings passed in and executes the callbacks passed in. + @param log: openvpn log + @type log: list of strings + @param error_matrix: tuples of strings and tuples of callbacks + @type error_matrix: tuples strings and call backs + """ + for line in log: + for each in error_matrix: + error, callbacks = each + if error in line: + for cb in callbacks: + cb() -- cgit v1.2.3 From 8139b39dedc3dc99d310d082f6edb10d2303a1ce Mon Sep 17 00:00:00 2001 From: antialias Date: Wed, 21 Nov 2012 11:06:19 -0800 Subject: added if callable sanity check. --- src/leap/base/checks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 587012fb..e5767018 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -152,8 +152,10 @@ class LeapNetworkChecker(object): @type error_matrix: tuples strings and call backs """ for line in log: + # we could compile a regex here to save some cycles up -- kali for each in error_matrix: error, callbacks = each if error in line: for cb in callbacks: - cb() + if callable(cb): + cb() -- cgit v1.2.3 From d6c8cb0f12e8924820c296a8114a7899f61e5180 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 17 Jan 2013 05:54:16 +0900 Subject: (osx) detect which interface is traffic going thru --- src/leap/base/checks.py | 98 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 23 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index e5767018..0bdfd593 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -1,20 +1,25 @@ # -*- coding: utf-8 -*- import logging import platform +import re import socket import netifaces import ping import requests +import sh from leap.base import constants from leap.base import exceptions logger = logging.getLogger(name=__name__) +_platform = platform.system() #EVENTS OF NOTE EVENT_CONNECT_REFUSED = "[ECONNREFUSED]: Connection refused (code=111)" +ICMP_TARGET = "8.8.8.8" + class LeapNetworkChecker(object): """ @@ -43,6 +48,7 @@ class LeapNetworkChecker(object): try: # XXX remove this hardcoded random ip # ping leap.se or eip provider instead...? + # XXX could use icmp instead.. requests.get('http://216.172.161.165') except requests.ConnectionError as e: error = "Unidentified Connection Error" @@ -65,59 +71,104 @@ class LeapNetworkChecker(object): return False return True - def check_tunnel_default_interface(self): - """ - Raises an TunnelNotDefaultRouteError - (including when no routes are present) - """ - if not platform.system() == "Linux": - raise NotImplementedError - - # XXX GET DARWIN IMPLEMENTATION + def _get_route_table_linux(self): - f = open("/proc/net/route") - route_table = f.readlines() - f.close() + with open("/proc/net/route") as f: + route_table = f.readlines() #toss out header route_table.pop(0) - if not route_table: raise exceptions.TunnelNotDefaultRouteError() + return route_table + def _get_def_iface_osx(self): + default_iface = None + gateway = None + routes = list(sh.route('-n', 'get', ICMP_TARGET, _iter=True)) + iface = filter(lambda l: "interface" in l, routes) + if not iface: + return None, None + def_ifacel = re.findall('\w+\d', iface[0]) + default_iface = def_ifacel[0] if def_ifacel else None + if not default_iface: + return None, None + _gw = filter(lambda l: "gateway" in l, routes) + gw = re.findall('\d+\.\d+\.\d+\.\d+', _gw[0])[0] + return default_iface, gw + + def _get_tunnel_iface_linux(): + # XXX review. + # valid also when local router has a default entry? + route_table = self._get_route_table_linux() line = route_table.pop(0) iface, destination = line.split('\t')[0:2] if not destination == '00000000' or not iface == 'tun0': raise exceptions.TunnelNotDefaultRouteError() + return True - def get_default_interface_gateway(self): - """only impletemented for linux so far.""" - if not platform.system() == "Linux": + def check_tunnel_default_interface(self): + """ + Raises an TunnelNotDefaultRouteError + if tun0 is not the chosen default route + (including when no routes are present) + """ + #logger.debug('checking tunnel default interface...') + + if _platform == "Linux": + valid = self._get_tunnel_iface_linux() + return valid + elif _platform == "Darwin": + default_iface, gw = self._get_def_iface_osx() + #logger.debug('iface: %s', default_iface) + if default_iface != "tun0": + logger.debug('tunnel not default route! gw: %s', default_iface) + # XXX should catch this and act accordingly... + # but rather, this test should only be launched + # when we have successfully completed a connection + # ... TRIGGER: Connection stablished (or whatever it is) + # in the logs + raise exceptions.TunnelNotDefaultRouteError + else: + logger.debug('PLATFORM !!! %s', _platform) raise NotImplementedError - # XXX use psutil - f = open("/proc/net/route") - route_table = f.readlines() - f.close() - #toss out header - route_table.pop(0) + def _get_def_iface_linux(self): default_iface = None gateway = None + + route_table = self._get_route_table_linux() while route_table: line = route_table.pop(0) iface, destination, gateway = line.split('\t')[0:3] if destination == '00000000': default_iface = iface break + return default_iface, gateway + + + def get_default_interface_gateway(self): + """ + gets the interface we are going thru. + (this should be merged with check tunnel default interface, + imo...) + """ + if _platform == "Linux": + default_iface, gw = self.get_def_iface_linux() + elif _platform == "Darwin": + default_iface, gw = self.get_def_iface_osx() + else: + raise NotImplementedError if not default_iface: raise exceptions.NoDefaultInterfaceFoundError if default_iface not in netifaces.interfaces(): raise exceptions.InterfaceNotFoundError - + logger.debug('-- default iface', default_iface) return default_iface, gateway + def ping_gateway(self, gateway): # TODO: Discuss how much packet loss (%) is acceptable. @@ -132,6 +183,7 @@ class LeapNetworkChecker(object): # or wrap around system traceroute (using sh module, fi) # -- kali packet_loss = ping.quiet_ping(gateway)[0] + logger.debug('packet loss %s' % packet_loss) if packet_loss > constants.MAX_ICMP_PACKET_LOSS: raise exceptions.NoConnectionToGateway -- cgit v1.2.3 From 97f4324be1be58e7d0c38da8bdc6474af1aae78f Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 17 Jan 2013 07:37:11 +0900 Subject: pep8 --- src/leap/base/checks.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 0bdfd593..8abdf774 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -61,6 +61,9 @@ class LeapNetworkChecker(object): raise exceptions.NoInternetConnection(error) except (requests.HTTPError, requests.RequestException) as e: raise exceptions.NoInternetConnection(e.message) + + # XXX should redirect this to netcheck logger. + # and don't clutter main log. logger.debug('Network appears to be up.') def is_internet_up(self): @@ -83,8 +86,8 @@ class LeapNetworkChecker(object): def _get_def_iface_osx(self): default_iface = None - gateway = None - routes = list(sh.route('-n', 'get', ICMP_TARGET, _iter=True)) + #gateway = None + routes = list(sh.route('-n', 'get', ICMP_TARGET, _iter=True)) iface = filter(lambda l: "interface" in l, routes) if not iface: return None, None @@ -96,7 +99,7 @@ class LeapNetworkChecker(object): gw = re.findall('\d+\.\d+\.\d+\.\d+', _gw[0])[0] return default_iface, gw - def _get_tunnel_iface_linux(): + def _get_tunnel_iface_linux(self): # XXX review. # valid also when local router has a default entry? route_table = self._get_route_table_linux() @@ -129,10 +132,9 @@ class LeapNetworkChecker(object): # in the logs raise exceptions.TunnelNotDefaultRouteError else: - logger.debug('PLATFORM !!! %s', _platform) + #logger.debug('PLATFORM !!! %s', _platform) raise NotImplementedError - def _get_def_iface_linux(self): default_iface = None gateway = None @@ -146,7 +148,6 @@ class LeapNetworkChecker(object): break return default_iface, gateway - def get_default_interface_gateway(self): """ gets the interface we are going thru. @@ -166,8 +167,7 @@ class LeapNetworkChecker(object): if default_iface not in netifaces.interfaces(): raise exceptions.InterfaceNotFoundError logger.debug('-- default iface', default_iface) - return default_iface, gateway - + return default_iface, gw def ping_gateway(self, gateway): # TODO: Discuss how much packet loss (%) is acceptable. -- cgit v1.2.3 From 9cdc193c587631986e579c1ba37a8b982be01238 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 24 Jan 2013 18:47:41 +0900 Subject: all tests green again plus: * added soledad test requirements * removed soledad from run_tests run (+1K tests failing) * added option to run All tests to run_tests script * pep8 cleanup --- src/leap/base/checks.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 8abdf774..0ebf4f2f 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -75,9 +75,10 @@ class LeapNetworkChecker(object): return True def _get_route_table_linux(self): - - with open("/proc/net/route") as f: - route_table = f.readlines() + # do not use context manager, tests pass a StringIO + f = open("/proc/net/route") + route_table = f.readlines() + f.close() #toss out header route_table.pop(0) if not route_table: @@ -87,7 +88,7 @@ class LeapNetworkChecker(object): def _get_def_iface_osx(self): default_iface = None #gateway = None - routes = list(sh.route('-n', 'get', ICMP_TARGET, _iter=True)) + routes = list(sh.route('-n', 'get', ICMP_TARGET, _iter=True)) iface = filter(lambda l: "interface" in l, routes) if not iface: return None, None @@ -155,7 +156,7 @@ class LeapNetworkChecker(object): imo...) """ if _platform == "Linux": - default_iface, gw = self.get_def_iface_linux() + default_iface, gw = self._get_def_iface_linux() elif _platform == "Darwin": default_iface, gw = self.get_def_iface_osx() else: -- cgit v1.2.3 From aaeb78c2a93025b6a7c72d136336f16acccbc23c Mon Sep 17 00:00:00 2001 From: antialias Date: Thu, 24 Jan 2013 17:07:12 -0500 Subject: removed ping and root dependency (1456). improved default network request (771). fixed ERROR "cannot concatenate 'str' and 'list' objects" (1449). --- src/leap/base/checks.py | 53 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'src/leap/base/checks.py') diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py index 0ebf4f2f..0bf44f59 100644 --- a/src/leap/base/checks.py +++ b/src/leap/base/checks.py @@ -5,8 +5,6 @@ import re import socket import netifaces -import ping -import requests import sh from leap.base import constants @@ -45,26 +43,25 @@ class LeapNetworkChecker(object): checker.parse_log_and_react([], ()) def check_internet_connection(self): - try: - # XXX remove this hardcoded random ip - # ping leap.se or eip provider instead...? - # XXX could use icmp instead.. - requests.get('http://216.172.161.165') - except requests.ConnectionError as e: - error = "Unidentified Connection Error" - if e.message == "[Errno 113] No route to host": + if _platform == "Linux": + try: + output = sh.ping("-c", "5", "-w", "5", ICMP_TARGET) + # XXX should redirect this to netcheck logger. + # and don't clutter main log. + logger.debug('Network appears to be up.') + except sh.ErrorReturnCode_1 as e: + packet_loss = re.findall("\d+% packet loss", e.message)[0] + logger.debug("Unidentified Connection Error: " + packet_loss) if not self.is_internet_up(): error = "No valid internet connection found." else: error = "Provider server appears to be down." - logger.error(error) - raise exceptions.NoInternetConnection(error) - except (requests.HTTPError, requests.RequestException) as e: - raise exceptions.NoInternetConnection(e.message) - # XXX should redirect this to netcheck logger. - # and don't clutter main log. - logger.debug('Network appears to be up.') + logger.error(error) + raise exceptions.NoInternetConnection(error) + + else: + raise NotImplementedError def is_internet_up(self): iface, gateway = self.get_default_interface_gateway() @@ -82,7 +79,7 @@ class LeapNetworkChecker(object): #toss out header route_table.pop(0) if not route_table: - raise exceptions.TunnelNotDefaultRouteError() + raise exceptions.NoDefaultInterfaceFoundError return route_table def _get_def_iface_osx(self): @@ -158,7 +155,7 @@ class LeapNetworkChecker(object): if _platform == "Linux": default_iface, gw = self._get_def_iface_linux() elif _platform == "Darwin": - default_iface, gw = self.get_def_iface_osx() + default_iface, gw = self._get_def_iface_osx() else: raise NotImplementedError @@ -167,7 +164,7 @@ class LeapNetworkChecker(object): if default_iface not in netifaces.interfaces(): raise exceptions.InterfaceNotFoundError - logger.debug('-- default iface', default_iface) + logger.debug('-- default iface %s', default_iface) return default_iface, gw def ping_gateway(self, gateway): @@ -178,13 +175,15 @@ class LeapNetworkChecker(object): # -- is it a domain? # -- can we resolve? -- raise NoDNSError if not. - # XXX -- needs review! - # We cannout use this ping implementation; it needs root. - # We need to look for another, poors-man implementation - # or wrap around system traceroute (using sh module, fi) - # -- kali - packet_loss = ping.quiet_ping(gateway)[0] - logger.debug('packet loss %s' % packet_loss) + # XXX -- sh.ping implemtation needs review! + try: + output = sh.ping("-c", "10", gateway).stdout + except sh.ErrorReturnCode_1 as e: + output = e.message + finally: + packet_loss = int(re.findall("(\d+)% packet loss", output)[0]) + + logger.debug('packet loss %s%%' % packet_loss) if packet_loss > constants.MAX_ICMP_PACKET_LOSS: raise exceptions.NoConnectionToGateway -- cgit v1.2.3