
    !:ZH                        	 d dl Z n# e$ r d dlZ Y nw xY w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mZ d d	lmZ d d
lmZ d dlmZ ddlmZmZ  ej        e           Z!dZ"dZ#dZ$ G d de%          Z& G d de%          Z' G d de          Z(d Z)d Z*d Z+ G d de          Z,dS )    N)x509)default_backend)hashes)UnsupportedAlgorithm)AuthBase)Response)urlparseStringIO)CaseInsensitiveDict)cookiejar_from_dict)HTTPResponse   )MutualAuthenticationErrorKerberosExchangeError      c                       e Zd ZdS )NoCertificateRetrievedWarningN__name__
__module____qualname__     =/usr/lib/python3/dist-packages/requests_kerberos/kerberos_.pyr   r   *           Dr   r   c                       e Zd ZdS )UnknownSignatureAlgorithmOIDNr   r   r   r   r   r   -   r   r   r   c                   "     e Zd ZdZ fdZ xZS )SanitizedResponseaT  The :class:`Response <Response>` object, which contains a server's
    response to an HTTP request.

    This differs from `requests.models.Response` in that it's headers and
    content have been sanitized. This is only used for HTTP Error messages
    which do not support mutual authentication when mutual authentication is
    required.c                    t          t          |                                            |j        | _        |j        | _        |j        | _        |j        | _        |j        | _        |j        | _        |j	        | _	        d| _
        d| _        t          i           | _        t                      | _        d| j        d<   dD ] }||j        v r|j        |         | j        |<   !d S )NT 0zcontent-length)dateserver)superr    __init__status_codeencodingrawreasonurlrequest
