summaryrefslogtreecommitdiffstats
path: root/settings_manager.py
diff options
context:
space:
mode:
authorVishwanatha Subbanna <vishwa@linux.vnet.ibm.com>2016-09-21 15:49:26 +0530
committerPatrick Williams <patrick@stwcx.xyz>2016-09-27 18:42:55 +0000
commit5b090c61086f196fbaa9279ae7728d3680f52e43 (patch)
tree60e7a49d53e282c9a84b1f25397a1c240bc69050 /settings_manager.py
parentd5b7e9385bd62dddaf765810c16f68ea2a1c6324 (diff)
downloadphosphor-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.py101
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)
OpenPOWER on IntegriCloud