
    sj,!                    T   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ZddlZ	ddl
Z	ddlmZmZ ddlmZ ddlmZ  ej        e          Z eddh          Zd	d
dZdZd$dZ G d de	j        j                  Z G d de	j        j                  Zd%dZddd&dZ dddd'd"Z!g d#Z"dS )(z>Security policy for credential-bearing stdlib urllib requests.    )annotationsN)CallableIterable)Path)Anyacceptz
user-agentP   i  )httphttps)HERMES_CA_BUNDLESSL_CERT_FILEREQUESTS_CA_BUNDLECURL_CA_BUNDLEurlstrreturntuple[str, str, int | None]c                   t           j                            |           }|j        pd                                }|j        }||j        pd                                                    d          ||nt          	                    |          fS )z>Return a normalized (scheme, hostname, effective port) origin. .)
urllibparseurlparseschemelowerporthostnamerstrip_DEFAULT_PORTSget)r   parsedr   r   s       >/home/agent/.hermes/hermes-agent/hermes_cli/urllib_security.py
url_originr#      s    \""3''Fm!r((**F ;D		B%%''..s33 n&8&8&@&@     c                  0     e Zd ZdZeddd	Z fd
Z xZS )SafeCredentialRedirectHandlerzAPreserve request headers only while redirects stay on one origin.)cross_origin_safe_headersoriginal_urlr   r'   Iterable[str]r   Nonec               j    t          |          | _        t          d |D                       | _        d S )Nc              3  X   K   | ]%}t          |                                          V  &d S N)r   r   ).0names     r"   	<genexpr>z9SafeCredentialRedirectHandler.__init__.<locals>.<genexpr>6   sC       4
 4
"&CIIOO4
 4
 4
 4
 4
 4
r$   )r#   _original_origin	frozenset_cross_origin_safe_headers)selfr(   r'   s      r"   __init__z&SafeCredentialRedirectHandler.__init__/   sH     !+< 8 8*3 4
 4
*C4
 4
 4
 +
 +