connection_content_consumed_contentr   cookiesr   headers)selfresponseheader	__class__s      r   r'   zSanitizedResponse.__init__:   s    &&//111#/ )<o<'"-!%*2..*,,),%&( 	@ 	@F)))'/'7'?V$	@ 	@r   )r   r   r   __doc__r'   __classcell__)r6   s   @r   r    r    1   sK         @ @ @ @ @ @ @ @ @r   r    c                 2   t          t          d          rt          j        }n+t          j        dt          j                  }|t          _        | j                            dd          }|r,|                    |          }|r|	                    d          S dS )zDExtracts the gssapi authentication token from the appropriate headerregexz (?:.*,)*\s*Negotiate\s*([^,]*),?zwww-authenticateNr   )
hasattr_negotiate_valuer:   recompileIr2   getsearchgroup)r4   r:   authreq	match_objs       r   r<   r<   N   s    )) ' & 
=rtDD!&""#5t<<G &LL))	 	&??1%%%4r   c                    t          j        | t                                }	 |j        }nB# t          $ r5}t          j        dt          |          z  t                     Y d }~d S d }~ww xY w|j	        dv r3t          j        t          j                    t                                }n!t          j        |t                                }|                    |            |                                }|S )NzWFailed to get signature algorithm from certificate, unable to pass channel bindings: %s)md5sha1)r   load_der_x509_certificater   signature_hash_algorithmr   warningswarnstrr   namer   HashSHA256updatefinalize)certificate_dercerthash_algorithmexdigestcertificate_hashs         r   _get_certificate_hashrX   b   s    )/?;L;LMMD6    <>A"ggFGc	e 	e 	ettttt o--V]__o.?.?@@^_->->??
MM/"""((s   + 
A**A%%A*c                    d}| j         }t          |t                    r	 t          j        dk    r|j        j        j         j        }n|j        j        j        }	 |                    d          }t          |          }d|z   }nT# t          $ r Y nHw xY w# t          $ r t          j        dt                     Y nw xY wt          j        dt                     |S )a  
    https://tools.ietf.org/html/rfc5929 4. The 'tls-server-end-point' Channel Binding Type

    Gets the application_data value for the 'tls-server-end-point' CBT Type.
    This is ultimately the SHA256 hash of the certificate of the HTTPS endpoint
    appended onto tls-server-end-point. This value is then passed along to the
    kerberos library to bind to the auth response. If the socket is not an SSL
    socket or the raw HTTP object is not a urllib3 HTTPResponse then None will
    be returned and the Kerberos auth will use GSS_C_NO_CHANNEL_BINDINGS

    :param response: The original 401 response from the server
    :return: byte string used on the application_data.value field on the CBT struct
    N)r   r   Ts   tls-server-end-point:z:Failed to get raw socket for CBT; has urllib3 impl changedzZRequests is running with a non urllib3 backend, cannot retrieve server certificate for CBT)r*   
isinstancer   sysversion_info_fpfp_sockgetpeercertrX   AttributeErrorrJ   rK   r   )r4   application_dataraw_responsesocketserver_certificaterW   s         r   &_get_channel_bindings_application_datarf   z   s    <L,-- +	O&((%),06%),2
O%+%7%7%=%=" $99K#L#L #;>N#N  	 "     	9 	9 	9MV79 9 9 9 9	9 	h)	+ 	+ 	+ s#   8B B 
BB$B:9B:c                   h    e Zd ZdZedddddddfdZddZd Zd	 Zd
 Z	d Z
d Zd Zd Zd Zd ZdS )HTTPKerberosAuthzMAttaches HTTP GSSAPI/Kerberos Authentication to the given Request
    object.HTTPFNTc	                     i | _         || _        || _        d | _        || _        || _        || _        || _        || _        d| _	        t          t          d          | _        || _        d| _        d | _        d S )NFauthGSSWinRMEncryptMessage)contextmutual_authenticationdelegateposserviceforce_preemptive	principalhostname_overridesanitize_mutual_error_response	auth_doner;   kerberoswinrm_encryption_availablesend_cbtcbt_binding_tried
cbt_struct)	r3   rm   rp   rn   rq   rr   rs   rt   rx   s	            r   r'   zHTTPKerberosAuth.__init__   s}    
 %:"  0"!2.L+*1(<X*Y*Y' !!&r   c                 t   t           j        t           j        z  }| j        r|t           j        z  }	 d}| j        | j        n|}d                    | j        |          }t          j        ||| j	                  \  }| j
        |<   |dk     rt          ||          |rdnt          |          }	d}| j        r(t          j        | j
        |         |	| j                  }n t          j        | j
        |         |	          }|d	k     rt          ||          d
}t          j        | j
        |                   }
d                    |
          S # t           j        $ rr}t"                              d                    |                     t"                              |           t'          |dt)          |j                            d}~wt          $ rc}|j        |k    r d                    ||          }t"                              d                    |                     t'          |          d}~ww xY w)z
        Generates the GSSAPI authentication token with kerberos.

        If any GSSAPI step fails, raise KerberosExchangeError
        with failure detail.

        zauthGSSClientInit()Nz{0}@{1})gssflagsrr   r   r"   zauthGSSClientStep()channel_bindingsr   zauthGSSClientResponse()zNegotiate {0}z&generate_request_header(): {0} failed:z	 failed: z{0} failed, result: {1}zgenerate_request_header(): {0})rv   GSS_C_MUTUAL_FLAGGSS_C_SEQUENCE_FLAGrn   GSS_C_DELEG_FLAGrs   formatrp   authGSSClientInitrr   rl   EnvironmentErrorr<   rz   authGSSClientStepauthGSSClientResponseGSSErrorlog	exceptionr   rL   argserrnoerror)r3   r4   hostis_preemptiver|   
kerb_stage	kerb_hostkerb_spnresultnegotiate_resp_valuegss_responser   messages                r   generate_request_headerz(HTTPKerberosAuth.generate_request_header   s]    -0LL= 	211H2	1.J
 372H2T..Z^I ''i@@H)1)CH!T^*= *= *=&FDL& zz&vz::: *7#V22<LX<V<V .J J!3DL4F4HEI_V V V "3DL4F4HJ J zz&vz:::2J#9$,t:LMML")),777  	Y 	Y 	YMM8??
KKM M MMM%   ':::s5:(WXXX 	1 	1 	1 {f$$/66z6JJGII6==gFFGGG'000	1s&   DE H7A-GH7AH22H7c                    t          |j                  j        }	 |                     ||          }n# t          $ r |cY S w xY wt
                              d                    |                     ||j        j	        d<   |j
         |j                                          |j        j        |j        fi |}|j                            |           t
                              d                    |                     |S )z0Handles user authentication with gssapi/kerberosz.authenticate_user(): Authorization header: {0}Authorizationz"authenticate_user(): returning {0})r	   r,   hostnamer   r   r   debugr   r-   r2   contentr*   release_connr.   sendhistoryappend)r3   r4   kwargsr   auth_header_rs         r   authenticate_userz"HTTPKerberosAuth.authenticate_user   s    %%.	66xFFKK$ 	 	 	OOO	 			BII  	 	 	4? 1 	!!###%X %h&6AA&AA

(###		6==bAABBB	s   2 A Ac                 `   t                               d           t          |          = | j        |fi |}t                               d                    |                     |S t                               d           t                               d                    |                     |S )z=Handles 401's, attempts to use gssapi/kerberos authenticationzhandle_401(): Handling: 401Nzhandle_401(): returning {0}z'handle_401(): Kerberos is not supported)r   r   r<   r   r   )r3   r4   r   r   s       r   
handle_401zHTTPKerberosAuth.handle_401  s     			/000H%%1'';;F;;BII3::2>>???III?@@@II3::8DDEEEOr   c                    t                               d|j        z             | j        t          t
          fv rr| j        sj|j        dk    }t          |          t                               d           |                     |          s<t           	                    d           t          d                    |                    t                               d                    |                     d| _        |S |s| j        t
          k    ra|j        s2t           	                    d	                    |j                             | j        t          k    r| j        rt          |          S |S t           	                    d           t          d                    |                    t                               d                    |                     |S )
zHandles all responses with the exception of 401s.

        This is necessary so that we can authenticate responses if requestedzhandle_other(): Handling: %di  Nz)handle_other(): Authenticating the serverz,handle_other(): Mutual authentication failedzUnable to authenticate {0}zhandle_other(): returning {0}TzAhandle_other(): Mutual authentication unavailable on {0} response)r   r   r(   rm   REQUIREDOPTIONALru   r<   authenticate_serverr   r   r   okrt   r    )r3   r4   is_http_errors      r   handle_otherzHTTPKerberosAuth.handle_other&  s   
 			083GGHHH%(H)===dn=$0C7M))5		EFFF//99 L IILMMM3 5::@&:J:JL L L 		9@@JJKKK!% H$"<"H"H{ NII 006x7K0L0LN N N -99: :,X666#O
 		HIII/ 166<fX6F6FH H H II5<<XFFGGGOr   c                    t                               d                    t          |                               t	          |j                  j        }	 | j        r5t          j	        | j
        |         t          |          | j                  }n-t          j	        | j
        |         t          |                    }n0# t          j        $ r t                               d           Y dS w xY w|dk     r/t                               d                    |                     dS t                               d                    |                     dS )	zm
        Uses GSSAPI to authenticate the server.

        Returns True on success, False on failure.
        z/authenticate_server(): Authenticate header: {0}r}   z2authenticate_server(): authGSSClientStep() failed:Fr   z6authenticate_server(): authGSSClientStep() failed: {0}z$authenticate_server(): returning {0}T)r   r   r   r<   r	   r,   r   rz   rv   r   rl   r   r   r   )r3   r4   r   r   s       r   r   z$HTTPKerberosAuth.authenticate_serverU  sP    			CJJX&&( ( 	) 	) 	) %%.	 P!3DL4F4DX4N4NEI_V V V "3DL4F4DX4N4NP P  	 	 	MMNOOO55	 A::II "F6NN, , ,5		8??IIJJJts   A)B? ?)C,+C,c                    |                     dd          }| j        sR| j        rKt          |          }|r3	 t	          j        |          | _        n# t          $ r
 d| _        Y nw xY wd| _        | j        $|j	        j
                            | j                   |j        dk    r_|dk     rY | j        |fi |}t                              d|           t                              d	|           |d
z  } | j        |fd|i|S |j        dk    r#|dk    rt                              d|           |S |                     |          }t                              d|           |S )z<Takes the given response and tries kerberos-auth, as needed.num_401sr   )rb   NTi  r   zhandle_response(): returning %sz+handle_response() has seen %d 401 responsesr   z#handle_response(): returning 401 %s)popry   rx   rf   rv   channelBindingsrz   ra   ro   r-   bodyseekr(   r   r   r   handle_responser   )r3   r4   r   r   cbt_application_datar   s         r   r   z HTTPKerberosAuth.handle_responsev  s   ::j!,, % 	*$- 	*#I(#S#S # ++&.&>Pd&e&e&eDOO% + + +&*DOOO+ &*D"8 !&&tx0003&&8a<< !44V44BII7<<<IICXNNNMH'4'HHXHHHH!S((X]] II;XFFFO""8,,BII7<<<Is   A A&%A&c                 F    |j                             d| j                   dS )z Deregisters the response handlerr4   N)r-   deregister_hookr   )r3   r4   s     r   
deregisterzHTTPKerberosAuth.deregister  s$    ((T5IJJJJJr   c                 n    | j         st          d          t          j        | j        |         |          S NzHWinRM encryption is not available on the installed version of pykerberos)rw   NotImplementedErrorrv   rk   rl   )r3   r   r   s      r   
wrap_winrmzHTTPKerberosAuth.wrap_winrm  s7    . 	r%&pqqq24<3EwOOOr   c                 p    | j         st          d          t          j        | j        |         ||          S r   )rw   r   rv   authGSSWinRMDecryptMessagerl   )r3   r   r   r5   s       r   unwrap_winrmzHTTPKerberosAuth.unwrap_winrm  s:    . 	r%&pqqq24<3EwPVWWWr   c                    | j         ro| j        sht          |j                  j        }|                     d |d          }t                              d                    |                     ||j	        d<   |
                    d| j                   	 |j                                        | _        n# t          $ r
 d | _        Y nw xY w|S )NT)r   z6HTTPKerberosAuth: Preemptive Authorization header: {0}r   r4   )rq   ru   r	   r,   r   r   r   r   r   r2   register_hookr   r   tellro   ra   )r3   r-   r   r   s       r   __call__zHTTPKerberosAuth.__call__  s      		; 		; GK((1D66tTQU6VVKIINUUVabbccc/:GOO,j$*>???	|((**DHH 	 	 	
 DHHH	 s   B2 2CC)F)r   r   r   r7   r   r'   r   r   r   r   r   r   r   r   r   r   r   r   r   rh   rh      s          )1UUd+/$	   ,@1 @1 @1 @1D  4  - - -^  B' ' 'RK K KP P PX X X    r   rh   )-rv   ImportErrorwinkerberosloggingr=   r[   rJ   cryptographyr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   cryptography.exceptionsr   requests.authr   requests.modelsr   requests.compatr	   r
   requests.structuresr   requests.cookiesr   requests.packages.urllib3r   
exceptionsr   r   	getLoggerr   r   r   r   DISABLEDWarningr   r   r    r<   rX   rf   rh   r   r   r   <module>r      sM  #OOOO # # #""""""#  				 



        8 8 8 8 8 8 1 1 1 1 1 1 8 8 8 8 8 8 " " " " " " $ $ $ $ $ $ . . . . . . . . 3 3 3 3 3 3 0 0 0 0 0 0 2 2 2 2 2 2 H H H H H H H Hg!! 	 	 	 	 	G 	 	 		 	 	 	 	7 	 	 	@ @ @ @ @ @ @ @:  (  0( ( (T` ` ` ` `x ` ` ` ` `s    	