
    XR_(U                     l   d Z ddlZddlZ ej        e          ZddlmZmZm	Z	m
Z
 ddlmZ ddlmZmZmZmZ ddlmc mZ ddgZdZd	Zd
ZdZddZ ed          Z ed          Z ed          Z G d dej        ej         ej!        ej"                  Z# G d de#          Z$ G d de#          Z%dS )z9passlib.handlers.sha2_crypt - SHA256-Crypt / SHA512-Crypt    N)
safe_crypt
test_cryptrepeat_string
to_unicode)h64)byte_elem_valueuuascii_to_strunicodesha512_cryptsha256_crypt    ))r            r   r   )r      r   r   r   r   )   r   r   r   )r   r   r   r   r   )r   r   r   r   )r   r   r   r   r   )    
   r      r      r               r      r      r                                          	         )@*   r   r   r   +   r   r   r   ,   -   r    r   r   .   r!   r#   r   /   0   r(   r%   r'   1   r*   r,   r)   2   3   r/   r.   r   4   r0       r   5   6   !   r   r   7   "   #   r   8   9   $   r"   r$   :   %   &   r&   ;   <   '   r+   r-   =   (   )   r   >   ?   Fc                    t          | t                    r|                     d          } t          | t                    sJ t          | v r-t
          j                            |rt          nt                    t          |           }d|cxk    rdk    sn J d            t          |t                    s
J d            |                    d          }t          |          }|dk     s
J d            |rt          j        }t          }nt          j        }t          } || |z   | z                                             } || |z             }	|	j        }
 |
t%          ||                     |}|r |
|d	z  r|n|            |d	z  }||	                                }|d
k     r/t%           || |z                                            |          }nM ||           }|j        }|d	z
  }|r ||            |d	z  }|t%          |                                |          }t          |          |k    sJ  ||dt'          |d                   z   z                                            d|         }t          |          |k    s
