o
    iiD                     @   s  U d Z ddlZddlZddlZddlZddlZddlmZmZm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ G dd deddZejejejejej ej ej ej ej!ej!ej!ej!dZ"ee#ee$gdf f e%d< e&ej'dk rdndZ(dZ)e	eed df  e%d< e*e+e", Z-e	ee#df  e%d< e.h dZ/e	e
e#  e%d< de#de#fddZ0de#de#fdd Z1d!e#dee#e#f fd"d#Z2G d$d% d%Z3dS )&av  
Digest authentication middleware for aiohttp client.

This middleware implements HTTP Digest Authentication according to RFC 7616,
providing a more secure alternative to Basic Authentication. It supports all
standard hash algorithms including MD5, SHA, SHA-256, SHA-512 and their session
variants, as well as both 'auth' and 'auth-int' quality of protection (qop) options.
    N)	CallableDictFinal	FrozenSetListLiteralTuple	TypedDictUnion)URL   )hdrs)ClientError)ClientHandlerType)ClientRequestClientResponse)Payloadc                   @   sF   e Zd ZU eed< eed< eed< eed< eed< eed< eed< dS )	DigestAuthChallengerealmnonceqop	algorithmopaquedomainstaleN)__name__
__module____qualname__str__annotations__ r    r    m/var/www/scraper.webshop2u.hu/html/venv/lib/python3.10/site-packages/aiohttp/client_middleware_digest_auth.pyr   $   s   
 r   F)total)MD5zMD5-SESSSHAzSHA-SESSSHA256zSHA256-SESSzSHA-256zSHA-256-SESSSHA512zSHA512-SESSzSHA-512zSHA-512-SESSzhashlib._HashDigestFunctions)      z:(?:^|\s|,\s*)(\w+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]+))z>(?:^|\s|,\s*)((?>\w+))\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]+)))r   r   r   r   r   r   r   .CHALLENGE_FIELDSSUPPORTED_ALGORITHMS>   urir   r   cnoncer   responseusernameQUOTED_AUTH_FIELDSvaluereturnc                 C      |  ddS )z,Escape double quotes for HTTP header values."\"replacer1   r    r    r!   escape_quotesu      r9   c                 C   r3   )z-Unescape double quotes in HTTP header values.r5   r4   r6   r8   r    r    r!   unescape_quotesz   r:   r;   headerc                    s    fddt | D S )a  
    Parse key-value pairs from WWW-Authenticate or similar HTTP headers.

    This function handles the complex format of WWW-Authenticate header values,
    supporting both quoted and unquoted values, proper handling of commas in
    quoted values, and whitespace variations per RFC 7616.

    Examples of supported formats:
      - key1="value1", key2=value2
      - key1 = "value1" , key2="value, with, commas"
      - key1=value1,key2="value2"
      - realm="example.com", nonce="12345", qop="auth"

    Args:
        header: The header value string to parse

    Returns:
        Dictionary mapping parameter names to their values
    c                    s0   i | ]\}}}|    r |rt|n|qS r    )stripr;   ).0key
quoted_valunquoted_valstripped_keyr    r!   
<dictcomp>   s    
z&parse_header_pairs.<locals>.<dictcomp>)_HEADER_PAIRS_PATTERNfindall)r<   r    rB   r!   parse_header_pairs   s   
rG   c                	   @   s   e Zd ZdZ	ddedededdfdd	Zd
ededee	e
d f defddZdedefddZdedefddZdededefddZdS )DigestAuthMiddlewarea  
    HTTP digest authentication middleware for aiohttp client.

    This middleware intercepts 401 Unauthorized responses containing a Digest
    authentication challenge, calculates the appropriate digest credentials,
    and automatically retries the request with the proper Authorization header.

    Features:
    - Handles all aspects of Digest authentication handshake automatically
    - Supports all standard hash algorithms:
      - MD5, MD5-SESS
      - SHA, SHA-SESS
      - SHA256, SHA256-SESS, SHA-256, SHA-256-SESS
      - SHA512, SHA512-SESS, SHA-512, SHA-512-SESS
    - Supports 'auth' and 'auth-int' quality of protection modes
    - Properly handles quoted strings and parameter parsing
    - Includes replay attack protection with client nonce count tracking
    - Supports preemptive authentication per RFC 7616 Section 3.6

    Standards compliance:
    - RFC 7616: HTTP Digest Access Authentication (primary reference)
    - RFC 2617: HTTP Authentication (deprecated by RFC 7616)
    - RFC 1945: Section 11.1 (username restrictions)

    Implementation notes:
    The core digest calculation is inspired by the implementation in
    https://github.com/requests/requests/blob/v2.18.4/requests/auth.py
    with added support for modern digest auth features and error handling.
    Tloginpassword
preemptiver2   Nc                 C   sp   |d u rt d|d u rt dd|v rt d|| _|d| _|d| _d| _d| _i | _|| _g | _	d S )Nz"None is not allowed as login valuez%None is not allowed as password value:z8A ":" is not allowed in username (RFC 1945#section-11.1)utf-8    r   )

ValueError
_login_strencode_login_bytes_password_bytes_last_nonce_bytes_nonce_count
_challenge_preemptive_protection_space)selfrI   rJ   rK   r    r    r!   __init__   s   
zDigestAuthMiddleware.__init__methodurlbodyrN   c           "   
      sJ  | j }d|vrtdd|vrtd|d }|d }|s"td|dd}|dd	}| }	|d
