Improve handling rejected access to properties

When qubesd reject access to property (do not return anything), it may
mean various things - invalid property, permission denied, or even
invalid VM. Handle all of those with exception inheriting from
AttributeError.
This commit is contained in:
Marek Marczykowski-Górecki 2017-03-11 01:44:06 +01:00
parent 5615510da5
commit f027aa5385
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 40 additions and 20 deletions

View File

@ -137,11 +137,14 @@ class PropertyHolder(object):
def __getattr__(self, item): def __getattr__(self, item):
if item.startswith('_'): if item.startswith('_'):
raise AttributeError(item) raise AttributeError(item)
property_str = self.qubesd_call( try:
self._method_dest, property_str = self.qubesd_call(
self._method_prefix + 'Get', self._method_dest,
item, self._method_prefix + 'Get',
None) item,
None)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(item)
(_default, value) = property_str.split(b' ', 1) (_default, value) = property_str.split(b' ', 1)
value = value.decode() value = value.decode()
if value[0] == '\'': if value[0] == '\'':
@ -153,25 +156,34 @@ class PropertyHolder(object):
if key.startswith('_') or key in dir(self): if key.startswith('_') or key in dir(self):
return super(PropertyHolder, self).__setattr__(key, value) return super(PropertyHolder, self).__setattr__(key, value)
if value is qubesmgmt.DEFAULT: if value is qubesmgmt.DEFAULT:
self.qubesd_call( try:
self._method_dest, self.qubesd_call(
self._method_prefix + 'Reset', self._method_dest,
key, self._method_prefix + 'Reset',
None) key,
None)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(key)
else: else:
if isinstance(value, qubesmgmt.vm.QubesVM): if isinstance(value, qubesmgmt.vm.QubesVM):
value = value.name value = value.name
self.qubesd_call( try:
self._method_dest, self.qubesd_call(
self._method_prefix + 'Set', self._method_dest,
key, self._method_prefix + 'Set',
str(value).encode('utf-8')) key,
str(value).encode('utf-8'))
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(key)
def __delattr__(self, name): def __delattr__(self, name):
if name.startswith('_') or name in dir(self): if name.startswith('_') or name in dir(self):
return super(PropertyHolder, self).__delattr__(name) return super(PropertyHolder, self).__delattr__(name)
self.qubesd_call( try:
self._method_dest, self.qubesd_call(
self._method_prefix + 'Reset', self._method_dest,
name self._method_prefix + 'Reset',
) name
)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(name)

View File

@ -111,3 +111,11 @@ class QubesDaemonCommunicationError(QubesException, IOError):
# pylint: disable=too-many-ancestors # pylint: disable=too-many-ancestors
class QubesDaemonNoResponseError(QubesDaemonCommunicationError): class QubesDaemonNoResponseError(QubesDaemonCommunicationError):
'''Got empty response from qubesd''' '''Got empty response from qubesd'''
class QubesPropertyAccessError(QubesException, AttributeError):
'''Failed to read/write property value, cause is unknown (insufficient
permissions, no such property, invalid value, other)'''
def __init__(self, prop):
super(QubesPropertyAccessError, self).__init__(
'Failed to access \'%s\' property' % prop)