'''r$   c                   t                                          ||||||          }|d S t          j                            |j        |          }t          |          | j        k    rWt          |	                                          D ]5\  }	}
|	
                                | j        vr|                    |	           6|S r-   )superredirect_requestr   r   urljoinfull_urlr#   r1   listheader_itemsr   r3   remove_header)r4   reqfpcodemsgheadersnewurl
redirectedresolved_urlr/   _value	__class__s              r"   r8   z.SafeCredentialRedirectHandler.redirect_request:   s    WW--c2tS'6RR
4|++CL&AAl##t'<<< !%Z%<%<%>%> ? ? 3 3f::<<t'FFF,,T222r$   )r(   r   r'   r)   r   r*   )__name__
__module____qualname____doc___CROSS_ORIGIN_SAFE_HEADERSr5   r8   __classcell__)rG   s   @r"   r&   r&   ,   sb        KK 4N		
 	
 	
 	
 	
 	
        r$   r&   c                  @    e Zd ZdZ ed          ZddZdd
ZeZeZ	dS )_CrossOriginRequestSanitizerz:Strip headers after installed request processors have run.infr(   r   r   r*   c                .    t          |          | _        d S r-   )r#   r1   )r4   r(   s     r"   r5   z%_CrossOriginRequestSanitizer.__init__U   s     *< 8 8r$   requesturllib.request.Requestc                    t          |j                  | j        k    rWt          |                                          D ]5\  }}|                                t          vr|                    |           6|S r-   )r#   r:   r1   r;   r<   r   rL   r=   )r4   rR   r/   rF   s       r"   	_sanitizez&_CrossOriginRequestSanitizer._sanitizeX   sp    g&''4+@@@ $W%9%9%;%; < < 0 0f::<<'AAA))$///r$   N)r(   r   r   r*   )rR   rS   )
rH   rI   rJ   rK   floathandler_orderr5   rU   http_requesthttps_request r$   r"   rO   rO   J   sW        DD E%LLM9 9 9 9    LMMMr$   rO   ssl.SSLContext | Nonec                    t          fdt          D             d          } | rt          |                                           }|                                rb	 t          j        t          |                    S # t          t
          j	        f$ r&}t                              d| |           Y d}~n#d}~ww xY wt                              d|            t          j        dk    rdS 	 ddl}t          j        |                                          S # t           t          t
          j	        f$ r&}t                              d	|           Y d}~dS d}~ww xY w)
z?Return the explicit CA context for Hermes-owned urllib openers.c              3  n   K   | ]/}t          j        |d                                           x+V  0dS )r   N)osgetenvstrip)r.   r/   values     r"   r0   z*_resolved_https_context.<locals>.<genexpr>f   sZ       	
 	
4,,22444	
	
 	
 	
 	
 	
 	
r$   r   )cafileuR   CA bundle could not be loaded from %s: %s — falling back to default certificatesNuJ   CA bundle path does not exist: %s — falling back to default certificatesdarwinr   ua   Could not load certifi for urllib HTTPS verification: %s — falling back to default certificates)next_CA_BUNDLE_ENV_VARSr   
expanduseris_filesslcreate_default_contextr   OSErrorSSLErrorloggerwarningsysplatformcertifiwhereImportError)	ca_bundleca_pathexcrp   ra   s       @r"   _resolved_https_contextrv   c   s   	
 	
 	
 	
+	
 	
 	

 	 I  y//,,..?? 	1WFFFFS\*   h        NN\  
 |xt	)AAAA#,/   o	
 	
 	
 ttttts0   !A= =B9B44B9**D E1EEssl_contextr(   c                  t          t          j        dd          }|lt                      }|t          j                                        }n=t          j                            t          j                            |                    }t          t          j        dd          fdt          |dd          D             }!|                                          |                    t          |                      |                    t          |                      t          j        j        | }t          |dt          t          |d	d                               g |_        |S )
a  Clone the installed opener's handlers, replacing redirect policy only.

    When ``ssl_context`` is provided, the cloned HTTPS handler is replaced with
    one bound to that context so per-provider TLS settings (``ssl_ca_cert`` /
    ``ssl_verify``) apply to this request. When it is None, Hermes-owned
    openers get an explicit CA default via ``_resolved_https_context`` (env
    bundle first, certifi on macOS); an application-installed opener's TLS
    policy is preserved unchanged.
    _openerN)contextHTTPSHandlerc                    g | ]I}t          |t          j        j                  s(t          |          5t	          j        |          JS r-   )
isinstancer   rR   HTTPRedirectHandlercopy)r.   handler_https_handler_clsrx   s     r"   
<listcomp>z8_secure_opener_from_installed_policy.<locals>.<listcomp>   sg     	 	 	'6>#EFF	
 #".7$677 / 		'
 /..r$   handlersrZ   _hermes_initial_addheaders
addheaders)getattrr   rR   rv   build_openerr|   appendr&   rO   setattrr;   r   )r(   rx   	installedr{   r   securedr   s    `    @r"   $_secure_opener_from_installed_policyr      st    	488I)++?3355II33++G+<< I !FF	 	 	 	 	y*b99	 	 	H #5#A**;???@@@OO1,??@@@OO0>>???n)84G $WYb1122  
 GNr$   )opener_factoryrx   rR   rS   timeoutrV   r   Callable[..., Any] | Nonec                   |Yt          | j        |          }t          |dd          D ]0\  }}|                     |          s|                     ||           1n |t          | j                            }|                    | |          S )a  Open a request without forwarding credentials across origins.

    The default preserves an application-installed opener's proxy, TLS,
    cookies, custom protocol handlers, and instrumentation while replacing its
    redirect handler. ``opener_factory`` is an explicit test seam; security is
    never disabled based on global ``urlopen`` identity.

    ``ssl_context`` (an ``ssl.SSLContext``) overrides the HTTPS handler's TLS
    policy for this request only. It is used to honor a custom provider's
    ``ssl_ca_cert`` / ``ssl_verify`` on the ``/models`` discovery path, which
    otherwise falls back to the process-wide ``SSL_CERT_FILE`` / certifi bundle.
    Nrw   r   rZ   )r   )r   r:   r   
has_header
add_headerr&   open)rR   r   r   rx   openerr/   ra   s          r"   open_credentialed_urlr      s    & 5+
 
 
 #6+GLL 	0 	0KD%%%d++ 0""4///	0   =g>N O OPP;;w;000r$   )r&   r   r#   )r   r   r   r   )r   r[   )r(   r   )rR   rS   r   rV   r   r   )#rK   
__future__r   r   loggingr^   rh   rn   urllib.parser   urllib.requestcollections.abcr   r   pathlibr   typingr   	getLoggerrH   rl   r2   rL   r   re   r#   rR   r   r&   BaseHandlerrO   rv   r   r   __all__rZ   r$   r"   <module>r      s   D D " " " " " "   				 



 



         . . . . . . . .            		8	$	$ 'Y,'?@@ s++        FN$F   <    6>#=   2' ' ' 'T LP - - - - - -h 151 1 1 1 1 1>  r$   