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/leap') 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