From 7ebbbaaeef0ded0f39b8bf863ee7fd324b19c9f9 Mon Sep 17 00:00:00 2001 From: k clair Date: Tue, 9 Oct 2012 12:13:13 -0700 Subject: Add source files for python-gnutls version 1.1.9 --- python-gnutls-1.1.9/gnutls/validators.py | 286 +++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 python-gnutls-1.1.9/gnutls/validators.py (limited to 'python-gnutls-1.1.9/gnutls/validators.py') diff --git a/python-gnutls-1.1.9/gnutls/validators.py b/python-gnutls-1.1.9/gnutls/validators.py new file mode 100644 index 0000000..11c29c3 --- /dev/null +++ b/python-gnutls-1.1.9/gnutls/validators.py @@ -0,0 +1,286 @@ +# Copyright (C) 2007 AG Projects. See LICENSE for details. +# + +"""GNUTLS data validators""" + +__all__ = ['function_args', 'method_args', 'none', 'ignore', 'list_of', 'one_of', 'ProtocolListValidator', + 'KeyExchangeListValidator', 'CipherListValidator', 'MACListValidator', 'CompressionListValidator'] + +from gnutls.constants import * + +# +# Priority list validators. They take a tuple or list on input and output a +# tuple with the same elements if they check valid, else raise an exception. +# + +class ProtocolListValidator(tuple): + _protocols = set((PROTO_TLS1_1, PROTO_TLS1_0, PROTO_SSL3)) + + def __new__(cls, arg): + if not isinstance(arg, (tuple, list)): + raise TypeError("Argument must be a tuple or list") + if not arg: + raise ValueError("Protocol list cannot be empty") + if not cls._protocols.issuperset(set(arg)): + raise ValueError("Got invalid protocol") + return tuple.__new__(cls, arg) + + +class KeyExchangeListValidator(tuple): + _algorithms = set((KX_RSA, KX_DHE_DSS, KX_DHE_RSA, KX_RSA_EXPORT, KX_ANON_DH)) + + def __new__(cls, arg): + if not isinstance(arg, (tuple, list)): + raise TypeError("Argument must be a tuple or list") + if not arg: + raise ValueError("Key exchange algorithm list cannot be empty") + if not cls._algorithms.issuperset(set(arg)): + raise ValueError("Got invalid key exchange algorithm") + return tuple.__new__(cls, arg) + + +class CipherListValidator(tuple): + _ciphers = set((CIPHER_AES_128_CBC, CIPHER_3DES_CBC, CIPHER_ARCFOUR_128, CIPHER_AES_256_CBC, CIPHER_DES_CBC)) + + def __new__(cls, arg): + if not isinstance(arg, (tuple, list)): + raise TypeError("Argument must be a tuple or list") + if not arg: + raise ValueError("Cipher list cannot be empty") + if not cls._ciphers.issuperset(set(arg)): + raise ValueError("Got invalid cipher") + return tuple.__new__(cls, arg) + + +class MACListValidator(tuple): + _algorithms = set((MAC_SHA1, MAC_MD5, MAC_RMD160)) + + def __new__(cls, arg): + if not isinstance(arg, (tuple, list)): + raise TypeError("Argument must be a tuple or list") + if not arg: + raise ValueError("MAC algorithm list cannot be empty") + if not cls._algorithms.issuperset(set(arg)): + raise ValueError("Got invalid MAC algorithm") + return tuple.__new__(cls, arg) + + +class CompressionListValidator(tuple): + _compressions = set((COMP_DEFLATE, COMP_LZO, COMP_NULL)) + + def __new__(cls, arg): + if not isinstance(arg, (tuple, list)): + raise TypeError("Argument must be a tuple or list") + if not arg: + raise ValueError("Compression list cannot be empty") + if not cls._compressions.issuperset(set(arg)): + raise ValueError("Got invalid compression") + return tuple.__new__(cls, arg) + +# +# Argument validating +# + +# Helper functions (internal use) +# + +def isclass(obj): + return hasattr(obj, '__bases__') or isinstance(obj, type) + +# Internal validator classes +# + +class Validator(object): + _registered = [] + def __init__(self, typ): + self.type = typ + def check(self, value): + return False + @staticmethod + def can_validate(typ): + return False + @classmethod + def register(cls, validator): + cls._registered.append(validator) + @classmethod + def get(cls, typ): + for validator in cls._registered: + if validator.can_validate(typ): + return validator(typ) + else: + return None + @staticmethod + def join_names(names): + if type(names) in (tuple, list): + if len(names) <= 2: + return ' or '.join(names) + else: + return ' or '.join((', '.join(names[:-1]), names[-1])) + else: + return names + def _type_names(self): + if isinstance(self.type, tuple): + return self.join_names([t.__name__.replace('NoneType', 'None') for t in self.type]) + else: + return self.type.__name__.replace('NoneType', 'None') + @property + def name(self): + name = self._type_names() + if name.startswith('None'): + prefix = '' + elif name[0] in ('a', 'e', 'i', 'o', 'u'): + prefix = 'an ' + else: + prefix = 'a ' + return prefix + name + +class IgnoringValidator(Validator): + def __init__(self, typ): + self.type = none + def check(self, value): + return True + @staticmethod + def can_validate(obj): + return obj is ignore + +class TypeValidator(Validator): + def check(self, value): + return isinstance(value, self.type) + @staticmethod + def can_validate(obj): + return isclass(obj) + +class MultiTypeValidator(TypeValidator): + @staticmethod + def can_validate(obj): + return isinstance(obj, tuple) and not filter(lambda x: not isclass(x), obj) + +class OneOfValidator(Validator): + def __init__(self, typ): + self.type = typ.type + def check(self, value): + return value in self.type + @staticmethod + def can_validate(obj): + return isinstance(obj, one_of) + @property + def name(self): + return 'one of %s' % self.join_names(["`%r'" % e for e in self.type]) + +class ListOfValidator(Validator): + def __init__(self, typ): + self.type = typ.type + def check(self, value): + return isinstance(value, (tuple, list)) and not filter(lambda x: not isinstance(x, self.type), value) + @staticmethod + def can_validate(obj): + return isinstance(obj, list_of) + @property + def name(self): + return 'a list of %s' % self._type_names() + +class ComplexValidator(Validator): + def __init__(self, typ): + self.type = [Validator.get(x) for x in typ] + def check(self, value): + return bool(sum(t.check(value) for t in self.type)) + @staticmethod + def can_validate(obj): + return isinstance(obj, tuple) and not filter(lambda x: Validator.get(x) is None, obj) + @property + def name(self): + return self.join_names([x.name for x in self.type]) + +Validator.register(IgnoringValidator) +Validator.register(TypeValidator) +Validator.register(MultiTypeValidator) +Validator.register(OneOfValidator) +Validator.register(ListOfValidator) +Validator.register(ComplexValidator) + + +# Extra types to be used with argument validating decorators +# + +none = type(None) + +class one_of(object): + def __init__(self, *args): + if len(args) < 2: + raise ValueError("one_of must have at least 2 arguments") + self.type = args + +class list_of(object): + def __init__(self, *args): + if filter(lambda x: not isclass(x), args): + raise TypeError("list_of arguments must be types") + if len(args) == 1: + self.type = args[0] + else: + self.type = args + +ignore = type('ignore', (), {})() + + +# Helpers for writing well behaved decorators +# + +def decorator(func): + """A syntactic marker with no other effect than improving readability.""" + return func + +def preserve_signature(func): + """Preserve the original function signature and attributes in decorator wrappers.""" + from inspect import getargspec, formatargspec + from gnutls.constants import GNUTLSConstant + constants = [c for c in (getargspec(func)[3] or []) if isinstance(c, GNUTLSConstant)] + signature = formatargspec(*getargspec(func))[1:-1] + parameters = formatargspec(*getargspec(func), **{'formatvalue': lambda value: ""})[1:-1] + def fix_signature(wrapper): + if constants: + ## import the required GNUTLSConstants used as function default arguments + code = "from gnutls.constants import %s\n" % ', '.join(c.name for c in constants) + exec code in locals(), locals() + code = "def %s(%s): return wrapper(%s)\nnew_wrapper = %s\n" % (func.__name__, signature, parameters, func.__name__) + exec code in locals(), locals() + new_wrapper.__name__ = func.__name__ + new_wrapper.__doc__ = func.__doc__ + new_wrapper.__module__ = func.__module__ + new_wrapper.__dict__.update(func.__dict__) + return new_wrapper + return fix_signature + +# Argument validating decorators +# + +def _callable_args(*args, **kwargs): + """Internal function used by argument checking decorators""" + start = kwargs.get('_start', 0) + validators = [] + for i, arg in enumerate(args): + validator = Validator.get(arg) + if validator is None: + raise TypeError("unsupported type `%r' at position %d for argument checking decorator" % (arg, i+1)) + validators.append(validator) + def check_args_decorator(func): + @preserve_signature(func) + def check_args(*func_args): + pos = start + for validator in validators: + if not validator.check(func_args[pos]): + raise TypeError("argument %d must be %s" % (pos+1-start, validator.name)) + pos += 1 + return func(*func_args) + return check_args + return check_args_decorator + +@decorator +def method_args(*args): + """Check class or instance method arguments""" + return _callable_args(*args, **{'_start': 1}) + +@decorator +def function_args(*args): + """Check functions or staticmethod arguments""" + return _callable_args(*args) + -- cgit v1.2.3