Skip to content

Commit

Permalink
Improve handling rejected access to properties
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
marmarek committed Mar 13, 2017
1 parent 5615510 commit f027aa5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
52 changes: 32 additions & 20 deletions qubesmgmt/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,14 @@ def property_is_default(self, item):
def __getattr__(self, item):
if item.startswith('_'):
raise AttributeError(item)
property_str = self.qubesd_call(
self._method_dest,
self._method_prefix + 'Get',
item,
None)
try:
property_str = self.qubesd_call(
self._method_dest,
self._method_prefix + 'Get',
item,
None)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(item)
(_default, value) = property_str.split(b' ', 1)
value = value.decode()
if value[0] == '\'':
Expand All @@ -153,25 +156,34 @@ def __setattr__(self, key, value):
if key.startswith('_') or key in dir(self):
return super(PropertyHolder, self).__setattr__(key, value)
if value is qubesmgmt.DEFAULT:
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Reset',
key,
None)
try:
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Reset',
key,
None)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(key)
else:
if isinstance(value, qubesmgmt.vm.QubesVM):
value = value.name
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Set',
key,
str(value).encode('utf-8'))
try:
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Set',
key,
str(value).encode('utf-8'))
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(key)

def __delattr__(self, name):
if name.startswith('_') or name in dir(self):
return super(PropertyHolder, self).__delattr__(name)
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Reset',
name
)
try:
self.qubesd_call(
self._method_dest,
self._method_prefix + 'Reset',
name
)
except qubesmgmt.exc.QubesDaemonNoResponseError:
raise qubesmgmt.exc.QubesPropertyAccessError(name)
8 changes: 8 additions & 0 deletions qubesmgmt/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@ class QubesDaemonCommunicationError(QubesException, IOError):
# pylint: disable=too-many-ancestors
class QubesDaemonNoResponseError(QubesDaemonCommunicationError):
'''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)

0 comments on commit f027aa5

Please sign in to comment.