J d            ||z   }||z   }|||||z   ||z   ||z   gfdt(          D             }|}t+          |d          \  }}|rM|D ]C\  }} || |||z                                             z                                             }D|d	z  }|M|r|d	z	  }|d|         D ]C\  }} || |||z                                             z                                             }D|d	z  r, ||||         d         z                                             }t-          j        ||                              d          S )a  perform raw sha256-crypt / sha512-crypt

    this function provides a pure-python implementation of the internals
    for the SHA256-Crypt and SHA512-Crypt algorithms; it doesn't
    handle any of the parsing/validation of the hash strings themselves.

    :arg pwd: password chars/bytes to hash
    :arg salt: salt chars to use
    :arg rounds: linear rounds cost
    :arg use_512: use sha512-crypt instead of sha256-crypt mode

    :returns:
        encoded checksum chars
    zutf-8  ɚ;zinvalid roundszsalt not unicodeasciir&   zsalt too larger   `   r$   r   Nzsalt_len somehow > hash_len!c                 6    g | ]\  }}|         |         fS  rW   ).0evenoddpermss      =/usr/lib/python3/dist-packages/passlib/handlers/sha2_crypt.py
<listcomp>z#_raw_sha2_crypt.<locals>.<listcomp>   s*    JJJ94eDk5:&JJJ    r1   )
isinstancer   encodebytes_BNULLuhexcNullPasswordErrorr   r   lenhashlibsha512_512_transpose_mapsha256_256_transpose_mapdigestupdater   r   _c_digest_offsetsdivmodr   encode_transposed_bytesdecode)pwdsaltroundsuse_512pwd_lensalt_len
hash_consttranspose_mapdba_ctxa_ctx_updateidadptmp_ctxtmp_ctx_updatedsdp_dpdp_dsdatadcblockstailrY   rZ   pairsr[   s                             @r\   _raw_sha2_cryptr   8   sn   B #w "jj!!c5!!!!!}}f&&w'P||LQQQ#hhG 6&&&&Y&&&&&(8&&& dG$$88&8888;;wD4yyHb===*===  +^
*^
*
 
C$J$	%	%	,	,	.	.B JsTz""E<L Lr7++,,, 	A
 1q5)RRc***	a  
 
B || ::cGm44;;==wGG *S// AI 	N3FA  	 7>>++W55r77g
 
DBA!7!778	9	9	@	@	B	B9H9	MBr77h >\ rEErEEuRxB59E KJJJ8IJJJD 
B&"%%LFD
  	K 	KID#C**R$Y"7"7">">"@"@@AAHHJJBB!    	:afuf 	K 	KID#C**R$Y"7"7">">"@"@@AAHHJJBB !8 	:BeQ/007799B
 &r=99@@IIIr^   zrounds=$0c                        e Zd ZdZdZej        ZdZej        Z	dZ
dZdZdZdZdZd fd		Zd
 Zd Zed             Zd ZdZdZed             Zd Zed             Zd Z xZS )_SHA2_CommonzBclass containing common code shared by sha256_crypt & sha512_crypt)rs   rt   implicit_rounds	salt_sizer$   rR   rS   linearFNc                 ~     t          t          |           j        di | || j        o
| j        dk    }|| _        d S )N  rW   )superr   __init__use_defaultsrt   r   )selfr   kwds	__class__s      r\   r   z_SHA2_Common.__init__  sN    *lD!!*22T222"#0HT[D5HO.r^   c                 >    |                      || j        d u           S N)relaxed)
_norm_saltchecksum)r   rs   s     r\   _parse_saltz_SHA2_Common._parse_salt  s    tT]d-BCCCr^   c                 >    |                      || j        d u           S r   )_norm_roundsr   )r   rt   s     r\   _parse_roundsz_SHA2_Common._parse_rounds#  s"      $1F GGGr^   c                 8   t          |dd          }| j        }|                    |          st          j                            |           t          |          dk    sJ |dd                              t                    }|d                             t                    rt          t                    dk    sJ |
                    d          dd          }|                    t                    r*|t          k    rt          j                            |           t          |          }d}nd}d}t          |          d	k    r|\  }}n=t          |          d
k    r|d         }d }nt          j                            |            | |||pd |          S )NrT   hashr   r   r'   Fr   Tr   r   )rt   rs   r   r   )r   ident
startswithrc   rd   InvalidHashErrorrf   split_UDOLLAR_UROUNDSpop_UZEROZeroPaddedRoundsErrorintMalformedHashError)clsr   r   partsrt   r   rs   chks           r\   from_stringz_SHA2_Common.from_string'  s    $00	u%% 	/&))#...5zzQQRRx(( 8x(( 		#x==A%%%%YYq\\!""%F  (( 8Vv-=-=f223777[[F#OOF"O u::??ID##ZZ1__8DCC&++C000 s[D+	   	r^   c                    | j         dk    r;| j        r4t          d          | j        | j        | j        pt          d          fz  }n9t          d          | j        | j         | j        | j        pt          d          fz  }t          |          S )Nr   z%s%s$%s z%srounds=%d$%s$%s)rt   r   r	   r   rs   r   r
   )r   r   s     r\   	to_stringz_SHA2_Common.to_stringT  s    ;$4#7Y<<4:ty#'=#9AbEE#; ;DD ())TZ-1Y8N2-P PDT"""r^   )os_cryptbuiltinc                 Z    t          | j         r|                     | j                   dS dS )NTF)r   
_test_hash_set_calc_checksum_backend_calc_checksum_os_cryptr   s    r\   _load_backend_os_cryptz#_SHA2_Common._load_backend_os_crypti  s2    s~& 	**3+FGGG45r^   c                 <   |                                  }t          ||          }||                     |          S | j        }|                    | j                  r|| dz
           t          k    r!t          j        	                    | ||          || d          S )Nr   )
r   r   _calc_checksum_builtinchecksum_sizer   r   r   rc   rd   CryptBackendError)r   secretconfigr   css        r\   r   z$_SHA2_Common._calc_checksum_os_cryptq  s    !!&&))< ..v666 tz** 	?dB3q5kX.E.E&**4>>>RCDDzr^   c                 :    |                      | j                   dS )NT)r   r   r   s    r\   _load_backend_builtinz"_SHA2_Common._load_backend_builtin  s    &&s'ABBBtr^   c                 D    t          || j        | j        | j                  S N)r   rs   rt   _cdb_use_512)r   r   s     r\   r   z#_SHA2_Common._calc_checksum_builtin  s$    vty$+#02 2 	2r^   r   )__name__
__module____qualname____doc__setting_kwdsrc   HASH64_CHARSchecksum_charsmax_salt_size
salt_chars
min_rounds
max_roundsrounds_costr   _rounds_prefixr   r   r   r   classmethodr   r   backendsr   r   r   r   r   __classcell__)r   s   @r\   r   r      s/       LL
 FL_N MJJJKLN
 O/ / / / / /D D DH H H * * [*X# # # 'H J  [  "   [2 2 2 2 2 2 2r^   r   c                   8    e Zd ZdZd Z ed          ZdZdZdZ	dS )r   aK  This class implements the SHA256-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt, and a variable number of rounds.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: str
    :param salt:
        Optional salt string.
        If not specified, one will be autogenerated (this is recommended).
        If specified, it must be 0-16 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        Defaults to 535000, must be between 1000 and 999999999, inclusive.

        .. note::
            per the official specification, when the rounds parameter is set to 5000,
            it may be omitted from the hash string.

    :type relaxed: bool
    :param relaxed:
        By default, providing an invalid value for one of the other
        keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
        and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
        will be issued instead. Correctable errors include ``rounds``
        that are too small or too large, and ``salt`` strings that are too long.

        .. versionadded:: 1.6

    ..
        commented out, currently only supported by :meth:`hash`, and not via :meth:`using`:

        :type implicit_rounds: bool
        :param implicit_rounds:
            this is an internal option which generally doesn't need to be touched.

            this flag determines whether the hash should omit the rounds parameter
            when encoding it to a string; this is only permitted by the spec for rounds=5000,
            and the flag is ignored otherwise. the spec requires the two different
            encodings be preserved as they are, instead of normalizing them.
    z$5$r2   i) )testz?$5$rounds=1000$test$QmQADEXMG8POI5WDsaeho0P36yK3Tcrgboabng6bkb/N)
r   r   r   r   namer	   r   r   default_roundsr   rW   r^   r\   r   r     s>        * *\ DAeHHEMN
:JJJr^   c                   <    e Zd ZdZd Z ed          ZdZdZdZ	dZ
dS )r   aK  This class implements the SHA512-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt, and a variable number of rounds.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: str
    :param salt:
        Optional salt string.
        If not specified, one will be autogenerated (this is recommended).
        If specified, it must be 0-16 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        Defaults to 656000, must be between 1000 and 999999999, inclusive.

        .. note::
            per the official specification, when the rounds parameter is set to 5000,
            it may be omitted from the hash string.

    :type relaxed: bool
    :param relaxed:
        By default, providing an invalid value for one of the other
        keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
        and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
        will be issued instead. Correctable errors include ``rounds``
        that are too small or too large, and ``salt`` strings that are too long.

        .. versionadded:: 1.6

    ..
        commented out, currently only supported by :meth:`hash`, and not via :meth:`using`:

        :type implicit_rounds: bool
        :param implicit_rounds:
            this is an internal option which generally doesn't need to be touched.

            this flag determines whether the hash should omit the rounds parameter
            when encoding it to a string; this is only permitted by the spec for rounds=5000,
            and the flag is ignored otherwise. the spec requires the two different
            encodings be preserved as they are, instead of normalizing them.
    z$6$V   Ti
 )r   zj$6$rounds=1000$test$2M/Lx6MtobqjLjobw0Wmo4Q5OFx5nVLJvmgseatA6oMnyWeBdRDx4DU.1H3eGmse6pgsOgDisWBGI5c7TZauS0N)r   r   r   r   r   r	   r   r   r   r   r   rW   r^   r\   r   r     sC        * *^ DAeHHEMLN
(JJJr^   )F)&r   rg   logging	getLoggerr   logpasslib.utilsr   r   r   r   passlib.utils.binaryr   passlib.utils.compatr   r	   r
   r   passlib.utils.handlersutilshandlersrc   __all__rb   rn   rk   ri   r   r   r   r   HasManyBackends	HasRoundsHasSaltGenericHandlerr   r   r   rW   r^   r\   <module>r      s   ? ?
  'g'114 4 4 4 4 4 4 4 4 4 4 4 $ $ $ $ $ $8 8 8 8 8 8 8 8 8 8 8 8 # # # # # # # # #  
   |J |J |J |JB 1Y<<1S66	
3L2 L2 L2 L2 L22%r|RZ$L2 L2 L2d9: 9: 9: 9: 9:< 9: 9: 9:D=( =( =( =( =(< =( =( =( =( =(r^   