d}
|d}|d}t|j}d}d}|rrddhdd |dD }|setd| d|v rkdnd}|d}|	t	vrtd|	 dd
t t	|	 dtdtffdd dtdtdtf fdd}d
| j|| jf}|  d|  }|dkrt|tr| I d H }n|} |}d
||f} |} |}|| jkr|  jd!7  _nd!| _|| _| jd"}|d}td
t| jd|t dtd#g d d$ }|d}|	 d%r. d
|||f}|rAd
|||||f}|||}n
||d
||f}t| jt|t||| |d&}|
rft|
|d
< |ru||d< ||d'< ||d(< g }|  D ]!\} }!| t!v r|"|  d)|! d* q{|"|  d+|!  q{d,d
| S )-a  
        Build digest authorization header for the current challenge.

        Args:
            method: The HTTP method (GET, POST, etc.)
            url: The request URL
            body: The request body (used for qop=auth-int)

        Returns:
            A fully formatted Digest authorization header string

        Raises:
            ClientError: If the challenge is missing required parameters or
                         contains unsupported values

        r   z:Malformed Digest auth challenge: Missing 'realm' parameterr   z:Malformed Digest auth challenge: Missing 'nonce' parameterzBSecurity issue: Digest auth challenge contains empty 'nonce' valuer    r   r#   r   rM   rN   authzauth-intc                 S   s   h | ]
}|  r|  qS r    )r=   )r>   qr    r    r!   	<setcomp>  s    z/DigestAuthMiddleware._encode.<locals>.<setcomp>,zEDigest auth error: Unsupported Quality of Protection (qop) value(s): z/Digest auth error: Unsupported hash algorithm: z. Supported algorithms: z, xr2   c                    s    |    S )z<RFC 7616 Section 3: Hash function H(data) = hex(hash(data)).)	hexdigestrQ   )rc   )hash_fnr    r!   H  s   z'DigestAuthMiddleware._encode.<locals>.Hsdc                    s    d | |fS )zDRFC 7616 Section 3: KD(secret, data) = H(concat(secret, ":", data)).   :)join)rg   rh   )rf   r    r!   KD   s   z(DigestAuthMiddleware._encode.<locals>.KDri   rL   Nr   08x      z-SESS)r/   r   r   r,   r.   r   ncr-   z="r4   =zDigest )#rV   r   getupperrQ   r   path_qsintersectionsplitr'   rj   r+   bytesrR   rS   
isinstancer   as_bytesrT   rU   hashlibsha1r   timectimeosurandomrd   endswithr9   rP   decodeitemsr0   append)"rY   r[   r\   r]   	challenger   r   qop_rawalgorithm_originalr   r   nonce_bytesrealm_bytespathr   	qop_bytes
valid_qopsrk   A1A2entity_bytesentity_hashHA1HA2ncvaluencvalue_bytesr-   cnonce_bytesnoncebitresponse_digestheader_fieldspairsfieldr1   r    )rf   re   r!   _encode   s   








	


zDigestAuthMiddleware._encodec                 C   s\   t |}| jD ]$}||sqt|t|ks|d dkr  dS |t| dkr+ dS qdS )z
        Check if the given URL is within the current protection space.

        According to RFC 7616, a URI is in the protection space if any URI
        in the protection space is a prefix of it (after both have been made absolute).
        /TF)r   rX   
startswithlen)rY   r\   request_str	space_strr    r    r!   _in_protection_spacev  s   

z)DigestAuthMiddleware._in_protection_spacer.   c                 C   s  |j dkrdS |jdd}|sdS |d\}}}|sdS | dkr&dS |s*dS t| }s2dS i | _tD ]}|| }rE|| j|< q7|j	 }	| jd }
rg | _
|
 D ]$}|d}|d	rt| j
t|	t| qZ| j
tt| qZnt|	g| _
t| jS )
z
        Takes the given response and tries digest-auth, if needed.

        Returns true if the original request must be resent.
        i  Fzwww-authenticater^    digestr   r4   r   )statusheadersrq   	partitionlowerrG   rV   r*   r\   originrX   ru   r=   r   r   r   rj   r   bool)rY   r.   auth_headerr[   sepr   header_pairsr   r1   r   r   r,   r    r    r!   _authenticate  s<   





z"DigestAuthMiddleware._authenticaterequesthandlerc                    s   d}t dD ]1}|dks| jr*| jr*| |jr*| |j|j|jI dH |jt	j
< ||I dH }| |s8 nq|dus?J |S )zRun the digest auth middleware.N   r   )rangerW   rV   r   r\   r   r[   r]   r   r   AUTHORIZATIONr   )rY   r   r   r.   retry_countr    r    r!   __call__  s&   

zDigestAuthMiddleware.__call__)T)r   r   r   __doc__r   r   rZ   r   r
   r   r   r   r   r   r   r   r   r   r    r    r    r!   rH      s>    "

 $;rH   )4r   ry   r}   resysr{   typingr   r   r   r   r   r   r   r	   r
   yarlr   r^   r   client_exceptionsr   client_middlewaresr   client_reqrepr   r   payloadr   r   md5rz   sha256sha512r'   r   rv   r   compileversion_inforE   r*   tuplesortedkeysr+   	frozensetr0   r9   r;   rG   rH   r    r    r    r!   <module>   s\    	, 

$