From 7cea25f531f46a1425ea54a79d96a3b662a8a7fd Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 1 Aug 2012 03:41:00 +0900 Subject: remove old namespace egg-info dir --- src/eip_client.egg-info/PKG-INFO | 11 ----------- src/eip_client.egg-info/SOURCES.txt | 28 ---------------------------- src/eip_client.egg-info/dependency_links.txt | 1 - src/eip_client.egg-info/entry_points.txt | 3 --- src/eip_client.egg-info/not-zip-safe | 1 - src/eip_client.egg-info/top_level.txt | 1 - 6 files changed, 45 deletions(-) delete mode 100644 src/eip_client.egg-info/PKG-INFO delete mode 100644 src/eip_client.egg-info/SOURCES.txt delete mode 100644 src/eip_client.egg-info/dependency_links.txt delete mode 100644 src/eip_client.egg-info/entry_points.txt delete mode 100644 src/eip_client.egg-info/not-zip-safe delete mode 100644 src/eip_client.egg-info/top_level.txt (limited to 'src') diff --git a/src/eip_client.egg-info/PKG-INFO b/src/eip_client.egg-info/PKG-INFO deleted file mode 100644 index e4bc754e..00000000 --- a/src/eip_client.egg-info/PKG-INFO +++ /dev/null @@ -1,11 +0,0 @@ -Metadata-Version: 1.0 -Name: eip-client -Version: 0.1dev -Summary: the internet encryption toolkit -Home-page: http://leap.se -Author: leap project -Author-email: info@leap.se -License: GPL -Description: UNKNOWN -Keywords: leap,client,qt,encryption -Platform: all diff --git a/src/eip_client.egg-info/SOURCES.txt b/src/eip_client.egg-info/SOURCES.txt deleted file mode 100644 index 05688ff1..00000000 --- a/src/eip_client.egg-info/SOURCES.txt +++ /dev/null @@ -1,28 +0,0 @@ -MANIFEST.in -README.txt -setup.cfg -setup.py -docs/LICENSE.txt -docs/leap.1 -setup/linux/polkit/net.openvpn.gui.leap.policy -setup/scripts/leap -src/eip_client.egg-info/PKG-INFO -src/eip_client.egg-info/SOURCES.txt -src/eip_client.egg-info/dependency_links.txt -src/eip_client.egg-info/entry_points.txt -src/eip_client.egg-info/not-zip-safe -src/eip_client.egg-info/top_level.txt -src/leap/__init__.py -src/leap/app.py -src/leap/baseapp/__init__.py -src/leap/baseapp/config.py -src/leap/baseapp/mainwindow.py -src/leap/eip/__init__.py -src/leap/eip/conductor.py -src/leap/eip/vpnmanager.py -src/leap/eip/vpnwatcher.py -src/leap/gui/__init__.py -src/leap/gui/mainwindow_rc.py -src/leap/utils/__init__.py -src/leap/utils/coroutines.py -src/leap/utils/leap_argparse.py \ No newline at end of file diff --git a/src/eip_client.egg-info/dependency_links.txt b/src/eip_client.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/src/eip_client.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/eip_client.egg-info/entry_points.txt b/src/eip_client.egg-info/entry_points.txt deleted file mode 100644 index a184cd05..00000000 --- a/src/eip_client.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ - - # -*- Entry points: -*- - \ No newline at end of file diff --git a/src/eip_client.egg-info/not-zip-safe b/src/eip_client.egg-info/not-zip-safe deleted file mode 100644 index 8b137891..00000000 --- a/src/eip_client.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/eip_client.egg-info/top_level.txt b/src/eip_client.egg-info/top_level.txt deleted file mode 100644 index 2905ed7d..00000000 --- a/src/eip_client.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -leap -- cgit v1.2.3 From 6e197c1353c788109df07ee6d1242a5c2327e8f9 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 1 Aug 2012 09:58:08 +0900 Subject: fileutil.which implementation --- src/leap/app.py | 2 +- src/leap/eip/conductor.py | 2 +- src/leap/util/__init__.py | 0 src/leap/util/coroutines.py | 107 ++++++++++++++++++++++++++++++++++++++++ src/leap/util/fileutil.py | 73 +++++++++++++++++++++++++++ src/leap/util/leap_argparse.py | 20 ++++++++ src/leap/utils/__init__.py | 0 src/leap/utils/coroutines.py | 107 ---------------------------------------- src/leap/utils/leap_argparse.py | 20 -------- 9 files changed, 202 insertions(+), 129 deletions(-) create mode 100644 src/leap/util/__init__.py create mode 100644 src/leap/util/coroutines.py create mode 100644 src/leap/util/fileutil.py create mode 100644 src/leap/util/leap_argparse.py delete mode 100644 src/leap/utils/__init__.py delete mode 100644 src/leap/utils/coroutines.py delete mode 100644 src/leap/utils/leap_argparse.py (limited to 'src') diff --git a/src/leap/app.py b/src/leap/app.py index 0a61fd4f..186eb048 100644 --- a/src/leap/app.py +++ b/src/leap/app.py @@ -15,7 +15,7 @@ def main(): long live to the (hidden) leap window! """ import sys - from leap.utils import leap_argparse + from leap.util import leap_argparse parser, opts = leap_argparse.init_leapc_args() debug = getattr(opts, 'debug', False) diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index e3adadc4..3ce062aa 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -6,7 +6,7 @@ from __future__ import (division, unicode_literals, print_function) from functools import partial import logging -from leap.utils.coroutines import spawn_and_watch_process +from leap.util.coroutines import spawn_and_watch_process from leap.baseapp.config import get_config, get_vpn_stdout_mockup from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError diff --git a/src/leap/util/__init__.py b/src/leap/util/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/leap/util/coroutines.py b/src/leap/util/coroutines.py new file mode 100644 index 00000000..5e25eb63 --- /dev/null +++ b/src/leap/util/coroutines.py @@ -0,0 +1,107 @@ +# the problem of watching a stdout pipe from +# openvpn binary: using subprocess and coroutines +# acting as event consumers + +from __future__ import division, print_function + +from subprocess import PIPE, Popen +import sys +from threading import Thread + +ON_POSIX = 'posix' in sys.builtin_module_names + + +# +# Coroutines goodies +# + +def coroutine(func): + def start(*args, **kwargs): + cr = func(*args, **kwargs) + cr.next() + return cr + return start + + +@coroutine +def process_events(callback): + """ + coroutine loop that receives + events sent and dispatch the callback. + :param callback: callback to be called\ +for each event + :type callback: callable + """ + try: + while True: + m = (yield) + if callable(callback): + callback(m) + else: + #XXX log instead + print('not a callable passed') + except GeneratorExit: + return + +# +# Threads +# + + +def launch_thread(target, args): + """ + launch and demonize thread. + :param target: target function that will run in thread + :type target: function + :param args: args to be passed to thread + :type args: list + """ + t = Thread(target=target, + args=args) + t.daemon = True + t.start() + return t + + +def watch_output(out, observers): + """ + initializes dict of observer coroutines + and pushes lines to each of them as they are received + from the watched output. + :param out: stdout of a process. + :type out: fd + :param observers: tuple of coroutines to send data\ +for each event + :type ovservers: tuple + """ + observer_dict = {observer: process_events(observer) + for observer in observers} + for line in iter(out.readline, b''): + for obs in observer_dict: + observer_dict[obs].send(line) + out.close() + + +def spawn_and_watch_process(command, args, observers=None): + """ + spawns a subprocess with command, args, and launch + a watcher thread. + :param command: command to be executed in the subprocess + :type command: str + :param args: arguments + :type args: list + :param observers: tuple of observer functions to be called \ +for each line in the subprocess output. + :type observers: tuple + :return: a tuple containing the child process instance, and watcher_thread, + :rtype: (Subprocess, Thread) + """ + subp = Popen([command] + args, + stdout=PIPE, + stderr=PIPE, + bufsize=1, + close_fds=ON_POSIX) + watcher = launch_thread( + watch_output, + (subp.stdout, observers)) + return subp, watcher diff --git a/src/leap/util/fileutil.py b/src/leap/util/fileutil.py new file mode 100644 index 00000000..86a44a89 --- /dev/null +++ b/src/leap/util/fileutil.py @@ -0,0 +1,73 @@ +from itertools import chain +import os +import platform +import stat + + +def is_user_executable(fpath): + st = os.stat(fpath) + return bool(st.st_mode & stat.S_IXUSR) + + +def extend_path(): + ourplatform = platform.system() + if ourplatform == "Linux": + return "/usr/local/sbin:/usr/sbin" + # XXX add mac / win extended search paths? + + +def which(program): + """ + an implementation of which + that extends the path with + other locations, like sbin + (f.i., openvpn binary is likely to be there) + @param program: a string representing the binary we're looking for. + """ + def is_exe(fpath): + """ + check that path exists, + it's a file, + and is executable by the owner + """ + # we would check for access, + # but it's likely that we're + # using uid 0 + polkitd + + return os.path.isfile(fpath)\ + and is_user_executable(fpath) + + def ext_candidates(fpath): + yield fpath + for ext in os.environ.get("PATHEXT", "").split(os.pathsep): + yield fpath + ext + + def iter_path(pathset): + """ + returns iterator with + full path for a given path list + and the current target bin. + """ + for path in pathset.split(os.pathsep): + exe_file = os.path.join(path, program) + #print 'file=%s' % exe_file + for candidate in ext_candidates(exe_file): + if is_exe(candidate): + yield candidate + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + # extended iterator + # with extra path + extended_path = chain( + iter_path(os.environ["PATH"]), + iter_path(extend_path())) + for candidate in extended_path: + if candidate is not None: + return candidate + + # sorry bro. + return None diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py new file mode 100644 index 00000000..9c355134 --- /dev/null +++ b/src/leap/util/leap_argparse.py @@ -0,0 +1,20 @@ +import argparse + + +def build_parser(): + epilog = "Copyright 2012 The Leap Project" + parser = argparse.ArgumentParser(description=""" +Launches main LEAP Client""", epilog=epilog) + parser.add_argument('--debug', action="store_true", + help='launches in debug mode') + parser.add_argument('--config', metavar="CONFIG FILE", nargs='?', + action="store", dest="config_file", + type=argparse.FileType('r'), + help='optional config file') + return parser + + +def init_leapc_args(): + parser = build_parser() + opts = parser.parse_args() + return parser, opts diff --git a/src/leap/utils/__init__.py b/src/leap/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/leap/utils/coroutines.py b/src/leap/utils/coroutines.py deleted file mode 100644 index 5e25eb63..00000000 --- a/src/leap/utils/coroutines.py +++ /dev/null @@ -1,107 +0,0 @@ -# the problem of watching a stdout pipe from -# openvpn binary: using subprocess and coroutines -# acting as event consumers - -from __future__ import division, print_function - -from subprocess import PIPE, Popen -import sys -from threading import Thread - -ON_POSIX = 'posix' in sys.builtin_module_names - - -# -# Coroutines goodies -# - -def coroutine(func): - def start(*args, **kwargs): - cr = func(*args, **kwargs) - cr.next() - return cr - return start - - -@coroutine -def process_events(callback): - """ - coroutine loop that receives - events sent and dispatch the callback. - :param callback: callback to be called\ -for each event - :type callback: callable - """ - try: - while True: - m = (yield) - if callable(callback): - callback(m) - else: - #XXX log instead - print('not a callable passed') - except GeneratorExit: - return - -# -# Threads -# - - -def launch_thread(target, args): - """ - launch and demonize thread. - :param target: target function that will run in thread - :type target: function - :param args: args to be passed to thread - :type args: list - """ - t = Thread(target=target, - args=args) - t.daemon = True - t.start() - return t - - -def watch_output(out, observers): - """ - initializes dict of observer coroutines - and pushes lines to each of them as they are received - from the watched output. - :param out: stdout of a process. - :type out: fd - :param observers: tuple of coroutines to send data\ -for each event - :type ovservers: tuple - """ - observer_dict = {observer: process_events(observer) - for observer in observers} - for line in iter(out.readline, b''): - for obs in observer_dict: - observer_dict[obs].send(line) - out.close() - - -def spawn_and_watch_process(command, args, observers=None): - """ - spawns a subprocess with command, args, and launch - a watcher thread. - :param command: command to be executed in the subprocess - :type command: str - :param args: arguments - :type args: list - :param observers: tuple of observer functions to be called \ -for each line in the subprocess output. - :type observers: tuple - :return: a tuple containing the child process instance, and watcher_thread, - :rtype: (Subprocess, Thread) - """ - subp = Popen([command] + args, - stdout=PIPE, - stderr=PIPE, - bufsize=1, - close_fds=ON_POSIX) - watcher = launch_thread( - watch_output, - (subp.stdout, observers)) - return subp, watcher diff --git a/src/leap/utils/leap_argparse.py b/src/leap/utils/leap_argparse.py deleted file mode 100644 index 9c355134..00000000 --- a/src/leap/utils/leap_argparse.py +++ /dev/null @@ -1,20 +0,0 @@ -import argparse - - -def build_parser(): - epilog = "Copyright 2012 The Leap Project" - parser = argparse.ArgumentParser(description=""" -Launches main LEAP Client""", epilog=epilog) - parser.add_argument('--debug', action="store_true", - help='launches in debug mode') - parser.add_argument('--config', metavar="CONFIG FILE", nargs='?', - action="store", dest="config_file", - type=argparse.FileType('r'), - help='optional config file') - return parser - - -def init_leapc_args(): - parser = build_parser() - opts = parser.parse_args() - return parser, opts -- cgit v1.2.3 From 23502b72f8cd8a9ec2fd28387f7788aeef54c2d1 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 2 Aug 2012 02:21:45 +0900 Subject: create config file if not exist. also locate openvpn binary when building eip configparser defaults. implement half of feature #356 --- src/leap/baseapp/config.py | 40 -------------------------- src/leap/eip/conductor.py | 14 +++++++-- src/leap/eip/config.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++ src/leap/util/fileutil.py | 14 +++++++++ 4 files changed, 97 insertions(+), 43 deletions(-) delete mode 100644 src/leap/baseapp/config.py create mode 100644 src/leap/eip/config.py (limited to 'src') diff --git a/src/leap/baseapp/config.py b/src/leap/baseapp/config.py deleted file mode 100644 index efdb4726..00000000 --- a/src/leap/baseapp/config.py +++ /dev/null @@ -1,40 +0,0 @@ -import ConfigParser -import os - - -def get_config(config_file=None): - """ - temporary method for getting configs, - mainly for early stage development process. - in the future we will get preferences - from the storage api - """ - config = ConfigParser.ConfigParser() - #config.readfp(open('defaults.cfg')) - #XXX does this work on win / mac also??? - conf_path_list = ['eip.cfg', # XXX build a - # proper path with platform-specific places - # XXX make .config/foo - os.path.expanduser('~/.eip.cfg')] - if config_file: - config.readfp(config_file) - else: - config.read(conf_path_list) - return config - - -# XXX wrapper around config? to get default values - -def get_with_defaults(config, section, option): - if config.has_option(section, option): - return config.get(section, option) - else: - # XXX lookup in defaults dict??? - pass - - -def get_vpn_stdout_mockup(): - command = "python" - args = ["-u", "-c", "from eip_client import fakeclient;\ -fakeclient.write_output()"] - return command, args diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 3ce062aa..1d5e4b59 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -7,7 +7,8 @@ from functools import partial import logging from leap.util.coroutines import spawn_and_watch_process -from leap.baseapp.config import get_config, get_vpn_stdout_mockup + +from leap.eip.config import get_config, get_vpn_stdout_mockup from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -39,6 +40,10 @@ class UnrecoverableError(EIPClientError): """ we cannot do anything about it, sorry """ + # XXX we should catch this and raise + # to qtland, so we emit signal + # to translate whatever kind of error + # to user-friendly msg in dialog. pass @@ -78,7 +83,7 @@ to be triggered for each one of them. self.autostart = True - self._get_config() + self._get_or_create_config() def _set_command_mockup(self): """ @@ -88,16 +93,19 @@ to be triggered for each one of them. command, args = get_vpn_stdout_mockup() self.command, self.args = command, args - def _get_config(self): + def _get_or_create_config(self): """ retrieves the config options from defaults or home file, or config file passed in command line. """ config = get_config(config_file=self.config_file) self.config = config + import ipdb;ipdb.set_trace() if config.has_option('openvpn', 'command'): commandline = config.get('openvpn', 'command') + #XXX remove mockup from here. + #it was just for testing early. if commandline == "mockup": self._set_command_mockup() return diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py new file mode 100644 index 00000000..d8ffeb28 --- /dev/null +++ b/src/leap/eip/config.py @@ -0,0 +1,72 @@ +import ConfigParser +import os + +from leap.util.fileutil import which, mkdir_p + + +def get_sensible_defaults(): + """ + gathers a dict of sensible defaults, + platform sensitive, + to be used to initialize the config parser + """ + defaults = dict() + defaults['openvpn_binary'] = which('openvpn') + return defaults + + +def get_config(config_file=None): + """ + temporary method for getting configs, + mainly for early stage development process. + in the future we will get preferences + from the storage api + """ + # TODO + # - refactor out common things and get + # them to util/ or baseapp/ + + defaults = get_sensible_defaults() + config = ConfigParser.ConfigParser(defaults) + + if not config_file: + fpath = os.path.expanduser('~/.config/leap/eip.cfg') + if not os.path.isfile(fpath): + dpath, cfile = os.path.split(fpath) + if not os.path.isdir(dpath): + mkdir_p(dpath) + with open(fpath, 'wb') as configfile: + config.write(configfile) + config_file = open(fpath) + + #TODO + # - get a more sensible path for win/mac + # - convert config_file to list; + # look in places like /etc/leap/eip.cfg + # for global settings. + # - raise warnings/error if bad options. + + try: + config.readfp(config_file) + except: + # XXX no file exists? + raise + return config + + +# XXX wrapper around config? to get default values +def get_with_defaults(config, section, option): + # XXX REMOVE ME + if config.has_option(section, option): + return config.get(section, option) + else: + # XXX lookup in defaults dict??? + pass + + +def get_vpn_stdout_mockup(): + # XXX REMOVE ME + command = "python" + args = ["-u", "-c", "from eip_client import fakeclient;\ +fakeclient.write_output()"] + return command, args diff --git a/src/leap/util/fileutil.py b/src/leap/util/fileutil.py index 86a44a89..bb2c243b 100644 --- a/src/leap/util/fileutil.py +++ b/src/leap/util/fileutil.py @@ -1,3 +1,4 @@ +import errno from itertools import chain import os import platform @@ -71,3 +72,16 @@ def which(program): # sorry bro. return None + + +def mkdir_p(path): + """ + implements mkdir -p functionality + """ + try: + os.makedirs(path) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + raise -- cgit v1.2.3 From 3e95ac1493da40b77bec110e0c59c2f11aeb2b62 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 2 Aug 2012 03:48:24 +0900 Subject: start with disconnected icon --- src/leap/baseapp/mainwindow.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index 68b6de8f..f2c48acc 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -222,6 +222,7 @@ technolust") self.trayIconMenu.addAction(self.quitAction) self.trayIcon = QSystemTrayIcon(self) + self.setIcon('disconnected') self.trayIcon.setContextMenu(self.trayIconMenu) def createLogBrowser(self): -- cgit v1.2.3 From 65db011c13aa6bf03867cc0e579f191cbf611ef6 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 06:44:17 +0900 Subject: fix icon change on disconnect --- src/leap/eip/conductor.py | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 1d5e4b59..b1683e7d 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -98,32 +98,40 @@ to be triggered for each one of them. retrieves the config options from defaults or home file, or config file passed in command line. """ + #print('get or create config') config = get_config(config_file=self.config_file) self.config = config - import ipdb;ipdb.set_trace() if config.has_option('openvpn', 'command'): commandline = config.get('openvpn', 'command') + #XXX remove mockup from here. #it was just for testing early. if commandline == "mockup": self._set_command_mockup() return + command_split = commandline.split(' ') command = command_split[0] if len(command_split) > 1: args = command_split[1:] else: args = [] + + # XXX CALL BUILD COMMAND self.command = command - #print("debug: command = %s" % command) self.args = args else: self._set_command_mockup() if config.has_option('openvpn', 'autostart'): - autostart = config.get('openvpn', 'autostart') + autostart = config.getboolean('openvpn', 'autostart') + print('autostart = %s' % autostart) self.autostart = autostart + else: + if config.has_option('DEFAULT', 'autostart'): + autostart = config.getboolean('DEFAULT', 'autostart') + self.autostart = autostart def _launch_openvpn(self): """ @@ -194,7 +202,7 @@ class EIPConductor(OpenVPNConnection): """ self.manager.forget_errors() self._try_connection() - # XXX should capture errors? + # XXX should capture errors here? def disconnect(self): """ @@ -202,25 +210,7 @@ class EIPConductor(OpenVPNConnection): """ self._disconnect() self.status.change_to(self.status.DISCONNECTED) - pass - def shutdown(self): - """ - shutdown and quit - """ - self.desired_con_state = self.status.DISCONNECTED - - def connection_state(self): - """ - returns the current connection state - """ - return self.status.current - - def desired_connection_state(self): - """ - returns the desired_connection state - """ - return self.desired_con_state def poll_connection_state(self): """ -- cgit v1.2.3 From b9c9b5536f9d1648a196e741cdf4570f64c3fb11 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 07:32:47 +0900 Subject: build default invocation command + options if not found in config file. fix #182 and #356 --- src/leap/eip/conductor.py | 26 +++------ src/leap/eip/config.py | 144 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index b1683e7d..bf7f0fb2 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -8,7 +8,7 @@ import logging from leap.util.coroutines import spawn_and_watch_process -from leap.eip.config import get_config, get_vpn_stdout_mockup +from leap.eip.config import get_config, build_ovpn_command from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -82,21 +82,13 @@ to be triggered for each one of them. self.proto = None self.autostart = True - self._get_or_create_config() - def _set_command_mockup(self): - """ - sets command and args for a command mockup - that just mimics the output from the real thing - """ - command, args = get_vpn_stdout_mockup() - self.command, self.args = command, args - def _get_or_create_config(self): """ retrieves the config options from defaults or home file, or config file passed in command line. + populates command and args to be passed to subprocess. """ #print('get or create config') config = get_config(config_file=self.config_file) @@ -105,12 +97,6 @@ to be triggered for each one of them. if config.has_option('openvpn', 'command'): commandline = config.get('openvpn', 'command') - #XXX remove mockup from here. - #it was just for testing early. - if commandline == "mockup": - self._set_command_mockup() - return - command_split = commandline.split(' ') command = command_split[0] if len(command_split) > 1: @@ -122,11 +108,14 @@ to be triggered for each one of them. self.command = command self.args = args else: - self._set_command_mockup() + # no command in config, we build it up. + # XXX check also for command-line --command flag + command, args = build_ovpn_command(config) + self.command = command + self.args = args if config.has_option('openvpn', 'autostart'): autostart = config.getboolean('openvpn', 'autostart') - print('autostart = %s' % autostart) self.autostart = autostart else: if config.has_option('DEFAULT', 'autostart'): @@ -211,7 +200,6 @@ class EIPConductor(OpenVPNConnection): self._disconnect() self.status.change_to(self.status.DISCONNECTED) - def poll_connection_state(self): """ """ diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index d8ffeb28..3fca329c 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -1,17 +1,132 @@ import ConfigParser +import grp import os +import platform from leap.util.fileutil import which, mkdir_p +def build_ovpn_options(): + """ + build a list of options + to be passed in the + openvpn invocation + @rtype: list + @rparam: options + """ + # XXX review which of the + # options we don't need. + + # TODO pass also the config file, + # since we will need to take some + # things from there if present. + + # get user/group name + # also from config. + user = os.getlogin() + gid = os.getgroups()[-1] + group = grp.getgrgid(gid).gr_name + + opts = [] + opts.append('--persist-tun') + + # set user and group + opts.append('--user') + opts.append('%s' % user) + opts.append('--group') + opts.append('%s' % group) + + opts.append('--management-client-user') + opts.append('%s' % user) + opts.append('--management-signal') + + # set default options for management + # interface. unix sockets or telnet interface for win. + # XXX take them from the config object. + + ourplatform = platform.system() + if ourplatform in ("Linux", "Mac"): + opts.append('--management') + opts.append('/tmp/.eip.sock') + opts.append('unix') + if ourplatform == "Windows": + opts.append('--management') + opts.append('localhost') + # XXX which is a good choice? + opts.append('7777') + + # remaining config options, in a file + # NOTE: we will build this file from + # the service definition file. + ovpncnf = os.path.expanduser( + '~/.config/leap/openvpn.conf') + opts.append('--config') + opts.append(ovpncnf) + + return opts + + +def build_ovpn_command(config): + """ + build a string with the + complete openvpn invocation + + @param config: config object + @type config: ConfigParser instance + + @rtype [string, [list of strings]] + @rparam: a list containing the command string + and a list of options. + """ + command = [] + use_pkexec = False + ovpn = None + + if config.has_option('openvpn', 'openvpn_binary'): + ovpn = config.get('openvpn', 'openvpn_binary') + if not ovpn and config.has_option('DEFAULT', 'openvpn_binary'): + ovpn = config.get('DEFAULT', 'openvpn_binary') + + if config.has_option('openvpn', 'use_pkexec'): + use_pkexec = config.get('openvpn', 'use_pkexec') + + if use_pkexec: + command.append('pkexec') + if ovpn: + command.append(ovpn) + + for opt in build_ovpn_options(): + command.append(opt) + + # XXX check len and raise proper error + + return [command[0], command[1:]] + + def get_sensible_defaults(): """ gathers a dict of sensible defaults, platform sensitive, to be used to initialize the config parser + @rtype: dict + @rparam: default options. """ + + # this way we're passing a simple dict + # that will initialize the configparser + # and will get written to "DEFAULTS" section, + # which is fine for now. + # if we want to write to a particular section + # we can better pass a tuple of triples + # (('section1', 'foo', '23'),) + # and config.set them + defaults = dict() defaults['openvpn_binary'] = which('openvpn') + defaults['autostart'] = 'true' + + # TODO + # - management. return defaults @@ -21,6 +136,9 @@ def get_config(config_file=None): mainly for early stage development process. in the future we will get preferences from the storage api + + @rtype: ConfigParser instance + @rparam: a config object """ # TODO # - refactor out common things and get @@ -30,7 +148,8 @@ def get_config(config_file=None): config = ConfigParser.ConfigParser(defaults) if not config_file: - fpath = os.path.expanduser('~/.config/leap/eip.cfg') + fpath = os.path.expanduser( + '~/.config/leap/eip.cfg') if not os.path.isfile(fpath): dpath, cfile = os.path.split(fpath) if not os.path.isdir(dpath): @@ -46,27 +165,16 @@ def get_config(config_file=None): # for global settings. # - raise warnings/error if bad options. - try: - config.readfp(config_file) - except: - # XXX no file exists? - raise - return config - + # at this point, the file should exist. + # errors would have been raised above. + config.readfp(config_file) -# XXX wrapper around config? to get default values -def get_with_defaults(config, section, option): - # XXX REMOVE ME - if config.has_option(section, option): - return config.get(section, option) - else: - # XXX lookup in defaults dict??? - pass + return config def get_vpn_stdout_mockup(): # XXX REMOVE ME command = "python" - args = ["-u", "-c", "from eip_client import fakeclient;\ -fakeclient.write_output()"] + args = ["-u", "-c", ("from eip_client import fakeclient;" + "fakeclient.write_output()")] return command, args -- cgit v1.2.3 From 81613b2ef70e5d73b7c34eb4b78ee63189b45ab6 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 09:42:14 +0900 Subject: pkexec check --- src/leap/baseapp/dialogs.py | 22 ++++++++++++++++++++++ src/leap/baseapp/mainwindow.py | 25 +++++++++++++++++++++---- src/leap/baseapp/permcheck.py | 10 ++++++++++ src/leap/eip/conductor.py | 37 +++++++++++++++++++++++++++---------- src/leap/eip/config.py | 35 ++++++++++++++++++++++++++++------- 5 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 src/leap/baseapp/dialogs.py create mode 100644 src/leap/baseapp/permcheck.py (limited to 'src') diff --git a/src/leap/baseapp/dialogs.py b/src/leap/baseapp/dialogs.py new file mode 100644 index 00000000..d4e51a39 --- /dev/null +++ b/src/leap/baseapp/dialogs.py @@ -0,0 +1,22 @@ +from PyQt4.QtGui import (QDialog, QFrame, QPushButton, QLabel, QMessageBox) + + +class ErrorDialog(QDialog): + def __init__(self, parent=None): + super(ErrorDialog, self).__init__(parent) + + frameStyle = QFrame.Sunken | QFrame.Panel + self.warningLabel = QLabel() + self.warningLabel.setFrameStyle(frameStyle) + self.warningButton = QPushButton("QMessageBox.&warning()") + + def warningMessage(self, msg, label): + msgBox = QMessageBox(QMessageBox.Warning, + "QMessageBox.warning()", msg, + QMessageBox.NoButton, self) + msgBox.addButton("&Ok", QMessageBox.AcceptRole) + msgBox.addButton("&Cancel", QMessageBox.RejectRole) + if msgBox.exec_() == QMessageBox.AcceptRole: + self.warningLabel.setText("Save Again") + else: + self.warningLabel.setText("Continue") diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index f2c48acc..fec49282 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -11,8 +11,9 @@ from PyQt4.QtGui import (QMainWindow, QWidget, QVBoxLayout, QMessageBox, QTextBrowser, qApp) from PyQt4.QtCore import (pyqtSlot, pyqtSignal, QTimer) +from leap.baseapp.dialogs import ErrorDialog +from leap.eip.conductor import EIPConductor, EIPNoCommandError from leap.gui import mainwindow_rc -from leap.eip.conductor import EIPConductor class LeapWindow(QMainWindow): @@ -64,15 +65,24 @@ class LeapWindow(QMainWindow): # we pass a tuple of signals that will be # triggered when status changes. # + self.trayIcon.show() config_file = getattr(opts, 'config_file', None) + self.conductor = EIPConductor( watcher_cb=self.newLogLine.emit, config_file=config_file, status_signals=(self.statusChange.emit, )) - self.trayIcon.show() + 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') - self.setWindowTitle("Leap") + self.setWindowTitle("LEAP Client") self.resize(400, 300) self.set_statusbarMessage('ready') @@ -316,7 +326,14 @@ technolust") stub for running child process with vpn """ if self.vpn_service_started is False: - self.conductor.connect() + try: + self.conductor.connect() + except EIPNoCommandError: + dialog = ErrorDialog() + dialog.warningMessage( + 'No suitable openvpn command found. ' + '
(Might be a permissions problem)', + 'error') if self.debugmode: self.startStopButton.setText('&Disconnect') self.vpn_service_started = True diff --git a/src/leap/baseapp/permcheck.py b/src/leap/baseapp/permcheck.py new file mode 100644 index 00000000..58748761 --- /dev/null +++ b/src/leap/baseapp/permcheck.py @@ -0,0 +1,10 @@ +import os + +from leap.util.fileutil import which + + +def is_pkexec_in_system(): + pkexec_path = which('pkexec') + if not pkexec_path: + return False + return os.access(pkexec_path, os.X_OK) diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index bf7f0fb2..2d6ad764 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -8,7 +8,9 @@ import logging from leap.util.coroutines import spawn_and_watch_process -from leap.eip.config import get_config, build_ovpn_command + +from leap.eip.config import (get_config, build_ovpn_command, + EIPNoPkexecAvailable) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -17,6 +19,9 @@ logger = logging.getLogger(name=__name__) # TODO Move exceptions to their own module +class EIPNoCommandError(Exception): + pass + class ConnectionError(Exception): """ @@ -81,6 +86,10 @@ to be triggered for each one of them. self.port = None self.proto = None + self.missing_pkexec = False + self.command = None + self.args = None + self.autostart = True self._get_or_create_config() @@ -94,6 +103,14 @@ to be triggered for each one of them. config = get_config(config_file=self.config_file) self.config = config + if config.has_option('openvpn', 'autostart'): + autostart = config.getboolean('openvpn', 'autostart') + self.autostart = autostart + else: + if config.has_option('DEFAULT', 'autostart'): + autostart = config.getboolean('DEFAULT', 'autostart') + self.autostart = autostart + if config.has_option('openvpn', 'command'): commandline = config.get('openvpn', 'command') @@ -110,18 +127,16 @@ to be triggered for each one of them. else: # no command in config, we build it up. # XXX check also for command-line --command flag - command, args = build_ovpn_command(config) + try: + command, args = build_ovpn_command(config) + except EIPNoPkexecAvailable: + command = args = None + self.missing_pkexec = True + + # XXX if not command, signal error. self.command = command self.args = args - if config.has_option('openvpn', 'autostart'): - autostart = config.getboolean('openvpn', 'autostart') - self.autostart = autostart - else: - if config.has_option('DEFAULT', 'autostart'): - autostart = config.getboolean('DEFAULT', 'autostart') - self.autostart = autostart - def _launch_openvpn(self): """ invocation of openvpn binaries in a subprocess. @@ -152,6 +167,8 @@ to be triggered for each one of them. """ attempts to connect """ + if self.command is None: + raise EIPNoCommandError if self.subp is not None: print('cowardly refusing to launch subprocess again') return diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 3fca329c..c632ba40 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -4,6 +4,11 @@ import os import platform from leap.util.fileutil import which, mkdir_p +from leap.baseapp.permcheck import is_pkexec_in_system + + +class EIPNoPkexecAvailable(Exception): + pass def build_ovpn_options(): @@ -79,19 +84,35 @@ def build_ovpn_command(config): and a list of options. """ command = [] - use_pkexec = False + use_pkexec = True ovpn = None - if config.has_option('openvpn', 'openvpn_binary'): - ovpn = config.get('openvpn', 'openvpn_binary') - if not ovpn and config.has_option('DEFAULT', 'openvpn_binary'): - ovpn = config.get('DEFAULT', 'openvpn_binary') - if config.has_option('openvpn', 'use_pkexec'): use_pkexec = config.get('openvpn', 'use_pkexec') + if platform.system() == "Linux" and use_pkexec: + + # XXX check for both pkexec (done) + # AND a suitable authentication + # agent running. + + if not is_pkexec_in_system(): + raise EIPNoPkexecAvailable + + #TBD -- + #if not is_auth_agent_running() + # raise EIPNoPolkitAuthAgentAvailable - if use_pkexec: command.append('pkexec') + + if config.has_option('openvpn', + 'openvpn_binary'): + ovpn = config.get('openvpn', + 'openvpn_binary') + if not ovpn and config.has_option('DEFAULT', + 'openvpn_binary'): + ovpn = config.get('DEFAULT', + 'openvpn_binary') + if ovpn: command.append(ovpn) -- cgit v1.2.3 From 5c34052ef9261a47947e3e03616fe34b099b9fa4 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 10:18:50 +0900 Subject: stub for daemon mode; disabled by now until #383 is fixed --- src/leap/baseapp/mainwindow.py | 10 +++++++--- src/leap/eip/conductor.py | 9 ++++++--- src/leap/eip/config.py | 22 +++++++++++----------- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index fec49282..cd6600b4 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -59,19 +59,23 @@ class LeapWindow(QMainWindow): mainLayout.addWidget(self.loggerBox) widget.setLayout(mainLayout) + self.trayIcon.show() + config_file = getattr(opts, 'config_file', None) + # # conductor is in charge of all # vpn-related configuration / monitoring. # we pass a tuple of signals that will be # triggered when status changes. # - self.trayIcon.show() - config_file = getattr(opts, 'config_file', None) self.conductor = EIPConductor( watcher_cb=self.newLogLine.emit, config_file=config_file, - status_signals=(self.statusChange.emit, )) + status_signals=(self.statusChange.emit, ), + debug=self.debugmode) + + print('debugmode:%s' % self.debugmode) if self.conductor.missing_pkexec is True: dialog = ErrorDialog() diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 2d6ad764..eeb7f8f8 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -59,7 +59,8 @@ class OpenVPNConnection(object): """ # Connection Methods - def __init__(self, config_file=None, watcher_cb=None): + def __init__(self, config_file=None, + watcher_cb=None, debug=False): #XXX FIXME #change watcher_cb to line_observer """ @@ -74,6 +75,8 @@ to be triggered for each one of them. """ # XXX get host/port from config self.manager = OpenVPNManager() + self.debug = debug + print('conductor:%s' % debug) self.config_file = config_file self.watcher_cb = watcher_cb @@ -99,7 +102,6 @@ to be triggered for each one of them. home file, or config file passed in command line. populates command and args to be passed to subprocess. """ - #print('get or create config') config = get_config(config_file=self.config_file) self.config = config @@ -128,7 +130,8 @@ to be triggered for each one of them. # no command in config, we build it up. # XXX check also for command-line --command flag try: - command, args = build_ovpn_command(config) + command, args = build_ovpn_command(config, + debug=self.debug) except EIPNoPkexecAvailable: command = args = None self.missing_pkexec = True diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index c632ba40..4577837a 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -11,7 +11,7 @@ class EIPNoPkexecAvailable(Exception): pass -def build_ovpn_options(): +def build_ovpn_options(daemon=False): """ build a list of options to be passed in the @@ -68,10 +68,16 @@ def build_ovpn_options(): opts.append('--config') opts.append(ovpncnf) + # we cannot run in daemon mode + # with the current subp setting. + # see: https://leap.se/code/issues/383 + #if daemon is True: + # opts.append('--daemon') + return opts -def build_ovpn_command(config): +def build_ovpn_command(config, debug=False): """ build a string with the complete openvpn invocation @@ -116,7 +122,9 @@ def build_ovpn_command(config): if ovpn: command.append(ovpn) - for opt in build_ovpn_options(): + daemon_mode = not debug + + for opt in build_ovpn_options(daemon=daemon_mode): command.append(opt) # XXX check len and raise proper error @@ -191,11 +199,3 @@ def get_config(config_file=None): config.readfp(config_file) return config - - -def get_vpn_stdout_mockup(): - # XXX REMOVE ME - command = "python" - args = ["-u", "-c", ("from eip_client import fakeclient;" - "fakeclient.write_output()")] - return command, args -- cgit v1.2.3 From 0bb8cca027ab32a54f6792ab1b1368e2f1845368 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 10:46:22 +0900 Subject: check also for a suitable polkit-authentication-agent running fix #382. --- src/leap/baseapp/mainwindow.py | 10 ++++++++++ src/leap/baseapp/permcheck.py | 7 +++++++ src/leap/eip/conductor.py | 6 +++++- src/leap/eip/config.py | 13 +++++++++---- 4 files changed, 31 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index cd6600b4..0e2f4e1d 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -77,6 +77,16 @@ class LeapWindow(QMainWindow): print('debugmode:%s' % self.debugmode) + 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( diff --git a/src/leap/baseapp/permcheck.py b/src/leap/baseapp/permcheck.py index 58748761..6b74cb6e 100644 --- a/src/leap/baseapp/permcheck.py +++ b/src/leap/baseapp/permcheck.py @@ -1,3 +1,4 @@ +import commands import os from leap.util.fileutil import which @@ -8,3 +9,9 @@ def is_pkexec_in_system(): if not pkexec_path: return False return os.access(pkexec_path, os.X_OK) + + +def is_auth_agent_running(): + return bool( + commands.getoutput( + 'ps aux | grep polkit-[g]nome-authentication-agent-1')) diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index eeb7f8f8..7b927143 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -10,7 +10,7 @@ from leap.util.coroutines import spawn_and_watch_process from leap.eip.config import (get_config, build_ovpn_command, - EIPNoPkexecAvailable) + EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -90,6 +90,7 @@ to be triggered for each one of them. self.proto = None self.missing_pkexec = False + self.missing_auth_agent = False self.command = None self.args = None @@ -132,6 +133,9 @@ to be triggered for each one of them. try: command, args = build_ovpn_command(config, debug=self.debug) + except EIPNoPolkitAuthAgentAvailable: + command = args = None + self.missing_auth_agent = True except EIPNoPkexecAvailable: command = args = None self.missing_pkexec = True diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 4577837a..9583720e 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -4,13 +4,18 @@ import os import platform from leap.util.fileutil import which, mkdir_p -from leap.baseapp.permcheck import is_pkexec_in_system +from leap.baseapp.permcheck import (is_pkexec_in_system, + is_auth_agent_running) class EIPNoPkexecAvailable(Exception): pass +class EIPNoPolkitAuthAgentAvailable(Exception): + pass + + def build_ovpn_options(daemon=False): """ build a list of options @@ -34,6 +39,7 @@ def build_ovpn_options(daemon=False): opts = [] opts.append('--persist-tun') + opts.append('--persist-key') # set user and group opts.append('--user') @@ -104,9 +110,8 @@ def build_ovpn_command(config, debug=False): if not is_pkexec_in_system(): raise EIPNoPkexecAvailable - #TBD -- - #if not is_auth_agent_running() - # raise EIPNoPolkitAuthAgentAvailable + if not is_auth_agent_running(): + raise EIPNoPolkitAuthAgentAvailable command.append('pkexec') -- cgit v1.2.3 From a6416bd5e4dc57390ba0748878d229098aeca42e Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 Aug 2012 11:17:04 +0900 Subject: added log info for polkit checks --- src/leap/eip/config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 9583720e..f0cf1d86 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -1,5 +1,6 @@ import ConfigParser import grp +import logging import os import platform @@ -7,6 +8,8 @@ from leap.util.fileutil import which, mkdir_p from leap.baseapp.permcheck import (is_pkexec_in_system, is_auth_agent_running) +logger = logging.getLogger(name=__name__) + class EIPNoPkexecAvailable(Exception): pass @@ -106,11 +109,18 @@ def build_ovpn_command(config, debug=False): # XXX check for both pkexec (done) # AND a suitable authentication # agent running. + logger.info('use_pkexec set to True') if not is_pkexec_in_system(): + logger.error('no pkexec in system') raise EIPNoPkexecAvailable if not is_auth_agent_running(): + logger.warning( + "no polkit auth agent found. " + "pkexec will use its own text " + "based authentication agent. " + "that's probably a bad idea") raise EIPNoPolkitAuthAgentAvailable command.append('pkexec') -- cgit v1.2.3 From 36b0dfacca794e9cb899b5dde2dae3b8bbc6cc43 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 7 Aug 2012 04:14:06 +0900 Subject: build default provider openvpn config. preparation for completion of #356, #355, #354, #182 if no default openvpn config is present, we build one with a preset template and the remote_ip of the eip service as the only input. right now we're taking it from the eip.cfg file. --- src/leap/app.py | 4 +- src/leap/baseapp/mainwindow.py | 8 +-- src/leap/eip/conductor.py | 58 +++++++++++----- src/leap/eip/config.py | 149 ++++++++++++++++++++++++++++++++++++++--- src/leap/eip/vpnmanager.py | 3 +- 5 files changed, 191 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/leap/app.py b/src/leap/app.py index 186eb048..db48701b 100644 --- a/src/leap/app.py +++ b/src/leap/app.py @@ -6,6 +6,7 @@ from PyQt4.QtGui import (QApplication, QSystemTrayIcon, QMessageBox) from leap.baseapp.mainwindow import LeapWindow +logging.basicConfig() logger = logging.getLogger(name=__name__) @@ -21,7 +22,8 @@ def main(): #XXX get debug level and set logger accordingly if debug: - logger.debug('args: ', opts) + logger.setLevel('DEBUG') + logger.debug('args: %s' % opts) app = QApplication(sys.argv) diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index 0e2f4e1d..d5251a5c 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -75,7 +75,7 @@ class LeapWindow(QMainWindow): status_signals=(self.statusChange.emit, ), debug=self.debugmode) - print('debugmode:%s' % self.debugmode) + #print('debugmode:%s' % self.debugmode) if self.conductor.missing_auth_agent is True: dialog = ErrorDialog() @@ -310,11 +310,11 @@ technolust") updating icon, status bar, etc. """ - print('STATUS CHANGED! (on Qt-land)') - print('%s -> %s' % (status.previous, status.current)) + #print('STATUS CHANGED! (on Qt-land)') + #print('%s -> %s' % (status.previous, status.current)) icon_name = self.conductor.get_icon_name() self.setIcon(icon_name) - print 'icon = ', icon_name + #print 'icon = ', icon_name # change connection pixmap widget self.setConnWidget(icon_name) diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 7b927143..243f1fde 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -5,12 +5,15 @@ from __future__ import (division, unicode_literals, print_function) #import threading from functools import partial import logging +import os from leap.util.coroutines import spawn_and_watch_process from leap.eip.config import (get_config, build_ovpn_command, - EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable) + check_or_create_default_vpnconf, + EIPNoPkexecAvailable, + EIPNoPolkitAuthAgentAvailable) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -51,6 +54,10 @@ class UnrecoverableError(EIPClientError): # to user-friendly msg in dialog. pass +# +# Openvpn related classes +# + class OpenVPNConnection(object): """ @@ -76,7 +83,7 @@ to be triggered for each one of them. # XXX get host/port from config self.manager = OpenVPNManager() self.debug = debug - print('conductor:%s' % debug) + #print('conductor:%s' % debug) self.config_file = config_file self.watcher_cb = watcher_cb @@ -97,23 +104,20 @@ to be triggered for each one of them. self.autostart = True self._get_or_create_config() - def _get_or_create_config(self): - """ - retrieves the config options from defaults or - home file, or config file passed in command line. - populates command and args to be passed to subprocess. - """ - config = get_config(config_file=self.config_file) - self.config = config - + def _set_autostart(self): + config = self.config if config.has_option('openvpn', 'autostart'): - autostart = config.getboolean('openvpn', 'autostart') + autostart = config.getboolean('openvpn', + 'autostart') self.autostart = autostart else: if config.has_option('DEFAULT', 'autostart'): - autostart = config.getboolean('DEFAULT', 'autostart') + autostart = config.getboolean('DEFAULT', + 'autostart') self.autostart = autostart + def _set_ovpn_command(self): + config = self.config if config.has_option('openvpn', 'command'): commandline = config.get('openvpn', 'command') @@ -124,7 +128,6 @@ to be triggered for each one of them. else: args = [] - # XXX CALL BUILD COMMAND self.command = command self.args = args else: @@ -144,6 +147,29 @@ to be triggered for each one of them. self.command = command self.args = args + def _check_ovpn_config(self): + """ + checks if there is a default openvpn config. + if not, it writes one with info from the provider + definition file + """ + # TODO + # - get --with-openvpn-config from opts + check_or_create_default_vpnconf(self.config) + + def _get_or_create_config(self): + """ + retrieves the config options from defaults or + home file, or config file passed in command line. + populates command and args to be passed to subprocess. + """ + config = get_config(config_file=self.config_file) + self.config = config + + self._set_autostart() + self._set_ovpn_command() + self._check_ovpn_config() + def _launch_openvpn(self): """ invocation of openvpn binaries in a subprocess. @@ -167,8 +193,8 @@ to be triggered for each one of them. self.subp = subp self.watcher = watcher - conn_result = self.status.CONNECTED - return conn_result + #conn_result = self.status.CONNECTED + #return conn_result def _try_connection(self): """ diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index f0cf1d86..9af6f57a 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -9,6 +9,7 @@ from leap.baseapp.permcheck import (is_pkexec_in_system, is_auth_agent_running) logger = logging.getLogger(name=__name__) +logger.setLevel('DEBUG') class EIPNoPkexecAvailable(Exception): @@ -19,6 +20,129 @@ class EIPNoPolkitAuthAgentAvailable(Exception): pass +OPENVPN_CONFIG_TEMPLATE = """#Autogenerated by eip-client wizard +remote {VPN_REMOTE_HOST} {VPN_REMOTE_PORT} + +client +dev tun +persist-tun +persist-key +proto udp +tls-client +remote-cert-tls server + +cert {LEAP_EIP_KEYS} +key {LEAP_EIP_KEYS} +ca {LEAP_EIP_KEYS} +""" + + +def get_config_dir(): + """ + get the base dir for all leap config + @rparam: config path + @rtype: string + """ + # TODO + # check for $XDG_CONFIG_HOME var? + # get a more sensible path for win/mac + # kclair: opinion? ^^ + return os.path.expanduser( + os.path.join('~', + '.config', + 'leap')) + + +def get_config_file(filename, folder=None): + """ + concatenates the given filename + with leap config dir. + @param filename: name of the file + @type filename: string + @rparam: full path to config file + """ + path = [] + path.append(get_config_dir()) + if folder is not None: + path.append(folder) + path.append(filename) + return os.path.join(*path) + + +def get_default_provider_path(): + default_subpath = os.path.join("providers", + "default") + default_provider_path = get_config_file( + '', + folder=default_subpath) + return default_provider_path + + +def check_or_create_default_vpnconf(config): + """ + checks that a vpn config file + exists for a default provider, + or creates one if it does not. + ATM REQURES A [provider] section in + eip.cfg with _at least_ a remote_ip value + """ + default_provider_path = get_default_provider_path() + + if not os.path.isdir(default_provider_path): + mkdir_p(default_provider_path) + + conf_file = get_config_file( + 'openvpn.conf', + folder=default_provider_path) + + if os.path.isfile(conf_file): + return + else: + logger.debug( + 'missing default openvpn config\n' + 'creating one...') + + # We're getting provider from eip.cfg + # by now. Get it from a list of gateways + # instead. + + remote_ip = config.get('provider', + 'remote_ip') + + # XXX check that IT LOOKS LIKE AN IP!!! + if config.has_option('provider', 'remote_port'): + remote_port = config.get('provider', + 'remote_port') + else: + remote_port = 1194 + + default_subpath = os.path.join("providers", + "default") + default_provider_path = get_config_file( + '', + folder=default_subpath) + + if not os.path.isdir(default_provider_path): + mkdir_p(default_provider_path) + + conf_file = get_config_file( + 'openvpn.conf', + folder=default_provider_path) + + # XXX keys have to be manually placed by now + keys_file = get_config_file( + 'openvpn.keys', + folder=default_provider_path) + + ovpn_config = OPENVPN_CONFIG_TEMPLATE.format( + VPN_REMOTE_HOST=remote_ip, + VPN_REMOTE_PORT=remote_port, + LEAP_EIP_KEYS=keys_file) + + with open(conf_file, 'wb') as f: + f.write(ovpn_config) + + def build_ovpn_options(daemon=False): """ build a list of options @@ -41,8 +165,10 @@ def build_ovpn_options(daemon=False): group = grp.getgrgid(gid).gr_name opts = [] - opts.append('--persist-tun') - opts.append('--persist-key') + + #moved to config files + #opts.append('--persist-tun') + #opts.append('--persist-key') # set user and group opts.append('--user') @@ -69,19 +195,25 @@ def build_ovpn_options(daemon=False): # XXX which is a good choice? opts.append('7777') - # remaining config options, in a file + # remaining config options will go in a file + # NOTE: we will build this file from # the service definition file. - ovpncnf = os.path.expanduser( - '~/.config/leap/openvpn.conf') + # XXX override from --with-openvpn-config + opts.append('--config') + + default_provider_path = get_default_provider_path() + ovpncnf = get_config_file( + 'openvpn.conf', + folder=default_provider_path) opts.append(ovpncnf) # we cannot run in daemon mode # with the current subp setting. # see: https://leap.se/code/issues/383 #if daemon is True: - # opts.append('--daemon') + #opts.append('--daemon') return opts @@ -192,8 +324,7 @@ def get_config(config_file=None): config = ConfigParser.ConfigParser(defaults) if not config_file: - fpath = os.path.expanduser( - '~/.config/leap/eip.cfg') + fpath = get_config_file('eip.cfg') if not os.path.isfile(fpath): dpath, cfile = os.path.split(fpath) if not os.path.isdir(dpath): @@ -203,7 +334,6 @@ def get_config(config_file=None): config_file = open(fpath) #TODO - # - get a more sensible path for win/mac # - convert config_file to list; # look in places like /etc/leap/eip.cfg # for global settings. @@ -211,6 +341,7 @@ def get_config(config_file=None): # at this point, the file should exist. # errors would have been raised above. + config.readfp(config_file) return config diff --git a/src/leap/eip/vpnmanager.py b/src/leap/eip/vpnmanager.py index 78777cfb..caf7ab76 100644 --- a/src/leap/eip/vpnmanager.py +++ b/src/leap/eip/vpnmanager.py @@ -6,6 +6,7 @@ import telnetlib import time logger = logging.getLogger(name=__name__) +logger.setLevel('DEBUG') TELNET_PORT = 23 @@ -74,7 +75,7 @@ class OpenVPNManager(object): self.with_errors = False def forget_errors(self): - print('forgetting errors') + logger.debug('forgetting errors') self.with_errors = False def connect(self): -- cgit v1.2.3 From 530e10214a6f018909714b288d997df13ab4f9df Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 8 Aug 2012 06:53:10 +0900 Subject: check for bad permissions on vpn key files --- src/leap/baseapp/dialogs.py | 11 +++++++++ src/leap/baseapp/mainwindow.py | 14 ++++++++--- src/leap/eip/conductor.py | 21 +++++++++++++--- src/leap/eip/config.py | 56 +++++++++++++++++++++++++++++++++++++++++- src/leap/util/fileutil.py | 24 ++++++++++++++++++ 5 files changed, 119 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/leap/baseapp/dialogs.py b/src/leap/baseapp/dialogs.py index d4e51a39..4b1b5b62 100644 --- a/src/leap/baseapp/dialogs.py +++ b/src/leap/baseapp/dialogs.py @@ -20,3 +20,14 @@ class ErrorDialog(QDialog): self.warningLabel.setText("Save Again") else: self.warningLabel.setText("Continue") + + def criticalMessage(self, msg, label): + msgBox = QMessageBox(QMessageBox.Critical, + "QMessageBox.critical()", msg, + QMessageBox.NoButton, self) + msgBox.addButton("&Ok", QMessageBox.AcceptRole) + msgBox.addButton("&Cancel", QMessageBox.RejectRole) + if msgBox.exec_() == QMessageBox.AcceptRole: + self.warningLabel.setText("Save Again") + else: + self.warningLabel.setText("Continue") diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index d5251a5c..cbdd2d07 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -12,7 +12,12 @@ from PyQt4.QtGui import (QMainWindow, QWidget, QVBoxLayout, QMessageBox, from PyQt4.QtCore import (pyqtSlot, pyqtSignal, QTimer) from leap.baseapp.dialogs import ErrorDialog -from leap.eip.conductor import EIPConductor, EIPNoCommandError +from leap.eip.conductor import (EIPConductor, + EIPNoCommandError) + +from leap.eip.config import (EIPInitBadKeyFilePermError) +# from leap.eip import exceptions as eip_exceptions + from leap.gui import mainwindow_rc @@ -68,14 +73,17 @@ class LeapWindow(QMainWindow): # we pass a tuple of signals that will be # triggered when status changes. # - self.conductor = EIPConductor( watcher_cb=self.newLogLine.emit, config_file=config_file, status_signals=(self.statusChange.emit, ), debug=self.debugmode) - #print('debugmode:%s' % self.debugmode) + 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() diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 243f1fde..3f40f068 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -5,15 +5,16 @@ from __future__ import (division, unicode_literals, print_function) #import threading from functools import partial import logging -import os from leap.util.coroutines import spawn_and_watch_process - +# XXX import eip.config as eipconfig from leap.eip.config import (get_config, build_ovpn_command, check_or_create_default_vpnconf, + check_vpn_keys, EIPNoPkexecAvailable, - EIPNoPolkitAuthAgentAvailable) + EIPNoPolkitAuthAgentAvailable, + EIPInitBadKeyFilePermError) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -21,6 +22,7 @@ logger = logging.getLogger(name=__name__) # TODO Move exceptions to their own module +# eip.exceptions class EIPNoCommandError(Exception): pass @@ -98,11 +100,14 @@ to be triggered for each one of them. self.missing_pkexec = False self.missing_auth_agent = False + self.bad_keyfile_perms = False + self.command = None self.args = None self.autostart = True self._get_or_create_config() + self._check_vpn_keys() def _set_autostart(self): config = self.config @@ -170,6 +175,16 @@ to be triggered for each one of them. self._set_ovpn_command() self._check_ovpn_config() + def _check_vpn_keys(self): + """ + checks for correct permissions on vpn keys + """ + try: + check_vpn_keys(self.config) + except EIPInitBadKeyFilePermError: + logger.error('error while checking vpn keys') + self.bad_keyfile_perms = True + def _launch_openvpn(self): """ invocation of openvpn binaries in a subprocess. diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 9af6f57a..91c3953b 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -4,13 +4,17 @@ import logging import os import platform -from leap.util.fileutil import which, mkdir_p +from leap.util.fileutil import (which, mkdir_p, + check_and_fix_urw_only) from leap.baseapp.permcheck import (is_pkexec_in_system, is_auth_agent_running) logger = logging.getLogger(name=__name__) logger.setLevel('DEBUG') +# XXX move exceptions to +# from leap.eip import exceptions as eip_exceptions + class EIPNoPkexecAvailable(Exception): pass @@ -20,6 +24,14 @@ class EIPNoPolkitAuthAgentAvailable(Exception): pass +class EIPInitNoKeyFileError(Exception): + pass + + +class EIPInitBadKeyFilePermError(Exception): + pass + + OPENVPN_CONFIG_TEMPLATE = """#Autogenerated by eip-client wizard remote {VPN_REMOTE_HOST} {VPN_REMOTE_PORT} @@ -345,3 +357,45 @@ def get_config(config_file=None): config.readfp(config_file) return config + + +def check_vpn_keys(config): + """ + performs an existance and permission check + over the openvpn keys file. + Currently we're expecting a single file + per provider, containing the CA cert, + the provider key, and our client certificate + """ + + keyopt = ('provider', 'keyfile') + + # XXX at some point, + # should separate between CA, provider cert + # and our certificate. + # make changes in the default provider template + # accordingly. + + # get vpn keys + if config.has_option(*keyopt): + keyfile = config.get(*keyopt) + else: + keyfile = get_config_file( + 'openvpn.keys', + folder=get_default_provider_path()) + logger.debug('keyfile = %s', keyfile) + + # if no keys, raise error. + # should be catched by the ui and signal user. + + if not os.path.isfile(keyfile): + logger.error('key file %s not found. aborting.', + keyfile) + raise EIPInitNoKeyFileError + + # check proper permission on keys + # bad perms? try to fix them + try: + check_and_fix_urw_only(keyfile) + except OSError: + raise EIPInitBadKeyFilePermError diff --git a/src/leap/util/fileutil.py b/src/leap/util/fileutil.py index bb2c243b..cc3bf34b 100644 --- a/src/leap/util/fileutil.py +++ b/src/leap/util/fileutil.py @@ -1,10 +1,14 @@ import errno from itertools import chain +import logging import os import platform import stat +logger = logging.getLogger() + + def is_user_executable(fpath): st = os.stat(fpath) return bool(st.st_mode & stat.S_IXUSR) @@ -85,3 +89,23 @@ def mkdir_p(path): pass else: raise + + +def check_and_fix_urw_only(_file): + """ + test for 600 mode and try + to set it if anything different found + """ + mode = os.stat(_file).st_mode + if mode != int('600', 8): + try: + logger.warning( + 'bad permission on %s ' + 'attempting to set 600', + _file) + os.chmod(_file, stat.S_IRUSR | stat.S_IWUSR) + except OSError: + logger.error( + 'error while trying to chmod 600 %s', + _file) + raise -- cgit v1.2.3 From e81ddf7648e1075a15d8add11cd975a73aa09926 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 8 Aug 2012 07:01:27 +0900 Subject: catch missing keyfile error --- src/leap/baseapp/mainwindow.py | 13 +++++++++++++ src/leap/eip/conductor.py | 4 ++++ 2 files changed, 17 insertions(+) (limited to 'src') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index cbdd2d07..c54eb97f 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -79,6 +79,19 @@ class LeapWindow(QMainWindow): status_signals=(self.statusChange.emit, ), debug=self.debugmode) + # bunch of self checks. + # XXX move somewhere else alltogether. + + 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_keyfile_perms is True: dialog = ErrorDialog() dialog.criticalMessage( diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 3f40f068..11b0358c 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -14,6 +14,7 @@ from leap.eip.config import (get_config, build_ovpn_command, check_vpn_keys, EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable, + EIPInitNoKeyFileError, EIPInitBadKeyFilePermError) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -101,6 +102,7 @@ to be triggered for each one of them. self.missing_pkexec = False self.missing_auth_agent = False self.bad_keyfile_perms = False + self.missing_vpn_keyfile = False self.command = None self.args = None @@ -181,6 +183,8 @@ to be triggered for each one of them. """ try: check_vpn_keys(self.config) + except EIPInitNoKeyFileError: + self.missing_vpn_keyfile = True except EIPInitBadKeyFilePermError: logger.error('error while checking vpn keys') self.bad_keyfile_perms = True -- cgit v1.2.3 From c217bd1f1456cf10ceabf698ea6f4dd8f636f454 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 8 Aug 2012 07:22:36 +0900 Subject: check for validity of the remote_ip entry (is ip?) --- src/leap/baseapp/mainwindow.py | 16 ++++++++++++++++ src/leap/eip/conductor.py | 17 +++++++++++++++-- src/leap/eip/config.py | 31 ++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index c54eb97f..85129a9b 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -79,8 +79,17 @@ class LeapWindow(QMainWindow): status_signals=(self.statusChange.emit, ), debug=self.debugmode) + # # bunch of self checks. # XXX move somewhere else alltogether. + # + + 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() @@ -92,6 +101,13 @@ class LeapWindow(QMainWindow): # 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( diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 11b0358c..8f9d6051 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -8,12 +8,16 @@ import logging from leap.util.coroutines import spawn_and_watch_process -# XXX import eip.config as eipconfig +# XXX from leap.eip import config as eipconfig +# from leap.eip import exceptions as eip_exceptions + from leap.eip.config import (get_config, build_ovpn_command, check_or_create_default_vpnconf, check_vpn_keys, EIPNoPkexecAvailable, EIPNoPolkitAuthAgentAvailable, + EIPInitNoProviderError, + EIPInitBadProviderError, EIPInitNoKeyFileError, EIPInitBadKeyFilePermError) from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher @@ -103,6 +107,8 @@ to be triggered for each one of them. self.missing_auth_agent = False self.bad_keyfile_perms = False self.missing_vpn_keyfile = False + self.missing_provider = False + self.bad_provider = False self.command = None self.args = None @@ -162,7 +168,14 @@ to be triggered for each one of them. """ # TODO # - get --with-openvpn-config from opts - check_or_create_default_vpnconf(self.config) + try: + check_or_create_default_vpnconf(self.config) + except EIPInitNoProviderError: + logger.error('missing default provider definition') + self.missing_provider = True + except EIPInitBadProviderError: + logger.error('bad provider definition') + self.bad_provider = True def _get_or_create_config(self): """ diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 91c3953b..6118c9de 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -3,6 +3,7 @@ import grp import logging import os import platform +import socket from leap.util.fileutil import (which, mkdir_p, check_and_fix_urw_only) @@ -24,6 +25,14 @@ class EIPNoPolkitAuthAgentAvailable(Exception): pass +class EIPInitNoProviderError(Exception): + pass + + +class EIPInitBadProviderError(Exception): + pass + + class EIPInitNoKeyFileError(Exception): pass @@ -90,6 +99,14 @@ def get_default_provider_path(): return default_provider_path +def validate_ip(ip_str): + """ + raises exception if the ip_str is + not a valid representation of an ip + """ + socket.inet_aton(ip_str) + + def check_or_create_default_vpnconf(config): """ checks that a vpn config file @@ -118,10 +135,18 @@ def check_or_create_default_vpnconf(config): # by now. Get it from a list of gateways # instead. - remote_ip = config.get('provider', - 'remote_ip') + try: + remote_ip = config.get('provider', + 'remote_ip') + validate_ip(remote_ip) + + except ConfigParser.NoOptionError: + raise EIPInitNoProviderError + + except socket.error: + # this does not look like an ip, dave + raise EIPInitBadProviderError - # XXX check that IT LOOKS LIKE AN IP!!! if config.has_option('provider', 'remote_port'): remote_port = config.get('provider', 'remote_port') -- cgit v1.2.3