summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali <kali@leap.se>2013-01-17 05:54:16 +0900
committerkali <kali@leap.se>2013-01-17 05:55:01 +0900
commitd6c8cb0f12e8924820c296a8114a7899f61e5180 (patch)
tree203eee2a5cd90c12187007ba0a4bdd48243abd7d
parent68af5b2f807ac8acd9525d46d37cfd2a28a06b47 (diff)
(osx) detect which interface is traffic going thru
-rw-r--r--pkg/requirements.pip3
-rw-r--r--src/leap/app.py7
-rw-r--r--src/leap/base/checks.py98
-rw-r--r--src/leap/eip/checks.py1
-rw-r--r--src/leap/eip/config.py2
-rw-r--r--src/leap/eip/openvpnconnection.py3
-rw-r--r--src/leap/util/certs.py3
7 files changed, 90 insertions, 27 deletions
diff --git a/pkg/requirements.pip b/pkg/requirements.pip
index fa40c490..69d435dc 100644
--- a/pkg/requirements.pip
+++ b/pkg/requirements.pip
@@ -1,5 +1,5 @@
# in order of addition to the project.
-# do not change it, we will freeze the requirements before tagging a release.
+# do not change the ordering.
argparse # only for python 2.6
requests<1.0.0
@@ -16,3 +16,4 @@ python-gnupg
u1db
oauth
couchdb
+sh
diff --git a/src/leap/app.py b/src/leap/app.py
index 7b8ac3cd..5f4fd656 100644
--- a/src/leap/app.py
+++ b/src/leap/app.py
@@ -49,6 +49,13 @@ def main():
logger.addHandler(console)
#logger.debug(opts)
+ import os
+ ldlib = os.environ.get("LD_LIBRARY_PATH", None)
+ dyldlib = os.environ.get("DYLD_LIBRARY_PATH", None)
+
+ logger.debug("LD_LIBRARY_PATH %s" % ldlib)
+ logger.debug("DYLD_LIBRARY_PATH %s" % dyldlib)
+
logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
logger.info('LEAP client version %s', VERSION)
logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
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
diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py
index 9fb13c74..0d07ef08 100644
--- a/src/leap/eip/checks.py
+++ b/src/leap/eip/checks.py
@@ -187,7 +187,6 @@ class ProviderCertChecker(object):
def check_new_cert_needed(self, skip_download=False, verify=True):
# XXX add autocacert
- logger.debug('is new cert needed?')
if not self.is_cert_valid(do_raise=False):
logger.debug('cert needed: true')
self.download_new_client_cert(
diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py
index 6a19633d..a60d7ed5 100644
--- a/src/leap/eip/config.py
+++ b/src/leap/eip/config.py
@@ -253,7 +253,7 @@ def build_ovpn_options(daemon=False, socket_path=None, **kwargs):
#if daemon is True:
#opts.append('--daemon')
- logger.debug('vpn options: %s', opts)
+ logger.debug('vpn options: %s', ' '.join(opts))
return opts
diff --git a/src/leap/eip/openvpnconnection.py b/src/leap/eip/openvpnconnection.py
index a36d99de..e5169465 100644
--- a/src/leap/eip/openvpnconnection.py
+++ b/src/leap/eip/openvpnconnection.py
@@ -6,6 +6,7 @@ import logging
import os
import psutil
import shutil
+import select
import socket
from functools import partial
@@ -103,6 +104,8 @@ class OpenVPNManagement(object):
return []
except socket.error as exc:
logger.debug('socket error: %s' % exc.message)
+ except select.error as exc:
+ logger.debug('select error: %s' % exc.message)
def _send_short_command(self, cmd):
"""
diff --git a/src/leap/util/certs.py b/src/leap/util/certs.py
index 304db08a..f0f790e9 100644
--- a/src/leap/util/certs.py
+++ b/src/leap/util/certs.py
@@ -14,4 +14,5 @@ def get_mac_cabundle():
#logger.error('VERIFY PATH = %s' % verify)
exists = os.path.isfile(verify)
#logger.error('do exist? %s', exists)
- return verify
+ if exists:
+ return verify