관리-도구
편집 파일: handlers.cpython-39.opt-1.pyc
a ����f�WcF����������������������@���s���d�Z�ddlmZ�ddlZddlZe�e�ZddlZddl Z ddl mZ�ddlm Z �ddlmZ�ddlmZmZmZ�ddlmZ�ddlmZ�ddlmZmZmZmZmZmZmZmZmZm Z m!Z!�dd l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)�dd l*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m0Z0m3Z3m4Z4m5Z5�ddl6m7Z7m8Z8�g�d�Z9e$Z:e#Z;e%Z<e'Z=e(Z>d d��Z?dRdd�Z@dd��ZAdd��ZBe-d�ZCe-d�ZDdd��ZEdd��ZFeCdfdd�ZGeCdddfdd �ZHdSd"d#�ZIe-d�fd$d%�ZJe-d�dfd&d'�ZKdTd+d,�ZLdUd-d.�ZMdVd0d1�ZNG�d2d3��d3e�ZOG�d4d5��d5eO�ZPG�d6d7��d7eO�ZQG�d8d9��d9eQ�ZRG�d:d;��d;eQ�ZSG�d<d=��d=eQ�ZTG�d>d?��d?eQ�ZUG�d@dA��dAeQ�ZVG�dBdC��dCeQ�ZWG�dDdE��dEeW�ZXG�dFdG��dGeQ�ZYG�dHdI��dIeQ�ZZe �[��Z\G�dJdK��dKe�Z]G�dLdM��dMe]�Z^G�dNdO��dOe]eQ�Z_G�dPdQ��dQe`�ZadS�)WzRpasslib.handler - code for implementing handlers, and global registry for handlers�����)�with_statementN)�warn)�MissingBackendError�PasslibConfigWarning�PasslibHashWarning)�PasswordHash)�get_crypt_handler)�consteq� getrandstr�getrandbytes�rng� to_native_str�is_crypt_handler� to_unicode�MAX_PASSWORD_SIZE�accepts_keyword�as_bool�update_mixin_classes)�BASE64_CHARS�HASH64_CHARS�PADDED_BASE64_CHARS� HEX_CHARS�UPPER_HEX_CHARS�LOWER_HEX_CHARS�ALL_BYTE_VALUES)�join_byte_values�irange�u�native_string_types� uascii_to_str�join_unicode�unicode� str_to_uasciir ����unicode_or_bytes_types�PY2� int_types)� classproperty�deprecated_method)� parse_mc2� parse_mc3� render_mc2� render_mc3�GenericHandler� StaticHandler�HasUserContext�HasRawChecksum� HasManyIdents�HasSalt� HasRawSalt� HasRounds�HasManyBackends� PrefixWrapperc�����������������C���s0���|r(|�r(ddl�}t|�|�t|�d���S�dS�dS�)zhelper for bitsize() methodsr���N����)�math�int�log�len)�count�charsr7�����r=����:/usr/lib/python3.9/site-packages/passlib/utils/handlers.py�_bitsizeJ���s����r?�������c�����������������C���sd���t����}|��}zL|rT|j�dd�}|�d�s6|�d�sDtd|�W�~S�|d7�}|j}q|�W�~S�~0�dS�)zi try to guess stacklevel for application warning. looks for first frame not part of passlib. �__name__��zpasslib.tests.zpasslib.r@���N)�inspectZcurrentframe� f_globals�get� startswith�max�f_back)�start�framer;����namer=���r=���r>����guess_app_stacklevelR���s���� ��rL���c�����������������C���s"���t�dt|�jd��ttd�d��d�S�)Nz�passing settings to %(handler)s.hash() is deprecated, and won't be supported in Passlib 2.0; use '%(handler)s.using(**settings).hash(secret)' instead)�handlerr6���)� stacklevel)r����dictrK����DeprecationWarningrL����rM����kwdsr=���r=���r>����warn_hash_settings_deprecationd���s ���� ��rS���c��������������������s&���t�|�j���t���fdd�t��D���S�)z� helper to extract settings kwds from mix of context & settings kwds. pops settings keys from kwds, returns them as a dict. c�����������������3���s$���|�]}|��vr|���|�fV��qd�S��N)�pop��.0�key�Zcontext_keysrR���r=���r>���� <genexpr>o��������z(extract_settings_kwds.<locals>.<genexpr>)�set�context_kwdsrO����listrQ���r=���rY���r>����extract_settings_kwdsi���s���� r_����$�0c�����������������C���s0���t�|�t�st�|�d��t|��tkr,t�t��dS�)z%ensure secret has correct type & size�secretN)� isinstancer#����exc�ExpectedStringErrorr:���r���ZPasswordSizeError)rb���r=���r=���r>����validate_secretw���s���� rf���c�����������������C���sT���t�|�t�r|�S�t�|�t�rDz|��d�W�S��ty@���|��d��Y�S�0�nt�|�d��dS�)z+convert hash to unicode for identify method�utf-8zlatin-1�hashN)rc���r!����bytes�decode�UnicodeDecodeErrorrd���re����rh���r=���r=���r>����to_unicode_for_identify~���s���� rm���c�����������������C���s|���t�|�dd�}�|��|�s t�|��|�t|�d���|�}t|�dkrV|\}}||pRdfS�t|�dkrn|d�dfS�t�|��dS�)a���parse hash using 2-part modular crypt format. this expects a hash of the format :samp:`{prefix}{salt}[${checksum}]`, such as md5_crypt, and parses it into salt / checksum portions. :arg hash: the hash to parse (bytes or unicode) :arg prefix: the identifying prefix (unicode) :param sep: field separator (unicode, defaults to ``$``). :param handler: handler class to pass to error constructors. :returns: a ``(salt, chk | None)`` tuple. �asciirh���Nr6���r@���r���)r���rF���rd����InvalidHashErrorr:����split�MalformedHashError)rh����prefix�seprM����parts�salt�chkr=���r=���r>���r(�������s���� r(���� ���c����������� ������C���s����t�|�dd�}�|��|�s t�|��|�t|�d���|�}t|�dkrN|\}}} n$t|�dkrh|\}}d} n t�|��|�t�r�|tkr�t�|��n*|r�t ||�}n|du�r�t�|d��n|}||| p�dfS�)ar��parse hash using 3-part modular crypt format. this expects a hash of the format :samp:`{prefix}[{rounds}]${salt}[${checksum}]`, such as sha1_crypt, and parses it into rounds / salt / checksum portions. tries to convert the rounds to an integer, and throws error if it has zero-padding. :arg hash: the hash to parse (bytes or unicode) :arg prefix: the identifying prefix (unicode) :param sep: field separator (unicode, defaults to ``$``). :param rounds_base: the numeric base the rounds are encoded in (defaults to base 10). :param default_rounds: the default rounds value to return if the rounds field was omitted. if this is ``None`` (the default), the rounds field is *required*. :param handler: handler class to pass to error constructors. :returns: a ``(rounds : int, salt, chk | None)`` tuple. rn���rh���N����r6���zempty rounds field) r���rF���rd���ro���r:���rp���rq����_UZEROZZeroPaddedRoundsErrorr8���) rh���rr���rs����rounds_base�default_roundsrM���rt����roundsru���rv���r=���r=���r>���r)�������s$���� r)����valuec�����������������C���sT���|���t�r$|�tkr$t�|d|���n,|�r2t|�|�S�|du�rLt�|d|���n|S�dS�)a�� helper to parse an integer config field :arg source: unicode source string :param base: numeric base :param default: optional default if source is empty :param param: name of variable, for error msgs :param handler: handler class, for error msgs zzero-padded %s fieldNzempty %s field)rF���ry���rd���rq���r8���)�source�base�default�paramrM���r=���r=���r>���� parse_int����s���� r����c�����������������C���s&���|r|�|||g}n|�|g}t�t|��S�)a���format hash using 2-part modular crypt format; inverse of parse_mc2() returns native string with format :samp:`{ident}{salt}[${checksum}]`, such as used by md5_crypt. :arg ident: identifier prefix (unicode) :arg salt: encoded salt (unicode) :arg checksum: encoded checksum (unicode or None) :param sep: separator char (unicode, defaults to ``$``) :returns: config or hash (native str) )r���r ���)�identru����checksumrs���rt���r=���r=���r>���r*��� ��s����r*���c�����������������C���s^���|du�rt�d�}n|dkr(t�d�|�}nt|�}|rF|�|||||g}n|�|||g}tt|��S�)a.��format hash using 3-part modular crypt format; inverse of parse_mc3() returns native string with format :samp:`{ident}[{rounds}$]{salt}[${checksum}]`, such as used by sha1_crypt. :arg ident: identifier prefix (unicode) :arg rounds: rounds field (int or None) :arg salt: encoded salt (unicode) :arg checksum: encoded checksum (unicode or None) :param sep: separator char (unicode, defaults to ``$``) :param rounds_base: base to encode rounds value (defaults to base 10) :returns: config or hash (native str) NrB�������z%x)r���r!���r���r ���)r����r|���ru���r����rs���rz���rt���r=���r=���r>���r+���!��s���� r+���������������?�*c�����������������C���sv���|�du�rdS�t�|�t�sDt�|�t�r<ddlm}�||���d�}�nt|��}�t|��}t|t||���}|�d|��|||���S�)a:�� helper to mask contents of sensitive field. :param value: raw value (str, bytes, etc) :param show: max # of characters to remain visible :param pct: don't show more than this % of input. :param char: character to use for masking :rtype: str | None Nr���)�ab64_encodern���) rc���r!���ri����passlib.utils.binaryr����rj���r:����minr8���)r}���ZshowZpct�charr�����sizer=���r=���r>���� mask_value?��s���� r����c�����������������C���s���dS�)z� assert helper that quickly validates default value. designed to get out of the way and reduce overhead when asserts are stripped. Tr=���)rM���r����Znormr����r=���r=���r>����validate_default_valuea��s����r����Fc�����������������C���s����t�|t�st�|d|��||k�rPd|�j|||f�}|rHt|tj��|}nt|��|r�||kr�d|�j|||f�}|r�t|tj��|}nt|��|S�)a��� helper to normalize and validate an integer value (e.g. rounds, salt_size) :arg value: value provided to constructor :arg default: default value if none provided. if set to ``None``, value is required. :arg param: name of parameter (xxx: move to first arg?) :param min: minimum value (defaults to 1) :param max: maximum value (default ``None`` means no maximum) :returns: validated value Zintegerz+%s: %s (%d) is too low, must be at least %dz0%s: %s (%d) is too large, cannot be more than %d)rc���r%���rd����ExpectedTypeErrorrK���r���r���� ValueError)rM���r}���r����rG���r�����relaxed�msgr=���r=���r>����norm_integerj��s���� r����c�������������������@���s"���e�Zd�ZdZdZeddd��ZdS�)�MinimalHandlerz� helper class for implementing hash handlers. provides nothing besides a base implementation of the .using() subclass constructor. Fc�����������������C���s,���|�j�}|�jsd|�}t||�ft|�jdd��S�)Nz<customized %s hasher>T)� __module__�_configured)rA���r�����typerO���r����)�clsr����rK���r=���r=���r>����using���s����zMinimalHandler.usingN)F)rA���r�����__qualname__�__doc__r�����classmethodr����r=���r=���r=���r>���r�������s��� r����c�����������������������s:���e�Zd�ZdZdZdZed��fdd� �Zedd���Z���Z S�) � TruncateMixina��� PasswordHash mixin which provides a method that will check if secret would be truncated, and can be configured to throw an error. .. warning:: Hashers using this mixin will generally need to override the default PasswordHash.truncate_error policy of "True", and will similarly want to override .truncate_verify_reject as well. TODO: This should be done explicitly, but for now this mixin sets these flags implicitly. FNc��������������������s<���t�t|��jf�i�|��}|d�ur8t|dd�}|d�ur8||_|S�)N�truncate_error)r����)�superr����r����r���r����)r����r����rR����subcls�� __class__r=���r>���r�������s����zTruncateMixin.usingc�����������������C���s"���|�j�rt|�|�jkrt�|���dS�)z� make sure secret won't be truncated. NOTE: this should only be called for .hash(), not for .verify(), which should honor the .truncate_verify_reject policy. N)r����r:���� truncate_sizerd���ZPasswordTruncateError)r����rb���r=���r=���r>����_check_truncate_policy���s����z$TruncateMixin._check_truncate_policy)N) rA���r����r����r����r�����truncate_verify_rejectr����r����r����� __classcell__r=���r=���r����r>���r�������s���r����c�����������������������s��e�Zd�ZdZdZdZdZdZdZdZ dZ dZd+��fdd� Zd,dd�Z ed d ���Zedd���Zd d��Zedd���Zdd��Zedd���Zedd���Zeddd�edd����Zeddd�edd����Zed-dd��Zd.d d!�ZdZd"Zd#Zed$d%���Z ed/d'd(��Z!e��fd)d*��Z"���Z#S�)0r,���a4��helper class for implementing hash handlers. GenericHandler-derived classes will have (at least) the following constructor options, though others may be added by mixins and by the class itself: :param checksum: this should contain the digest portion of a parsed hash (mainly provided when the constructor is called by :meth:`from_string()`). defaults to ``None``. :param use_defaults: If ``False`` (the default), a :exc:`TypeError` should be thrown if any settings required by the handler were not explicitly provided. If ``True``, the handler should attempt to provide a default for any missing values. This means generate missing salts, fill in default cost parameters, etc. This is typically only set to ``True`` when the constructor is called by :meth:`hash`, allowing user-provided values to be handled in a more permissive manner. :param relaxed: If ``False`` (the default), a :exc:`ValueError` should be thrown if any settings are out of bounds or otherwise invalid. If ``True``, they should be corrected if possible, and a warning issue. If not possible, only then should an error be raised. (e.g. under ``relaxed=True``, rounds values will be clamped to min/max rounds). This is mainly used when parsing the config strings of certain hashes, whose specifications implementations to be tolerant of incorrect values in salt strings. Class Attributes ================ .. attribute:: ident [optional] If this attribute is filled in, the default :meth:`identify` method will use it as a identifying prefix that can be used to recognize instances of this handler's hash. Filling this out is recommended for speed. This should be a unicode str. .. attribute:: _hash_regex [optional] If this attribute is filled in, the default :meth:`identify` method will use it to recognize instances of the hash. If :attr:`ident` is specified, this will be ignored. This should be a unique regex object. .. attribute:: checksum_size [optional] Specifies the number of characters that should be expected in the checksum string. If omitted, no check will be performed. .. attribute:: checksum_chars [optional] A string listing all the characters allowed in the checksum string. If omitted, no check will be performed. This should be a unicode str. .. attribute:: _stub_checksum Placeholder checksum that will be used by genconfig() in lieu of actually generating a hash for the empty string. This should be a string of the same datatype as :attr:`checksum`. Instance Attributes =================== .. attribute:: checksum The checksum string provided to the constructor (after passing it through :meth:`_norm_checksum`). Required Subclass Methods ========================= The following methods must be provided by handler subclass: .. automethod:: from_string .. automethod:: to_string .. automethod:: _calc_checksum Default Methods =============== The following methods have default implementations that should work for most cases, though they may be overridden if the hash subclass needs to: .. automethod:: _norm_checksum .. automethod:: genconfig .. automethod:: genhash .. automethod:: identify .. automethod:: hash .. automethod:: verify Nr=���Fc��������������������s4���||�_�tt|��jf�i�|���|d�ur0|��|�|�_d�S�rT���)�use_defaultsr����r,����__init__�_norm_checksumr����)�selfr����r����rR���r����r=���r>���r����k��s����zGenericHandler.__init__c��������������������s����|�j�}|r$t|t�s`t�|dd��n<t|t�s`t|t�rR|rRtdt��|�d�}nt�|dd��|�j }|r�t |�|kr�tj|�|d��|s�|�j����r�t ��fdd�|D���r�td |�jf���|S�) zovalidates checksum keyword against class requirements, returns normalized version of checksum. ri���r����z%checksum should be unicode, not bytesrn���r!���)�rawc�����������������3���s���|�]}|��vV��qd�S�rT���r=����rW����c��csr=���r>���rZ������r[���z0GenericHandler._norm_checksum.<locals>.<genexpr>z!invalid characters in %s checksum)�_checksum_is_bytesrc���ri���rd���r����r!���r���r���rj���� checksum_sizer:���ZChecksumSizeError�checksum_chars�anyr����rK���)r����r����r����r�����ccr=���r����r>���r����t��s"���� zGenericHandler._norm_checksumc�����������������C���sn���t�|�}|sdS�|�j}|d�ur(|�|�S�|�j}|d�urD|�|�d�uS�z|��|��W�dS��tyh���Y�dS�0�d�S�)NFT)rm���r����rF����_hash_regex�match�from_stringr����)r����rh���r�����patr=���r=���r>����identify���s���� zGenericHandler.identifyc�����������������K���s���t�d|�f���dS�)aX�� return parsed instance from hash/configuration string :param \\*\\*context: context keywords to pass to constructor (if applicable). :raises ValueError: if hash is incorrectly formatted :returns: hash parsed into components, for formatting / calculating checksum. �%s must implement from_string()N��NotImplementedError)r����rh����contextr=���r=���r>���r�������s����zGenericHandler.from_stringc�����������������C���s���t�d|�jf���dS�)z�render instance to hash or configuration string :returns: hash string with salt & digest included. should return native string type (ascii-bytes under python 2, unicode under python 3) r����N�r����r�����r����r=���r=���r>���� to_string���s���� zGenericHandler.to_stringc�����������������C���sn���|�j�r,|�jrd|�j��S�|�jr,|�jd�|�j��S�t|�t�rd|�j}|�jpDd|�_z|��d�W�||�_S�||�_0�|��d�S�)zi placeholder used by default .genconfig() so it can avoid expense of calculating digest. �����r���r@���rB���)r����r����r����rc���r3���r|���� min_rounds�_calc_checksum)r�����origr=���r=���r>����_stub_checksum���s���� �zGenericHandler._stub_checksumc�����������������C���s���t�d|�jf���dS�)a��given secret; calcuate and return encoded checksum portion of hash string, taking config from object state calc checksum implementations may assume secret is always either unicode or bytes, checks are performed by verify/etc. �"%s must implement _calc_checksum()Nr�����r����rb���r=���r=���r>���r�������s�����zGenericHandler._calc_checksumc�����������������K���sh���|r:t�|�|�}|r:t|�|��|�jf�i�|��j|fi�|��S�t|��|�f�ddi|��}|�|�|_|���S��Nr����T)r_���rS���r����rh���rf���r����r����r����)r����rb���rR����settingsr����r=���r=���r>���rh������s���� zGenericHandler.hashc�����������������K���sB���t�|��|�j|fi�|��}|j}|d�u�r2t�|���t|�|�|�S�rT���)rf���r����r����rd���ZMissingDigestErrorr ���r����)r����rb���rh���r����r����rv���r=���r=���r>����verify��s���� zGenericHandler.verify�1.7�2.0�� deprecated�removedc�����������������K���sL���t�|�|�}|r*|�jf�i�|��jf�i�|��S�|�f�ddi|��}|j|_|���S�r����)r_���r����� genconfigr����r����r����)r����rR���r����r����r=���r=���r>���r������s���� zGenericHandler.genconfigc�����������������K���s>���|d�u�rt�d��t|��|�j|fi�|��}|�|�|_|���S�)N�config must be string)� TypeErrorrf���r����r����r����r����)r����rb����configr����r����r=���r=���r>����genhash+��s����zGenericHandler.genhashc�����������������K���s���|���|�}|jf�d|i|��S�)Nrb���)r�����_calc_needs_update)r����rh���rb���rR���r����r=���r=���r>����needs_update9��s���� zGenericHandler.needs_updatec�����������������C���s���dS�)z; internal helper for :meth:`needs_update`. Fr=���r����r=���r=���r>���r����A��s����z!GenericHandler._calc_needs_update)� salt_sizer����)ru���r����c��������������������s���t���fdd���jD���S�)z� helper for :meth:`parsehash` -- returns list of attributes which should be extracted by parse_hash() from hasher object. default implementation just takes setting_kwds, and excludes _unparsed_settings c�����������������3���s���|�]}|��j�vr|V��qd�S�rT���)�_unparsed_settingsrV����r����r=���r>���rZ���_��r[���z2GenericHandler._parsed_settings.<locals>.<genexpr>)�tuple�setting_kwdsr����r=���r����r>����_parsed_settingsW��s����zGenericHandler._parsed_settingsTc��������������������s�������|��t�����j�t�����fdd��jD���}|rL�jdurL�j|d<�|r�|du�r\t}�jD�]}||v�rb|||��||<�qb|S�)a���[experimental method] parse hash into dictionary of settings. this essentially acts as the inverse of :meth:`hash`: for most cases, if ``hash = cls.hash(secret, **opts)``, then ``cls.parsehash(hash)`` will return a dict matching the original options (with the extra keyword *checksum*). this method may not work correctly for all hashes, and may not be available on some few. its interface may change in future releases, if it's kept around at all. :arg hash: hash to parse :param checksum: include checksum keyword? (defaults to True) :param sanitize: mask data for sensitive fields? (defaults to False) c�����������������3���s:���|�]2}|�v�s$t��|�t��|���kr|t��|�fV��qd�S�rT�����getattrrV����ZUNSET�alwaysr����r����r=���r>���rZ���}��s����z+GenericHandler.parsehash.<locals>.<genexpr>Nr����T)r�����object�_always_parse_settingsrO���r����r����r�����_unsafe_settings)r����rh���r����ZsanitizerR���rX���r=���r����r>���� parsehasha��s���� zGenericHandler.parsehashc��������������������s`���zt�t|��jf�i�|��}W�n�ty0���i�}Y�n0�|�jr<tn|�j}|�jr\|r\t|�j|�|d<�|S�)�8[experimental method] return info about bitsizes of hashr����) r����r,����bitsize�AttributeErrorr����r���r����r����r?���)r����rR����infor����r����r=���r>���r�������s���� zGenericHandler.bitsize)NF)F)N)N)TF)$rA���r����r����r����r����r]���r����r����r����r����r����r����r����r����r����r����r����r�����propertyr����r����rh���r����r'���r����r����r����r����r����r����r����r&���r����r����r����r����r=���r=���r����r>���r,������sR���o ' 'r,���c�������������������@���sH���e�Zd�ZdZdZed�Zedd���Zedd���Z dd ��Z d Zdd��Zd S�) r-���a;��GenericHandler mixin for classes which have no settings. This mixin assumes the entirety of the hash ise stored in the :attr:`checksum` attribute; that the hash has no rounds, salt, etc. This class provides the following: * a default :meth:`genconfig` that always returns None. * a default :meth:`from_string` and :meth:`to_string` that store the entire hash within :attr:`checksum`, after optionally stripping a constant prefix. All that is required by subclasses is an implementation of the :meth:`_calc_checksum` method. r=���rB���c�����������������K���sX���t�|dd�}|��|�}|�j}|rF|�|�r<|t|�d���}n t�|���|�f�d|i|��S�)Nrn���rh���r����)r���� _norm_hash�_hash_prefixrF���r:���rd���ro���)r����rh���r����rr���r=���r=���r>���r�������s���� zStaticHandler.from_stringc�����������������C���s���|S�)z1helper for subclasses to normalize case if neededr=����r����rh���r=���r=���r>���r�������s����zStaticHandler._norm_hashc�����������������C���s���t�|�j|�j��S�rT���)r���r����r����r����r=���r=���r>���r�������s����zStaticHandler.to_stringNc�������������� ������s�����j�����j}|du�rD��fdd�}t��jd���ft|��jd���}��_t�fdd��jD���}z|j|dfi�|��}W�nB�ty��}�z*t |�dkr�t d ��f���n��W�Y�d}~n d}~0�0�td ���t��t |�S�)z{given secret; calcuate and return encoded checksum portion of hash string, taking config from object state Nc��������������������s���t�d��f���d�S�)Nr����r����r����r����r=���r>����inner���s�����z+StaticHandler._calc_checksum.<locals>.innerZ_wrapper)r����r����c�����������������3���s���|�]}|t���|�fV��qd�S�rT���r����)rW����kr����r=���r>���rZ������r[���z/StaticHandler._calc_checksum.<locals>.<genexpr>r����r����z�%r should be updated to implement StaticHandler._calc_checksum() instead of StaticHandler.genhash(), support for the latter style will be removed in Passlib 1.8)r�����_StaticHandler__cc_compat_hackr����rA���rO���r����r]���r����r�����strr����r���rP���r"���)r����rb���Zwrapper_clsr����r����rh����errr=���)r����r����r>���r�������s,���� � ���zStaticHandler._calc_checksum) rA���r����r����r����r����r���r����r����r����r����r����r����r����r=���r=���r=���r>���r-������s��� r-���c�����������������������s*���e�Zd�ZdZdZdZd��fdd� Z���ZS�)�HasEncodingContextz?helper for classes which require knowledge of the encoding used)�encodingrg���Nc��������������������s&���t�t|��jf�i�|���|p|�j|�_d�S�rT���)r����r����r�����default_encodingr����)r����r����rR���r����r=���r>���r�������s����zHasEncodingContext.__init__)N)rA���r����r����r����r]���r����r����r����r=���r=���r����r>���r�������s���r����c�����������������������sh���e�Zd�ZdZdZd��fdd� Zed��fdd� �Zed��fdd � �Ze d dd�ed��fd d� ��Z ���ZS�)r.���z7helper for classes which require a user context keyword)�userNc��������������������s ���t�t|��jf�i�|���||�_d�S�rT���)r����r.���r����r����)r����r����rR���r����r=���r>���r������s����zHasUserContext.__init__c��������������������s���t�t|��j|fd|i|��S��Nr����)r����r.���rh���)r����rb���r����r����r����r=���r>���rh��� ��s����zHasUserContext.hashc��������������������s���t�t|��j||fd|i|��S�r����)r����r.���r����)r����rb���rh���r����r����r����r=���r>���r������s����zHasUserContext.verifyr����r����r����c��������������������s���t�t|��j||fd|i|��S�r����)r����r.���r����)r����rb���r����r����r����r����r=���r>���r������s����zHasUserContext.genhash)N)N)N)N)rA���r����r����r����r]���r����r����rh���r����r'���r����r����r=���r=���r����r>���r.������s��� r.���c�������������������@���s���e�Zd�ZdZdZdS�)r/���zqmixin for classes which work with decoded checksum bytes .. todo:: document this class's usage TN)rA���r����r����r����r����r=���r=���r=���r>���r/���%��s���r/���c�����������������������sh���e�Zd�ZdZdZdZdZdZed ��fdd� �Z d��fdd� Z edd���Zed d ���Zedd���Z ���ZS�)r0���a ��mixin for hashes which use multiple prefix identifiers For the hashes which may use multiple identifier prefixes, this mixin adds an ``ident`` keyword to constructor. Any value provided is passed through the :meth:`norm_idents` method, which takes care of validating the identifier, as well as allowing aliases for easier specification of the identifiers by the user. .. todo:: document this class's usage Class Methods ============= .. todo:: document using() and needs_update() options Nc��������������������sN���|dur|durt�d��|}tt|��jf�i�|��}|durJ|�|dd�j|_|S�)a4�� This mixin adds support for the following :meth:`~passlib.ifc.PasswordHash.using` keywords: :param default_ident: default identifier that will be used by resulting customized hasher. :param ident: supported as alternate alias for **default_ident**. Nz2'default_ident' and 'ident' are mutually exclusiveT)r����r����)r����r����r0���r����r����� default_ident)r����r����r����rR���r����r����r=���r>���r����^��s���� zHasManyIdents.usingc��������������������sJ���t�t|��jf�i�|���|d�ur*|��|�}n|�jr8|�j}ntd��||�_d�S�)Nzno ident specified)r����r0���r�����_norm_identr����r����r����r����)r����r����rR���r����r=���r>���r����|��s����zHasManyIdents.__init__c�����������������C���sn���t�|t�r|�d�}|�j}||v�r&|S�|�j}|r\z||�}W�n�tyN���Y�n0�||v�r\|S�td|f���dS�)zD helper which normalizes & validates 'ident' value. rn���zinvalid ident: %rN)rc���ri���rj����ident_values� ident_aliases�KeyErrorr����)r����r����Ziv�iar}���r=���r=���r>���r�������s���� zHasManyIdents._norm_identc�����������������C���s���t�|�}|�|�j�S�rT���)rm���rF���r����r����r=���r=���r>���r�������s����zHasManyIdents.identifyc�����������������C���sH���t�|dd�}|�jD�]&}|�|�r||t|�d��f��S�qt�|���dS�)zDextract ident prefix from hash, helper for subclasses' from_string()rn���rh���N)r���r����rF���r:���rd���ro���)r����rh���r����r=���r=���r>����_parse_ident���s ���� zHasManyIdents._parse_ident)NN)N)rA���r����r����r����r����r����r����r����r����r����r����r����r����r����r����r=���r=���r����r>���r0���6��s����� r0���c�����������������������s����e�Zd�ZdZdZdZdZedd���Zedd���Z dZ d ZdZe d��fd d� �Ze ddd��Zd��fdd� Zdd��Ze ddd��Zedd���Ze dd���Ze d ��fdd� �Z���ZS�)!r1���a2 ��mixin for validating salts. This :class:`GenericHandler` mixin adds a ``salt`` keyword to the class constuctor; any value provided is passed through the :meth:`_norm_salt` method, which takes care of validating salt length and content, as well as generating new salts if one it not provided. :param salt: optional salt string :param salt_size: optional size of salt (only used if no salt provided); defaults to :attr:`default_salt_size`. Class Attributes ================ In order for :meth:`!_norm_salt` to do its job, the following attributes should be provided by the handler subclass: .. attribute:: min_salt_size The minimum number of characters allowed in a salt string. An :exc:`ValueError` will be throw if the provided salt is too small. Defaults to ``0``. .. attribute:: max_salt_size The maximum number of characters allowed in a salt string. By default an :exc:`ValueError` will be throw if the provided salt is too large; but if ``relaxed=True``, it will be clipped and a warning issued instead. Defaults to ``None``, for no maximum. .. attribute:: default_salt_size [required] If no salt is provided, this should specify the size of the salt that will be generated by :meth:`_generate_salt`. By default this will fall back to :attr:`max_salt_size`. .. attribute:: salt_chars A string containing all the characters which are allowed in the salt string. An :exc:`ValueError` will be throw if any other characters are encountered. May be set to ``None`` to skip this check (but see in :attr:`default_salt_chars`). .. attribute:: default_salt_chars [required] This attribute controls the set of characters use to generate *new* salt strings. By default, it mirrors :attr:`salt_chars`. If :attr:`!salt_chars` is ``None``, this attribute must be specified in order to generate new salts. Aside from that purpose, the main use of this attribute is for hashes which wish to generate salts from a restricted subset of :attr:`!salt_chars`; such as accepting all characters, but only using a-z. Instance Attributes =================== .. attribute:: salt This instance attribute will be filled in with the salt provided to the constructor (as adapted by :meth:`_norm_salt`) Subclassable Methods ==================== .. automethod:: _norm_salt .. automethod:: _generate_salt r���Nc�����������������C���s���|�j�S�)z/default salt size (defaults to *max_salt_size*))� max_salt_sizer����r=���r=���r>����default_salt_size��s����zHasSalt.default_salt_sizec�����������������C���s���|�j�S�)zDcharset used to generate new salt strings (defaults to *salt_chars*))� salt_charsr����r=���r=���r>����default_salt_chars��s����zHasSalt.default_salt_charsFr<���c��������������������s����|d�ur|d�urt�d��|}tt|��jf�i�|��}|�d�}|d�urht|t�rVt|�}|j|d|d�|_ ��d�ur�|j ��|d���t��fdd��|_|S�)NzB'salt_size' and 'default_salt_size' aliases are mutually exclusiver����r�����r����r�����r����c����������������������s�����S�rT���r=���r=����ru���r=���r>����<lambda>G��r[���zHasSalt.using.<locals>.<lambda>) r����r����r1���r����rE���rc���r���r8����_clip_to_valid_salt_sizer���� _norm_salt�staticmethod�_generate_salt)r����r���r����ru���rR���r����r����r����r��r>���r����*��s"���� �z HasSalt.usingr����Tc�����������������C���s����|�j�}|�j}||krJ||krFd|�j|||f�}|r>t|t��nt|��|S�||k�r�d|�j|||f�}|rxt|t��|}nt|��|r�||kr�d|�j|||f�}|r�t|t��|}nt|��|S�)a��� internal helper -- clip salt size value to handler's absolute limits (min_salt_size / max_salt_size) :param relaxed: if ``True`` (the default), issues PasslibHashWarning is rounds are outside allowed range. if ``False``, raises a ValueError instead. :param param: optional name of parameter to insert into error/warning messages. :returns: clipped rounds value z%s: %s (%d) must be exactly %dz$%s: %s (%r) below min_salt_size (%d)z$%s: %s (%r) above max_salt_size (%d))� min_salt_sizer����rK���r���r���r����)r����r����r����r�����mn�mxr����r=���r=���r>���r��L��s,���� z HasSalt._clip_to_valid_salt_sizec��������������������sL���t�t|��jf�i�|���|d�ur*|��|�}n|�jr:|����}ntd��||�_d�S�)Nzno salt specified)r����r1���r�����_parse_saltr����r ��r����ru���)r����ru���rR���r����r=���r>���r�������s����zHasSalt.__init__c�����������������C���s ���|���|�S�rT���)r��)r����ru���r=���r=���r>���r�����s����zHasSalt._parse_saltc��������������������s,��|�j�r t|t�s�t�|dd��nht|t�sVt|t�rHts<|rH|�d�}nt�|dd��|�j����dur�t ��fdd�|D���r�t d|�j���|�j}|r�t |�|k�r�d |�j||�jkr�d nd||�jf�}t |��|�j}|�r(t |�|k�r(d|�j||kr�d nd ||�jf�}|�r t|t��|��||�}nt |��|S�)aT��helper to normalize & validate user-provided salt string :arg salt: salt string :raises TypeError: If salt not correct type. :raises ValueError: * if salt contains chars that aren't in :attr:`salt_chars`. * if salt contains less than :attr:`min_salt_size` characters. * if ``relaxed=False`` and salt has more than :attr:`max_salt_size` characters (if ``relaxed=True``, the salt is truncated and a warning is issued instead). :returns: normalized salt ri���ru���rn���r!���Nc�����������������3���s���|�]}|��vV��qd�S�rT���r=���r�����Zscr=���r>���rZ������r[���z%HasSalt._norm_salt.<locals>.<genexpr>zinvalid characters in %s saltz%salt too small (%s requires %s %d %s)Zexactlyz>=z%salt too large (%s requires %s %d %s)z<=)�_salt_is_bytesrc���ri���rd���r����r!���r$���rj���r��r����r����rK���r��r:���r����� _salt_unitr���r����_truncate_salt)r����ru���r����r��r����r ��r=���r��r>���r�����s4���� �� zHasSalt._norm_saltc�����������������C���s���|�d�|��S�rT���r=���)ru���r ��r=���r=���r>���r�����s����zHasSalt._truncate_saltc�����������������C���s���t�t|�j|�j�S�)zU helper method for _init_salt(); generates a new random salt string. )r ���r���r��r���r����r=���r=���r>���r �����s����zHasSalt._generate_saltc��������������������s8���t�t|��jf�i�|��}|du�r$|�j}t||�j�|d<�|S�)r����Nru���)r����r1���r����r���r?���r��)r����r����rR���r����r����r=���r>���r�������s ����zHasSalt.bitsize)NNN)r����T)N)F)N)rA���r����r����r����r��r����r��r&���r���r��r��r��ru���r����r����r��r����r��r��r ��r��r ��r����r����r=���r=���r����r>���r1������s8���L ����!39 r1���c�������������������@���s(���e�Zd�ZdZeZdZdZedd���Z dS�)r2���z�mixin for classes which use decoded salt parameter A variant of :class:`!HasSalt` which takes in decoded bytes instead of an encoded string. .. todo:: document this class's usage Tri���c�����������������C���s���t�t|�j�S�rT���)r���r���r���r����r=���r=���r>���r �����s����zHasRawSalt._generate_saltN) rA���r����r����r����r���r��r��r��r����r ��r=���r=���r=���r>���r2������s��� r2���c�����������������������s����e�Zd�ZdZdZdZdZdZdZdZ dZ dZdZe d��fdd� �Ze dd ���Ze d d���Zd��fdd � Zdd��Ze ddd��Ze dd���Z��fdd�Ze d��fdd� �Z���ZS�)r3���a3��mixin for validating rounds parameter This :class:`GenericHandler` mixin adds a ``rounds`` keyword to the class constuctor; any value provided is passed through the :meth:`_norm_rounds` method, which takes care of validating the number of rounds. :param rounds: optional number of rounds hash should use Class Attributes ================ In order for :meth:`!_norm_rounds` to do its job, the following attributes must be provided by the handler subclass: .. attribute:: min_rounds The minimum number of rounds allowed. A :exc:`ValueError` will be thrown if the rounds value is too small. Defaults to ``0``. .. attribute:: max_rounds The maximum number of rounds allowed. A :exc:`ValueError` will be thrown if the rounds value is larger than this. Defaults to ``None`` which indicates no limit to the rounds value. .. attribute:: default_rounds If no rounds value is provided to constructor, this value will be used. If this is not specified, a rounds value *must* be specified by the application. .. attribute:: rounds_cost [required] The ``rounds`` parameter typically encodes a cpu-time cost for calculating a hash. This should be set to ``"linear"`` (the default) or ``"log2"``, depending on how the rounds value relates to the actual amount of time that will be required. Class Methods ============= .. todo:: document using() and needs_update() options Instance Attributes =================== .. attribute:: rounds This instance attribute will be filled in with the rounds value provided to the constructor (as adapted by :meth:`_norm_rounds`) Subclassable Methods ==================== .. automethod:: _norm_rounds r���NZlinear)�min_desired_rounds�max_desired_roundsr����� max_roundsr{����vary_roundsc����������� ���������s���|d�ur|d�urt�d��|}|d�ur8|d�ur4t�d��|}|d�urd|d�u�rL|}|d�u�rX|}|d�u�rd|}tt|��jf�i�|��} |�d�} |d�u�r�d}|�j}n(d}t|t�r�t|�}| j |d| d�| _|d�u�r�|�j }nbt|t�r�t|�}|�r ||k��r d| j||f�}|�rt|��nt |t��|}| j |d | d�| _ |d�u�r�t|t��rPt|�}|�rv||k��rvtd | j||f���n$|�r�||k�r�td| j||f���| j |d| d�| _| jd�u�r�| �| j�| _|d�u�r�t|t��r|�d ��r�t|d�d���d�}nd|v��rt|�}nt|�}|dk��r8td| j|f���n>t|t��rb|dk�rvtd| j|f���nt|t��svt�d��|�r�t dt��|| _| S�)NzD'min_rounds' and 'min_desired_rounds' aliases are mutually exclusivezD'max_rounds' and 'max_desired_rounds' aliases are mutually exclusiver����FTr��r��z9%s: max_desired_rounds (%r) below min_desired_rounds (%r)r��z5%s: default_rounds (%r) below min_desired_rounds (%r)z5%s: default_rounds (%r) above max_desired_rounds (%r)r{����%���g{�G�z�?�.r���z%s: vary_rounds (%r) below 0r@���z%s: vary_rounds (%r) above 1.0z vary_rounds must be int or floatz\The 'vary_rounds' option is deprecated as of Passlib 1.7, and will be removed in Passlib 2.0)r����r����r3���r����rE���r��rc���r���r8����_norm_roundsr��rK���r����r���r���r{����_clip_to_desired_rounds�endswith�floatr��) r����r��r��r{���r��r����r��r|���rR���r����r����Zexplicit_min_roundsr����r����r=���r>���r����W��s����� � � � � �� � ��zHasRounds.usingc�����������������C���s0���|�j�pd}||k�r|S�|�j}|r,||kr,|S�|S�)z| helper for :meth:`_generate_rounds` -- clips rounds value to desired min/max set by class (if any) r���)r��r��)r����r|���ZmndZmxdr=���r=���r>���r�����s���� z!HasRounds._clip_to_desired_roundsc�����������������C���sn���|�j�}dd��}t|t�r>|�jdkr2d|>�}dd��}t||��}|||�d�}|||�d�}|��|�|��|�fS�)z� helper for :meth:`_generate_rounds` -- returns range for vary rounds generation. :returns: (lower, upper) limits suitable for random.randint() c�����������������S���s���|�S�rT���r=����r}����upperr=���r=���r>����linear_to_native���s����z;HasRounds._calc_vary_rounds_range.<locals>.linear_to_native�log2r@���c�����������������S���s:���|�dkrdS�|r t�t�|�d��S�t�t�t�|�d���S�d�S�)Nr���r6���)r8���r7���r9���Zceilr��r=���r=���r>���r �����s ����FT)r��rc���r���rounds_costr8���r��)r����r{���r��r ���lowerr��r=���r=���r>����_calc_vary_rounds_range���s���� z!HasRounds._calc_vary_rounds_rangec��������������������sL���t�t|��jf�i�|���|d�ur*|��|�}n|�jr:|����}ntd��||�_d�S�)Nzno rounds specified)r����r3���r����� _parse_roundsr�����_generate_roundsr����r|���)r����r|���rR���r����r=���r>���r������s����zHasRounds.__init__c�����������������C���s ���|���|�S�rT���)r��)r����r|���r=���r=���r>���r%�� ��s����zHasRounds._parse_roundsFr|���c�����������������C���s���t�|�||�j|�j||d�S�)a��� helper for normalizing rounds value. :arg rounds: an integer cost parameter. :param relaxed: if ``True`` (the default), issues PasslibHashWarning is rounds are outside allowed range. if ``False``, raises a ValueError instead. :param param: optional name of parameter to insert into error/warning messages. :raises TypeError: * if ``use_defaults=False`` and no rounds is specified * if rounds is not an integer. :raises ValueError: * if rounds is ``None`` and class does not specify a value for :attr:`default_rounds`. * if ``relaxed=False`` and rounds is outside bounds of :attr:`min_rounds` and :attr:`max_rounds` (if ``relaxed=True``, the rounds value will be clamped, and a warning issued). :returns: normalized rounds value r��)r����r����r��)r����r|���r����r����r=���r=���r>���r����s�����zHasRounds._norm_roundsc�����������������C���sJ���|�j�}|du�rtd|�jf���|�jrF|��|�\}}||k�rFt�||�}|S�)z� internal helper for :meth:`_norm_rounds` -- returns default rounds value, incorporating vary_rounds, and any other limitations hash may place on rounds parameter. Nz,%s rounds value must be specified explicitly)r{���r����rK���r��r$��r���Zrandint)r����r|���r#��r��r=���r=���r>���r&��1��s����zHasRounds._generate_roundsc��������������������sF���|�j�}|r|�j|k�rdS�|�j}|r0|�j|kr0dS�tt|��jf�i�|��S��zR mark hash as needing update if rounds is outside desired bounds. T)r��r|���r��r����r3���r����)r����rR���r��r��r����r=���r>���r����J��s����zHasRounds._calc_needs_update皙�����?c��������������������s\���t�t|��jf�i�|��}|�jdkrXddl}|du�r6|�j}tdtd|�||�d����|d<�|S�)r����r!��r���Nr@���r6���r|���) r����r3���r����r"��r7���r{���rG���r8���r9���)r����r|���r��rR���r����r7���r����r=���r>���r����Y��s���� "zHasRounds.bitsize)NNNNNNN)N)Fr|���)Nr(��)rA���r����r����r����r����r��r"��Zusing_rounds_kwdsr��r��r{���r��r|���r����r����r��r$��r����r%��r��r&��r����r����r����r=���r=���r����r>���r3������s8���>����k * r3���c�����������������������sR���e�Zd�ZdZdZed ��fdd� �Zd��fdd� Zedd d ��Z��fdd�Z ���Z S�)�ParallelismMixinzH mixin which provides common behavior for 'parallelism' setting r@���Nc��������������������sJ���t�t|��jf�i�|��}|d�urFt|t�r0t|�}|j||�d�d�|_|S�)Nr����r��) r����r)��r����rc���r���r8����_norm_parallelismrE����parallelism)r����r+��rR���r����r����r=���r>���r�������s���� zParallelismMixin.usingc��������������������s0���t�t|��jf�i�|���|d�u�r n|��|�|�_d�S�rT���)r����r)��r����r*��r+��)r����r+��rR���r����r=���r>���r�������s����zParallelismMixin.__init__Fc�����������������C���s���t�|�|dd|d�S�)Nr@���r+��)r����r����r����)r����)r����r+��r����r=���r=���r>���r*�����s����z"ParallelismMixin._norm_parallelismc��������������������s*���|�j�t|��j�krdS�tt|��jf�i�|��S�r'��)r+��r����r����r)��r����)r����rR���r����r=���r>���r�������s����z#ParallelismMixin._calc_needs_update)N)N)F)rA���r����r����r����r+��r����r����r����r*��r����r����r=���r=���r����r>���r)��v��s��� r)��c�������������������@���s|���e�Zd�ZdZdZdZdZdZdZe dd���Z e ddd��Ze dd d ��Ze dd���Z e d d���Ze dd���Ze dd���ZdS�)�BackendMixina��� PasswordHash mixin which provides generic framework for supporting multiple backends within the class. Public API ---------- .. attribute:: backends This attribute should be a tuple containing the names of the backends which are supported. Two common names are ``"os_crypt"`` (if backend uses :mod:`crypt`), and ``"builtin"`` (if the backend is a pure-python fallback). .. automethod:: get_backend .. automethod:: set_backend .. automethod:: has_backend .. warning:: :meth:`set_backend` is intended to be called during application startup -- it affects global state, and switching backends is not guaranteed threadsafe. Private API (Subclass Hooks) ---------------------------- Subclasses should set the :attr:`!backends` attribute to a tuple of the backends they wish to support. They should also define one method: .. classmethod:: _load_backend_{name}(dryrun=False) One copy of this method should be defined for each :samp:`name` within :attr:`!backends`. It will be called in order to load the backend, and should take care of whatever is needed to enable the backend. This may include importing modules, running tests, issuing warnings, etc. :param name: [Optional] name of backend. :param dryrun: [Optional] True/False if currently performing a "dry run". if True, the method should perform all setup actions *except* switching the class over to the new backend. :raises passlib.exc.PasslibSecurityError: if the backend is available, but cannot be loaded due to a security issue. :returns: False if backend not available, True if backend loaded. .. warning:: Due to the way passlib's internals are arranged, backends should generally store stateful data at the class level (not the module level), and be prepared to be called on subclasses which may be set to a different backend from their parent. (Idempotent module-level data such as lazy imports are fine). .. automethod:: _finalize_backend .. versionadded:: 1.7 NFc�����������������C���s���|�j�s|�����|�j�S�)a�� Return name of currently active backend. if no backend has been loaded, loads and returns name of default backend. :raises passlib.exc.MissingBackendError: if no backends are available. :returns: name of active backend )�_BackendMixin__backend�set_backendr����r=���r=���r>����get_backend��s����zBackendMixin.get_backendr����c�������������� ���C���s6���z|�j�|dd��W�dS��tjtjfy0���Y�dS�0�dS�)a��� Check if support is currently available for specified backend. :arg name: name of backend to check for. can be any string accepted by :meth:`set_backend`. :raises ValueError: if backend name is unknown :returns: * ``True`` if backend is available. * ``False`` if it's available / can't be loaded. * ``None`` if it's present, but won't load due to a security issue. T��dryrunFN)r.��rd���r����PasslibSecurityError�r����rK���r=���r=���r>����has_backend,��s ����zBackendMixin.has_backendc�����������������C���s���|dkr|�j�s|r"||�j�kr"|�j�S�|����}||�ur@|j||d�S�|dksP|dkr�d}|�jD�]n}z|�j||d�W���S��tjy����Y�qZY�qZ�tjy��}�z$|du�r�|}W�Y�d}~qZW�Y�d}~qZd}~0�0�qZ|du�r�d|�j�}|�jr�||�j7�}t�|�}|�||�jv�rt� |�|��t �d�|�j|�jf}z(||�_||�_|�� ||��W�|\|�_|�_n|\|�_|�_0�|�sh||�_�|W��d����S�1��s�0����Y��dS�)a�� Load specified backend. :arg name: name of backend to load, can be any of the following: * ``"any"`` -- use current backend if one is loaded, otherwise load the first available backend. * ``"default"`` -- use the first available backend. * any string in :attr:`backends`, loads specified backend. :param dryrun: If True, this perform all setup actions *except* switching over to the new backend. (this flag is used to implement :meth:`has_backend`). .. versionadded:: 1.7 :raises ValueError: If backend name is unknown. :raises passlib.exc.MissingBackendError: If specific backend is missing; or in the case of ``"any"`` / ``"default"``, if *no* backends are available. :raises passlib.exc.PasslibSecurityError: If ``"any"`` or ``"default"`` was specified, but the only backend available has a PasslibSecurityError. r����r0��r����Nz%s: no backends available)r-���_get_backend_ownerr.���backendsrd���r���r2��rK����_no_backend_suggestionZUnknownBackendError� _backend_lock�_pending_backend�_pending_dry_run�_set_backend)r����rK���r1���ownerZ default_errorr����r����r����r=���r=���r>���r.��C��sD����" $ zBackendMixin.set_backendc�����������������C���s���|�S�)z� return class that set_backend() should actually be modifying. for SubclassBackendMixin, this may not always be the class that was invoked. r=���r����r=���r=���r>���r5�����s����zBackendMixin._get_backend_ownerc�����������������C���sx���|���|�}i�}t|d�r ||d<�t|d�r2||d<�|f�i�|��}|du�r^t�d|�j|f���n|durttd|f���dS�)a%�� Internal method invoked by :meth:`set_backend`. handles actual loading of specified backend. global _backend_lock will be held for duration of this method, and _pending_dry_run & _pending_backend will also be set. should return True / False. rK���r1��Fz%s: backend not available: %sTz-backend loaders must return True or False: %rN)�_get_backend_loaderr���rd���r���rK����AssertionError)r����rK���r1���loaderrR����okr=���r=���r>���r;�����s���� ��zBackendMixin._set_backendc�����������������C���s���t�d��dS�)af�� Hook called to get the specified backend's loader. Should return callable which optionally takes ``"name"`` and/or ``"dryrun"`` keywords. Callable should return True if backend initialized successfully. If backend can't be loaded, callable should return False OR raise MissingBackendError directly. zimplement in subclassNr����r3��r=���r=���r>���r=�����s����z BackendMixin._get_backend_loaderc�����������������C���s:���|�j�rtd|�j|�j�f���|�����|�j�s6td|�j���dS�)zW helper for subclasses to create stub methods which auto-load backend. z7%s: _finalize_backend(%r) failed to replace lazy loaderz2%s: set_backend() failed to load a default backendN)r-��r>��rK���r.��r����r=���r=���r>����_stub_requires_backend���s���� ��z#BackendMixin._stub_requires_backend)r����)r����F)rA���r����r����r����r6��r-��r7��r9��r:��r����r/��r4��r.��r5��r;��r=��rA��r=���r=���r=���r>���r,�����s(���E S r,��c�����������������������sD���e�Zd�ZdZdZdZedd���Ze��fdd��Zedd ���Z ���Z S�) �SubclassBackendMixina��� variant of BackendMixin which allows backends to be implemented as separate mixin classes, and dynamically switches them out. backend classes should implement a _load_backend() classmethod, which will be invoked with an optional 'dryrun' keyword, and should return True or False. _load_backend() will be invoked with ``cls`` equal to the mixin, *not* the overall class. .. versionadded:: 1.7 FNc�����������������C���s:���|�j�std��|�jD�]}|j�d�r|��S�qtd��dS�)z� return base class that we're actually switching backends on (needed in since backends frequently modify class attrs, and .set_backend may be called from a subclass). z_backend_mixin_target not set�_backend_mixin_targetz5expected to find class w/ '_backend_mixin_target' setN)rC��r>���__mro__�__dict__rE���)r����r���r=���r=���r>���r5�����s���� z'SubclassBackendMixin._get_backend_ownerc��������������������s<���t�t|���||��|�j}||�}t|�||���dt|d��d�S�)NT)�add�remove�append�beforer1��)r����rB��r;���_backend_mixin_mapr����values)r����rK���r1��Z mixin_mapZ mixin_clsr����r=���r>���r;�� ��s�����z!SubclassBackendMixin._set_backendc�����������������C���s���|�j�|�jS�rT���)rJ��Z_load_backend_mixinr3��r=���r=���r>���r=�� ��s����z(SubclassBackendMixin._get_backend_loader)rA���r����r����r����rC��rJ��r����r5��r;��r=��r����r=���r=���r����r>���rB�����s��� rB��c�������������������@���sD���e�Zd�ZdZdd��Zdd��Zedd���Zedd ���Zed d���Z dS�) r4���a��� GenericHandler mixin which provides selecting from multiple backends. .. todo:: finish documenting this class's usage For hashes which need to select from multiple backends, depending on the host environment, this class offers a way to specify alternate :meth:`_calc_checksum` methods, and will dynamically chose the best one at runtime. .. versionchanged:: 1.7 This class now derives from :class:`BackendMixin`, which abstracts out a more generic framework for supporting multiple backends. The public api (:meth:`!get_backend`, :meth:`!has_backend`, :meth:`!set_backend`) is roughly the same. Private API (Subclass Hooks) ---------------------------- As of version 1.7, classes should implement :meth:`!_load_backend_{name}`, per :class:`BackendMixin`. This hook should invoke :meth:`!_set_calc_checksum_backcend` to install it's backend method. .. deprecated:: 1.7 The following api is deprecated, and will be removed in Passlib 2.0: .. attribute:: _has_backend_{name} private class attribute checked by :meth:`has_backend` to see if a specific backend is available, it should be either ``True`` or ``False``. One of these should be provided by the subclass for each backend listed in :attr:`backends`. .. classmethod:: _calc_checksum_{name} private class method that should implement :meth:`_calc_checksum` for a given backend. it will only be called if the backend has been selected by :meth:`set_backend`. One of these should be provided by the subclass for each backend listed in :attr:`backends`. c�����������������C���s ���|���|�S�)z$wrapper for backend, for common code)�_calc_checksum_backendr����r=���r=���r>���r����U ��s����zHasManyBackends._calc_checksumc�����������������C���s���|������|��|�S�)z� stub for _calc_checksum_backend() -- should load backend if one hasn't been loaded; if one has been loaded, this method should have been monkeypatched by _finalize_backend(). )rA��rL��r����r=���r=���r>���rL��\ ��s����z&HasManyBackends._calc_checksum_backendc��������������������s,���t���d��d�}|du�r(���fdd�}n�|S�)zp subclassed to support legacy 1.6 HasManyBackends api. (will be removed in passlib 2.0) Z_load_backend_Nc����������������������s ���������S�rT���)�%_HasManyBackends__load_legacy_backendr=���r3��r=���r>���r?��r ��s����z3HasManyBackends._get_backend_loader.<locals>.loaderr����)r����rK���r?��r=���r3��r>���r=��h ��s����z#HasManyBackends._get_backend_loaderc�����������������C���sL���t�|�d|��}td|�j||f�t��|rDt�|�d|��}|��|��dS�dS�d�S�)NZ _has_backend_z�%s: support for ._has_backend_%s is deprecated as of Passlib 1.7, and will be removed in Passlib 1.9/2.0, please implement ._load_backend_%s() insteadZ_calc_checksum_TF)r����r���rK���rP����_set_calc_checksum_backend)r����rK���r}����funcr=���r=���r>���Z__load_legacy_backend| ��s���� �� z%HasManyBackends.__load_legacy_backendc�����������������C���s2���|�j�}t|�s"td|�j||f���|�js.||�_dS�)zl helper used by subclasses to validate & set backend-specific calc checksum helper. z,%s: backend %r returned invalid callable: %rN)r9���callable�RuntimeErrorrK���r:��rL��)r����rO��Zbackendr=���r=���r>���rN��� ��s���� �z*HasManyBackends._set_calc_checksum_backendN) rA���r����r����r����r����rL��r����r=��rM��rN��r=���r=���r=���r>���r4���% ��s���/ r4���c�������������������@���s��e�Zd�ZdZdZed�ed�dddfdd�ZdZdZdd ��Z d d��Z ee �ZdZ edd ���ZdZedd���ZdZdd��Zdd��Zdd��Zdd��Zdd��Zdd��ZdZdd��Zdd ��Zd!d"��Zed#d$d%�d&d'���Zed#d$d%�d(d)���Zed#d$d*d+�d,d-���Zd.d/��Z d0d1��Z!dS�)2r5���aU��wraps another handler, adding a constant prefix. instances of this class wrap another password hash handler, altering the constant prefix that's prepended to the wrapped handlers' hashes. this is used mainly by the :doc:`ldap crypt <passlib.hash.ldap_crypt>` handlers; such as :class:`~passlib.hash.ldap_md5_crypt` which wraps :class:`~passlib.hash.md5_crypt` and adds a ``{CRYPT}`` prefix. usage:: myhandler = PrefixWrapper("myhandler", "md5_crypt", prefix="$mh$", orig_prefix="$1$") :param name: name to assign to handler :param wrapped: handler object or name of registered handler :param prefix: identifying prefix to prepend to all hashes :param orig_prefix: prefix to strip (defaults to ''). :param lazy: if True and wrapped handler is specified by name, don't look it up until needed. r=���rB���FNc�����������������C���s����||�_�t|t�r|�d�}||�_t|t�r4|�d�}||�_|rD||�_t|d�rZ|��|��n||�_ |sl|�� ���|d�ur�|du�r�|r�|}ntd��t|t�r�|�d�}|d�t|���|d�t|���kr�td��||�_ d�S�)Nrn���rK���Tzno prefix specifiedzident must agree with prefix)rK���rc���ri���rj���rr����orig_prefixr�����hasattr�_set_wrapped� _wrapped_name�_get_wrappedr����r:����_ident)r����rK����wrappedrr���rR��Zlazy�docr����r=���r=���r>���r����� ��s0���� zPrefixWrapper.__init__c�����������������C���s.���d|j�v�r$|�jr$td|jf�tj��||�_d�S�)Nr����zkPrefixWrapper: 'orig_prefix' option may not work correctly for handlers which have multiple identifiers: %r)r����rR��r���rK���rd���ZPasslibRuntimeWarning�_wrapped_handler�r����rM���r=���r=���r>���rT��� ��s������zPrefixWrapper._set_wrappedc�����������������C���s&���|�j�}|d�u�r"t|�j�}|��|��|S�rT���)rZ��r���rU��rT��r[��r=���r=���r>���rV��� ��s ���� zPrefixWrapper._get_wrappedc�����������������C���sF���|�j�}|du�rBd�}|�js<|�j}t|dd��}|d�ur<|��|�}||�_�|S�)NFr����)rW��rR��rX��r����� _wrap_hash)r����r}���rX��r����r=���r=���r>���r����� ��s���� zPrefixWrapper.identc��������������������sN�����j�}|du�rJd�}��jsD��j}t|dd��}|rDt��fdd�|D���}|��_�|S�)NFr����c�����������������3���s���|�]}����|�V��qd�S�rT���)r\��)rW���r����r����r=���r>���rZ��� ��r[���z-PrefixWrapper.ident_values.<locals>.<genexpr>)� _ident_valuesrR��rX��r����r����)r����r}���rX��Zidentsr=���r����r>���r���� ��s����zPrefixWrapper.ident_values)r����r]���r{���r����r��r"��r��r��r��r���r��r����r��r��r6��r4��r/��r.��Zis_disabledr����r����r����r��c�����������������C���sV���t�|�jp|�j�g}|�jr(|�d|�j���|�jr>|�d|�j���d�|�}d|�j|f�S�)Nz prefix=%rzorig_prefix=%rz, zPrefixWrapper(%r, %s))�reprrU��rZ��rr���rH��rR���joinrK���)r�����argsr=���r=���r>����__repr__& ��s���� zPrefixWrapper.__repr__c��������������������sB���t�t|�j��}|�|�j��|�j��|���fdd�|�jD����t|�S�)Nc�����������������3���s���|�]}t���|�r|V��qd�S�rT���)rS��)rW����attr�rX��r=���r>���rZ���3 ��s��� �z(PrefixWrapper.__dir__.<locals>.<genexpr>)r\����dirr�����updaterE��rX���_proxy_attrsr^���)r�����attrsr=���rc��r>����__dir__/ ��s�����zPrefixWrapper.__dir__c�����������������C���s(���||�j�v�rt|�j|�S�td|f���dS�)zFproxy most attributes from wrapped class (e.g. rounds, salt size, etc)zmissing attribute: %rN)rf��r����rX��r����)r����rb��r=���r=���r>����__getattr__9 ��s���� zPrefixWrapper.__getattr__c�����������������C���s>���||�j�v�r0|�jr0|�j}t||�r0t|||��d�S�t�|�||�S�rT���)rf��� _derived_fromrX��rS���setattrr�����__setattr__)r����rb��r}���rX��r=���r=���r>���rl��? ��s���� zPrefixWrapper.__setattr__c�����������������C���s0���|�j�}|�|�st�|���|�j|t|�d���S�)z4given hash belonging to wrapper, return orig versionN)rr���rF���rd���ro���rR��r:���)r����rh���rr���r=���r=���r>����_unwrap_hashL ��s���� zPrefixWrapper._unwrap_hashc�����������������C���sN���t�|t�r|�d�}|�j}|�|�s0t�|�j��|�j|t |�d���}t |�S�)z0given orig hash; return one belonging to wrapperrn���N)rc���ri���rj���rR��rF���rd���ro���rX��rr���r:���r���)r����rh���rR��rX��r=���r=���r>���r\��U ��s���� zPrefixWrapper._wrap_hashc�����������������K���sP���|�j�jf�i�|��}t|�j||�j|�jd�}|�|_|�jD�]}t||t |�|���q4|S�)N)rr���rR��) rX��r����r5���rK���rr���rR��rj���_using_clone_attrsrk��r����)r����rR���r�����wrapperrb��r=���r=���r>���r����d ��s���� zPrefixWrapper.usingc�����������������K���s���|���|�}|�jj|fi�|��S�rT���)rm��rX��r����)r����rh���rR���r=���r=���r>���r����o ��s���� zPrefixWrapper.needs_updatec�����������������C���s.���t�|�}|�|�j�sdS�|��|�}|�j�|�S�)NF)rm���rF���rr���rm��rX��r����)r����rh���r=���r=���r>���r����s ��s ���� zPrefixWrapper.identifyr����r����r����c�����������������K���s,���|�j�jf�i�|��}|d�u�r"td��|��|�S�)Nz+.genconfig() must return a string, not None)rX��r����rQ��r\��)r����rR���r����r=���r=���r>���r����z ��s����zPrefixWrapper.genconfigc�����������������K���s:���|d�urt�|dd�}|��|�}|��|�jj||fi�|���S�)Nrn���zconfig/hash)r���rm��r\��rX��r����)r����rb���r����rR���r=���r=���r>���r����� ��s���� zPrefixWrapper.genhashz.hash())r����r����Zreplacementc�����������������K���s���|�j�|fi�|��S�rT���rl����r����rb���rR���r=���r=���r>����encrypt� ��s����zPrefixWrapper.encryptc�����������������K���s���|���|�jj|fi�|���S�rT���)r\��rX��rh���rp��r=���r=���r>���rh���� ��s����zPrefixWrapper.hashc�����������������K���s,���t�|dd�}|��|�}|�jj||fi�|��S�)Nrn���rh���)r���rm��rX��r����)r����rb���rh���rR���r=���r=���r>���r����� ��s���� zPrefixWrapper.verify)"rA���r����r����r����rn��r���r����rU��rZ��rT��rV��r����rX��rW��r����r]��r����rf��ra��rh��ri��rl��rm��r\��rj��r����r����r����r'���r����r����rq��rh���r����r=���r=���r=���r>���r5���� ��sF���� r5���)r@���)rw���Nr}���N)r����r����r����)r}���)r@���Nr}���F)br����Z __future__r���rC���ZloggingZ getLoggerrA���r9���r7���� threading�warningsr���Zpasslib.excrd���Zpasslib.ifcZifcr���r���r���r���Zpasslib.registryr���Z passlib.utilsr ���r ���r���r���r ���r���r���r���r���r���r���r����r���r���r���r���r���r���r���Zpasslib.utils.compatr���r���r���r���r���r ���r!���r"���r#���r$���r%���Zpasslib.utils.decorr&���r'����__all__Z H64_CHARSZ B64_CHARSZPADDED_B64_CHARSZUC_HEX_CHARSZLC_HEX_CHARSr?���rL���rS���r_���Z_UDOLLARry���rf���rm���r(���r)���r����r*���r+���r����r����r����r����r����r,���r-���r����r.���r/���r0���r1���r2���r3���r)���RLockr8��r,��rB��r4���r����r5���r=���r=���r=���r>����<module>���s����4$8 � K " ��� '!*���BZ '���'��yH��N|