
    lKjq                        d Z ddlm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Zd	d
ddZddZ G d de      Zy)zFSSRF protection and IP allowlist utilities for outbound HTTP requests.    )annotationsN)urlparse)BaseHTTPMiddleware)JSONResponse)ASGIAppc                    t        | j                  | j                  | j                  | j                  | j
                  | j                  f      S N)any
is_privateis_loopbackis_link_localis_multicastis_reservedis_unspecified)ips    r/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/macos_mcp/infrastructure/security.py_is_private_targetr      sB    





      F)allow_privatec                  	 t        |       }|j                  dvrt        d|j                   d      |j                  st        d|        |j
                  s|j                  rt        d      |ry	 t        j                  |j                  |j                  t        j                        D ch c]
  }|d	   d
    }}|D ]1  }	 t        j                  |      }t        |      s%t        d|        y# t        $ r}t        d|        |d}~ww xY wc c}w # t        j                  $ r!}t        d|j                   d|       |d}~ww xY w# t        $ r t        d|       w xY w)a+  Raise ValueError if the URL is unsafe to fetch (SSRF protection).

    Blocks non-http/https schemes, credential-embedded URLs, and hostnames
    that resolve to private, loopback, link-local, multicast, reserved, or
    unspecified addresses. Pass allow_private=True to skip the address check.
    zInvalid URL: N)httphttpszURL scheme 'z$' is not allowed; use http or https.zURL has no hostname: z/URLs with embedded credentials are not allowed.)type   r   zCould not resolve hostname 'z': z%Could not validate resolved address: zNPrivate, loopback, link-local, multicast, and reserved addresses are blocked: )r   	Exception
ValueErrorschemehostnameusernamepasswordsocketgetaddrinfoportSOCK_STREAMgaierror	ipaddress
ip_addressr   )urlr   parsedexcinfo	addressesraw_addrr   s           r   validate_urlr.      s   9# }}--<6Z[\\??0677&//JKK\ **6??FKKfN`N`a
a GAJa 	 
 	Q%%h/B b!`ac`de  /  9=./S89 
 ?? \77HC5QRX[[\  	QDXJOPP	QsM   C9 5<D 1D D E9	DDDD E1EEE-c                   g }g }| D ]  }|j                         }|s	 d|v r'|j                  t        j                  |d             nRt        j                  |      }|j
                  dk(  rdnd}|j                  t        j                  | | d              |rt        d	d
j                  |      z         |S # t        $ r }|j                  |d|        Y d}~d}~ww xY w)zParse a list of IP addresses and CIDR ranges into network objects.

    Accepts individual IPs (e.g. '192.168.1.5') and CIDR ranges
    (e.g. '10.0.0.0/8', '2001:db8::/32'). Raises ValueError on invalid entries.
    /F)strictr   z/32z/128z: NzInvalid IP allowlist entries: z; )stripappendr&   
ip_networkr'   versionr   join)raw_entriesr)   errorsentryvaluer   suffixr*   s           r   parse_ip_allowlistr<   D   s     ,.FF	/e|i225GH))%0"$**/vi22bT&?5QR  9DIIf<MMNNM  	/MMUIRu-..	/s   A=B>>	C'C""C'c                  *     e Zd ZdZd fdZd Z xZS )IPAllowlistMiddlewarezQRestrict inbound connections to a configured set of IP networks (CIDR supported).c               2    t         |   |       || _        y r	   )super__init__	allowlist)selfapprB   	__class__s      r   rA   zIPAllowlistMiddleware.__init__d   s    "r   c                  K   |j                   j                  dk(  r ||       d {   S |j                  }|t        ddid      S 	 t	        j
                  |j                        t        fd| j                  D              st        dd	 d
id      S  ||       d {   S 7 # t        $ r  t        dd|j                   did      cY S w xY w7 2w)Nz/healtherrorz!Forbidden: missing client addressi  )status_codez#Forbidden: invalid client address ''c              3  &   K   | ]  }|v  
 y wr	    ).0net	client_ips     r   	<genexpr>z1IPAllowlistMiddleware.dispatch.<locals>.<genexpr>w   s     >~9#~s   zForbidden: z is not in the IP allowlist)
r(   pathclientr   r&   r'   hostr   r
   rB   )rC   request	call_nextrQ   rN   s       @r   dispatchzIPAllowlistMiddleware.dispatchh   s     ;;y("7+++>*M N\_``	!,,V[[9I >t~~>>K	{2MNO]`  w'''% ,  	?}ANO]` 	 (s?   %CB+!CB- *<C&C'C-&CCCC)rD   r   rB   list[ipaddress._BaseNetwork]returnNone)__name__
__module____qualname____doc__rA   rU   __classcell__)rE   s   @r   r>   r>   a   s    [#(r   r>   )r   zipaddress._BaseAddressrW   bool)r(   strr   r^   rW   rX   )r7   z	list[str]rW   rV   )r\   
__future__r   r&   r!   urllib.parser   starlette.middleware.baser   starlette.responsesr   starlette.typesr   r   r.   r<   r>   rK   r   r   <module>re      s?    L "   ! 8 , # 5: (V:(. (r   