
    @OOf>                    J   d Z ddlmZ ddlZddlZddlZddl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 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 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 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" 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( 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/ dd"l0m1Z1 ejd                  d#k  rdd$l3m4Z4 ndd$l
m4Z4  ejj                  e6      Z7	 	 	 	 	 	 d+d%Z8 G d& d'e9      Z: G d( d)      Z;d,d*Z<y)-a|  
This addon determines the next protocol layer in our proxy stack.
Whenever a protocol layer in the proxy wants to pass a connection to a child layer and isn't sure which protocol comes
next, it calls the `next_layer` hook, which ends up here.
For example, if mitmproxy runs as a regular proxy, we first need to determine if
new clients start with a TLS handshake right away (Secure Web Proxy) or send a plaintext HTTP CONNECT request.
This addon here peeks at the incoming bytes and then makes a decision based on proxy mode, mitmproxy options, etc.

For a typical HTTPS request, this addon is called a couple of times: First to determine that we start with an HTTP layer
which processes the `CONNECT` request, a second time to determine that the client then starts negotiating TLS, and a
third time when we check if the protocol within that TLS stream is actually HTTP or something else.

Sometimes it's useful to hardcode specific logic in next_layer when one wants to do fancy things.
In that case it's not necessary to modify mitmproxy's source, adding a custom addon with a next_layer event hook
that sets nextlayer.layer works just as well.
    )annotationsN)Iterable)Sequence)Any)cast)ctx)dns)starts_like_dtls_record)starts_like_tls_record)layer)layers)
mode_specs)tunnel)Context)Layer)ClientQuicLayer)ClientTLSLayer)DNSLayer)	HttpLayer)modes)RawQuicLayer)ServerQuicLayer)ServerTLSLayer)TCPLayer)UDPLayer)HTTPMode)quic_parse_client_hello)dtls_parse_client_hello)HTTP1_ALPNS)
HTTP_ALPNS)parse_client_hello)ClientHello)      )assert_neverc                    t        | j                        t        |      k7  ryt        d t        | j                  |      D              S )NFc              3  N   K   | ]  \  }}|t         u xs t        ||        y wN)r   
isinstance).0actualexpecteds      \/var/www/premiumrankchecker/venv/lib/python3.12/site-packages/mitmproxy/addons/next_layer.py	<genexpr>zstack_match.<locals>.<genexpr>F   s/      FH 	C7:fh77s   #%)lenr   allzip)contextr   s     r-   stack_matchr3   A   sA     7>>c&k)  #GNNF ;      c                      e Zd ZdZy)NeedsMoreDatazdSignal that the decision on which layer to put next needs to be deferred within the NextLayer addon.N)__name__
__module____qualname____doc__ r4   r-   r6   r6   L   s    nr4   r6   c                      e Zd ZU dZded<   dZded<   dZded<   dZded<   d ZddZ		 	 	 	 	 	 	 	 dd	Z
	 	 	 	 	 	 	 	 dd
Ze	 	 	 	 	 	 	 	 dd       Zedd       Zedd       Zedd       Zedd       Zy)	NextLayerr;   zSequence[re.Pattern]ignore_hostsallow_hosts	tcp_hosts	udp_hostsc                   d|v rOt         j                  j                  D cg c]&  }t        j                  |t        j
                        ( c}| _        d|v rOt         j                  j                  D cg c]&  }t        j                  |t        j
                        ( c}| _        d|v sd|v rt         j                  j                  D cg c]&  }t        j                  |t        j
                        ( c}| _        t         j                  j                  D cg c]&  }t        j                  |t        j
                        ( c}| _        y y c c}w c c}w c c}w c c}w )Nr@   rA   r?   r>   )	r   optionsr@   recompile
IGNORECASErA   r>   r?   )selfupdatedxs      r-   	configurezNextLayer.configureV   s   '!69kk6K6K12

1bmm,DN '!69kk6K6K12

1bmm,DN G#~'@69kk6N6N!12

1bmm,!D 7:kk6M6M 12

1bmm, D	 (A! s   +E4+E+E+Ec                "   |j                   ry 	 | j                  |j                  |j                         |j	                               |_         y # t
        $ r7 t        j                  d|j                         j                                 Y y w xY w)Nz+Deferring layer decision, not enough data: )	r   _next_layerr2   data_clientdata_serverr6   loggerinfohex)rG   	nextlayers     r-   
next_layerzNextLayer.next_layerg   s~    ??		"..!!%%'%%'IO
  	KK=i>S>S>U>Y>Y>[=\]	s   >A =BBc                |   j                   sJ fd}j                  j                  dk(  }j                  j                  dk(  }| j                  ||      r0|rt        j                  d      S t        j
                  d      S  |t        j                        r| j                  |      S  |t        j                  t        j                  f      r| j                  |      S |xr t        |      xs |xr t        |      }|rt              }t              |_        |S |r(t#        |      rt%              }	t'              |	_        |	S |r1| j)                  | j*                        rt        j                        S |r1| j)                  | j,                        rt        j
                        S |r5	 t.        j0                  j3                  |       t        j4                        S |rt        j
                        S j                  j:                  t<        v }
