U
    n5{i)2  ã                	   @   s(  d Z ddlmZmZmZ ddlmZmZ ddlm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZmZmZ ddlmZmZmZ dd	lmZmZmZ dd
lmZ ddl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* zddl+m,Z, W n e-k
�r   dZ,Y nX ddl.m/Z/m0Z0m1Z1 G dd„ dƒZ2G dd„ dƒZ3eeƒG dd„ dƒƒZ4G dd„ dee3ƒZ5G dd„ dƒZ6G dd„ de2eeƒZ7G dd „ d ee3ƒZ8G d!d"„ d"e2ee3ee6ƒZ9G d#d$„ d$e2e3e6e!e"eƒZ:e;ƒ  <e9 =¡ ¡ e;ƒ  <e7 =¡ ¡ e;ƒ  <e:ƒ  =¡ ¡ G d%d&„ d&ee e3ƒZ>e;ƒ  <e> =¡ ¡ dS )'z0
Tests for implementations of L{ITLSTransport}.
é    )ÚOptionalÚSequenceÚType)Ú	InterfaceÚimplementer)ÚDeferredÚDeferredList)ÚSSL4ClientEndpointÚSSL4ServerEndpointÚTCP4ClientEndpoint)ÚConnectionClosed)ÚIReactorSSLÚIStreamClientEndpointÚITLSTransport)ÚClientFactoryÚProtocolÚServerFactory)ÚBrokenContextFactoryÚConnectionTestsMixinÚEndpointCreator)ÚReactorBuilder)ÚAbortConnectionMixinÚConnectToTCPListenerMixinÚStreamTransportTestsMixin)ÚnetworkString)ÚFilePath)Úplatform)ÚSkipTest)ÚFILETYPE_PEMN)ÚClientContextFactoryÚKeyPairÚPrivateCertificatec                   @   s>   e Zd ZU egZeeee   e	d< e
 ¡ r:dZeedœZdS )ÚTLSMixinÚrequiredInterfaceszcFor some reason, these reactors don't deal with SSL disconnection correctly on Windows.  See #3371.)z*twisted.internet.glib2reactor.Glib2Reactorz(twisted.internet.gtk2reactor.Gtk2ReactorN)Ú__name__Ú
__module__Ú__qualname__r   r#   r   r   r   r   Ú__annotations__r   Z	isWindowsÚmsgZskippedReactors© r)   r)   úB/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/internet/test/test_tls.pyr"   2   s   
ÿþr"   c                   @   s@   e Zd ZddlZeeejƒƒ d¡ d¡Z	[dd„ Z
dd„ ZdS )	ÚContextGeneratingMixinr   Ns   tests
   server.pemc                 C   s(   | j  ¡ }t |t |t¡t¡}| ¡ S )zM
        Return a new SSL context suitable for use in a test server.
        )Ú_pemZ
getContentr!   Úloadr    r   Úoptions)ÚselfZpemÚcertr)   r)   r*   ÚgetServerContextH   s    
 
 ÿz'ContextGeneratingMixin.getServerContextc                 C   s   t ƒ S ©N)r   ©r/   r)   r)   r*   ÚgetClientContextR   s    z'ContextGeneratingMixin.getClientContext)r$   r%   r&   Ztwistedr   r   Ú__file__ZsiblingÚchildr,   r1   r4   r)   r)   r)   r*   r+   @   s   ÿ
