From fd6d67001c762919ad3769865285a5a8c76630a1 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 9 Feb 2020 10:44:23 +0100 Subject: snmp: T1931: harden logic when re-reading config fpr encrypted keys --- src/conf_mode/snmp.py | 71 +++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 6cccf2032..cd63d6d62 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -743,8 +743,8 @@ def apply(snmp): # Passwords are not available immediately in the configuration file, # after daemon startup - we wait until they have been processed by # snmpd, which we see when a magic line appears in this file. - snmpReady = False - while not snmpReady: + ready = False + while not ready: while not os.path.exists(config_file_user): sleep(0.1) @@ -752,37 +752,46 @@ def apply(snmp): for line in f: # Search for our magic string inside the file if '**** DO NOT EDIT THIS FILE ****' in line: - snmpReady = True + ready = True break - # Back in the Perl days the configuration was re-read and any - # plaintext password inside the configuration was replaced by - # the encrypted one which can be found in 'config_file_user' - with open(config_file_user, 'r') as f: - engineID = '' - for line in f: - if line.startswith('oldEngineID'): - string = line.split(' ') - engineID = string[1] - - if line.startswith('usmUser'): - string = line.split(' ') - cfg = { - 'user': string[4].replace(r'"', ''), - 'auth_pw': string[8], - 'priv_pw': string[10] - } - # No need to take care about the VyOS internal user - if cfg['user'] == snmp['vyos_user']: - continue - - # Now update the running configuration - # - # Currently when executing os.system() the environment does not have the vyos_libexec_dir variable set, see T685 - os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_set service snmp v3 user "{0}" auth encrypted-key {1} > /dev/null'.format(cfg['user'], cfg['auth_pw'])) - os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_set service snmp v3 user "{0}" privacy encrypted-key {1} > /dev/null'.format(cfg['user'], cfg['priv_pw'])) - os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_delete service snmp v3 user "{0}" auth plaintext-key > /dev/null'.format(cfg['user'])) - os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_delete service snmp v3 user "{0}" privacy plaintext-key > /dev/null'.format(cfg['user'])) + # net-snmp is now regenerating the configuration file in the background + # thus we need to re-open and re-read the file as the content changed. + # After that we can no read the encrypted password from the config and + # replace the CLI plaintext password with its encrypted version. + ready = False + while not ready: + while not os.path.exists(config_file_user): + sleep(0.1) + + with open(config_file_user, 'r') as f: + engineID = '' + for line in f: + if line.startswith('oldEngineID'): + string = line.split(' ') + engineID = string[1] + + if line.startswith('usmUser'): + string = line.split(' ') + cfg = { + 'user': string[4].replace(r'"', ''), + 'auth_pw': string[8], + 'priv_pw': string[10] + } + # No need to take care about the VyOS internal user + if cfg['user'] == snmp['vyos_user']: + continue + + # Now update the running configuration + # + # Currently when executing os.system() the environment does not have the vyos_libexec_dir variable set, see T685 + os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_set service snmp v3 user "{0}" auth encrypted-key {1} > /dev/null'.format(cfg['user'], cfg['auth_pw'])) + os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_set service snmp v3 user "{0}" privacy encrypted-key {1} > /dev/null'.format(cfg['user'], cfg['priv_pw'])) + os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_delete service snmp v3 user "{0}" auth plaintext-key > /dev/null'.format(cfg['user'])) + os.system('vyos_libexec_dir=/usr/libexec/vyos /opt/vyatta/sbin/my_delete service snmp v3 user "{0}" privacy plaintext-key > /dev/null'.format(cfg['user'])) + + # set marker + ready = True # Enable AgentX in FRR os.system('vtysh -c "configure terminal" -c "agentx" >/dev/null') -- cgit v1.2.3