|
 xr( t?        |      dk  xs |d d jA                          xs |}tB        jD                  jF                  r|rt        j                        S t        jH                  tJ        jL                        S # t6        j8                  $ r Y w xY w)Nc                     t        |       S r(   )r3   )r   r2   s    r-   sz NextLayer._next_layer.<locals>.sz   s    w//r4   tcpudpT)ignorer#   )'r   clienttransport_protocol_ignore_connectionr   r   r   ReverseProxy_setup_reverse_proxy	HttpProxyHttpUpstreamProxy_setup_explicit_http_proxyr   r
   r   r   child_layer_starts_like_quicr   r   _is_destination_in_hostsr@   rA   r	   Messageunpackr   structerroralpnr    r/   isalphar   rC   rawtcpr   r   transparent)rG   r2   rM   rN   rV   	tcp_based	udp_basedis_tls_or_dtls
server_tlsserver_quicvery_likely_httpprobably_no_https    `          r-   rL   zNextLayer._next_layeru   sy    ~~~	0 NN55>	NN55>	 ""7KE  5 __WT: U ,,WkBBeoou6678227KHH
  4&{35 5'4	 	 '0J%3G%<J"*;7)'2K&5g&>K# 66wO??7++66wO??7++ 0"";/ w//??7++">>..*<// 
q  r?**,,  	 ;;"2??7++)=)=>>' << s   <J% %J;:J;c                   t         j                  j                  st         j                  j                  syt	        |j
                  j                  t        j                        r|j                  j                  dk(  ryg }|j                  j                  r/|j                  j                  ^}}}|j                  | d|        |j                  j                  r|j                  j                  ^}}}|j                  | d|        | j                  |||      x}r.t        j                  d|      s| d| }|j                  |       | j!                  ||      x}	r,|	j"                  r |j                  |	j"                   d|        |syt         j                  j                  rt%        d |D               }
|
ryt         j                  j                  rt%        d |D              }|ryy)z
        Returns:
            True, if the connection should be ignored.
            False, if it should not be ignored.

        Raises:
            NeedsMoreData, if we need to wait for more input data.
        F)z	10.0.0.535   :z:\d+$c              3     K   | ]H  }t         j                  j                  D ])  }t        j                  ||t        j
                         + J y wr(   )r   rC   r?   rD   searchrF   r*   hostrexs      r-   r.   z/NextLayer._ignore_connection.<locals>.<genexpr>   sH      ";;22"  		#tR]]3"3"   AATc              3     K   | ]H  }t         j                  j                  D ])  }t        j                  ||t        j
                         + J y wr(   )r   rC   r>   rD   rx   rF   ry   s      r-   r.   z/NextLayer._ignore_connection.<locals>.<genexpr>   sH      ;;33  		#tR]]33r|   )r   rC   r>   r?   r)   rZ   
proxy_moder   WireGuardModeserveraddresspeernameappend_get_host_headerrD   rx   _get_client_hellosniany)rG   r2   rM   rN   	hostnamesrz   port_host_headerclient_hellonot_allowedignoreds               r-   r\   zNextLayer._ignore_connection   s    {{''0G0GNN%%z'?'?
nn$$(99!	>>""$^^44ND$vQtf-.>>!!$^^33ND$vQtf-.
 #33G[+VV{Vyy;7%0M4&"9K  - $ 6 6w LLL""  L$4$4#5Qtf!=>;;""! "%"  K
 ;;## % G
 r4   c                l   | j                   j                  dk7  s|ry| j                   j                  t        v xs% t	        j
                  d|t        j                        }|rSt	        j                  d|t        j                        x}r&|j                  d      x}r|j                  dd      S yt        y)z
        Try to read a host header from data_client.

        Returns:
            The host header value, or None, if no host header was found.

        Raises:
            NeedsMoreData, if the HTTP request is incomplete.
        rW   Ns   [A-Z]{3,}.+HTTP/s   \r\n(?:Host:\s+(.+?)\s*)?\r\n   zutf-8surrogateescape)rZ   r[   ri   r   rD   matchrF   rx   groupdecoder6   )r2   rM   rN   host_header_expectedmrz   s         r-   r   zNextLayer._get_host_header  s     >>,,5&~~22kA  
RXX +r}}F
  II1; q  771:%4%;;w0ABB##r4   c                d   | j                   j                  xdk(  r# t        |      r	 t        |      }|t        |S ydk(  r	 t        |      S 	 t        | j                   j                         y# t
        $ r Y yw xY w# t
        $ r Y nw xY w	 t        |      }|t        |S # t
        $ r Y yw xY w)z
        Try to read a TLS/DTLS/QUIC ClientHello from data_client.

        Returns:
            A complete ClientHello, or None, if no ClientHello was found.

        Raises:
            NeedsMoreData, if the ClientHello is incomplete.
        rW   NrX   )	rZ   r[   r   r!   r6   
ValueErrorr   r   r%   )r2   rM   chs      r-   r   zNextLayer._get_client_hello%  s     nn//)+6"/< :"//!	2;?? W^^>>?/ & 
  " 0=B z++I " 
 s5   A/ 
A> /	A;:A;>	B
	B
B# #	B/.B/c                   t        t        j                  | j                  j                        }t        j                         }|j                  xdk(  r< t        |      r|t        |       z  }|t        | t        j                        z  }|d
   S xdk(  rJ |t        |       z  }t        |      r|t        |       z  }|t        | t        j                        z  }|d
   S xdk(  r- t        |      r|t        |       z  }|t        |       z  }|d
   S xdk(  r; |t        |       z  }t        |      r|t        |       z  }|t        |       z  }|d
   S xdk(  r- t        |      r|t        |       z  }|t!        |       z  }|d
   S xdk(  r; |t        |       z  }t        |      r|t        |       z  }|t!        |       z  }|d
   S xdk(  r |t#        |       z  }|d
   S xdk(  r? |t%        |       z  }|t'        |       z  }|t        | t        j                        z  }|d
   S d	k(  r/|t%        |       z  }|t'        |       z  }|t)        |       z  }|d
   S 	 t+        |j                         |d
   S )NhttphttpsrW   tlsrX   dtlsr	   http3quicr   )r   r   ReverseModerZ   r~   r   
LayerStackschemer   r   r   r   rl   r   r   r
   r   r   r   r   r   r%   )r2   rM   specstacks       r-   r^   zNextLayer._setup_reverse_proxyN  sw   J**GNN,E,EF!!#kk)+6^G44E7H,@,@AAd Qxc 00)+6^G44E7H,@,@AAZ QxW )+6^G44E'**P QxO 00)+6^G44E'**F QxC *;7^G44E'**< Qx; 00*;7^G44E'**2 Qx/  '** Qx 11117H,@,@AA Qx 1111g..
 Qx T[[)Qxr4   c                   t        j                         }| j                  j                  dk(  r|t	        j
                  |       z  }n#t        |      r|t	        j                  |       z  }t        | j                  d   t        j                        r,|t	        j                  | t        j                        z  }|d   S |t	        j                  | t        j                        z  }|d   S )NrX   r   )r   r   rZ   r[   r   r   r   r   r)   r   r`   r   r   upstreamregular)r2   rM   r   s      r-   ra   z$NextLayer._setup_explicit_http_proxy  s    !!#>>,,5V++G44E#K0V**733EgnnQ')@)@AV%%gx/@/@AAE Qx V%%gx/?/?@@EQxr4   c                ,     t         fd|D              S )Nc              3    K   | ]  }j                   j                  xr( |j                  j                   j                  d          xs= j                  j                  xr% |j                  j                  j                          yw)r   N)r   r   rx   rZ   r   )r*   r{   r2   s     r-   r.   z5NextLayer._is_destination_in_hosts.<locals>.<genexpr>  ss      
  ^^##M

