
    XR_5                        d Z ddlmZ ddlZ ej        e          ZddlmZm	Z	m
Z
 ddlmZ ddlmZmZ ddlmc mZ ddgZd	Zd
ZdZdZdZddZ G d dej        ej                  Z G d dej        e          Z G d de          Z dS )z0passlib.handlers.md5_crypt - md5-crypt algorithm    )md5N)
safe_crypt
test_cryptrepeat_string)h64)unicodeu	md5_cryptapr_md5_crypt    s   $1$s   $apr1$))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      Fc                 "   t          | t                    r|                     d          } t          | t                    s
J d            t          | v r$t
          j                            t                    t          |           }t          |t                    s
J d            |                    d          }t          |          dk     s
J d            |rt          }nt          }t          | |z   | z                                             }t          | |z   |z             }|j        } |t          ||                     |}| dd         }	|r ||dz  rt          n|	           |dz  }||                                }
| | z   }| |z   }| |||| z   || z   ||z   gfd	t           D             }|
}d
}|rU|D ]K\  }}t          |t          ||z                                             z                                             }L|dz  }|U|dd         D ]K\  }}t          |t          ||z                                             z                                             }Lt#          j        |t&                                        d          S )a  perform raw md5-crypt calculation

    this function provides a pure-python implementation of the internals
    for the MD5-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 use_apr: use apache variant

    :returns:
        encoded checksum chars
    zutf-8zpwd not unicode or byteszsalt not unicodeasciir   zsalt too largeNr   c                 6    g | ]\  }}|         |         fS  r"   ).0evenoddpermss      </usr/lib/python3/dist-packages/passlib/handlers/md5_crypt.py
<listcomp>z"_raw_md5_crypt.<locals>.<listcomp>   s*    JJJ94eDk5:&JJJ          )
isinstancer   encodebytes_BNULLuhexcNullPasswordErrorr
   len
_APR_MAGIC
_MD5_MAGICr   digestupdater   _c_digest_offsetsr   encode_transposed_bytes_transpose_mapdecode)pwdsaltuse_aprpwd_lenmagicdba_ctxa_ctx_updateievenchardapwd_pwdpwd_saltdatadcblocksr$   r%   r&   s                     @r'   _raw_md5_cryptrL   ,   s   4 #w "jj!!c5!!==#====}}f&&y111#hhG dG$$88&8888;;wDt99q===*===  
 
S4Z#			%	%	'	'B ed"##E<L Lr7++,,, 	A2A2wH
 q1u2VV(333	a  
 
B\ #gG4xH'8Xc\48T'\JE KJJJ8IJJJD 
BF
  	= 	=ID#S3rDy>>0022233::<<BB!   #2#Y 9 9	cs29~~,,...//6688
 &r>::AA'JJJr)   c                   V    e Zd ZdZdZdZej        ZdZ	ej        Z
ed             Zd ZdS )_MD5_Commonz+common code for md5_crypt and apr_md5_crypt)r=   	salt_size   r   c                 Z    t          j        || j        |           \  }} | ||          S )N)handler)r=   checksum)r0   	parse_mc2ident)clshashr=   chks       r'   from_stringz_MD5_Common.from_string   s3    Lsy#>>>	css++++r)   c                 L    t          j        | j        | j        | j                  S N)r0   
render_mc2rU   r=   rS   )selfs    r'   	to_stringz_MD5_Common.to_string   s    }TZDMBBBr)   N)__name__
__module____qualname____doc__setting_kwdschecksum_sizer0   HASH64_CHARSchecksum_charsmax_salt_size
salt_charsclassmethodrY   r^   r"   r)   r'   rN   rN      sh        55
 )LM_NMJ , , [,C C C C Cr)   rN   c                   h    e Zd ZdZd Z ed          ZdZed             Z	d Z
ed             Zd ZdS )	r
   a  This class implements the MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt.

    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-8 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :type salt_size: int
    :param salt_size:
        Optional number of characters to use when autogenerating new salts.
        Defaults to 8, but can be any value between 0 and 8.
        (This is mainly needed when generating Cisco-compatible hashes,
        which require ``salt_size=4``).

    :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
        ``salt`` strings that are too long.

        .. versionadded:: 1.6
    z$1$)os_cryptbuiltinc                 ^    t          dd          r|                     | j                   dS dS )Ntestz$1$test$pi/xDtU5WFVRqYS6BMU8X/TF)r   _set_calc_checksum_backend_calc_checksum_os_cryptrV   s    r'   _load_backend_os_cryptz md5_crypt._load_backend_os_crypt  s6    f>?? 	**3+FGGG45r)   c                 4   | j         | j        z   }t          ||          }||                     |          S |                    |          r#t          |          t          |          dz   k    r!t          j                            | ||          |dd          S )Nr*   i)	rU   r=   r   _calc_checksum_builtin
startswithr3   r0   r1   CryptBackendError)r]   secretconfigrW   s       r'   rp   z!md5_crypt._calc_checksum_os_crypt  s    di'&&))< ..v666v&& 	?#d))s6{{R7G*G*G&**4>>>CDDzr)   c                 :    |                      | j                   dS )NT)ro   rt   rq   s    r'   _load_backend_builtinzmd5_crypt._load_backend_builtin%  s    &&s'ABBBtr)   c                 ,    t          || j                  S r[   rL   r=   r]   rw   s     r'   rt   z md5_crypt._calc_checksum_builtin*  s    fdi000r)   N)r_   r`   ra   rb   namer	   rU   backendsri   rr   rp   rz   rt   r"   r)   r'   r
   r
      s         @ DAeHHE 'H
   [	 	 	   [1 1 1 1 1r)   c                   2    e Zd ZdZd Z ed          Zd ZdS )r   ap  This class implements the Apr-MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt.

    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-8 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :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
        ``salt`` strings that are too long.

        .. versionadded:: 1.6
    z$apr1$c                 0    t          || j        d          S )NT)r>   r|   r}   s     r'   _calc_checksumzapr_md5_crypt._calc_checksumQ  s    fdi>>>>r)   N)r_   r`   ra   rb   r~   r	   rU   r   r"   r)   r'   r   r   1  sA         2 DAhKKE
? ? ? ? ?r)   )F)!rb   hashlibr   logging	getLoggerr_   logpasslib.utilsr   r   r   passlib.utils.binaryr   passlib.utils.compatr   r	   passlib.utils.handlersutilshandlersr0   __all__r/   r5   r4   r8   r:   rL   HasSaltGenericHandlerrN   HasManyBackendsr
   r   r"   r)   r'   <module>r      s   6 6
       'g'11 @ ? ? ? ? ? ? ? ? ? $ $ $ $ $ $ + + + + + + + + # # # # # # # # #  


  HOK OK OK OKhC C C C C"*b/ C C C@K1 K1 K1 K1 K1"K K1 K1 K1b!? !? !? !? !?K !? !? !? !? !?r)   