
    g?                     >   S r SSKJrJr  SSKJr  SSKr\R                  " \5      r	SSK
Jr  SSKJrJrJrJr  SSKJr  SSKJrJrJrJrJrJr  SSKJs  Jr  / S	QrS
r " S S\R@                  \RB                  5      r" " S S\"5      r# " S S\RH                  5      r%g)z1
passlib.handlers.cisco -- Cisco password hashes
    )hexlify	unhexlify)md5N)warn)right_pad_string
to_unicoderepeat_stringto_bytes)h64)unicodeujoin_byte_valuesjoin_byte_elemsiter_byte_valuesuascii_to_str)	cisco_pix	cisco_asacisco_type7s    c                   N    \ rS rSrSrS rSrSrSrSr	\
R                  rSrS rSrg)	r   $   a6  
This class implements the password hash used by older Cisco PIX firewalls,
and follows the :ref:`password-hash-api`.
It does a single round of hashing, and relies on the username
as the salt.

This class only allows passwords <= 16 bytes, anything larger
will result in a :exc:`~passlib.exc.PasswordSizeError` if passed to :meth:`~cisco_pix.hash`,
and be silently rejected if passed to :meth:`~cisco_pix.verify`.

The :meth:`~passlib.ifc.PasswordHash.hash`,
:meth:`~passlib.ifc.PasswordHash.genhash`, and
:meth:`~passlib.ifc.PasswordHash.verify` methods
all support the following extra keyword:

:param str user:
    String containing name of user account this password is associated with.

    This is *required* in order to correctly hash passwords associated
    with a user account on the Cisco device, as it is used to salt
    the hash.

    Conversely, this *must* be omitted or set to ``""`` in order to correctly
    hash passwords which don't have an associated user account
    (such as the "enable" password).

.. versionadded:: 1.6

