
     h?                     >   d Z ddlmZmZ ddlmZ ddlZ ej                  e      Z	ddl
m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mZmZ ddlmc mZ g d	Zd
Z G d dej@                  ejB                        Z" G d de"      Z# G d dejH                        Z%y)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                   F    e Zd ZdZd ZdZdZdZdZe	j                  ZdZd Zy)r   a  
    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                    | j                   }t        |t              r|j                  d      }d}t	        |      | j
                  kD  r[| j                  rFd| j                  | j
                  fz  }t        j                  j                  | j
                  |      |t        z   }| j                  }|r@t        |t              r|j                  d      }|rt	        |      dk  r|t        |d      z  }|rt	        |      dkD  rd}nd}t        ||      }|r||z  }t        |      j!                         }t#        d	 t%        |      D              }t'        j(                  |      j+                  d
      S )a7  
        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   8   K   | ]  \  }}|d z   dz  s|  yw)      N ).0ics      X/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/passlib/handlers/cisco.py	<genexpr>z+cisco_pix._calc_checksum.<locals>.<genexpr>   s      Ptq!QUaK Ps   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   r2   pad_sizer3   s           r$   _calc_checksumzcisco_pix._calc_checksumg   sR    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
 l"FV##% ! Py/@ PP
 '..w77    N)__name__
__module____qualname____doc__r-   r+   truncate_errortruncate_verify_rejectchecksum_sizer.   HASH64_CHARSchecksum_charsr'   r<   r    r=   r$   r   r   $   s>    !R DM N!
 M__N G
|8r=   r   c                       e Zd ZdZd ZdZdZy)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   TN)r>   r?   r@   rA   r-   r+   r'   r    r=   r$   r   r      s    8 D
 M
 Gr=   r   c                        e Zd ZdZd ZdZej                  ZdZ	dZ
ed fd	       Zed        Zd fd	Zedd       Zed	        Zd
 Zd Zedd       Z ed      Zed        Z xZS )r   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                     t        t        | 
  di |}5|j                  |j	                  d            t        fd      |_        |S )Nrelaxed)rM   c                       S Nr    rI   s   r$   <lambda>z#cisco_type7.using.<locals>.<lambda>f  s     r=   r    )superr   using
_norm_saltgetstaticmethod_generate_salt)clsrJ   kwdssubcls	__class__s    `  r$   rR   zcisco_type7.usinga  sM    {C.66$$T488I3F$GD$0$>F!r=   c                     t        |dd      }t        |      dk  rt        j                  j	                  |       t        |d d       } | ||dd  j                               S )Nr&   hash   )rJ   checksum)r   r*   r.   r/   InvalidHashErrorintupper)rW   r\   rJ   s      r$   from_stringzcisco_type7.from_stringi  sY    $0t9q=&&))#..48}tABx~~'788r=   c                     t        t        | 
  di | || j                  |      }|| _        y | j                  r.| j                         }| j                  |      |k(  sJ d|       t        d      || _        y )Nzgenerated invalid salt: zno salt specifiedr    )rQ   r   __init__rS   r,   rV   	TypeErrorrJ   )r7   rJ   rX   rZ   s      r$   rd   zcisco_type7.__init__q  s{    k4)1D1??4(D 	 &&(D??4(D0XRV2XX/00	r=   c                    t        |t              s!t        j                  j	                  |dd      d|cxk  r| j
                  k  r|S  d}|r-t        |t        j                         |dk  rdS | j
                  S t        |      )z
        validate & normalize salt value.
        .. note::
            the salt for this algorithm is an integer 0-52, not a string
        integerrJ   r   z"salt/offset must be in 0..52 range)	r(   r`   r.   r/   ExpectedTypeErrormax_salt_valuer   PasslibHashWarning
ValueError)rW   rJ   rM   r   s       r$   rS   zcisco_type7._norm_salt|  s}     $$&&**4FCC****K +2b++,q18c&8&88S/!r=   c                  B    t         j                  j                  dd      S )Nr      )r.   rngrandintr    r=   r$   rV   zcisco_type7._generate_salt  s    vv~~a$$r=   c                 J    d| j                   t        | j                        fz  S )Nz%02d%s)rJ   r   r^   )r7   s    r$   	to_stringzcisco_type7.to_string  s    499mDMM&BCCCr=   c                     t        |t              r|j                  d      }t        | j	                  || j
                              j                  d      j                         S )Nr   r&   )r(   r   r)   r   _cipherrJ   r6   ra   )r7   r8   s     r$   r<   zcisco_type7._calc_checksum  sJ     fg&]]7+Ft||FDII67>>wGMMOOr=   c                     | j                  |      }t        |j                  j                  d            }|j	                  ||j
                        }|r|j                  |      S |S )zdecode hash, returning original password.

        :arg hash: encoded password
        :param encoding: optional encoding to use (defaults to ``UTF-8``).
        :returns: password as unicode
        r&   )rb   r   r^   r)   rs   rJ   r6   )rW   r\   encodingr7   tmpraws         r$   r6   zcisco_type7.decode  sU     t$,,W56ll3		*'/szz(#8S8r=   z5dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87c                     | j                   t              t        fdt        t	        |            D              S )z1xor static key against data - encrypts & decryptsc              3   R   K   | ]  \  }}|t        |z   z           z     y wrO   )ord)r!   idxvaluekeykey_sizerJ   s      r$   r%   z&cisco_type7._cipher.<locals>.<genexpr>  s5       
U CTCZ83455 
s   $')_keyr*   r   r4   r   )rW   datarJ   r}   r~   s     `@@r$   rs   zcisco_type7._cipher  s<     hhs8  
'(8(>? 
 
 	
r=   rO   )F)r   )r>   r?   r@   rA   r-   setting_kwdsr.   UPPER_HEX_CHARSrF   min_salt_valueri   classmethodrR   rb   rd   rS   rU   rV   rq   r<   r6   r   r   rs   __classcell__)rZ   s   @r$   r   r   )  s    F DL
 ''N NN
   9 9	 " "" % %DP 
9 
9 DED
 
r=   r   )&rA   binasciir   r   hashlibr   logging	getLoggerr>   logwarningsr   passlib.utilsr   r   r	   r
   passlib.utils.binaryr   passlib.utils.compatr   r   r   r   r   r   passlib.utils.handlersutilshandlersr.   __all__r1   HasUserContextStaticHandlerr   r   GenericHandlerr   r    r=   r$   <module>r      s    (  'g''1  P O $> > # # 
8!!2#3#3 8j'	 '`K
"## K
r=   