r+   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚStartTLSClientEndpointa!  
    An endpoint which wraps another one and adds a TLS layer immediately when
    connections are set up.

    @ivar wrapped: A L{IStreamClientEndpoint} provider which will be used to
        really set up connections.

    @ivar contextFactory: A L{ContextFactory} to use to do TLS.
    c                 C   s   || _ || _d S r2   )ÚwrappedÚcontextFactory)r/   r8   r9   r)   r)   r*   Ú__init__b   s    zStartTLSClientEndpoint.__init__c                    s$   G ‡ ‡fdd„dt ƒ}ˆj |ƒ ¡S )z¼
        Establish a connection using a protocol build by C{factory} and
        immediately start TLS on it.  Return a L{Deferred} which fires with the
        protocol instance.
        c                       s   e Zd Z‡ ‡fdd„ZdS )z6StartTLSClientEndpoint.connect.<locals>.WrapperFactoryc                    s(   ˆ  |¡‰ ˆ jf‡ ‡fdd„	}|ˆ _ˆ S )Nc                    s   ˆ j  ˆj¡ | ƒ  d S r2   )Ú	transportÚstartTLSr9   )Úorig)Úprotocolr/   r)   r*   ÚconnectionMades   s    z\StartTLSClientEndpoint.connect.<locals>.WrapperFactory.buildProtocol.<locals>.connectionMade)ÚbuildProtocolr?   )ZwrapperSelfÚaddrr?   ©Úfactoryr/   )r>   r*   r@   p   s    
zDStartTLSClientEndpoint.connect.<locals>.WrapperFactory.buildProtocolN)r$   r%   r&   r@   r)   rB   r)   r*   ÚWrapperFactoryo   s   rD   )r   r8   Úconnect)r/   rC   rD   r)   rB   r*   rE   f   s    	zStartTLSClientEndpoint.connectN)r$   r%   r&   Ú__doc__r:   rE   r)   r)   r)   r*   r7   V   s   
r7   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚStartTLSClientCreatorz{
    Create L{ITLSTransport.startTLS} endpoint for the client, and normal SSL
    for server just because it's easier.
    c                 C   s   t |d|  ¡ ƒS )zµ
        Construct an SSL server endpoint.  This should be constructing a TCP
        server endpoint which immediately calls C{startTLS} instead, but that
        is hard.
        r   ©r
   r1   ©r/   Úreactorr)   r)   r*   Úserverƒ   s    zStartTLSClientCreator.serverc                 C   s   t t|d|jƒtƒ ƒS )zS
        Construct a TCP client endpoint wrapped to immediately start TLS.
        ú	127.0.0.1)r7   r   Úportr   ©r/   rJ   ZserverAddressr)   r)   r*   Úclient‹   s    þzStartTLSClientCreator.clientN©r$   r%   r&   rF   rK   rO   r)   r)   r)   r*   rG   }   s   rG   c                   @   s   e Zd ZdZdd„ ZdS )ÚBadContextTestsMixinz�
    Mixin for L{ReactorBuilder} subclasses which defines a helper for testing
    the handling of broken context factories.
    c                 C   s0   |   ¡ }|  t||tƒ ¡}|  tjt|ƒ¡ dS )aÐ  
        Assert that the exception raised by a broken context factory's
        C{getContext} method is raised by some reactor method.  If it is not, an
        exception will be raised to fail the test.

        @param useIt: A two-argument callable which will be called with a
            reactor and a broken context factory and which is expected to raise
            the same exception as the broken context factory's C{getContext}
            method.
        N)ÚbuildReactorÚassertRaisesÚ
ValueErrorr   ÚassertEqualÚmessageÚstr)r/   ÚuseItrJ   Úexcr)   r)   r*   Ú_testBadContext›   s    z$BadContextTestsMixin._testBadContextN)r$   r%   r&   rF   rZ   r)   r)   r)   r*   rQ   •   s   rQ   c                   @   s   e Zd ZdZeƒ ZdS )ÚStartTLSClientTestsMixinzš
    Tests for TLS connections established using L{ITLSTransport.startTLS} (as
    opposed to L{IReactorSSL.connectSSL} or L{IReactorSSL.listenSSL}).
    N)r$   r%   r&   rF   rG   Ú	endpointsr)   r)   r)   r*   r[   «   s   r[   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú
SSLCreatorz
    Create SSL endpoints.
    c                 C   s   t |d|  ¡ ƒS )zQ
        Create an SSL server endpoint on a TCP/IP-stack allocated port.
        r   rH   rI   r)   r)   r*   rK   ¹   s    zSSLCreator.serverc                 C   s   t |d|jtƒ ƒS )z¨
        Create an SSL client endpoint which will connect localhost on
        the port given by C{serverAddress}.

        @type serverAddress: L{IPv4Address}
        rL   )r	   rM   r   rN   r)   r)   r*   rO   ¿   s       ÿzSSLCreator.clientNrP   r)   r)   r)   r*   r]   ´   s   r]   c                   @   s&   e Zd ZdZeƒ Zdd„ Zdd„ ZdS )ÚSSLClientTestsMixinz<
    Mixin defining tests relating to L{ITLSTransport}.
    c                 C   s   dd„ }|   |¡ dS )zÆ
        If the context factory passed to L{IReactorSSL.connectSSL} raises an
        exception from its C{getContext} method, that exception is raised by
        L{IReactorSSL.connectSSL}.
        c                 S   s   |   ddtƒ |¡S )NrL   iÒ  )Ú
