mgmt: implement mgmt.vm.property.Set
Sanitization of input value is tricky here, and also very important at the same time. If property define value type (and it's something more specific than 'str'), use that. Otherwise allow only printable ASCII characters, and let appropriate event and setter handle value. At this point I've reviewed all QubesVM properties in this category and added appropriate setters where needed. QubesOS/qubes-issues#2622
This commit is contained in:
parent
da51e6f032
commit
868dbeac3e
@ -188,6 +188,53 @@ class QubesMgmt(object):
|
||||
property_type,
|
||||
str(value) if value is not None else '')
|
||||
|
||||
@asyncio.coroutine
|
||||
def vm_property_set(self, untrusted_payload):
|
||||
assert self.arg in self.dest.property_list()
|
||||
|
||||
property_def = self.dest.property_get_def(self.arg)
|
||||
# do not treat type='str' as sufficient validation
|
||||
if isinstance(property_def, qubes.vm.VMProperty):
|
||||
try:
|
||||
untrusted_vmname = untrusted_payload.decode('ascii')
|
||||
except UnicodeDecodeError:
|
||||
raise qubes.exc.QubesValueError
|
||||
qubes.vm.qubesvm.validate_name(self.dest, property_def,
|
||||
untrusted_vmname)
|
||||
try:
|
||||
newvalue = self.app.domains[untrusted_vmname]
|
||||
except KeyError:
|
||||
raise qubes.exc.QubesPropertyValueError(
|
||||
self.dest, property_def, untrusted_vmname)
|
||||
elif property_def.type is not None and property_def.type is not str:
|
||||
if property_def.type is bool:
|
||||
try:
|
||||
untrusted_value = untrusted_payload.decode('ascii')
|
||||
except UnicodeDecodeError:
|
||||
raise qubes.exc.QubesValueError
|
||||
newvalue = qubes.property.bool(None, None, untrusted_value)
|
||||
else:
|
||||
try:
|
||||
newvalue = property_def.type(untrusted_payload)
|
||||
except ValueError:
|
||||
raise qubes.exc.QubesValueError
|
||||
else:
|
||||
# other types (including explicitly defined 'str') coerce to str
|
||||
# with limited characters allowed
|
||||
try:
|
||||
untrusted_value = untrusted_payload.decode('ascii')
|
||||
except UnicodeDecodeError:
|
||||
raise qubes.exc.QubesValueError
|
||||
allowed_set = string.printable
|
||||
if not all(x in allowed_set for x in untrusted_value):
|
||||
raise qubes.exc.QubesValueError(
|
||||
'Invalid characters in property value')
|
||||
newvalue = untrusted_value
|
||||
|
||||
self.fire_event_for_permission(newvalue=newvalue)
|
||||
|
||||
setattr(self.dest, self.arg, newvalue)
|
||||
|
||||
@asyncio.coroutine
|
||||
def vm_property_help(self, untrusted_payload):
|
||||
assert self.arg in self.dest.property_list()
|
||||
|
Loading…
Reference in New Issue
Block a user