.. versionchanged:: 1.7.1

    Passwords > 16 bytes are now rejected / throw error instead of being silently truncated,
    to match Cisco behavior.  A number of :ref:`bugs <passlib-asa96-bug>` were fixed
    which caused prior releases to generate unverifiable hashes in certain cases.
   TFc                 &   U R                   n[        U[        5      (       a  UR                  S5      nSn[	        U5      U R
                  :  a]  U R                  (       aC  SU R                  U R
                  4-  n[        R                  R                  U R
                  US9eU[        -   nU R                  nU(       aK  [        U[        5      (       a  UR                  S5      nU(       a  [	        U5      S:  a  U[        US5      -  nU(       a  [	        U5      S:  a  SnOSn[        X5      nU(       a  X-  n[        U5      R!                  5       n[#        S	 [%        U5       5       5      n[&        R(                  " U5      R+                  S
5      $ )a  
This function implements the "encrypted" hash format used by Cisco
PIX & ASA. It's behavior has been confirmed for ASA 9.6,
but is presumed correct for PIX & other ASA releases,
as it fits with known test vectors, and existing literature.

While nearly the same, the PIX & ASA hashes have slight differences,
so this function performs differently based on the _is_asa class flag.
Noteable changes from PIX to ASA include password size limit
increased from 16 -> 32, and other internal changes.
utf-8Nz.Password too long (%s allows at most %d bytes))msg      r       c              3   H   #    U  H  u  pUS -   S-  (       d  M  Uv   M     g7f)      N ).0ics      O/home/matz/Project1/venv/lib/python3.13/site-packages/passlib/handlers/cisco.py	<genexpr>+cisco_pix._calc_checksum.<locals>.<genexpr>   s       P/@tqQUaK/@s   "	"ascii)_is_asa
isinstancer   encodelentruncate_sizeuse_defaultsnameuhexcPasswordSizeError_DUMMY_BYTESuserr	   r   r   digestr   	enumerater   encode_bytesdecode)selfsecretasaspoil_digestr   r4   pad_sizer5   s           r%   _calc_checksumcisco_pix._calc_checksumg   sT    ll fg&&]]7+F, v;+++  Fyy$"4"456ff..t/A/As.KK  &4. yy$(({{7+#f+*-a00 3v;#HH!&3
 "FV##% ! Py/@ PP
 '..w77    r!   N)__name__
__module____qualname____firstlineno____doc__r/   r-   truncate_errortruncate_verify_rejectchecksum_sizer0   HASH64_CHARSchecksum_charsr)   r>   __static_attributes__r!   r@   r%   r   r   $   s>    !R DM N!
 M__N G
|8r@   r   c                   $    \ rS rSrSrS rSrSrSrg)r      a  
This class implements the password hash used by Cisco ASA/PIX 7.0 and newer (2005).
Aside from a different internal algorithm, it's use and format is identical
to the older :class:`cisco_pix` class.

For passwords less than 13 characters, this should be identical to :class:`!cisco_pix`,
but will generate a different hash for most larger inputs
(See the `Format & Algorithm`_ section for the details).

This class only allows passwords <= 32 bytes, anything larger
will result in a :exc:`~passlib.exc.PasswordSizeError` if passed to :meth:`~cisco_asa.hash`,
and be silently rejected if passed to :meth:`~cisco_asa.verify`.

.. versionadded:: 1.7

.. versionchanged:: 1.7.1

    Passwords > 32 bytes are now rejected / throw error instead of being silently truncated,
    to match Cisco behavior.  A number of :ref:`bugs <passlib-asa96-bug>` were fixed
    which caused prior releases to generate unverifiable hashes in certain cases.
r   Tr!   N)	rA   rB   rC   rD   rE   r/   r-   r)   rK   r!   r@   r%   r   r      s    8 D
 M
 Gr@   r   c                      ^  \ rS rSrSrS rSr\R                  r	Sr
Sr\SU 4S jj5       r\S 5       rSU 4S jjr\SS	 j5       r\S
 5       rS rS r\SS j5       r\" S5      r\S 5       rSrU =r$ )r   i)  a  
This class implements the "Type 7" password encoding used by Cisco IOS,
and follows the :ref:`password-hash-api`.
It has a simple 4-5 bit salt, but is nonetheless a reversible encoding
instead of a real hash.

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

:type salt: int
:param salt:
    This may be an optional salt integer drawn from ``range(0,16)``.
    If omitted, one will be chosen at random.

: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`` values that are out of range.

Note that while this class outputs digests in upper-case hexadecimal,
it will accept lower-case as well.

This class also provides the following additional method:

.. automethod:: decode
saltr   4   c                    >^ [         [        U ]
  " S0 UD6nTb3  UR                  TUR	                  S5      S9m[        U4S j5      Ul        U$ )Nrelaxed)rS   c                     > T $ Nr!   rO   s   r%   <lambda>#cisco_type7.using.<locals>.<lambda>f  s    r@   r!   )superr   using
_norm_saltgetstaticmethod_generate_salt)clsrP   kwdssubcls	__class__s    `  r%   rY   cisco_type7.usinga  sM    {C.66$$T488I3F$GD$0$>F!r@   c                     [        USS5      n[        U5      S:  a  [        R                  R	                  U 5      e[        US S 5      nU " X!SS  R                  5       S9$ )Nr(   hash   )rP   checksum)r   r,   r0   r1   InvalidHashErrorintupper)r^   rd   rP   s      r%   from_stringcisco_type7.from_stringi  sW    $0t9q=&&))#..48}ABx~~'788r@   c                    > [         [        U ]
  " S0 UD6  Ub  U R                  U5      nOMU R                  (       a1  U R                  5       nU R                  U5      U:X  d   SU< 35       eO[        S5      eXl        g )Nzgenerated invalid salt: zno salt specifiedr!   )rX   r   __init__rZ   r.   r]   	TypeErrorrP   )r9   rP   r_   ra   s      r%   rm   cisco_type7.__init__q  sq    k4)1D1??4(D&&(D??4(D0XRV2XX0/00	r@   c                 (   [        U[        5      (       d!  [        R                  R	                  USS5      eSUs=::  a  U R
                  ::  a   U$   SnU(       a.  [        U[        R                  5        US:  a  S$ U R
                  $ [        U5      e)zm
validate & normalize salt value.
.. note::
    the salt for this algorithm is an integer 0-52, not a string
integerrP   r   z"salt/offset must be in 0..52 range)	r*   rh   r0   r1   ExpectedTypeErrormax_salt_valuer   PasslibHashWarning
ValueError)r^   rP   rS   r   s       r%   rZ   cisco_type7._norm_salt|  s     $$$&&**4FCC****K +2b++,q18c&8&88S/!r@   c                  B    [         R                  R                  SS5      $ )Nr      )r0   rngrandintr!   r@   r%   r]   cisco_type7._generate_salt  s    vv~~a$$r@   c                 J    SU R                   [        U R                  5      4-  $ )Nz%02d%s)rP   r   rf   )r9   s    r%   	to_stringcisco_type7.to_string  s    499mDMM&BCCCr@   c                     [        U[        5      (       a  UR                  S5      n[        U R	                  XR
                  5      5      R                  S5      R                  5       $ )Nr   r(   )r*   r   r+   r   _cipherrP   r8   ri   )r9   r:   s     r%   r>   cisco_type7._calc_checksum  sK     fg&&]]7+Ft||FII67>>wGMMOOr@   c                     U R                  U5      n[        UR                  R                  S5      5      nUR	                  XCR
                  5      nU(       a  UR                  U5      $ U$ )zdecode hash, returning original password.

:arg hash: encoded password
:param encoding: optional encoding to use (defaults to ``UTF-8``).
:returns: password as unicode
r(   )rj   r   rf   r+   r   rP   r8   )r^   rd   encodingr9   tmpraws         r%   r8   cisco_type7.decode  sS     t$,,W56ll3		*'/szz(#8S8r@   z5dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87c                    ^^^ U R                   m[        T5      m[        UUU4S j[        [	        U5      5       5       5      $ )z1xor static key against data - encrypts & decryptsc              3   V   >#    U  H  u  pU[        TTU-   T-     5      -  v   M      g 7frU   )ord)r"   idxvaluekeykey_sizerP   s      r%   r&   &cisco_type7._cipher.<locals>.<genexpr>  s2       
?
 CTCZ83455?s   &))_keyr,   r   r6   r   )r^   datarP   r   r   s     `@@r%   r   cisco_type7._cipher  s<     hhs8  
'(8(>? 
 
 	
r@   rU   )F)r   )rA   rB   rC   rD   rE   r/   setting_kwdsr0   UPPER_HEX_CHARSrJ   min_salt_valuers   classmethodrY   rj   rm   rZ   r\   r]   r}   r>   r8   r   r   r   rK   __classcell__)ra   s   @r%   r   r   )  s    F DL
 ''N NN
   9 9	 " "" % %DP 
9 
9 DED
 
r@   r   )&rE   binasciir   r   hashlibr   logging	getLoggerrA   logwarningsr   passlib.utilsr   r   r	   r
   passlib.utils.binaryr   passlib.utils.compatr   r   r   r   r   r   passlib.utils.handlersutilshandlersr0   __all__r3   HasUserContextStaticHandlerr   r   GenericHandlerr   r!   r@   r%   <module>r      s    (  g''1  P O $> > # # 
8!!2#3#3 8j'	 '`K
"## K
r@   