diff options
author | Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com> | 2016-09-21 15:49:26 +0530 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2016-09-27 18:42:55 +0000 |
commit | 5b090c61086f196fbaa9279ae7728d3680f52e43 (patch) | |
tree | 60e7a49d53e282c9a84b1f25397a1c240bc69050 /settings_manager.py | |
parent | d5b7e9385bd62dddaf765810c16f68ea2a1c6324 (diff) | |
download | phosphor-settingsd-5b090c61086f196fbaa9279ae7728d3680f52e43.tar.gz phosphor-settingsd-5b090c61086f196fbaa9279ae7728d3680f52e43.zip |
Validate user inputs in settings daemon
Currently, the properties defined under /org/openbmc/settings/host0 can take any
value and it is upto the consumer daemons to act only if the valid data was
given.
This patch will provide a validation logic for all the properties and will raise
an exception in the case of invalid inputs. Only on a valid input, will the data
gets written and saved.
Validation methods and types per property are provided in the configuration file
and used by the manager whenever a particular property is changed.
Change-Id: I0731ce6e00ab3cb4e11deb98c03fda8d5adad913
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
Diffstat (limited to 'settings_manager.py')
-rw-r--r-- | settings_manager.py | 101 |
1 files changed, 94 insertions, 7 deletions
diff --git a/settings_manager.py b/settings_manager.py index 864ee9d..997c56f 100644 --- a/settings_manager.py +++ b/settings_manager.py @@ -8,10 +8,12 @@ import os import os.path as path import sys from obmc.dbuslib.bindings import DbusProperties, get_dbus +from IPy import IP settings_file_path = os.path.join(sys.prefix, 'share/obmc-phosphor-settings') sys.path.insert(1, settings_file_path) import settings_file as s +import re DBUS_NAME = 'org.openbmc.settings.Host' OBJ_NAME = '/org/openbmc/settings/host0' @@ -20,10 +22,14 @@ CONTROL_INTF = 'org.openbmc.Settings' class HostSettingsObject(DbusProperties): def __init__(self, bus, name, settings, path): - DbusProperties.__init__(self) - dbus.service.Object.__init__(self, bus, name) - + super(HostSettingsObject, self).__init__(conn=bus, object_path=name, + validator=self.input_validator) + self.bus = bus self.path = path + # Needed to ignore the validation on default networkconfig values as + # opposed to user giving the same. + self.adminmode = True + if not os.path.exists(path): os.mkdir(path) @@ -35,11 +41,13 @@ class HostSettingsObject(DbusProperties): path="/org/openbmc/settings/host0") # Create the dbus properties - for i in settings['host'].iterkeys(): - shk = settings['host'][i] + for i in settings[DBUS_NAME].iterkeys(): + shk = settings[DBUS_NAME][i] self.set_settings_property(shk['name'], shk['type'], shk['default']) + # Done with consuming factory settings. + self.adminmode = False def get_bmc_value(self, name): try: @@ -58,11 +66,11 @@ class HostSettingsObject(DbusProperties): if bmcv: value = bmcv if type == "i": - self.Set(DBUS_NAME, name, value) + self.Set(DBUS_NAME, name, int(value)) elif type == "s": self.Set(DBUS_NAME, name, str(value)) elif type == "b": - self.Set(DBUS_NAME, name, value) + self.Set(DBUS_NAME, name, bool(value)) # Save the settings to the BMC. This will write the settings value in # individual files named by the property name to the BMC. @@ -85,6 +93,85 @@ class HostSettingsObject(DbusProperties): def SettingsUpdated(self, sname): pass + def validate_regex(self, regex, value): + if not re.compile(regex).search(value): + raise ValueError, "Invalid input. Data does not satisfy regex" + + def validate_range(self, min, max, value): + if value not in range(min, max): + raise ValueError, "Invalid input. Data not in allowed range" + + def validate_list_ignore_case(self, lst, value): + if value.lower() not in map(lambda val: val.lower(), lst): + raise ValueError, "Invalid input. Data not in allowed values" + + # validate host network configuration + # need "ipaddress=,prefix=,gateway=,mac=,addr_type=" + # Must be able to handle any order + def validate_net_config(self, value): + if self.adminmode: + return + + # Need all of these to be given by the user. + user_config = [] + all_config = ['ipaddress', 'prefix', 'gateway', 'mac', 'addr_type'] + + # This has a hard data format mentioned above so no blanks allowed. + if value.count(" ") or value.count("=") != 5: + raise ValueError, "Invalid Network Data. No white spaces allowed" + + config = value.split(',') + for key_value in config: + key , value = key_value.split('=') + if not key or not value: + raise ValueError, "Invalid key or Data" + + # Add the current key seen so we can compare at the end to see + # if all values have been given + user_config.append(key.lower()) + + if key.lower() == 'ipaddress' or key.lower() == 'gateway': + IP(value) + + elif key.lower() == 'mac': + regex = '([a-fA-F0-9]{2}[:|\-]?){6}' + self.validate_regex(regex, value) + + elif key.lower() == 'prefix': + self.validate_range(0, 33, int(value)) + + elif key.lower() == 'addr_type': + allowed = ["STATIC", "DYNAMIC"] + self.validate_list_ignore_case(allowed, value) + + # Did user pass everything ?? + if set(all_config) - set(user_config): + raise ValueError, "Invalid Network Data. All information is mandatory" + + # Validate to see if the changes are in order + def input_validator(self, iface, proprty, value): + settings = s.SETTINGS + shk = {} + for key in settings[iface].iterkeys(): + if proprty == settings[iface][key]['name']: + shk = settings[iface][key] + break + + # User entered key is not present + if not shk: raise KeyError, "Invalid Property" + + if shk['validation'] == 'list': + self.validate_list_ignore_case(shk['allowed'], value) + + elif shk['validation'] == 'range': + self.validate_range(shk['min'], shk['max']+1, value) + + elif shk['validation'] == 'regex': + self.validate_regex(shk['regex'], value) + + elif shk['validation'] == 'custom': + getattr(self, shk['method'])(value) + if __name__ == '__main__': dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |