
    !:h99                        U d 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e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jJ                  d      Z&dZ'eeed   df      e$d<    e( e)e!jU                                     Z+eee"df      e$d<    e,h d      Z-ee	e"      e$d<   de"de"fdZ.de"de"fdZ/de"dee"e"f   fdZ0 G d d       Z1y)!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                   @    e Zd ZU eed<   eed<   eed<   eed<   eed<   y)DigestAuthChallengerealmnonceqop	algorithmopaqueN)__name__
__module____qualname__str__annotations__     _/var/www/html/turnos/venv/lib/python3.12/site-packages/aiohttp/client_middleware_digest_auth.pyr   r   #   s    JJ	HNKr!   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DigestFunctionsz-(\w+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]+)))r   r   r   r   r   .CHALLENGE_FIELDSSUPPORTED_ALGORITHMS>   urir   r   cnoncer   responseusernameQUOTED_AUTH_FIELDSvaluereturnc                 &    | j                  dd      S )z,Escape double quotes for HTTP header values."\"replacer0   s    r"   escape_quotesr8   k   s    ==e$$r!   c                 &    | j                  dd      S )z-Unescape double quotes in HTTP header values.r4   r3   r5   r7   s    r"   unescape_quotesr:   p   s    ==$$r!   headerc           	          t         j                  |       D ci c](  \  }}}|j                         x}r||rt        |      n|* c}}}S c c}}}w )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
    )_HEADER_PAIRS_PATTERNfindallstripr:   )r;   key
quoted_valunquoted_valstripped_keys        r"   parse_header_pairsrD   u   sZ    , .C-J-J6-R )C\IIK'L' 	Zoj1\Q  s   -Ac            	       p    e Zd ZdZdededdfdZdeded	eee	d
   f   defdZ
dedefdZdededefdZy)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

    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.
    loginpasswordr1   Nc                     |t        d      |t        d      d|v rt        d      || _        |j                  d      | _        |j                  d      | _        d| _        d| _        i | _        y )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-8r!   r   )
ValueError
_login_strencode_login_bytes_password_bytes_last_nonce_bytes_nonce_count
_challenge)selfrG   rH   s      r"   __init__zDigestAuthMiddleware.__init__   sz    
 =ABBDEE%<WXX&+*/,,w*?-5__W-E!$/1r!   methodurlbodyr!   c           
        "#K   | j                   }d|vrt        d      d|vrt        d      |d   }|d   }|st        d      |j                  dd      }|j                  dd	      j                         }|j                  d