connectSSLr   ©rJ   r9   r)   r)   r*   rX   ß   s       ÿz2SSLClientTestsMixin.test_badContext.<locals>.useItN©rZ   ©r/   rX   r)   r)   r*   Útest_badContextØ   s    z#SSLClientTestsMixin.test_badContextc                    s  G dd„ dt ƒ}|  ¡ ‰tƒ }tƒ |_||_|  ¡ |_tƒ }tƒ |_||_|  	¡ |_|jj
|j_
g ‰ t|j|jgdd�}‡ fdd„}| |¡ ˆjd|dd	�}|  |j¡ ˆ | ¡ j| ¡ j|¡}|  |j¡ | ‡fd
d„¡ |  ˆ¡ ˆ d  t¡ ˆ d  t¡ dS )aO  
        L{ITCPTransport.loseConnection} ends a connection which was set up with
        L{ITLSTransport.startTLS} and which has recently been written to.  This
        is intended to verify that a socket send error masked by the TLS
        implementation doesn't prevent the connection from being reported as
        closed.
        c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )zQSSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.ShortProtocolc                 S   sN   t  | j¡s.| jj}d | j_| tdƒ¡ d S | j | jj¡ | j 	d¡ d S )NzNo ITLSTransport supportó   x)
r   Z
providedByr;   rC   ÚfinishedZerrbackr   r<   ÚcontextÚwrite)r/   re   r)   r)   r*   r?   ð   s    z`SSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.ShortProtocol.connectionMadec                 S   s   | j  d¡ | j  ¡  d S )Nó   y)r;   rg   ZloseConnection)r/   Údatar)   r)   r*   ÚdataReceivedþ   s    z^SSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.ShortProtocol.dataReceivedc                 S   s&   | j j}|d k	r"d | j _| |¡ d S r2   )rC   re   Úcallback)r/   Úreasonre   r)   r)   r*   ÚconnectionLost  s    z`SSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.ShortProtocol.connectionLostN)r$   r%   r&   r?   rj   rm   r)   r)   r)   r*   ÚShortProtocolï   s   
rn   T)ZconsumeErrorsc                    s"   ˆ   | d d | d d g¡ d S )Nr   é   )Úextend)Úresults)ÚlostConnectionResultsr)   r*   Ú
cbFinished"  s    zNSSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.cbFinishedr   rL   )Z	interfacec                    s   ˆ   ¡ S r2   )Ústop)Zign)rJ   r)   r*   Ú<lambda>/  ó    zLSSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLS.<locals>.<lambda>ro   N)r   rR   r   r   re   r>   r1   rf   r   r4   Úmethodr   ZaddCallbackZ	listenTCPZ
addCleanupÚstopListeningZ
connectTCPÚgetHostÚhostrM   Z
disconnectZ
runReactorZtrapr   )r/   rn   ZserverFactoryZclientFactoryre   rs   rM   Z	connectorr)   )rr   rJ   r*   Ú&test_disconnectAfterWriteAfterStartTLSæ   s<    	!


 ÿ
  ÿ