7>>3I3I!3L(M G""Eszz'..2D2D'EG
s   B	B)r   )r2   hostss   ` r-   rd   z"NextLayer._is_destination_in_hosts  s     
 
 
 	
r4   N)rR   zlayer.NextLayer)r2   r   rM   bytesrN   r   returnzLayer | None)r2   r   rM   r   rN   r   r   zbool | None)r2   r   rM   r   rN   r   r   z
str | None)r2   r   rM   r   r   zClientHello | None)r2   r   rM   r   r   r   )r2   r   r   zIterable[re.Pattern]r   bool)r7   r8   r9   r>   __annotations__r?   r@   rA   rJ   rS   rL   r\   staticmethodr   r   r^   ra   rd   r;   r4   r-   r=   r=   P   s   )+L&+(*K%*&(I#(&(I#("L?L?-2L?AFL?	L?\>> > 	>
 
>@   
	 B &@ &@P : :x   
 
r4   r=   c                :    	 t        |        y# t        $ r Y yw xY w)NTF)r   r   )rM   s    r-   rc   rc     s(    ,   s    	)r2   r   r   z/Sequence[type[Layer] | tuple[type[Layer], ...]]r   r   )rM   r   r   r   )=r:   
__future__r   loggingrD   rg   syscollections.abcr   r   typingr   r   	mitmproxyr   r	   mitmproxy.net.tlsr
   r   mitmproxy.proxyr   r   r   r   mitmproxy.proxy.contextr   mitmproxy.proxy.layerr   mitmproxy.proxy.layersr   r   r   r   r   r   r   r   r   r   mitmproxy.proxy.layers.httpr   mitmproxy.proxy.layers.quicr   mitmproxy.proxy.layers.tlsr   r   r    r!   mitmproxy.tlsr"   version_infotyping_extensionsr%   	getLoggerr7   rO   r3   	Exceptionr6   r=   rc   r;   r4   r-   <module>r      s   " #  	  
 $ $     5 4 ! " & " + ' 2 1 + , ( / 2 1 + + 0 ? > 2 1 9 %g.#			8	$M	oI oQ
 Q
h
r4   