d      }	|j	                  d      }
|j	                  d      }t        |      j                  }d}d}|rxddhj                  |j                  d      D ch c]#  }|j                         s|j                         % c}      }|st        d|       d|v rdnd}|j	                  d      }|t        vr$t        d| ddj                  t                     t        |   #dt        dt        f#fd"dt        dt        dt        f"fd}dj                  | j                  || j                  f      }|j                          d| j	                         }|dk(  rFt!        |t"              r|j%                          d{   }n|} "|      }dj                  ||f      } "|      } "|      }|
| j&                  k(  r| xj(                  dz  c_        nd| _        |
| _        | j(                  d}|j	                  d      }t+        j,                  dj                  t/        | j(                        j	                  d      |
t1        j2                         j	                  d      t5        j6                  d      g            j9                         dd  }|j	                  d      }|j                         j;                  d!      r "dj                  ||
|f            }|r dj                  |
||||f      } |||      }n ||dj                  |
|f            }t=        | j>                        t=        |      t=        |      ||jA                         |d"}|	rt=        |	      |d
<   |r||d<   ||d#<   ||d$<   g }|jC                         D ];  \  } }!| tD        v r|jG                  |  d%|! d&       &|jG                  |  d'|!        = d(dj                  |       S c c}w 7 `w))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   rK   r!   authzauth-int,zEDigest auth error: Unsupported Quality of Protection (qop) value(s): z/Digest auth error: Unsupported hash algorithm: z. Supported algorithms: z, xr1   c                 L     |       j                         j                         S )z<RFC 7616 Section 3: Hash function H(data) = hex(hash(data)).)	hexdigestrN   )r]   hash_fns    r"   Hz'DigestAuthMiddleware._encode.<locals>.H  s    1:'')0022r!   sdc                 6     dj                  | |f            S )zDRFC 7616 Section 3: KD(secret, data) = H(concat(secret, ":", data)).   :)join)rb   rc   ra   s     r"   KDz(DigestAuthMiddleware._encode.<locals>.KD  s    TYY1v&''r!   re   rJ   Nr   08x      z-SESS)r.   r   r   r+   r-   r   ncr,   z="r3   =zDigest )$rS   r   getupperrN   r   path_qsintersectionsplitr?   r(   rf   r*   bytesrO   rP   
isinstancer   as_bytesrQ   rR   hashlibsha1r   timectimeosurandomr_   endswithr8   rM   decodeitemsr/   append)$rT   rV   rW   rX   	challenger   r   qop_rawr   r   nonce_bytesrealm_bytespathr   	qop_bytesq
valid_qopsrg   A1A2entity_bytesentity_hashHA1HA2ncvaluencvalue_bytesr,   cnonce_bytesnoncebitresponse_digestheader_fieldspairsfieldr0   ra   r`   s$                                     @@r"   _encodezDigestAuthMiddleware._encode   s    & OO	)#L  )#L 
 '"'" T  --r*MM+u5;;=	x, ll7+ll7+3x 	 *-::$+MM#$6Dq!'')DJ ![\c[de  !+j 8*fC

7+IO+A) M))-3G)H(IK  )3	3 	35 	3	(% 	(E 	(e 	(
 YY));8L8LMNq'..0*$(%)]]_4#L/KB,-Bee $000" !D!,&&s+w/ HH))*11':JJL''0JJqM		
 )+cr	 }}W- ??%%g.DIIsK>?@C yym\9cJH !h/O diic0B&CDO &doo6"5)"5)'..0"
 &3F&;M(# #&M% ")M$&,M(# )//1 	1LE5**wbq12waw/0		1 5)*++S E<  5s&   C#Q4'Q,=Q,DQ4Q1I Q4r-   c                 n   |j                   dk7  ry|j                  j                  dd      }|sy|j                  d      \  }}}|sy|j	                         dk7  ry|syt        |      x}syi | _        t        D ]%  }|j                  |      x}s|| j                  |<   ' 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-authenticaterZ    digest)	statusheadersrm   	partitionlowerrD   rS   r)   bool)	rT   r-   auth_headerrV   sepr   header_pairsr   r0   s	            r"   _authenticatez"DigestAuthMiddleware._authenticatee  s     ??c!&&**+=rB*44S9W<<>X% !37 ;;; % 	/E$((//u/).&	/
 DOO$$r!   requesthandlerc                 :  K   d}t        d      D ]~  }|dkD  rT| j                  |j                  |j                  |j                         d{   |j
                  t        j                  <    ||       d{   }| j                  |      r~ n |J |S 7 J7 !w)zRun the digest auth middleware.N   r   )	ranger   rV   rW   rX   r   r   AUTHORIZATIONr   )rT   r   r   r-   retry_counts        r"   __call__zDigestAuthMiddleware.__call__  s       8 	KQ<@LLNNGKK= 7 2 23
 %W--H %%h/	 ###7
 .s*   A
BB*B7B8B
BB)r   r   r   __doc__r   rU   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   rF   rF      s    :22 2 
	2,_,_, #_,+0'#,1F+G_,	_,B&%n &% &%P$/@	r!   rF   )2r   ru   ry   rerw   typingr   r   r   r   r   r   r	   r
   r   yarlr   rZ   r   client_exceptionsr   client_middlewaresr   client_reqrepr   r   payloadr   r   md5rv   sha256sha512r(   r   rr   r   compiler=   r)   tuplesortedkeysr*   	frozensetr/   r8   r:   rD   rF   r    r!   r"   <module>r      s    	 	 
 
 
   * 1 8 )5  ;;<<nn>>~~NNnn>>~~NNBc8UG_$<==> " #

4 2 %	'@
A3
FG  05VO<P<P<R5S/T eE#s(O, T -6I- E)C.) 
% % %
%3 %3 %
s tCH~ 6R Rr!   