z:SSLClientTestsMixin.test_disconnectAfterWriteAfterStartTLSN)r$   r%   r&   rF   r]   r\   rc   r{   r)   r)   r)   r*   r^   Ë   s   r^   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚTLSPortTestsBuilderz,
    Tests for L{IReactorSSL.listenSSL}
    c                 C   s   |  d||  ¡ ¡S )z0
        Get a TLS port from a reactor.
        r   )Ú	listenSSLr1   )r/   rJ   rC   r)   r)   r*   ÚgetListeningPortA  s    z$TLSPortTestsBuilder.getListeningPortc                 C   s   d||  ¡ jf S )zY
        Get the message expected to be logged when a TLS port starts listening.
        z%s (TLS) starting on %d©ry   rM   )r/   rM   rC   r)   r)   r*   Ú#getExpectedStartListeningLogMessageG  s    z7TLSPortTestsBuilder.getExpectedStartListeningLogMessagec                 C   s   d|  ¡ j› d�S )zJ
        Get the expected connection lost message for a TLS port.
        z
(TLS Port z Closed)r   )r/   rM   r)   r)   r*   ÚgetExpectedConnectionLostLogMsgM  s    z3TLSPortTestsBuilder.getExpectedConnectionLostLogMsgc                 C   s   dd„ }|   |¡ dS )zÄ
        If the context factory passed to L{IReactorSSL.listenSSL} raises an
        exception from its C{getContext} method, that exception is raised by
        L{IReactorSSL.listenSSL}.
        c                 S   s   |   dtƒ |¡S )Nr   )r}   r   r`   r)   r)   r*   rX   Z  s    z2TLSPortTestsBuilder.test_badContext.<locals>.useItNra   rb   r)   r)   r*   rc   S  s    z#TLSPortTestsBuilder.test_badContextc                 C   s   |  | j|j||  ¡ ¡S )a  
        Connect to the given listening TLS port, assuming the
        underlying transport is TCP.

        @param reactor: The reactor under test.
        @type reactor: L{IReactorSSL}

        @param address: The listening's address.  Only the C{port}
            component is used; see
            L{ConnectToTCPListenerMixin.LISTENER_HOST}.
        @type address: L{IPv4Address} or L{IPv6Address}

        @param factory: The client factory.
        @type factory: L{ClientFactory}

        @return: The connector
        )r_   ZLISTENER_HOSTrM   r4   )r/   rJ   ÚaddressrC   r)   r)   r*   ÚconnectToListener_  s    üz%TLSPortTestsBuilder.connectToListenerN)	r$   r%   r&   rF   r~   r€   r�   rc   rƒ   r)   r)   r)   r*   r|   5  s   r|   c                   @   s$   e Zd ZdZefZeƒ Zdd„ ZdS )ÚAbortSSLConnectionTestsz-
    C{abortConnection} tests using SSL.
    c                 C   s   t d krtdƒ‚d S )NzOpenSSL not available.)r   r   r3   r)   r)   r*   ÚsetUpˆ  s    zAbortSSLConnectionTests.setUpN)	r$   r%   r&   rF   r   r#   r]   r\   r…   r)   r)   r)   r*   r„   ~  s   r„   )?rF   Útypingr   r   r   Zzope.interfacer   r   Ztwisted.internet.deferr   r   Ztwisted.internet.endpointsr	   r
   r   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   r   r   Ztwisted.internet.protocolr   r   r   Z&twisted.internet.test.connectionmixinsr   r   r   Z#twisted.internet.test.reactormixinsr   Ztwisted.internet.test.test_tcpr   r   r   Ztwisted.python.compatr   Ztwisted.python.filepathr   Ztwisted.python.runtimer   Ztwisted.trial.unittestr   ZOpenSSL.cryptor   ÚImportErrorZtwisted.internet.sslr   r    r!   r"   r+   r7   rG   rQ   r[   r]   r^   r|   ÚglobalsÚupdateZmakeTestCaseClassesr„   r)   r)   r)   r*   Ú<module>   sf   
&	
ûj
úD
  ÿ