qubespolicy: move all syntax-level validation to one place
This will make analyzing the policy code slightly easier. While it makes verify_special_value function more complex, other places are much simpler now.
This commit is contained in:
		
							parent
							
								
									5e870e4b6a
								
							
						
					
					
						commit
						d4716832e2
					
				| @ -85,30 +85,43 @@ def verify_target_value(system_info, value): | |||||||
|         return value in system_info['domains'] |         return value in system_info['domains'] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def verify_special_value(value, for_target=True): | def verify_special_value(value, for_target=True, specific_target=False): | ||||||
|     ''' |     ''' | ||||||
|     Verify if given special VM-specifier ('$...') is valid |     Verify if given special VM-specifier ('$...') is valid | ||||||
| 
 | 
 | ||||||
|     :param value: value to verify |     :param value: value to verify | ||||||
|     :param for_target: should classify target-only values as valid ( |     :param for_target: should classify target-only values as valid ( | ||||||
|         '$default', '$dispvm') |         '$default', '$dispvm') | ||||||
|  |     :param specific_target: allow only values naming specific target | ||||||
|  |         (for use with target=, default= etc) | ||||||
|     :return: True or False |     :return: True or False | ||||||
|     ''' |     ''' | ||||||
|     # pylint: disable=too-many-return-statements |     # pylint: disable=too-many-return-statements | ||||||
| 
 | 
 | ||||||
|  |     # values used only for matching VMs, not naming specific one (for actual | ||||||
|  |     # call target) | ||||||
|  |     if not specific_target: | ||||||
|         if value.startswith('$tag:') and len(value) > len('$tag:'): |         if value.startswith('$tag:') and len(value) > len('$tag:'): | ||||||
|             return True |             return True | ||||||
|     elif value.startswith('$type:') and len(value) > len('$type:'): |         if value.startswith('$type:') and len(value) > len('$type:'): | ||||||
|             return True |             return True | ||||||
|     elif value == '$anyvm': |         if for_target and value.startswith('$dispvm:$tag:') and \ | ||||||
|  |                 len(value) > len('$dispvm:$tag:'): | ||||||
|             return True |             return True | ||||||
|     elif value == '$adminvm': |         if value == '$anyvm': | ||||||
|             return True |             return True | ||||||
|     elif value.startswith('$dispvm:') and for_target: |         if for_target and value == '$default': | ||||||
|             return True |             return True | ||||||
|     elif value == '$dispvm' and for_target: | 
 | ||||||
|  |     # those can be used to name one specific call VM | ||||||
|  |     if value == '$adminvm': | ||||||
|         return True |         return True | ||||||
|     elif value == '$default' and for_target: |     # allow only specific dispvm, not based on any $xxx keyword - don't name | ||||||
|  |     # $tag here specifically, to work also with any future keywords | ||||||
|  |     if for_target and value.startswith('$dispvm:') and \ | ||||||
|  |             not value.startswith('$dispvm:$'): | ||||||
|  |         return True | ||||||
|  |     if for_target and value == '$dispvm': | ||||||
|         return True |         return True | ||||||
|     return False |     return False | ||||||
| 
 | 
 | ||||||
| @ -179,12 +192,12 @@ class PolicyRule(object): | |||||||
| 
 | 
 | ||||||
|         # verify special values |         # verify special values | ||||||
|         if self.source.startswith('$'): |         if self.source.startswith('$'): | ||||||
|             if not verify_special_value(self.source, False): |             if not verify_special_value(self.source, False, False): | ||||||
|                 raise PolicySyntaxError(filename, lineno, |                 raise PolicySyntaxError(filename, lineno, | ||||||
|                     'invalid source specification: {}'.format(self.source)) |                     'invalid source specification: {}'.format(self.source)) | ||||||
| 
 | 
 | ||||||
|         if self.target.startswith('$'): |         if self.target.startswith('$'): | ||||||
|             if not verify_special_value(self.target, True): |             if not verify_special_value(self.target, True, False): | ||||||
|                 raise PolicySyntaxError(filename, lineno, |                 raise PolicySyntaxError(filename, lineno, | ||||||
|                     'invalid target specification: {}'.format(self.target)) |                     'invalid target specification: {}'.format(self.target)) | ||||||
| 
 | 
 | ||||||
| @ -196,10 +209,13 @@ class PolicyRule(object): | |||||||
| 
 | 
 | ||||||
|         if self.override_target is not None: |         if self.override_target is not None: | ||||||
|             if self.override_target.startswith('$') and \ |             if self.override_target.startswith('$') and \ | ||||||
|                     (not self.override_target.startswith('$dispvm') or |                     not verify_special_value(self.override_target, True, True): | ||||||
|                     self.override_target.startswith('$dispvm:$tag:') or |                 raise PolicySyntaxError(filename, lineno, | ||||||
|                     self.override_target.startswith('$tag:')) and \ |                     'target= option needs to name specific target') | ||||||
|                     self.override_target != '$adminvm': | 
 | ||||||
|  |         if self.default_target is not None: | ||||||
|  |             if self.default_target.startswith('$') and \ | ||||||
|  |                     not verify_special_value(self.default_target, True, True): | ||||||
|                 raise PolicySyntaxError(filename, lineno, |                 raise PolicySyntaxError(filename, lineno, | ||||||
|                     'target= option needs to name specific target') |                     'target= option needs to name specific target') | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki