diff options
-rw-r--r-- | python/vyos/ifconfig/control.py | 22 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 22 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-openvpn.py | 27 |
3 files changed, 43 insertions, 28 deletions
diff --git a/python/vyos/ifconfig/control.py b/python/vyos/ifconfig/control.py index 508b4e279..635b626e8 100644 --- a/python/vyos/ifconfig/control.py +++ b/python/vyos/ifconfig/control.py @@ -29,12 +29,13 @@ class Control: def _cmd(self, command): p = Popen(command, stdout=PIPE, stderr=STDOUT, shell=True) tmp = p.communicate()[0].strip() - self._debug_msg("cmd '{}'".format(command)) - if tmp.decode(): - self._debug_msg("returned:\n{}".format(tmp.decode())) - - # do we need some error checking code here? - return tmp.decode() + self._debug_msg(f"cmd '{command}'") + decoded = tmp.decode() + if decoded: + self._debug_msg(f"returned:\n{decoded}") + if p.returncode != 0: + raise RuntimeError(f'{command}\nreturned: {decoded}') + return decoded def _get_command(self, config, name): """ @@ -55,14 +56,17 @@ class Control: validate = self._command_set[name].get('validate', None) if validate: - validate(value) - - config = {**config, **{'value': value}} + try: + validate(value) + except Exception as e: + raise e.__class__(f'Could not set {name}. {e}') convert = self._command_set[name].get('convert', None) if convert: value = convert(value) + config = {**config, **{'value': value}} + cmd = self._command_set[name]['shellcmd'].format(**config) return self._cmd(cmd) diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index b002e0171..21ffa88f6 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -77,6 +77,10 @@ class Interface(Control): } _command_set = { + 'state': { + 'validate': lambda v: assert_list(v, ['up', 'down']), + 'shellcmd': 'ip link set dev {ifname} {value}', + }, 'mac': { 'validate': assert_mac, 'shellcmd': 'ip link set dev {ifname} address {value}', @@ -166,13 +170,15 @@ class Interface(Control): if k in kargs: self.config[k] = kargs[k] - for k in self.required: - if k not in kargs: - raise ConfigError('missing required option {} for {}'.format(k,self.__class__)) - if not os.path.exists('/sys/class/net/{}'.format(self.config['ifname'])): if not self.config['type']: raise Exception('interface "{}" not found'.format(self.config['ifname'])) + + for k in self.required: + if k not in kargs: + name = self.default['type'] + raise ConfigError(f'missing required option {k} for {name} {ifname} creation') + self._create() # per interface DHCP config files @@ -452,13 +458,7 @@ class Interface(Control): >>> Interface('eth0').get_state() 'down' """ - if state not in ['up', 'down']: - raise ValueError('state must be "up" or "down"') - - # Assemble command executed on system. Unfortunately there is no way - # to up/down an interface via sysfs - cmd = 'ip link set dev {} {}'.format(self.config['ifname'], state) - return self._cmd(cmd) + return self.set_interface('state', state) def set_proxy_arp(self, enable): """ diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 6b2e3e52e..463ae9fd7 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -365,7 +365,7 @@ def fixup_permission(filename, permission=S_IRUSR): def checkCertHeader(header, filename): """ Verify if filename contains specified header. - Returns True on success or on file not found to not trigger the exceptions + Returns True if match is found, False if no match or file is not found """ if not os.path.isfile(filename): return False @@ -375,7 +375,7 @@ def checkCertHeader(header, filename): if re.match(header, line): return True - return True + return False def get_config(): openvpn = deepcopy(default_config_data) @@ -658,6 +658,11 @@ def get_config(): if conf.exists('use-lzo-compression'): openvpn['compress_lzo'] = True + # Special case when using EC certificates: + # if key-file is EC and dh-file is unset, set tls_dh to 'none' + if not openvpn['tls_dh'] and openvpn['tls_key'] and checkCertHeader('-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']): + openvpn['tls_dh'] = 'none' + return openvpn def verify(openvpn): @@ -692,7 +697,7 @@ def verify(openvpn): if not openvpn['remote_host']: raise ConfigError('Must specify "remote-host" in client mode') - if openvpn['tls_dh']: + if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none': raise ConfigError('Cannot specify "tls dh-file" in client mode') # @@ -742,8 +747,8 @@ def verify(openvpn): if openvpn['protocol'] == 'tcp-passive' and len(openvpn['remote_host']) > 1: raise ConfigError('Cannot specify more than 1 "remote-host" with "tcp-passive"') - if not openvpn['tls_dh']: - raise ConfigError('Must specify "tls dh-file" in server mode') + if not openvpn['tls_dh'] and not checkCertHeader('-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']): + raise ConfigError('Must specify "tls dh-file" when not using EC keys in server mode') if not openvpn['server_subnet']: if not openvpn['bridge_member']: @@ -825,7 +830,7 @@ def verify(openvpn): raise ConfigError('Specified cert-file "{}" is invalid'.format(openvpn['tls_cert'])) if openvpn['tls_key']: - if not checkCertHeader('-----BEGIN (?:RSA )?PRIVATE KEY-----', openvpn['tls_key']): + if not checkCertHeader('-----BEGIN (?:RSA |EC )?PRIVATE KEY-----', openvpn['tls_key']): raise ConfigError('Specified key-file "{}" is not valid'.format(openvpn['tls_key'])) if openvpn['tls_crypt']: @@ -836,7 +841,7 @@ def verify(openvpn): if not checkCertHeader('-----BEGIN X509 CRL-----', openvpn['tls_crl']): raise ConfigError('Specified crl-file "{} not valid'.format(openvpn['tls_crl'])) - if openvpn['tls_dh']: + if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none': if not checkCertHeader('-----BEGIN DH PARAMETERS-----', openvpn['tls_dh']): raise ConfigError('Specified dh-file "{}" is not valid'.format(openvpn['tls_dh'])) @@ -849,7 +854,7 @@ def verify(openvpn): if openvpn['protocol'] == 'tcp-passive': raise ConfigError('Cannot specify "tcp-passive" when "tls role" is "active"') - if openvpn['tls_dh']: + if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none': raise ConfigError('Cannot specify "tls dh-file" when "tls role" is "active"') elif openvpn['tls_role'] == 'passive': @@ -859,6 +864,12 @@ def verify(openvpn): if not openvpn['tls_dh']: raise ConfigError('Must specify "tls dh-file" when "tls role" is "passive"') + if openvpn['tls_key'] and checkCertHeader('-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']): + if openvpn['tls_dh'] and openvpn['tls_dh'] != 'none': + print('Warning: using dh-file and EC keys simultaneously will lead to DH ciphers being used instead of ECDH') + else: + print('Diffie-Hellman prime file is unspecified, assuming ECDH') + # # Auth user/pass # |