U
    sÍ@g$o ã                   @   s¼  d Z ddlmZmZ ddlZddlZddlZddlZddlm	Z	 e	dƒZ
e	dƒZe
dk	r®edk	r®dZddlmZ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 nDe
dkr¼dZnedkrÈdZG dd„ dƒZG dd„ dƒZG dd„ dƒZddlmZmZ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( ddl)m*Z* ddl+m,Z, ddl-m.Z.m/Z0 ddlm1Z1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7 G dd „ d ej8ƒZ9G d!d"„ d"e:ƒZ;G d#d$„ d$ƒZ<G d%d&„ d&e2j=ƒZ>G d'd(„ d(ej?ƒZ@G d)d*„ d*e@ƒZAG d+d,„ d,e@ƒZBG d-d.„ d.e$jCƒZDG d/d0„ d0ƒZEG d1d2„ d2ƒZFG d3d4„ d4ƒZGG d5d6„ d6ƒZHG d7d8„ d8eHeDƒZIG d9d:„ d:eHƒZJG d;d<„ d<eJeEeDƒZKG d=d>„ d>eJeFeDƒZLG d?d@„ d@eJeGeDƒZMG dAdB„ dBƒZNG dCdD„ dDeNƒZOG dEdF„ dFeOeDƒZPG dGdH„ dHeOƒZQG dIdJ„ dJeQeEeDƒZRG dKdL„ dLeQeFeDƒZSG dMdN„ dNeNƒZTG dOdP„ dPeTeDƒZUG dQdR„ dReTƒZVG dSdT„ dTeVeEeDƒZWG dUdV„ dVeVeFeDƒZXG dWdX„ dXe$jCƒZYG dYdZ„ dZe$jCƒZZG d[d\„ d\e$jCƒZ[G d]d^„ d^e$jCƒZ\dS )_z5
Tests for ssh/transport.py and the classes therein.
é    )Úabsolute_importÚdivisionN)ÚrequireModuleÚpyasn1Úcryptography)ÚcommonÚ	transportÚkeysÚfactory)Úkeydata)Údefault_backend)Úec)ÚUnsupportedAlgorithmzCannot run without PyASN1zcan't run without cryptographyc                   @   s6   e Zd ZG dd„ dƒZG dd„ dƒZG dd„ dƒZdS )r   c                   @   s   e Zd ZdS )ztransport.SSHTransportBaseN©Ú__name__Ú
__module__Ú__qualname__© r   r   úC/usr/lib/python3/dist-packages/twisted/conch/test/test_transport.pyÚSSHTransportBase#   s    r   c                   @   s   e Zd ZdS )ztransport.SSHServerTransportNr   r   r   r   r   ÚSSHServerTransport$   s    r   c                   @   s   e Zd ZdS )ztransport.SSHClientTransportNr   r   r   r   r   ÚSSHClientTransport%   s    r   N)r   r   r   r   r   r   r   r   r   r   r   "   s   r   c                   @   s   e Zd ZG dd„ dƒZdS )r
   c                   @   s   e Zd ZdS )zfactory.SSHFactoryNr   r   r   r   r   Ú
SSHFactory)   s   r   N)r   r   r   r   r   r   r   r   r
   (   s   r
   c                   @   s   e Zd Zedd„ ƒZdS )r   c                 C   s   dS )Nó    r   )ÚselfÚargr   r   r   ÚNS-   s    z	common.NSN)r   r   r   Úclassmethodr   r   r   r   r   r   ,   s   r   )Úmd5Úsha1Úsha256Úsha384Úsha512)Ú__version__)Úunittest)Údefer)Úloopback)Ú	randbytes©ÚinsecureRandom)Ú	iterbytesÚ	_bytesChr)ÚaddressÚserviceÚ_kex)Úproto_helpers)Ú
ConchErrorc                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚMockTransportBasean  
    A base class for the client and server protocols.  Stores the messages
    it receives instead of ignoring them.

    @ivar errors: a list of tuples: (reasonCode, description)
    @ivar unimplementeds: a list of integers: sequence number
    @ivar debugs: a list of tuples: (alwaysDisplay, message, lang)
    @ivar ignoreds: a list of strings: ignored data
    c                 C   s.   t j | ¡ g | _g | _g | _g | _d| _dS )z,
        Set up instance variables.
        N)r   r   ÚconnectionMadeÚerrorsÚunimplementedsÚdebugsÚignoredsÚgotUnsupportedVersion©r   r   r   r   r2   I   s    z MockTransportBase.connectionMadec                 C   s   || _ tj | |¡S )zZ
        Intercept unsupported version call.

        @type remoteVersion: L{str}
        )r7   r   r   Ú_unsupportedVersionReceived)r   ZremoteVersionr   r   r   r9   U   s
     ÿz-MockTransportBase._unsupportedVersionReceivedc                 C   s   | j  ||f¡ dS )zp
        Store any errors received.

        @type reasonCode: L{int}
        @type description: L{str}
        N©r3   Úappend)r   Z
reasonCodeZdescriptionr   r   r   ÚreceiveError`   s    zMockTransportBase.receiveErrorc                 C   s   | j  |¡ dS )zX
        Store any unimplemented packet messages.

        @type seqnum: L{int}
        N)r4   r;   )r   Úseqnumr   r   r   ÚreceiveUnimplementedj   s    z&MockTransportBase.receiveUnimplementedc                 C   s   | j  |||f¡ dS )zŠ
        Store any debug messages.

        @type alwaysDisplay: L{bool}
        @type message: L{str}
        @type lang: L{str}
        N)r5   r;   )r   ZalwaysDisplayÚmessageZlangr   r   r   ÚreceiveDebugs   s    zMockTransportBase.receiveDebugc                 C   s   | j  |¡ dS )zG
        Store any ignored data.

        @type packet: L{str}
        N)r6   r;   ©r   Úpacketr   r   r   Ú
ssh_IGNORE~   s    zMockTransportBase.ssh_IGNOREN)
r   r   r   Ú__doc__r2   r9   r<   r>   r@   rC   r   r   r   r   r1   >   s   

	r1   c                   @   sh   e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ ZdS )Ú
MockCipherzH
    A mocked-up version of twisted.conch.ssh.transport.SSHCiphers.
    ó   testé   é   F)Nr   r   rH   r   c                 C   s>   d| _ t|ƒ| j dkr:tdt|ƒ| jt|ƒ| j f ƒ‚|S )z~
        Called to encrypt the packet.  Simply record that encryption was used
        and return the data unchanged.
        Tr   ú*length %i modulo blocksize %i is not 0: %i)ÚusedEncryptÚlenÚencBlockSizeÚRuntimeError©r   Úxr   r   r   Úencryptš   s    ÿzMockCipher.encryptc                 C   s>   d| _ t|ƒ| j dkr:tdt|ƒ| jt|ƒ| j f ƒ‚|S )z~
        Called to decrypt the packet.  Simply record that decryption was used
        and return the data unchanged.
        Tr   rI   )ÚusedDecryptrK   rL   rM   ÚdecBlockSizerN   r   r   r   Údecrypt¦   s    ÿzMockCipher.decryptc                 C   s   t |ƒS )zs
        Make a Message Authentication Code by sending the character value of
        the outgoing packet.
        ©Úchr)r   ÚoutgoingPacketSequenceÚpayloadr   r   r   ÚmakeMAC²   s    zMockCipher.makeMACc                 C   s   t |ƒ|kS )zy
        Verify the Message Authentication Code by checking that the packet
        sequence number is the same.
        rT   )r   ÚincomingPacketSequencerB   ZmacDatar   r   r   Úverifyº   s    zMockCipher.verifyc                 C   s   ||||||f| _ dS )z"
        Record the keys.
        N)r	   )r   ZivOutZkeyOutZivInZkeyInZmacInZmacOutr   r   r   ÚsetKeysÂ   s    zMockCipher.setKeysN)r   r   r   rD   Ú
outCipTyperL   Ú	inCipTyperR   Ú	inMACTypeÚ
outMACTypeÚverifyDigestSizerJ   rQ   ÚoutMACZinMACr	   rP   rS   rX   rZ   r[   r   r   r   r   rE   ˆ   s$   rE   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚMockCompressionz’
    A mocked-up compression, based on the zlib interface.  Instead of
    compressing, it reverses the data and adds a 0x66 byte to the end.
    c                 C   s   |d d d… S ©Néÿÿÿÿr   ©r   rW   r   r   r   ÚcompressÐ   s    zMockCompression.compressc                 C   s   |d d… d d d… S rc   r   re   r   r   r   Ú
decompressÔ   s    zMockCompression.decompressc                 C   s   dS )Nó   fr   ©r   Úkindr   r   r   ÚflushØ   s    zMockCompression.flushN)r   r   r   rD   rf   rg   rk   r   r   r   r   rb   Ê   s   rb   c                   @   sF   e Zd ZdZdZdZdZdddœZdd„ Zd	d
„ Z	dd„ Z
dd„ ZdS )ÚMockServicezÂ
    A mocked-up service, based on twisted.conch.ssh.service.SSHService.

    @ivar started: True if this service has been started.
    @ivar stopped: True if this service has been stopped.
    ó   MockServiceFZMSG_TESTZMSG_fiction)éÿ   éG   c                 C   s   dS )Nrl   r   r8   r   r   r   Ú	logPrefixê   s    zMockService.logPrefixc                 C   s
   d| _ dS )z6
        Record that the service was started.
        TN)Ústartedr8   r   r   r   ÚserviceStartedî   s    zMockService.serviceStartedc                 C   s
   d| _ dS )z6
        Record that the service was stopped.
        TN)Ústoppedr8   r   r   r   ÚserviceStoppedõ   s    zMockService.serviceStoppedc                 C   s   | j  d|¡ dS )z:
        A message that this service responds to.
        rn   N)r   Ú
sendPacketrA   r   r   r   Ússh_TESTü   s    zMockService.ssh_TESTN)r   r   r   rD   Únamerq   rs   ZprotocolMessagesrp   rr   rt   rv   r   r   r   r   rl   Ý   s   
rl   c                   @   s0   e Zd ZdZdeiZdd„ Zdd„ Zdd„ Zd	S )
ÚMockFactoryzL
    A mocked-up factory based on twisted.conch.ssh.factory.SSHFactory.
    ó   ssh-userauthc                 C   s   t j tj¡t j tj¡dœS )zG
        Return the public keys that authenticate this server.
        ©ó   ssh-rsas   ssh-dsa)r	   ÚKeyÚ
fromStringr   ÚpublicRSA_opensshZpublicDSA_opensshr8   r   r   r   ÚgetPublicKeys  s    þzMockFactory.getPublicKeysc                 C   s   t j tj¡t j tj¡dœS )zH
        Return the private keys that authenticate this server.
        rz   )r	   r|   r}   r   ÚprivateRSA_opensshZprivateDSA_opensshr8   r   r   r   ÚgetPrivateKeys  s    þzMockFactory.getPrivateKeysc                 C   s   dt  d¡d ffddœS )a/  
        Diffie-Hellman primes that can be used for key exchange algorithms
        that use group exchange to establish a prime / generator group.

        @return: The primes and generators.
        @rtype: L{dict} mapping the key size to a C{list} of
            C{(generator, prime)} tuple.
        é   ó   diffie-hellman-group14-sha1rH   ))é   é   )é   i   )r.   ÚgetDHGeneratorAndPrimer8   r   r   r   Ú	getPrimes  s    ÿÿýzMockFactory.getPrimesN)	r   r   r   rD   rl   Úservicesr   r   rˆ   r   r   r   r   rx     s    ÿ		rx   c                   @   s   e Zd ZdZdd„ ZdS )ÚMockOldFactoryPublicKeysz…
    The old SSHFactory returned mappings from key names to strings from
    getPublicKeys().  We return those here for testing.
    c                 C   s4   t  | ¡}| ¡ dd… D ]\}}| ¡ ||< q|S )zJ
        We used to map key types to public key blobs as strings.
        N)rx   r   ÚitemsÚblob©r   r	   rw   Úkeyr   r   r   r   8  s    
z&MockOldFactoryPublicKeys.getPublicKeysN)r   r   r   rD   r   r   r   r   r   rŠ   2  s   rŠ   c                   @   s   e Zd ZdZdd„ ZdS )ÚMockOldFactoryPrivateKeysz—
    The old SSHFactory returned mappings from key names to cryptography key
    objects from getPrivateKeys().  We return those here for testing.
    c                 C   s2   t  | ¡}| ¡ dd… D ]\}}|j||< q|S )zG
        We used to map key types to cryptography key objects.
        N)rx   r   r‹   Z	keyObjectr   r   r   r   r   I  s    
z(MockOldFactoryPrivateKeys.getPrivateKeysN)r   r   r   rD   r   r   r   r   r   r   C  s   r   c                   @   s4   e Zd ZdZdZereZdd„ Zdd„ Zdd„ Z	dS )	ÚTransportTestCasez.
    Base class for transport test cases.
    Nc                    sV   t  ¡ ˆ _ˆ  ¡ ˆ _g ˆ _dd„ }ˆ  td|¡ ‡ fdd„}ˆ j ˆ j¡ |ˆ j_	d S )Nc                 S   s   d|  S )z;
            Return a consistent entropy value
            ó   ™r   )rK   r   r   r   ÚsecureRandomb  s    z-TransportTestCase.setUp.<locals>.secureRandomr’   c                    s   ˆ j  | |f¡ d S ©N)Úpacketsr;   )ÚmessageTyperW   r8   r   r   ÚstubSendPacketh  s    z/TransportTestCase.setUp.<locals>.stubSendPacket)
r/   ÚStringTransportr   ÚklassÚprotor”   Zpatchr'   ÚmakeConnectionru   )r   r’   r–   r   r8   r   ÚsetUp^  s    

zTransportTestCase.setUpc                 C   s2   |  d¡ | tj| j¡ | dd¡ |j|_dS )zâ
        Deliver enough additional messages to C{proto} so that the key exchange
        which is started in L{SSHTransportBase.connectionMade} completes and
        non-key exchange messages can be sent and received.
        s   SSH-2.0-BogoClient-1.2i
ó   foos   barN)ÚdataReceivedÚdispatchMessager   ÚMSG_KEXINITÚ_A_KEXINIT_MESSAGEÚ	_keySetupZ_KEY_EXCHANGE_NONEÚ_keyExchangeState©r   r™   r   r   r   ÚfinishKeyExchangeo  s    
 ÿz#TransportTestCase.finishKeyExchangec                 C   s&   | j j| j _g | j _| j  ||¡ dS )zã
        Finish a key exchange by calling C{_keySetup} with the given arguments.
        Also do extra whitebox stuff to satisfy that method's assumption that
        some kind of key exchange has actually taken place.
        N)r™   Z_KEY_EXCHANGE_REQUESTEDr¢   Z_blockedByKeyExchanger¡   )r   ÚsharedSecretÚexchangeHashr   r   r   ÚsimulateKeyExchange‚  s    z%TransportTestCase.simulateKeyExchange)
r   r   r   rD   r˜   ÚdependencySkipÚskipr›   r¤   r§   r   r   r   r   r   T  s   r   c                   @   s   e Zd ZdZdZeZdS )ÚDHGroupExchangeSHA1Mixinz=
    Mixin for diffie-hellman-group-exchange-sha1 tests.
    ó"   diffie-hellman-group-exchange-sha1N)r   r   r   rD   ÚkexAlgorithmr   ÚhashProcessorr   r   r   r   rª   Ž  s   rª   c                   @   s   e Zd ZdZdZeZdS )ÚDHGroupExchangeSHA256Mixinz?
    Mixin for diffie-hellman-group-exchange-sha256 tests.
    ó$   diffie-hellman-group-exchange-sha256N©r   r   r   rD   r¬   r    r­   r   r   r   r   r®   ˜  s   r®   c                   @   s   e Zd ZdZdZeZdS )Ú	ECDHMixinz8
    Mixin for elliptic curve diffie-hellman tests.
    ó   ecdh-sha2-nistp256Nr°   r   r   r   r   r±   ¢  s   r±   c                   @   s   e Zd ZdZeZdS )ÚBaseSSHTransportBaseCasez,
    Base case for TransportBase tests.
    N)r   r   r   rD   r1   r˜   r   r   r   r   r³   ¬  s   r³   c                   @   sÈ  e Zd ZdZereZde d¡ e d¡ e d¡ e d¡ e d¡ e d¡ e d¡ e d¡ e d¡ e d¡ d	 d
 Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Z d;d<„ Z!d=d>„ Z"d?d@„ Z#dAdB„ Z$dCdD„ Z%dEdF„ Z&dGdH„ Z'dIdJ„ Z(dKdL„ Z)dMdN„ Z*dOdP„ Z+dQdR„ Z,dSdT„ Z-dUdV„ Z.dWdX„ Z/dYdZ„ Z0d[S )\ÚBaseSSHTransportTestszs
    Test TransportBase. It implements the non-server/client specific
    parts of the SSH transport protocol.
    ó   ªªªªªªªªªªªªªªªªrƒ   r{   ó
   aes256-ctró	   hmac-sha1ó   noner   ó    ó       c                 C   sp   | j  ¡  dd¡d }|  |dt d¡ ¡ | d¡tdƒd… }dd	 d
d„ t	j
D ƒ¡ d }|  ||¡ dS )a  
        Test that the first thing sent over the connection is the version
        string.  The 'softwareversion' part must consist of printable
        US-ASCII characters, with the exception of whitespace characters and
        the minus sign.

        RFC 4253, section 4.2.
        ó   
rH   r   s   SSH-2.0-Twisted_ÚasciizSSH-2.0-Nz^(ú|c                 s   s(   | ] }|d kr|  ¡ st |¡V  qdS )ú-N)ÚisspaceÚreÚescape©Ú.0Úcr   r   r   Ú	<genexpr>Ü  s    ÿz9BaseSSHTransportTests.test_sendVersion.<locals>.<genexpr>z)*$)r   ÚvalueÚsplitÚassertEqualÚtwisted_versionÚencodeÚdecoderK   ÚjoinÚstringZ	printableZassertRegex)r   ÚversionZsoftwareVersionZsoftwareVersionRegexr   r   r   Útest_sendVersionË  s    
ÿ
ÿÿüÿz&BaseSSHTransportTests.test_sendVersionc                 C   sl   t ƒ }| | j¡ | d¡ | d¡ | d¡ |  | jj¡ | d¡ |  | jj¡ |  d| j ¡ ¡ dS )zÈ
        When the peer is not sending its SSH version but keeps sending data,
        the connection is disconnected after 4KB to prevent buffering too
        much and running our of memory.
        s   SSH-2-Server-IdentifiersÜ  1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890s   1235678s   1234567s%   Preventing a denial of service attackN)	r1   rš   r   r   ÚassertFalseZdisconnectingÚ
assertTrueZassertInrÆ   ©r   Zsutr   r   r   Ú'test_dataReceiveVersionNotSentMemoryDOSã  s    



z=BaseSSHTransportTests.test_dataReceiveVersionNotSentMemoryDOSc                 C   sX   t ƒ }| | j¡ |  |¡ | j ¡  tdƒ}d}| ||¡ | j ¡ }|  |d¡ dS )a@  
        Test that plain (unencrypted, uncompressed) packets are sent
        correctly.  The format is::
            uint32 length (including type and padding length)
            byte padding length
            byte type
            bytes[length-padding length-2] data
            bytes[padding length] padding
        ÚAó   BCDEFGs      ABCDEFG™™™™N)	r1   rš   r   r¤   ÚclearÚordru   rÆ   rÈ   )r   r™   r?   rW   rÆ   r   r   r   Útest_sendPacketPlainù  s    



z*BaseSSHTransportTests.test_sendPacketPlainc                 C   sp   t ƒ }| | j¡ |  |¡ tƒ  |_}tdƒ}d}| j ¡  | ||¡ |  	|j
¡ | j ¡ }|  |d¡ dS )z‡
        Test that packets sent while encryption is enabled are sent
        correctly.  The whole packet should be encrypted.
        rÔ   ó   BCs      ABC™™™™N)r1   rš   r   r¤   rE   ÚcurrentEncryptionsr×   rÖ   ru   rÑ   rJ   rÆ   rÈ   ©r   r™   Ú
testCipherr?   rW   rÆ   r   r   r   Útest_sendPacketEncrypted  s    


ýz.BaseSSHTransportTests.test_sendPacketEncryptedc                 C   sX   t ƒ }| | j¡ |  |¡ tƒ |_| j ¡  | tdƒd¡ | j 	¡ }|  
|d¡ dS )z
        Test that packets sent while compression is enabled are sent
        correctly.  The packet type and data should be encrypted.
        rÔ   ó   Bs      BAf™™™™™™™™N)r1   rš   r   r¤   rb   ÚoutgoingCompressionrÖ   ru   r×   rÆ   rÈ   )r   r™   rÆ   r   r   r   Útest_sendPacketCompressed+  s    


þz/BaseSSHTransportTests.test_sendPacketCompressedc                 C   sx   t ƒ }| | j¡ |  |¡ tƒ  |_}tƒ |_tdƒ}d}| j 	¡  | 
||¡ |  |j¡ | j ¡ }|  |d¡ dS )z×
        Test that packets sent while compression and encryption are
        enabled are sent correctly.  The packet type and data should be
        compressed and then the whole packet should be encrypted.
        rÔ   rÙ   s      	CBAf™™™™™™™™™N)r1   rš   r   r¤   rE   rÚ   rb   rß   r×   rÖ   ru   rÑ   rJ   rÆ   rÈ   rÛ   r   r   r   Útest_sendPacketBoth<  s    


ýz)BaseSSHTransportTests.test_sendPacketBothc                 C   sh   t ƒ }| | j¡ |  |¡ | j ¡  | tdƒd¡ | j ¡ d |_|  	| 
¡ d¡ |  	|jd¡ dS )zt
        Test that packets are retrieved correctly out of the buffer when
        no encryption is enabled.
        rÔ   rÙ   s   extras   ABCN)r1   rš   r   r¤   rÖ   ru   r×   rÆ   ÚbufrÈ   Ú	getPacketr£   r   r   r   Útest_getPacketPlain[  s    

z)BaseSSHTransportTests.test_getPacketPlainc                 C   s¾   t ƒ }dd„ |_| | j¡ | j ¡  tƒ  |_}| tdƒd¡ | j 	¡ }|dtj
… |_|  | ¡ ¡ |  |j¡ |  |jd¡ | j|tj
d… 7  _|  | ¡ d¡ |  |jd¡ dS )	zl
        Test that encrypted packets are retrieved correctly.
        See test_sendPacketEncrypted.
        c                   S   s   d S r“   r   r   r   r   r   Ú<lambda>p  r   z?BaseSSHTransportTests.test_getPacketEncrypted.<locals>.<lambda>rÔ   ó   BCDNs      	Aó   ABCDr   )r1   ÚsendKexInitrš   r   rÖ   rE   rÚ   ru   r×   rÆ   rR   râ   ÚassertIsNonerã   rÑ   rQ   rÈ   Úfirst)r   r™   rÜ   rÆ   r   r   r   Útest_getPacketEncryptedj  s    


z-BaseSSHTransportTests.test_getPacketEncryptedc                 C   sf   t ƒ }| | j¡ |  |¡ | j ¡  tƒ |_|j|_| t	dƒd¡ | j 
¡ |_|  | ¡ d¡ dS )zo
        Test that compressed packets are retrieved correctly.  See
        test_sendPacketCompressed.
        rÔ   ræ   rç   N)r1   rš   r   r¤   rÖ   rb   rß   ÚincomingCompressionru   r×   rÆ   râ   rÈ   rã   r£   r   r   r   Útest_getPacketCompressed  s    

z.BaseSSHTransportTests.test_getPacketCompressedc                 C   sn   t ƒ }dd„ |_| | j¡ | j ¡  tƒ |_tƒ |_|j|_	| 
tdƒd¡ | j ¡ |_|  | ¡ d¡ dS )zv
        Test that compressed and encrypted packets are retrieved correctly.
        See test_sendPacketBoth.
        c                   S   s   d S r“   r   r   r   r   r   rå   •  r   z:BaseSSHTransportTests.test_getPacketBoth.<locals>.<lambda>rÔ   rÕ   s   ABCDEFGN)r1   rè   rš   r   rÖ   rE   rÚ   rb   rß   rì   ru   r×   rÆ   râ   rÈ   rã   r£   r   r   r   Útest_getPacketBoth  s    

z(BaseSSHTransportTests.test_getPacketBothc                 C   s>   t  dddd¡}d }}| jjD ]}|  | |||¡¡ q dS )z?
        Test that all the supportedCiphers are valid.
        ó   ArÞ   ó   Có   Dó                   N)r   Ú
SSHCiphersr™   ÚsupportedCiphersrÑ   Ú
_getCipher)r   ÚciphersÚivrŽ   ÚcipNamer   r   r   Útest_ciphersAreValid   s    z*BaseSSHTransportTests.test_ciphersAreValidc                 C   sl  | j  ¡  dd¡d }|| j_| j ¡ }|  |dd… tt jƒ¡ |  |dd… d¡ t	 
|dd… d¡\}}}}}}}	}
}}}|  |d | jj¡¡ |  |d | jj¡¡ |  |d | jj¡¡ |  |d | jj¡¡ |  |d | jj¡¡ |  |d | jj¡¡ |  |	d | jj¡¡ |  |
d | jj¡¡ |  |d | jj¡¡ |  |d | jj¡¡ |  |d	¡ dS )
a÷  
        Test that the KEXINIT (key exchange initiation) message is sent
        correctly.  Payload::
            bytes[16] cookie
            string key exchange algorithms
            string public key algorithms
            string outgoing ciphers
            string incoming ciphers
            string outgoing MACs
            string incoming MACs
            string outgoing compressions
            string incoming compressions
            bool first packet follows
            uint32 0
        r»   rH   r   é   s   ™™™™™™™™™™™™™™™™Né
   ó   ,s        )r   rÆ   rÇ   r™   râ   rã   rÈ   rU   rŸ   r   ZgetNSrÌ   ÚsupportedKeyExchangesÚsupportedPublicKeysrô   ÚsupportedMACsÚsupportedCompressionsÚsupportedLanguages)r   rÆ   rB   ZkeyExchangesZpubkeysZciphers1Zciphers2Zmacs1Zmacs2Zcompressions1Zcompressions2Z
languages1Z
languages2râ   r   r   r   Útest_sendKexInitª  s<    
þ    ÿÿÿz&BaseSSHTransportTests.test_sendKexInitc                 C   s.   | j  ¡  | j t j| j¡ |  | jg ¡ dS )zy
        Immediately after connecting, the transport expects a KEXINIT message
        and does not reply to it.
        N)r   rÖ   r™   rž   rŸ   r    rÈ   r”   r8   r   r   r   Útest_receiveKEXINITReplyÓ  s    
 ÿz.BaseSSHTransportTests.test_receiveKEXINITReplyc                 C   sX   |   | j¡ | jdd…= | j tj| j¡ |  t| jƒd¡ |  | jd d tj¡ dS )z˜
        When a KEXINIT message is received which is not a reply to an earlier
        KEXINIT message which was sent, a KEXINIT reply is sent.
        NrH   r   )	r¤   r™   r”   rž   r   rŸ   r    rÈ   rK   r8   r   r   r   Útest_sendKEXINITReplyÞ  s     ÿz+BaseSSHTransportTests.test_sendKEXINITReplyc                 C   s   |   t| jj¡ dS )a(  
        A new key exchange cannot be started while a key exchange is already in
        progress.  If an attempt is made to send a I{KEXINIT} message using
        L{SSHTransportBase.sendKexInit} while a key exchange is in progress
        causes that method to raise a L{RuntimeError}.
        N)ÚassertRaisesrM   r™   rè   r8   r   r   r   Útest_sendKexInitTwiceFailsì  s    z0BaseSSHTransportTests.test_sendKexInitTwiceFailsc                 C   s‚   t jt jg}| j  ¡  | j`|D ]$}| j |d¡ |  | j  ¡ d¡ q |  | j¡ t	ƒ | j_
| j ¡  |  | j  ¡  d¡d¡ dS )zù
        After L{SSHTransportBase.sendKexInit} has been called, messages types
        other than the following are queued and not sent until after I{NEWKEYS}
        is sent by L{SSHTransportBase._keySetup}.

        RFC 4253, section 7.1.
        rœ   r   é   N)r   ÚMSG_SERVICE_REQUESTrŸ   rÖ   r™   ru   rÈ   rÆ   r¤   rE   ÚnextEncryptionsZ_newKeysÚcount)r   ZdisallowedMessageTypesr•   r   r   r   Útest_sendKexInitBlocksOthersö  s    þ


z2BaseSSHTransportTests.test_sendKexInitBlocksOthersc                 C   s*   | j  ddd¡ |  | jtjdfg¡ dS )z¦
        Test that debug messages are sent correctly.  Payload::
            bool always display
            string debug message
            string language
        rF   Tó   enó      test   enN)r™   Z	sendDebugrÈ   r”   r   Ú	MSG_DEBUGr8   r   r   r   Útest_sendDebug  s    ÿþz$BaseSSHTransportTests.test_sendDebugc                 C   s8   | j  tjd¡ | j  tjd¡ |  | j jddg¡ dS )zW
        Test that debug messages are received correctly.  See test_sendDebug.
        r  s       silent   en)TrF   r  )Fs   silentr  N)r™   rž   r   r  rÈ   r5   r8   r   r   r   Útest_receiveDebug)  s    þþþz'BaseSSHTransportTests.test_receiveDebugc                 C   s&   | j  d¡ |  | jtjdfg¡ dS )zk
        Test that ignored messages are sent correctly.  Payload::
            string ignored data
        rF   s      testN)r™   Ú
sendIgnorerÈ   r”   r   Ú
MSG_IGNOREr8   r   r   r   Útest_sendIgnore8  s     ÿÿz%BaseSSHTransportTests.test_sendIgnorec                 C   s&   | j  tjd¡ |  | j jdg¡ dS )zb
        Test that ignored messages are received correctly.  See
        test_sendIgnore.
        rF   N)r™   rž   r   r  rÈ   r6   r8   r   r   r   Útest_receiveIgnoreC  s    z(BaseSSHTransportTests.test_receiveIgnorec                 C   s$   | j  ¡  |  | jtjdfg¡ dS )zt
        Test that unimplemented messages are sent correctly.  Payload::
            uint32 sequence number
        rº   N)r™   ZsendUnimplementedrÈ   r”   r   ÚMSG_UNIMPLEMENTEDr8   r   r   r   Útest_sendUnimplementedL  s    
 ÿÿz,BaseSSHTransportTests.test_sendUnimplementedc                 C   s&   | j  tjd¡ |  | j jdg¡ dS )zo
        Test that unimplemented messages are received correctly.  See
        test_sendUnimplemented.
        s      ÿrn   N)r™   rž   r   r  rÈ   r4   r8   r   r   r   Útest_receiveUnimplementedW  s    
ÿz/BaseSSHTransportTests.test_receiveUnimplementedc                    sP   dg‰ ‡ fdd„}|| j _| j dd¡ |  | jt jdfg¡ |  ˆ d ¡ dS )	z²
        Test that disconnection messages are sent correctly.  Payload::
            uint32 reason code
            string reason description
            string language
        Fc                      s   dˆ d< d S ©NTr   r   r   ©Zdisconnectedr   r   ÚstubLoseConnectioni  s    zEBaseSSHTransportTests.test_sendDisconnect.<locals>.stubLoseConnectionrn   rF   s      ÿ   test    r   N)r   ÚloseConnectionr™   ZsendDisconnectrÈ   r”   ÚMSG_DISCONNECTrÑ   ©r   r  r   r  r   Útest_sendDisconnecta  s    ÿþz)BaseSSHTransportTests.test_sendDisconnectc                    sN   dg‰ ‡ fdd„}|| j _| j t jd¡ |  | jjdg¡ |  ˆ d ¡ dS )zl
        Test that disconnection messages are received correctly.  See
        test_sendDisconnect.
        Fc                      s   dˆ d< d S r  r   r   r  r   r   r  z  s    zHBaseSSHTransportTests.test_receiveDisconnect.<locals>.stubLoseConnections      ÿ   test©rn   rF   r   N)r   r  r™   rž   r  rÈ   r3   rÑ   r  r   r  r   Útest_receiveDisconnectt  s    
ÿz,BaseSSHTransportTests.test_receiveDisconnectc                    s`   dg‰ ‡ fdd„}|| j _| j  | j ¡ ¡ |  | j j¡ |  | j j| j j	¡ |  ˆ d ¡ dS )ze
        Test that dataReceived parses packets and dispatches them to
        ssh_* methods.
        Fc                    s   dˆ d< d S r  r   )rB   ©ZkexInitr   r   ÚstubKEXINIT‰  s    z<BaseSSHTransportTests.test_dataReceived.<locals>.stubKEXINITr   N)
r™   Ússh_KEXINITr   r   rÆ   rÑ   Ú
gotVersionrÈ   ÚourVersionStringÚotherVersionString)r   r"  r   r!  r   Útest_dataReceivedƒ  s    
ÿz'BaseSSHTransportTests.test_dataReceivedc                 C   s’   t ƒ }| j |¡ |  | jj|¡ |  |j¡ | j dd¡ |  | jdg¡ t ƒ }| j |¡ |  |j¡ |  |j	¡ | j 
d¡ |  |j	¡ dS )zŒ
        Test that the transport can set the running service and dispatches
        packets to the service's packetReceived method.
        rn   rF   r  N)rl   r™   Ú
setServicerÈ   r-   rÑ   rq   rž   r”   rs   ÚconnectionLost)r   r-   Zservice2r   r   r   Útest_service“  s    z"BaseSSHTransportTests.test_servicec                    s@   dg‰ ‡ fdd„}|| j _d| j _| j  d¡ |  ˆ d ¡ dS )zP
        Test that the transport notifies the avatar of disconnections.
        Fc                      s   dˆ d< d S r  r   r   r  r   r   Úlogout­  s    z1BaseSSHTransportTests.test_avatar.<locals>.logoutTNr   )r™   ZlogoutFunctionZavatarr)  rÑ   )r   r+  r   r  r   Útest_avatar¨  s    z!BaseSSHTransportTests.test_avatarc                 C   sÖ   |   | j d¡¡ |   | j d¡¡ |   | j d¡¡ tƒ | j_|  | j d¡¡ |  | j d¡¡ |  | j d¡¡ t dddd¡| j_|   | j d¡¡ |   | j d¡¡ |   | j d¡¡ |  t	| jjd¡ dS )zS
        Test that the transport accurately reflects its encrypted status.
        ÚinÚoutÚbothr¸   ÚbadN)
rÐ   r™   ÚisEncryptedrE   rÚ   rÑ   r   ró   r  Ú	TypeErrorr8   r   r   r   Útest_isEncrypted¶  s    
 ÿz&BaseSSHTransportTests.test_isEncryptedc                 C   sÖ   |   | j d¡¡ |   | j d¡¡ |   | j d¡¡ tƒ | j_|  | j d¡¡ |  | j d¡¡ |  | j d¡¡ t dddd¡| j_|   | j d¡¡ |   | j d¡¡ |   | j d¡¡ |  t	| jjd¡ dS )zR
        Test that the transport accurately reflects its verified status.
        r-  r.  r/  r¸   r0  N)
rÐ   r™   Ú
isVerifiedrE   rÚ   rÑ   r   ró   r  r2  r8   r   r   r   Útest_isVerifiedÊ  s    
 ÿz%BaseSSHTransportTests.test_isVerifiedc                    sd   dg‰ ‡ fdd„}|| j _| j ¡  |  | jd d t j¡ |  | jd d dd… tt jƒ¡ dS )	zh
        Test that loseConnection sends a disconnect message and closes the
        connection.
        Fc                      s   dˆ d< d S r  r   r   r  r   r   r  ä  s    zEBaseSSHTransportTests.test_loseConnection.<locals>.stubLoseConnectionr   rH   r‚   é   N)r   r  r™   rÈ   r”   r  rU   ÚDISCONNECT_CONNECTION_LOSTr  r   r  r   Útest_loseConnectionÞ  s    
ÿz)BaseSSHTransportTests.test_loseConnectionc                    s(   ‡ fdd„}|dƒ |dƒ |dƒ dS )zU
        Test that the transport disconnects when it receives a bad version.
        c                    s”   g ˆ_ dˆj_dg‰ ‡ fdd„}|ˆj_t| d ƒD ]}ˆj |¡ q4ˆ ˆ d ¡ ˆ ˆj d d tj	¡ ˆ ˆj d d dd… t
tjƒ¡ d S )	NFc                      s   dˆ d< d S r  r   r   r  r   r   r  õ  s    zRBaseSSHTransportTests.test_badVersion.<locals>.testBad.<locals>.stubLoseConnectionr»   r   rH   r‚   r6  )r”   r™   r$  r   r  r*   r   rÑ   rÈ   r  rU   Z)DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED)rÎ   r  rÄ   r8   r  r   ÚtestBadñ  s    þz6BaseSSHTransportTests.test_badVersion.<locals>.testBads   SSH-1.5-OpenSSHs   SSH-3.0-Twisteds   GET / HTTP/1.1Nr   )r   r9  r   r8   r   Útest_badVersioní  s    z%BaseSSHTransportTests.test_badVersionc                    sX   t ƒ ‰ ˆ  t ¡ ¡ dˆ j d }‡ fdd„t|ƒD ƒ |  ˆ j¡ |  ˆ j	ˆ j¡ dS )zV
        Test that the transport ignores data sent before the version string.
        s5   here's some stuff beforehand
here's some other stuff
r»   c                    s   g | ]}ˆ   |¡‘qS r   )r   rÂ   ©r™   r   r   Ú
<listcomp>  s     z@BaseSSHTransportTests.test_dataBeforeVersion.<locals>.<listcomp>N)
r1   rš   r/   r—   r%  r*   rÑ   r$  rÈ   r&  ©r   Údatar   r;  r   Útest_dataBeforeVersion  s    þþz,BaseSSHTransportTests.test_dataBeforeVersionc                 C   s<   t ƒ }| t ¡ ¡ | d¡ |  |j¡ |  |jd¡ dS )zw
        Test that the transport treats the compatibility version (1.99)
        as equivalent to version 2.0.
        s   SSH-1.99-OpenSSH
s   SSH-1.99-OpenSSHN©	r1   rš   r/   r—   r   rÑ   r$  rÈ   r&  r£   r   r   r   Útest_compatabilityVersion  s
    
z/BaseSSHTransportTests.test_compatabilityVersionc                 C   s<   t ƒ }| t ¡ ¡ | d¡ |  |j¡ |  |jd¡ dS )zµ
        It can parse the SSH version string even when it ends only in
        Unix newlines (CR) and does not follows the RFC 4253 to use
        network newlines (CR LF).
        s,   SSH-2.0-PoorSSHD Some-comment here
more-datas"   SSH-2.0-PoorSSHD Some-comment hereNr@  rÒ   r   r   r   Ú&test_dataReceivedSSHVersionUnixNewline  s    ÿþz<BaseSSHTransportTests.test_dataReceivedSSHVersionUnixNewlinec                 C   s<   t ƒ }| t ¡ ¡ | d¡ |  |j¡ |  |jd¡ dS )a9  
        The trailing spaces from SSH version comment are not removed.

        The SSH version string needs to be kept as received
        (without CR LF end of line) as they are used in the host
        authentication process.

        This can happen with a Bitvise SSH server which hides its version.
        s>   SSH-2.0-9.99 FlowSsh: Bitvise SSH Server (WinSSHD) 
more-datas3   SSH-2.0-9.99 FlowSsh: Bitvise SSH Server (WinSSHD) Nr@  rÒ   r   r   r   Ú)test_dataReceivedSSHVersionTrailingSpaces2  s    
ÿþz?BaseSSHTransportTests.test_dataReceivedSSHVersionTrailingSpacesc                 C   s4   t ƒ }d|_| t ¡ ¡ | d¡ |  |j¡ dS )z•
        If an unusual SSH version is received and is included in
        C{supportedVersions}, an unsupported version error is not emitted.
        )ó   9.99ó   SSH-9.99-OpenSSH
N)r1   ÚsupportedVersionsrš   r/   r—   r   rÐ   r7   r£   r   r   r   Ú test_supportedVersionsAreAllowedJ  s
    
z6BaseSSHTransportTests.test_supportedVersionsAreAllowedc                 C   s6   t ƒ }d|_| t ¡ ¡ | d¡ |  d|j¡ dS )z•
        If an unusual SSH version is received and is not included in
        C{supportedVersions}, an unsupported version error is emitted.
        )s   2.0rE  rD  N)r1   rF  rš   r/   r—   r   rÈ   r7   r£   r   r   r   Ú6test_unsupportedVersionsCallUnsupportedVersionReceivedV  s
    
zLBaseSSHTransportTests.test_unsupportedVersionsCallUnsupportedVersionReceivedc                    s’   t jf‡ fdd„	}|dƒ |dƒ ˆ jj}tƒ ˆ j_|dt jƒ dd„ ˆ jj_|dƒ |ˆ j_tƒ ˆ j_d	d
„ }|ˆ jj_	|dt j
ƒ ˆ  ¡  dS )zi
        Test that the transport disconnects with an error when it receives
        bad packets.
        c                    sn   g ˆ _ | ˆ j_ˆ  ˆ j ¡ ¡ ˆ  tˆ j ƒd¡ ˆ  ˆ j d d tj¡ ˆ  ˆ j d d dd… t	|ƒ¡ d S )NrH   r   r‚   r6  )
r”   r™   râ   ré   rã   rÈ   rK   r   r  rU   )rB   Úerrorr8   r   r   r9  g  s    z6BaseSSHTransportTests.test_badPackets.<locals>.testBads   ÿÿÿÿÿÿÿÿs	       BCDEs      AB123456c                 S   s   | d d… S rc   r   )rO   r   r   r   rå   u  r   z7BaseSSHTransportTests.test_badPackets.<locals>.<lambda>s      BCDEFGHIJKc                 S   s   t dƒ‚d S )Nzbad compression)Ú	Exception)rW   r   r   r   ÚstubDecompressy  s    z=BaseSSHTransportTests.test_badPackets.<locals>.stubDecompresss	       BCDEN)r   ÚDISCONNECT_PROTOCOL_ERRORr™   rÚ   rE   ZDISCONNECT_MAC_ERRORrS   rb   rì   rg   ZDISCONNECT_COMPRESSION_ERRORZflushLoggedErrors)r   r9  ZoldEncryptionsrK  r   r8   r   Útest_badPacketsb  s$    
ÿ

ÿz%BaseSSHTransportTests.test_badPacketsc                    s˜   ˆ j j}|f‡ fdd„	}ˆ j  dd¡ |ƒ  dtjd< ˆ j  dd¡ |ƒ  ˆ j  dd¡ |ƒ  ˆ j  tƒ ¡ ˆ j  dd¡ |ƒ  ˆ j  d	d¡ |ƒ  d
S )zj
        Test that unimplemented packet types cause MSG_UNIMPLEMENTED packets
        to be sent.
        c                    sN   ˆ   ˆ jd d tj¡ ˆ   ˆ jd d dd… t| ƒ¡ g ˆ j_| d7 } d S )Nr   rH   r‚   r6  )rÈ   r”   r   r  rU   r™   )r=   r8   r   r   ÚcheckUnimplemented‡  s    ÿ"zKBaseSSHTransportTests.test_unimplementedPackets.<locals>.checkUnimplementedé(   r   s   MSG_fictioné)   é<   éF   ro   N)r™   rY   rž   r   Zmessagesr(  rl   )r   r=   rN  r   r8   r   Útest_unimplementedPackets  s    
z/BaseSSHTransportTests.test_unimplementedPacketsc                 C   s¼   | j }| | j ¡ ¡ tƒ |_tƒ |_tƒ |_| 	t
ƒ ¡ tƒ }| t ¡ ¡ | d¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ dS )zD
        Test that multiple instances have distinct states.
        r   N)r™   r   r   rÆ   rE   rÚ   rb   rß   rì   r(  rl   r1   rš   r/   r—   r  ZassertNotEqualr$  rV   rY   r-   )r   r™   Úproto2r   r   r   Útest_multipleClassesœ  s*    
ÿÿÿz*BaseSSHTransportTests.test_multipleClassesN)1r   r   r   rD   r¨   r©   r   r   r    rÏ   rÓ   rØ   rÝ   rà   rá   rä   rë   rí   rî   rù   r  r  r  r  r  r  r  r  r  r  r  r  r   r'  r*  r,  r3  r5  r8  r:  r?  rA  rB  rC  rG  rH  rM  rS  rU  r   r   r   r   r´   µ  sŠ   ÿþýüûúùø	÷
öõõÿ
)
%	
r´   c                   @   s   e Zd ZdZdd„ ZdS )Ú'BaseSSHTransportDHGroupExchangeBaseCasez@
    Diffie-Hellman group exchange tests for TransportBase.
    c                 C   sZ   | j | j_d| j_|  d| jj ¡ ¡ }|  d| ¡ ¡ }|  | j ddd¡|| ¡ dS )z?
        Test that _getKey generates the correct keys.
        ó   EFs   ABCDKrç   ó   Kó   ABó   CDN)r¬   r™   ÚkexAlgÚ	sessionIDr­   ÚdigestrÈ   Ú_getKey)r   Zk1Zk2r   r   r   Útest_getKeyº  s    

ÿz3BaseSSHTransportDHGroupExchangeBaseCase.test_getKeyN)r   r   r   rD   r_  r   r   r   r   rV  µ  s   rV  c                   @   s   e Zd ZdZdS )Ú(BaseSSHTransportDHGroupExchangeSHA1TestszE
    diffie-hellman-group-exchange-sha1 tests for TransportBase.
    N©r   r   r   rD   r   r   r   r   r`  È  s   r`  c                   @   s   e Zd ZdZdS )Ú*BaseSSHTransportDHGroupExchangeSHA256TestszG
    diffie-hellman-group-exchange-sha256 tests for TransportBase.
    Nra  r   r   r   r   rb  Ñ  s   rb  c                   @   s   e Zd ZdZdS )Ú"BaseSSHTransportEllipticCurveTestsz4
    ecdh-sha2-nistp256 tests for TransportBase
    Nra  r   r   r   r   rc  Ú  s   rc  c                   @   s\   e Zd ZdZddd„Zddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )Ú#ServerAndClientSSHTransportBaseCasezF
    Tests that need to be run on both the server and the client.
    Nc                 C   sL   |dkrt j}|  | jd d t j¡ |  | jd d dd… t|ƒ¡ dS )zI
        Helper function to check if the transport disconnected.
        Nrd   r   rH   r‚   r6  )r   rL  rÈ   r”   r  rU   ri   r   r   r   ÚcheckDisconnectedè  s    z5ServerAndClientSSHTransportBaseCase.checkDisconnectedc                 C   sP   |dkrt j}|  ¡ }||ƒ | t ¡ ¡ | j |j  ¡ ¡ |rL|  	|¡ |S )zy
        Helper function to connect a modified protocol to the test protocol
        and test for disconnection.
        N)
r   ÚDISCONNECT_KEY_EXCHANGE_FAILEDr˜   rš   r/   r—   r™   r   rÆ   re  )r   ZprotoModificationrj   rT  r   r   r   ÚconnectModifiedProtocolò  s    
z;ServerAndClientSSHTransportBaseCase.connectModifiedProtocolc                 C   s   dd„ }|   |¡ dS )z`
        Test that the transport disconnects if it can't match the key
        exchange
        c                 S   s
   g | _ d S r“   ©rý   ©rT  r   r   r   ÚblankKeyExchanges  s    z\ServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchKex.<locals>.blankKeyExchangesN©rg  )r   rj  r   r   r   Útest_disconnectIfCantMatchKex  s    zAServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchKexc                 C   s   dd„ }|   |¡ dS )zP
        Like test_disconnectIfCantMatchKex, but for the key algorithm.
        c                 S   s
   g | _ d S r“   )rþ   ri  r   r   r   ÚblankPublicKeys  s    z]ServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchKeyAlg.<locals>.blankPublicKeysNrk  )r   rm  r   r   r   Ú test_disconnectIfCantMatchKeyAlg  s    zDServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchKeyAlgc                 C   s   dd„ }|   |¡ dS )zN
        Like test_disconnectIfCantMatchKex, but for the compression.
        c                 S   s
   g | _ d S r“   ©r   ri  r   r   r   ÚblankCompressions  s    zdServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchCompression.<locals>.blankCompressionsNrk  )r   rp  r   r   r   Ú%test_disconnectIfCantMatchCompression  s    zIServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchCompressionc                 C   s   dd„ }|   |¡ dS )zM
        Like test_disconnectIfCantMatchKex, but for the encryption.
        c                 S   s
   g | _ d S r“   ©rô   ri  r   r   r   ÚblankCiphers#  s    zZServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchCipher.<locals>.blankCiphersNrk  )r   rs  r   r   r   Ú test_disconnectIfCantMatchCipher  s    zDServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchCipherc                 C   s   dd„ }|   |¡ dS )zF
        Like test_disconnectIfCantMatchKex, but for the MAC.
        c                 S   s
   g | _ d S r“   ©rÿ   ri  r   r   r   Ú	blankMACs,  s    zTServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchMAC.<locals>.blankMACsNrk  )r   rv  r   r   r   Útest_disconnectIfCantMatchMAC(  s    zAServerAndClientSSHTransportBaseCase.test_disconnectIfCantMatchMACc                 C   s$   |   | j ¡ t | jj ¡ ¡¡ dS )z‰
        Test that the transport's L{getPeer} method returns an
        L{SSHTransportAddress} with the L{IAddress} of the peer.
        N)rÈ   r™   ZgetPeerr,   ÚSSHTransportAddressr   r8   r   r   r   Útest_getPeer1  s
    
ÿÿz0ServerAndClientSSHTransportBaseCase.test_getPeerc                 C   s$   |   | j ¡ t | jj ¡ ¡¡ dS )z‰
        Test that the transport's L{getHost} method returns an
        L{SSHTransportAddress} with the L{IAddress} of the host.
        N)rÈ   r™   ZgetHostr,   rx  r   r8   r   r   r   Útest_getHost;  s
    
ÿÿz0ServerAndClientSSHTransportBaseCase.test_getHost)N)N)r   r   r   rD   re  rg  rl  rn  rq  rt  rw  ry  rz  r   r   r   r   rd  ã  s   
 ÿ

				
rd  c                   @   s&   e Zd ZdZejZdd„ Zdd„ ZdS )ÚServerSSHTransportBaseCasez1
    Base case for SSHServerTransport tests.
    c                 C   s$   t  | ¡ tƒ | j_| jj ¡  d S r“   )r   r›   rx   r™   r
   ÚstartFactoryr8   r   r   r   r›   N  s    

z ServerSSHTransportBaseCase.setUpc                 C   s    t  | ¡ | jj ¡  | j`d S r“   )r   ÚtearDownr™   r
   ZstopFactoryr8   r   r   r   r}  T  s    
z#ServerSSHTransportBaseCase.tearDownN)	r   r   r   rD   r   r   r˜   r›   r}  r   r   r   r   r{  F  s   r{  c                   @   sx   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚServerSSHTransportTestsz'
    Tests for SSHServerTransport.
    c                 C   s   | j  d¡ |  | j jd¡ |  | j jd¡ |  | j jd¡ |  | j jd¡ | j j}|  |jd¡ |  |j	d¡ |  |j
d¡ |  |jd¡ dS )z°
        Receiving a KEXINIT packet listing multiple supported algorithms will
        set up the first common algorithm found in the client's preference
        list.
        s	  SSH-2.0-Twisted
  ô™™™™™™™™™™™™™™™™   bdiffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256   ssh-dss,ssh-rsa   …aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc   …aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc   hmac-md5,hmac-sha1   hmac-md5,hmac-sha1   	none,zlib   	none,zlib             ™™™™r«   s   ssh-dssr¸   s
   aes128-ctró   hmac-md5N©r™   r   rÈ   r[  ÚkeyAlgÚoutgoingCompressionTypeÚincomingCompressionTyper	  r\   r]   r_   r^   ©r   Úner   r   r   Útest_KEXINITMultipleAlgorithms`  s(    ÿ
ÿ
ÿ
ÿ
ÿz6ServerSSHTransportTests.test_KEXINITMultipleAlgorithmsc                 C   sü   dd  dd„ dd„ | jjddd… | jj| jj| jj| jj| jj| jj| jj| jj| jjf
D ƒD ƒ¡ d }| j |¡ |  	| jj
¡ | j d	¡ |  	| jj
¡ | j d
¡ |  | jj
¡ |  | jg ¡ d| j_
| j d¡ |  | jj
¡ |  | jg ¡ dS )a<  
        The client is allowed to send a guessed key exchange packet
        after it sends the KEXINIT packet.  However, if the key exchanges
        do not match, that guess packet must be ignored.  This tests that
        the packet is ignored in the case of the key exchange method not
        matching.
        rò   r   c                 S   s   g | ]}t  |¡‘qS r   ©r   r   ©rÃ   rO   r   r   r   r<    s     zEServerSSHTransportTests.test_ignoreGuessPacketKex.<locals>.<listcomp>c                 S   s   g | ]}d   |¡‘qS ©rü   ©rÌ   ©rÃ   Úyr   r   r   r<    s     Nrd   ó   ÿ    ó      test    ó      Tó            ©rÌ   r™   rý   rþ   rô   rÿ   r   r  r#  rÑ   ZignoreNextPacketZ	ssh_DEBUGÚssh_KEX_DH_GEX_REQUEST_OLDrÐ   rÈ   r”   Ússh_KEX_DH_GEX_REQUEST©r   ZkexInitPacketr   r   r   Útest_ignoreGuessPacketKex†  s<    
÷ÿÿÿóz1ServerSSHTransportTests.test_ignoreGuessPacketKexc                 C   sü   dd  dd„ dd„ | jj| jjddd… | jj| jj| jj| jj| jj| jj| jj| jjf
D ƒD ƒ¡ d }| j |¡ |  	| jj
¡ | j d	¡ |  	| jj
¡ | j d
¡ |  | jj
¡ |  | jg ¡ d| j_
| j d¡ |  | jj
¡ |  | jg ¡ dS )zk
        Like test_ignoreGuessPacketKex, but for an incorrectly guessed
        public key format.
        rò   r   c                 S   s   g | ]}t  |¡‘qS r   r‡  rˆ  r   r   r   r<  ±  s     zEServerSSHTransportTests.test_ignoreGuessPacketKey.<locals>.<listcomp>c                 S   s   g | ]}d   |¡‘qS r‰  rŠ  r‹  r   r   r   r<  ²  s     Nrd   r  rŽ  r  Tr  r‘  r”  r   r   r   Útest_ignoreGuessPacketKey«  s<    
÷ÿÿÿóz1ServerSSHTransportTests.test_ignoreGuessPacketKeyc                 C   s`  |g| j _dg| j _| j  | j ¡ ¡ t |¡\}}t|d|ƒ}| j  	t
 |¡¡ t
 d¡d }t
 | j j|| j j¡}t
 ||| j j¡}tƒ }| t
 | j j¡d ¡ | t
 | j j¡d ¡ | t
 | j jjd  ¡ ¡¡ | t
 |¡¡ | |¡ | |¡ | ¡ }	| j jjd  |	¡}
|  | jtjt
 | j jjd  ¡ ¡| t
 |
¡ ftjdfg¡ dS )zó
        Test that the KEXDH_INIT packet causes the server to send a
        KEXDH_REPLY with the server's public key and a signature.

        @param kexAlgorithm: The key exchange algorithm to use.
        @type kexAlgorithm: L{str}
        r{   iˆ  sD      @™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™r   r  r   N)r™   rý   rþ   r   r   rÆ   r.   r‡   Úpowr’  r   ÚMPÚgetMPÚ_MPpowÚgÚpr   Úupdater   r%  ÚourKexInitPayloadr
   Ú
publicKeysrŒ   r]  ÚprivateKeysÚsignrÈ   r”   ZMSG_KEXDH_REPLYÚMSG_NEWKEYS)r   r¬   r›  rœ  ÚerŒ  Úfr¥   Úhr¦   Ú	signaturer   r   r   ÚassertKexDHInitResponseÍ  s@    



ÿÿÿÿýþz/ServerSSHTransportTests.assertKexDHInitResponsec                 C   s,   d| j _d| j _|  t| j jt d¡¡ dS )ú
        Test that if the server receives a KEX_DH_GEX_REQUEST_OLD message
        and the key exchange algorithm is not set, we raise a ConchError.
        s	   bad-curver{   s
   unused-keyN)r™   r[  r  r  r   Z_ssh_KEX_ECDH_INITr   r   r8   r   r   r   Ú%test_checkBad_KEX_ECDH_INIT_CurveNameõ  s    þz=ServerSSHTransportTests.test_checkBad_KEX_ECDH_INIT_CurveNamec                 C   s”   dt  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ d d	 }| j |¡ |  t¡ |  t¡ d
S )zy
        Test that if the server received a bad name for a curve
        we raise an UnsupportedAlgorithm error.
        rµ   r²   r{   r¶   r·   r¸   r   r¹   rº   N)r   r   r™   r#  r  ÚAttributeErrorr   )r   Úkexmsgr   r   r   Ú test_checkBad_KEX_INIT_CurveName  s:    ÿþýüûúùø	÷
öõõÿ
z8ServerSSHTransportTests.test_checkBad_KEX_INIT_CurveNamec                 C   s   |   d¡ dS )z…
        KEXDH_INIT messages are processed when the
        diffie-hellman-group14-sha1 key exchange algorithm is requested.
        rƒ   N)r§  r8   r   r   r   Útest_KEXDH_INIT_GROUP14  s    z/ServerSSHTransportTests.test_KEXDH_INIT_GROUP14c              
      s²   dˆ j _tƒ ˆ j _ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  ˆ jd tj	df¡ ‡ fdd„t
d	ƒD ƒ}ˆ  ˆ j jj|d
 |d |d |d |d |d f¡ dS )úG
        Test that _keySetup sets up the next encryption keys.
        rƒ   rY  rZ  rW  rd   r   c                    s   g | ]}ˆ j  |d d¡‘qS ©rY  rW  ©r™   r^  rÂ   r8   r   r   r<  ,  s   ÿz9ServerSSHTransportTests.test_keySetup.<locals>.<listcomp>ó   ABCDEFrH   r‚   r   r  r„   r6  N©r™   r[  rE   r	  r§   rÈ   r\  r”   r   r¢  r*   r	   ©r   ZnewKeysr   r8   r   Útest_keySetup!  s     

ÿÿþz%ServerSSHTransportTests.test_keySetupc              
      s²   dˆ j _tƒ ˆ j _ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  ˆ jd tj	df¡ ‡ fdd„t
d	ƒD ƒ}ˆ  ˆ j jj|d
 |d |d |d |d |d f¡ dS )r®  r²   rY  rZ  rW  rd   r   c                    s   g | ]}ˆ j  |d d¡‘qS r¯  r°  rÂ   r8   r   r   r<  ?  s   ÿz>ServerSSHTransportTests.test_ECDH_keySetup.<locals>.<listcomp>r±  rH   r‚   r   r  r„   r6  Nr²  r³  r   r8   r   Útest_ECDH_keySetup4  s     

ÿÿþz*ServerSSHTransportTests.test_ECDH_keySetupc                 C   s¸   |   ¡  t dddd¡| j_| j d¡ |  | jj| jj¡ |  | jj	¡ |  | jj
¡ d| j_|  dd¡ | j d¡ |  | jj	¡ d| j_|  dd¡ | j d¡ |  | jj
¡ dS )zj
        Test that NEWKEYS transitions the keys in nextEncryptions to
        currentEncryptions.
        r¸   r   ó   zlibrY  rZ  rW  N)r†  r   ró   r™   r	  Ússh_NEWKEYSÚassertIsrÚ   ré   rß   rì   r‚  r§   ÚassertIsNotNonerƒ  r8   r   r   r   Útest_NEWKEYSG  s&     ÿ
ÿz$ServerSSHTransportTests.test_NEWKEYSc                 C   sD   | j  t d¡¡ |  | jtjt d¡fg¡ |  | j jj	d¡ dS )z^
        Test that the SERVICE_REQUEST message requests and starts a
        service.
        ry   rm   N)
r™   Ússh_SERVICE_REQUESTr   r   rÈ   r”   r   ZMSG_SERVICE_ACCEPTr-   rw   r8   r   r   r   Útest_SERVICE_REQUEST_  s
    ÿz,ServerSSHTransportTests.test_SERVICE_REQUESTc                 C   s   | j  d¡ |  ¡  dS ©zD
        Test that NEWKEYS disconnects if it receives data.
        s
   bad packetN©r™   r·  re  r8   r   r   r   Útest_disconnectNEWKEYSDataj  s    z2ServerSSHTransportTests.test_disconnectNEWKEYSDatac                 C   s"   | j  t d¡¡ |  tj¡ dS )zd
        Test that SERVICE_REQUESTS disconnects if an unknown service is
        requested.
        s
   no serviceN)r™   r»  r   r   re  r   Z DISCONNECT_SERVICE_NOT_AVAILABLEr8   r   r   r   Ú(test_disconnectSERVICE_REQUESTBadServicer  s    z@ServerSSHTransportTests.test_disconnectSERVICE_REQUESTBadServiceN)r   r   r   rD   r†  r•  r–  r§  r©  r¬  r­  r´  rµ  rº  r¼  r¿  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 )Ú)ServerSSHTransportDHGroupExchangeBaseCasezE
    Diffie-Hellman group exchange tests for SSHServerTransport.
    c                 C   s’   | j g| j_dg| j_| j | j ¡ ¡ | j d¡ | jj 	¡  
d¡d \}}|  | jtjt |¡d fg¡ |  | jjd¡ |  | jj|¡ dS )z°
        Test that the KEX_DH_GEX_REQUEST_OLD message causes the server
        to reply with a KEX_DH_GEX_GROUP message with the correct
        Diffie-Hellman group.
        r{   ó      r†   r   ó      r‚   N)r¬   r™   rý   rþ   r   r   rÆ   r’  r
   rˆ   ÚgetrÈ   r”   ÚMSG_KEX_DH_GEX_GROUPr   r˜  r›  rœ  ©r   ZdhGeneratorZdhPrimer   r   r   Útest_KEX_DH_GEX_REQUEST_OLD  s    
ÿþzEServerSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_REQUEST_OLDc                 C   s   d| j _|  t| j jd¡ dS )r¨  N)r™   r[  r  r0   r’  r8   r   r   r   Ú%test_KEX_DH_GEX_REQUEST_OLD_badKexAlg”  s    ÿzOServerSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_REQUEST_OLD_badKexAlgc                 C   s’   | j g| j_dg| j_| j | j ¡ ¡ | j d¡ | jj 	¡  
d¡d \}}|  | jtjt |¡d fg¡ |  | jjd¡ |  | jj|¡ dS )z¬
        Test that the KEX_DH_GEX_REQUEST message causes the server to reply
        with a KEX_DH_GEX_GROUP message with the correct Diffie-Hellman
        group.
        r{   ó            r†   r   rÃ  r‚   N)r¬   r™   rý   rþ   r   r   rÆ   r“  r
   rˆ   rÄ  rÈ   r”   rÅ  r   r˜  r›  rœ  rÆ  r   r   r   Útest_KEX_DH_GEX_REQUESTž  s    
ÿþzAServerSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_REQUESTc              
   C   st  |   ¡  t| jjd| jjƒ}t d¡d }t | jj|| jj¡}t ||| jj¡}|  ¡ }| 	t 
| jj¡d ¡ | 	t 
| jj¡d ¡ | 	t 
| jjjd  ¡ ¡¡ | 	d¡ | 	t | jj¡¡ | 	t | jj¡¡ | 	t |¡¡ | 	|¡ | 	|¡ | ¡ }| j t |¡¡ |  | jdd… tjt 
| jjjd  ¡ ¡| t 
| jjjd  |¡¡ ftjd	fg¡ dS )
zÊ
        Test that the KEX_DH_GEX_INIT message after the client sends
        KEX_DH_GEX_REQUEST_OLD causes the server to send a KEX_DH_GEX_INIT
        message with a public key and signature.
        r‚   ó     ™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™r   r  r{   rÂ  rH   Nr   )rÇ  r—  r™   r›  rœ  r   r™  rš  r­   r  r   r%  rž  r
   rŸ  rŒ   r˜  r]  Ússh_KEX_DH_GEX_INITrÈ   r”   r   ÚMSG_KEX_DH_GEX_REPLYr   r¡  r¢  ©r   r£  rŒ  r¤  r¥   r¥  r¦   r   r   r   Ú&test_KEX_DH_GEX_INIT_after_REQUEST_OLD²  s>    


ÿÿÿÿüþzPServerSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_INIT_after_REQUEST_OLDc              
   C   sf  |   ¡  t| jjd| jjƒ}t d¡d }t | jj|| jj¡}t ||| jj¡}|  ¡ }| 	t 
| jj¡d ¡ | 	t 
| jj¡d ¡ | 	t 
| jjjd  ¡ ¡¡ | 	d¡ | 	t | jj¡¡ | 	t | jj¡¡ | 	t |¡¡ | 	|¡ | 	|¡ | ¡ }| j t |¡¡ |  | jd tjt 
| jjjd  ¡ ¡| t 
| jjjd  |¡¡ f¡ dS )	zÆ
        Test that the KEX_DH_GEX_INIT message after the client sends
        KEX_DH_GEX_REQUEST causes the server to send a KEX_DH_GEX_INIT message
        with a public key and signature.
        r‚   rË  r   r  r{   rÉ  rH   N)rÊ  r—  r™   r›  rœ  r   r™  rš  r­   r  r   r%  rž  r
   rŸ  rŒ   r˜  r]  rÌ  rÈ   r”   r   rÍ  r   r¡  rÎ  r   r   r   Ú"test_KEX_DH_GEX_INIT_after_REQUESTÒ  s:    


ÿÿÿÿþzLServerSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_INIT_after_REQUESTN)	r   r   r   rD   rÇ  rÈ  rÊ  rÏ  rÐ  r   r   r   r   rÁ  |  s   
 rÁ  c                   @   s   e Zd ZdZdS )Ú*ServerSSHTransportDHGroupExchangeSHA1TestszJ
    diffie-hellman-group-exchange-sha1 tests for SSHServerTransport.
    Nra  r   r   r   r   rÑ  ô  s   rÑ  c                   @   s   e Zd ZdZdS )Ú,ServerSSHTransportDHGroupExchangeSHA256TestszL
    diffie-hellman-group-exchange-sha256 tests for SSHServerTransport.
    Nra  r   r   r   r   rÒ  ý  s   rÒ  c                   @   s&   e Zd ZdZejZdd„ Zdd„ ZdS )ÚClientSSHTransportBaseCasez1
    Base case for SSHClientTransport tests.
    c                 C   s@   d| _ |  || j¡ |  | dd¡t t|ƒ ¡ ¡¡ t 	d¡S )zC
        Mock version of SSHClientTransport.verifyHostKey.
        Tó   :r   )
ÚcalledVerifyHostKeyrÈ   rŒ   ÚreplaceÚbinasciiÚhexlifyr   r]  r%   Úsucceed)r   ZpubKeyZfingerprintr   r   r   ÚverifyHostKey  s    ÿz(ClientSSHTransportBaseCase.verifyHostKeyc                 C   sB   t  | ¡ tj tj¡ ¡ | _tj tj¡| _	d| _
| j| j_d S )NF)r   r›   r	   r|   r}   r   r~   rŒ   r€   ÚprivObjrÕ  rÚ  r™   r8   r   r   r   r›     s
    
z ClientSSHTransportBaseCase.setUpN)	r   r   r   rD   r   r   r˜   rÚ  r›   r   r   r   r   rÓ    s   rÓ  c                   @   sˆ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd S )!ÚClientSSHTransportTestsz'
    Tests for SSHClientTransport.
    c                 C   s   | j  d¡ |  | j jd¡ |  | j jd¡ |  | j jd¡ |  | j jd¡ | j j}|  |jd¡ |  |j	d¡ |  |j
d¡ |  |jd¡ dS )z¨
        Receiving a KEXINIT packet listing multiple supported
        algorithms will set up the first common algorithm, ordered after our
        preference.
        s	  SSH-2.0-Twisted
  ô™™™™™™™™™™™™™™™™   bdiffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256   ssh-dss,ssh-rsa   …aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc   …aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc   hmac-md5,hmac-sha1   hmac-md5,hmac-sha1   	zlib,none   	zlib,none             ™™™™r¯   r{   r¸   r¶   r·   Nr€  r„  r   r   r   r†  '  s(    ÿ
ÿ
ÿ
ÿ
ÿz6ClientSSHTransportTests.test_KEXINITMultipleAlgorithmsc                 C   s<   |   t|  ¡ j¡ dd„ }|  ¡  dd¡}| | j¡ |¡S )z´
        verifyHostKey() should return a Deferred which fails with a
        NotImplementedError exception.  connectionSecure() should raise
        NotImplementedError().
        c                 S   s   |   t¡ d S r“   )ZtrapÚNotImplementedError)r¤  r   r   r   Ú_checkRaisesT  s    zNClientSSHTransportTests.test_notImplementedClientMethods.<locals>._checkRaisesN)r  rÝ  r˜   ÚconnectionSecurerÚ  ÚaddCallbackZfailZ
addErrback)r   rÞ  Údr   r   r   Ú test_notImplementedClientMethodsM  s    z8ClientSSHTransportTests.test_notImplementedClientMethodsc                 C   sX   |g| j _| j  | j ¡ ¡ |  t | j j¡dd… d¡ |  | j	tj
| j jfg¡ dS )zç
        Test that a KEXINIT packet with a group1 or group14 key exchange
        results in a correct KEXDH_INIT response.

        @param kexAlgorithm: The key exchange algorithm to use
        @type kexAlgorithm: L{str}
        r„   Ns@   ™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™)r™   rý   r   r   rÆ   rÈ   r   r˜  rO   r”   ZMSG_KEXDH_INITr£  )r   r¬   r   r   r   ÚassertKexInitResponseForDHZ  s    
 ÿz2ClientSSHTransportTests.assertKexInitResponseForDHc                 C   s   |   d¡ dS )zq
        KEXINIT messages requesting diffie-hellman-group14-sha1 result in
        KEXDH_INIT responses.
        rƒ   N)rã  r8   r   r   r   Útest_KEXINIT_group14p  s    z,ClientSSHTransportTests.test_KEXINIT_group14c                 C   s2   dg| j _| j ¡  dd¡}|  t| j j|¡ dS )z©
        Test that the client raises a ConchError if it receives a
        KEXINIT message but doesn't have a key exchange algorithm that we
        understand.
        s   diffie-hellman-group24-sha1s   group14s   group24N)r™   rý   r   rÆ   rÖ  r  r0   r   r=  r   r   r   Útest_KEXINIT_badKexAlgx  s    
z.ClientSSHTransportTests.test_KEXINIT_badKexAlgc                    sÞ   ˆ  ¡  t ˆjjˆjjˆjj¡}tƒ }| t 	ˆjj
¡d ¡ | t 	ˆjj¡d ¡ | t 	ˆj¡¡ | ˆjj¡ | d¡ | |¡ | ¡ ‰ ‡ ‡fdd„}ˆj ˆ ¡}ˆj t 	ˆj¡d t 	|¡ ¡}| |¡ |S )zH
        Test that the KEXDH_REPLY message verifies the server.
        r  s      c                    s*   ˆ  | ¡ ˆ ˆj¡ ˆ ˆjjˆ ¡ d S r“   ©ré   rÑ   rÕ  rÈ   r™   r\  ©rÆ   ©r¦   r   r   r   Ú_cbTestKEXDH_REPLY”  s    
zDClientSSHTransportTests.test_KEXDH_REPLY.<locals>._cbTestKEXDH_REPLY)rä  r   rš  r™   r›  rO   rœ  r   r  r   r%  rž  rŒ   r£  r]  rÛ  r¡  Ússh_KEX_DH_GEX_GROUPrà  )r   r¥   r¥  ré  r¦  rá  r   rè  r   Útest_KEXDH_REPLYƒ  s*    ÿ

ÿÿ
z(ClientSSHTransportTests.test_KEXDH_REPLYc              
      s²   dˆ j _tƒ ˆ j _ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  dd¡ ˆ  ˆ j jd¡ ˆ  ˆ jd tj	df¡ ‡ fdd„t
d	ƒD ƒ}ˆ  ˆ j jj|d
 |d |d |d |d |d f¡ dS )r®  rƒ   rY  rZ  rW  rd   r   c                    s   g | ]}ˆ j  |d d¡‘qS r¯  r°  rÂ   r8   r   r   r<  ®  s   ÿz9ClientSSHTransportTests.test_keySetup.<locals>.<listcomp>r±  r   r  rH   r‚   r6  r„   Nr²  r³  r   r8   r   r´  £  s     

ÿ ÿÿz%ClientSSHTransportTests.test_keySetupc                    s
  |   ¡  dg‰ ‡ fdd„}|| j_t dddd¡| j_|  dd¡ |  | jj| jj¡ t	ƒ | j_| j 
d¡ |  | jj¡ |  | jj¡ |  | jj| jj¡ |  ˆ d ¡ d	| j_|  dd
¡ | j 
d¡ |  | jj¡ d	| j_|  dd¡ | j 
d¡ |  | jj¡ dS )zl
        Test that NEWKEYS transitions the keys from nextEncryptions to
        currentEncryptions.
        Fc                      s   dˆ d< d S r  r   r   ©Zsecurer   r   ÚstubConnectionSecure¼  s    zBClientSSHTransportTests.test_NEWKEYS.<locals>.stubConnectionSecurer¸   rY  rZ  r   r   r¶  s   GHs   IJN)r†  r™   rß  r   ró   r	  r§   ZassertIsNotrÚ   rE   r·  ré   rß   rì   r¸  rÑ   r‚  r¹  rƒ  )r   rí  r   rì  r   rº  µ  s<       ÿ
ÿ

ÿz$ClientSSHTransportTests.test_NEWKEYSc                 C   s*   t ƒ | j_| j d¡ |  | jjj¡ dS )zS
        Test that the SERVICE_ACCEPT packet starts the requested service.
        ó      MockServiceN)rl   r™   ÚinstanceÚssh_SERVICE_ACCEPTrÑ   rq   r8   r   r   r   Útest_SERVICE_ACCEPT×  s    
z+ClientSSHTransportTests.test_SERVICE_ACCEPTc                 C   s(   | j  tƒ ¡ |  | jtjdfg¡ dS )zP
        Test that requesting a service sends a SERVICE_REQUEST packet.
        rî  N)r™   ZrequestServicerl   rÈ   r”   r   r  r8   r   r   r   Útest_requestServiceà  s    ÿz+ClientSSHTransportTests.test_requestServicec                 C   s,   |   ¡  | j d| jdd¡ |  tj¡ dS )zL
        Test that KEXDH_REPLY disconnects if the signature is bad.
        Nr‚   ó   bad signature)rë  r™   Z_continueKEXDH_REPLYrŒ   re  r   rf  r8   r   r   r   Ú&test_disconnectKEXDH_REPLYBadSignatureé  s    z>ClientSSHTransportTests.test_disconnectKEXDH_REPLYBadSignaturec                 C   s,  dt  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ d d	 }| j |¡ | j d
¡ t t ¡ tƒ ¡| j_	| jj	 
¡ | j_t t ¡ tƒ ¡}| 
¡ }| ¡  ¡ }t ¡ | j_d| j_| j t  tƒ  ¡ d  ¡ ¡t  |¡ t  d¡ ¡ |  tj¡ dS ©zO
        Test that KEX_ECDH_REPLY disconnects if the signature is bad.
        rµ   r²   r{   r¶   r·   r¸   r   r¹   rº   s   SSH-2.0-OpenSSH
s   bad-signatureN©r   r   r™   r#  r   r   Zgenerate_private_keyZ	SECP256R1r   ZecPrivZ
public_keyZecPubZpublic_numbersZencode_pointZcurver[  Z_ssh_KEX_ECDH_REPLYrx   r   rŒ   re  r   rf  ©r   r«  ZthisPrivZthisPubZencPubr   r   r   Ú)test_disconnectKEX_ECDH_REPLYBadSignatureò  sZ    ÿþýüûúùø	÷
öõõÿ
ÿÿÿÿzAClientSSHTransportTests.test_disconnectKEX_ECDH_REPLYBadSignaturec                 C   s   | j  d¡ |  ¡  dS r½  r¾  r8   r   r   r   r¿    s    z2ClientSSHTransportTests.test_disconnectNEWKEYSDatac                 C   s"   t ƒ | j_| j d¡ |  ¡  dS )z€
        Test that SERVICE_ACCEPT disconnects if the accepted protocol is
        differet from the asked-for protocol.
        s      badN)rl   r™   rï  rð  re  r8   r   r   r   Útest_disconnectSERVICE_ACCEPT$  s    
z5ClientSSHTransportTests.test_disconnectSERVICE_ACCEPTc                 C   s<   t ƒ | j_| j d¡ |  | jjj¡ |  t| jƒd¡ dS )z°
        Some commercial SSH servers don't send a payload with the
        SERVICE_ACCEPT message.  Conch pretends that it got the correct
        name of the service.
        r   r   N)	rl   r™   rï  rð  rÑ   rq   rÈ   rK   r”   r8   r   r   r   Útest_noPayloadSERVICE_ACCEPT.  s    
z4ClientSSHTransportTests.test_noPayloadSERVICE_ACCEPTN)r   r   r   rD   r†  râ  rã  rä  rå  rë  r´  rº  rñ  rò  rô  rø  r¿  rù  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 )Ú)ClientSSHTransportDHGroupExchangeBaseCasezE
    Diffie-Hellman group exchange tests for SSHClientTransport.
    c                 C   s8   | j g| j_| j | j ¡ ¡ |  | jtjdfg¡ dS )zt
        KEXINIT packet with a group-exchange key exchange results
        in a KEX_DH_GEX_REQUEST message.
        ó             N)	r¬   r™   rý   r   r   rÆ   rÈ   r”   ZMSG_KEX_DH_GEX_REQUESTr8   r   r   r   Útest_KEXINIT_groupexchange@  s    þzDClientSSHTransportDHGroupExchangeBaseCase.test_KEXINIT_groupexchangec              	   C   sš   |   ¡  | j d¡ |  | jjd¡ |  | jjd¡ |  t | jj¡dd… d¡ |  | jj	t t
d| jjdƒ¡¡ |  | jdd… tj| jj	fg¡ dS )z’
        Test that the KEX_DH_GEX_GROUP message results in a
        KEX_DH_GEX_INIT message with the client's Diffie-Hellman public key.
        ó
         é   r  r„   Ns(   ™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™rH   )rý  r™   rê  rÈ   rœ  r›  r   r˜  rO   r£  r—  r”   r   ZMSG_KEX_DH_GEX_INITr8   r   r   r   Útest_KEX_DH_GEX_GROUPM  s    ÿ
ÿÿz?ClientSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_GROUPc                    sð   ˆ  ¡  t dˆjjˆjj¡}ˆ ¡ }| t ˆjj	¡d ¡ | t ˆjj
¡d ¡ | t ˆj¡¡ | d¡ | d¡ | ˆjj¡ | d¡ | |¡ | ¡ ‰ ‡ ‡fdd„}ˆj ˆ ¡}ˆj t ˆj¡d t |¡ ¡}| |¡ |S )z^
        Test that the KEX_DH_GEX_REPLY message results in a verified
        server.
        r‚   r  rü  rþ  rÃ  c                    s*   ˆ  | ¡ ˆ ˆj¡ ˆ ˆjjˆ ¡ d S r“   ræ  rç  rè  r   r   Ú_cbTestKEX_DH_GEX_REPLYq  s    
z`ClientSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_REPLY.<locals>._cbTestKEX_DH_GEX_REPLY)r   r   rš  r™   rO   rœ  r­   r  r   r%  rž  rŒ   r£  r]  rÛ  r¡  Zssh_KEX_DH_GEX_REPLYrà  )r   r¥   r¥  r  r¦  rá  r   rè  r   Útest_KEX_DH_GEX_REPLY^  s.    




ÿþÿ
z?ClientSSHTransportDHGroupExchangeBaseCase.test_KEX_DH_GEX_REPLYc                 C   s,   |   ¡  | j d| jdd¡ |  tj¡ dS )zQ
        Test that KEX_DH_GEX_REPLY disconnects if the signature is bad.
        Nr‚   ró  )r  r™   Z_continueGEX_REPLYrŒ   re  r   rf  r8   r   r   r   Ú$test_disconnectGEX_REPLYBadSignature€  s    zNClientSSHTransportDHGroupExchangeBaseCase.test_disconnectGEX_REPLYBadSignaturec                 C   s,  dt  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ t  d¡ d d	 }| j |¡ | j d
¡ t t ¡ tƒ ¡| j_	| jj	 
¡ | j_t t ¡ tƒ ¡}| 
¡ }| ¡  ¡ }t ¡ | j_d| j_| j t  tƒ  ¡ d  ¡ ¡t  |¡ t  d¡ ¡ |  tj¡ dS rõ  rö  r÷  r   r   r   rø  ‰  sZ    ÿþýüûúùø	÷
öõõÿ
ÿÿÿÿzSClientSSHTransportDHGroupExchangeBaseCase.test_disconnectKEX_ECDH_REPLYBadSignatureN)	r   r   r   rD   rý  r   r  r  rø  r   r   r   r   rû  ;  s   "	rû  c                   @   s   e Zd ZdZdS )Ú*ClientSSHTransportDHGroupExchangeSHA1TestszJ
    diffie-hellman-group-exchange-sha1 tests for SSHClientTransport.
    Nra  r   r   r   r   r  ´  s   r  c                   @   s   e Zd ZdZdS )Ú,ClientSSHTransportDHGroupExchangeSHA256TestszL
    diffie-hellman-group-exchange-sha256 tests for SSHClientTransport.
    Nra  r   r   r   r   r  ½  s   r  c                   @   s`   e Zd ZdZereZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚGetMACTestsz*
    Tests for L{SSHCiphers._getMAC}.
    c                 C   s   t  dddd¡| _d S )Nrï   rÞ   rð   rñ   )r   ró   rö   r8   r   r   r   r›   Î  s    zGetMACTests.setUpc                 C   s   t dƒS )z‚
        Generate a new shared secret to be used with the tests.

        @return: A new secret.
        @rtype: L{bytes}
        é@   r(   r8   r   r   r   ÚgetSharedSecretÒ  s    zGetMACTests.getSharedSecretc           
      C   s€   |   ¡ }| j ||¡}|d|… d|  }d dd„ t|ƒD ƒ¡}d dd„ t|ƒD ƒ¡}	|  |||	|f|¡ |  ||j¡ dS )a¸  
        Check that when L{SSHCiphers._getMAC} is called with a supportd HMAC
        algorithm name it returns a tuple of
        (digest object, inner pad, outer pad, digest size) with a C{key}
        attribute set to the value of the key supplied.

        @param hmacName: Identifier of HMAC algorithm.
        @type hmacName: L{bytes}

        @param hashProcessor: Callable for the hash algorithm.
        @type hashProcessor: C{callable}

        @param digestSize: Size of the digest for algorithm.
        @type digestSize: L{int}

        @param blockPadSize: Size of padding applied to the shared secret to
            match the block size.
        @type blockPadSize: L{int}
        Nr¹   r   c                 s   s   | ]}t t|ƒd A ƒV  qdS )é6   N©rU   r×   ©rÃ   Úbr   r   r   rÅ   õ  s     z+GetMACTests.assertGetMAC.<locals>.<genexpr>c                 s   s   | ]}t t|ƒd A ƒV  qdS )é\   Nr
  r  r   r   r   rÅ   ö  s     )r  rö   Ú_getMACrÌ   r*   rÈ   rŽ   )
r   ZhmacNamer­   Ú
digestSizeÚblockPadSizeZsecretÚparamsrŽ   ZinnerPadZouterPadr   r   r   ÚassertGetMACÜ  s    
 ÿzGetMACTests.assertGetMACc                 C   s   | j dtddd dS )a  
        When L{SSHCiphers._getMAC} is called with the C{b"hmac-sha2-512"} MAC
        algorithm name it returns a tuple of (sha512 digest object, inner pad,
        outer pad, sha512 digest size) with a C{key} attribute set to the
        value of the key supplied.
        s   hmac-sha2-512r  ©r  r  N)r  r"   r8   r   r   r   Útest_hmacsha2512ü  s       ÿzGetMACTests.test_hmacsha2512c                 C   s   | j dtddd dS )a  
        When L{SSHCiphers._getMAC} is called with the C{b"hmac-sha2-384"} MAC
        algorithm name it returns a tuple of (sha384 digest object, inner pad,
        outer pad, sha384 digest size) with a C{key} attribute set to the
        value of the key supplied.
        s   hmac-sha2-384é0   éP   r  N)r  r!   r8   r   r   r   Útest_hmacsha2384	  s       ÿzGetMACTests.test_hmacsha2384c                 C   s   | j dtddd dS )a  
        When L{SSHCiphers._getMAC} is called with the C{b"hmac-sha2-256"} MAC
        algorithm name it returns a tuple of (sha256 digest object, inner pad,
        outer pad, sha256 digest size) with a C{key} attribute set to the
        value of the key supplied.
        s   hmac-sha2-256é    r  N)r  r    r8   r   r   r   Útest_hmacsha2256	  s       ÿzGetMACTests.test_hmacsha2256c                 C   s   | j dtddd dS )a  
        When L{SSHCiphers._getMAC} is called with the C{b"hmac-sha1"} MAC
        algorithm name it returns a tuple of (sha1 digest object, inner pad,
        outer pad, sha1 digest size) with a C{key} attribute set to the value
        of the key supplied.
        r·   é   é,   r  N)r  r   r8   r   r   r   Útest_hmacsha1	  s    zGetMACTests.test_hmacsha1c                 C   s   | j dtddd dS )a  
        When L{SSHCiphers._getMAC} is called with the C{b"hmac-md5"} MAC
        algorithm name it returns a tuple of (md5 digest object, inner pad,
        outer pad, md5 digest size) with a C{key} attribute set to the value of
        the key supplied.
        r  é   r  r  N)r  r   r8   r   r   r   Útest_hmacmd5'	  s    zGetMACTests.test_hmacmd5c                 C   s&   |   ¡ }| j d|¡}|  d|¡ dS )zŽ
        When L{SSHCiphers._getMAC} is called with the C{b"none"} MAC algorithm
        name it returns a tuple of (None, "", "", 0).
        r¸   )Nr   r   r   N)r  rö   r  rÈ   )r   rŽ   r  r   r   r   Ú	test_none1	  s    zGetMACTests.test_noneN)r   r   r   rD   r¨   r©   r›   r  r  r  r  r  r  r  r  r   r   r   r   r  Æ  s   
 

r  c                   @   s@   e Zd ZdZereZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dS )ÚSSHCiphersTestsz0
    Tests for the SSHCiphers helper class.
    c                 C   sL   t  dddd¡}|  |jd¡ |  |jd¡ |  |jd¡ |  |jd¡ dS )zJ
        Test that the initializer sets up the SSHCiphers object.
        rï   rÞ   rð   rñ   N)r   ró   rÈ   r\   r]   r_   r^   )r   rö   r   r   r   Ú	test_initF	  s
    zSSHCiphersTests.test_initc           	      C   sj   t  dddd¡}d }}|j ¡ D ]B\}\}}}| |||¡}|dkrV|  |t j¡ q"|  |j|¡ q"dS )zM
        Test that the _getCipher method returns the correct cipher.
        rï   rÞ   rð   rñ   rò   r¸   N)r   ró   Ú	cipherMapr‹   rõ   ZassertIsInstanceZ_DummyCipherÚ	algorithm)	r   rö   r÷   rŽ   rø   ZalgClassÚkeySizeÚcounterÚcipr   r   r   Útest_getCipherQ	  s    zSSHCiphersTests.test_getCipherc              	   C   s<  d}t jjD ](}t jj| \}}}t  |ddd¡}t  d|dd¡}| |||¡}|jjd }	| ||dddd¡ | dd||dd¡ |  	|j
|	¡ |  	|j|	¡ | ¡ }
|
 |d|	… ¡}|
 |d|	… ¡}|  	| |d|	… ¡|¡ |  	| |d|	… ¡|¡ |  	| |¡|d|	… ¡ |  	| |¡|d|	… ¡ qdS )z8
        Test that setKeys sets up the ciphers.
        ó@                                                                   r¸   é   r   N)r   r   rô   ró   r"  rõ   r#  Z
block_sizer[   rÈ   rL   rR   Ú	encryptorr  rP   rS   )r   rŽ   rø   ZmodNamer$  r%  Z	encCipherZ	decCipherr&  Zbsr*  ÚencZenc2r   r   r   Útest_setKeysCiphers_	  s,    
ÿ
ÿz#SSHCiphersTests.test_setKeysCiphersc              	   C   sü   d}t jj ¡ D ]æ\}}t  dd|d¡}t  ddd|¡}| dddd|d¡ | ddddd|¡ |rn|ƒ j}nd}|  |j|¡ |r˜| ||¡\}}}}d}	|}
d| }|rÊ||||| ƒ 	¡  ƒ 	¡ }nd}|  | 
|	|
¡|¡ |  | |	|
|¡¡ qdS )z5
        Test that setKeys sets up the MACs.
        r(  r¸   r   r   rº   N)r   ró   ZmacMapr‹   r[   Zdigest_sizerÈ   r`   r  r]  rX   rÑ   rZ   )r   rŽ   ZmacNameÚmodZoutMacZinMacZdsÚiÚoÚseqidr>  rB   Úmacr   r   r   Útest_setKeysMACsy	  s(    
z SSHCiphersTests.test_setKeysMACsc              
   C   s‚   dddg}|D ]n\}}}t  dddd¡}| d|¡|_t d|dd… ¡\}|dd… }|  |t | 	||¡¡d	||f ¡ qdS )
zŒ
        L{SSHCiphers.makeMAC} computes the HMAC of an outgoing SSH message with
        a particular sequence id and content data.
        )s   s   Hi Theres    9294727a3638bb1c13f48ef8158bfc9d)s   Jefes   what do ya want for nothing?s    750c783e6ab0b503eaa86e310a5db738)rµ   s2   ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝs    56be34521d144c88dbb8c733f0e8b3f6r¸   r  z>LNr6  z'Failed HMAC test vector; key=%r data=%r)
r   ró   r  ra   ÚstructZunpackrÈ   r×  rØ  rX   )r   ZvectorsrŽ   r>  r1  ra   r0  Z	shortenedr   r   r   Útest_makeMAC•	  s     û	
ÿ 
þzSSHCiphersTests.test_makeMACN)r   r   r   rD   r¨   r©   r!  r'  r,  r2  r4  r   r   r   r   r   >	  s   r   c                   @   s@   e Zd ZdZereZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dS )ÚTransportLoopbackTestszL
    Test the server transport and client transport against each other,
    c                    s²   t ƒ }t ¡ ‰|ˆ_| ¡  g ˆ_‡fdd„ˆ_t ¡ ‰ dd„ ˆ _g ˆ _‡ fdd„ˆ _‡ fdd„ˆ _	t
ˆj ¡  ¡ ƒˆ_|ˆƒ‰|ˆ ƒ‰ ‡fdd„}t ˆˆ ¡}| |ˆˆ ¡ |S )zö
        Run an async client and server, modifying each using the mod function
        provided.  Returns a Deferred called back when both Protocols have
        disconnected.

        @type mod: C{func}
        @rtype: C{defer.Deferred}
        c                    s   ˆ j  | |f¡S r“   r:   ©ÚcodeZdesc)Úserverr   r   rå   Æ	  s    ÿz9TransportLoopbackTests._runClientServer.<locals>.<lambda>c                 S   s
   t  d ¡S r“   )r%   rÙ  )rO   rŒ  r   r   r   rå   É	  r   c                    s   ˆ j  | |f¡S r“   r:   r6  ©Úclientr   r   rå   Ë	  s    ÿc                      s   ˆ   ¡ S r“   )r  r   r9  r   r   rå   Í	  r   c                    sð   t |jd |jd |jd |jd gƒ}ˆ  |jg ¡ ˆ  |jtjdfg¡ |jd dkr|ˆ  	| 
¡ |¡ ˆ  	| 
¡ |¡ n ˆ  | 
¡ |¡ ˆ  | 
¡ |¡ |jd dkrÌˆ  	| ¡ |¡ ˆ  	| ¡ |¡ n ˆ  | ¡ |¡ ˆ  | ¡ |¡ d S )Nr   s   user closed connectionr¸   )Úreprrô   rÿ   rý   r   rÈ   r3   r   r7  rÐ   r1  rÑ   r4  )Zignoredr8  r:  rw   r8   r   r   ÚcheckÒ	  s(    
ýþz6TransportLoopbackTests._runClientServer.<locals>.check)rx   r   r   r
   r|  r3   r<   r   rÚ  rß  Úlistr   r	   rþ   r&   ZloopbackAsyncrà  )r   r-  r
   r<  rá  r   )r:  r   r8  r   Ú_runClientServer¸	  s(    	
ÿz'TransportLoopbackTests._runClientServerc                    sB   g }t jjdg D ] ‰ ‡ fdd„}| |  |¡¡ qtj|ddS )z{
        Test that the client and server play nicely together, in all
        the various combinations of ciphers.
        r¸   c                    s   ˆ g| _ | S r“   rr  r;  ©Zcipherr   r   Ú	setCipherô	  s    z6TransportLoopbackTests.test_ciphers.<locals>.setCipherT©ZfireOnOneErrback)r   r   rô   r;   r>  r%   ÚDeferredList)r   Ú	deferredsr@  r   r?  r   Útest_ciphersí	  s
    z#TransportLoopbackTests.test_ciphersc                    sB   g }t jjdg D ] ‰ ‡ fdd„}| |  |¡¡ qtj|ddS )z>
        Like test_ciphers, but for the various MACs.
        r¸   c                    s   ˆ g| _ | S r“   ru  r;  ©r1  r   r   ÚsetMAC
  s    z0TransportLoopbackTests.test_macs.<locals>.setMACTrA  )r   r   rÿ   r;   r>  r%   rB  )r   rC  rF  r   rE  r   Ú	test_macsû	  s
    z TransportLoopbackTests.test_macsc                    s<   g }t jjD ] ‰ ‡ fdd„}| |  |¡¡ qtj|ddS )zG
        Like test_ciphers, but for the various key exchanges.
        c                    s   ˆ g| _ | S r“   rh  r;  ©r¬   r   r   ÚsetKeyExchange
  s    z@TransportLoopbackTests.test_keyexchanges.<locals>.setKeyExchangeTrA  )r   r   rý   r;   r>  r%   rB  )r   rC  rI  r   rH  r   Útest_keyexchanges
  s
    z(TransportLoopbackTests.test_keyexchangesc                    s<   g }t jjD ] ‰ ‡ fdd„}| |  |¡¡ qtj|ddS )zF
        Like test_ciphers, but for the various compressions.
        c                    s   ˆ g| _ | S r“   ro  r;  ©Zcompressionr   r   ÚsetCompression
  s    z@TransportLoopbackTests.test_compressions.<locals>.setCompressionTrA  )r   r   r   r;   r>  r%   rB  )r   rC  rL  r   rK  r   Útest_compressions
  s
    z(TransportLoopbackTests.test_compressionsN)r   r   r   rD   r¨   r©   r>  rD  rG  rJ  rM  r   r   r   r   r5  °	  s   5r5  c                   @   s8   e Zd ZdZereZdd„ Zdd„ Zdd„ Zdd	„ Z	d
S )ÚRandomNumberTestszp
    Tests for the random number generator L{_getRandomNumber} and private
    key generator L{_generateX}.
    c                 C   s    dd„ }|   t |d¡d¡ dS )z˜
        L{_getRandomNumber} returns an integer constructed directly from the
        bytes returned by the random byte generator passed to it.
        c                 S   s   t | ƒ|  S r“   rT   ©r>  r   r   r   Úrandom1
  s    zARandomNumberTests.test_usesSuppliedRandomFunction.<locals>.randomr  iN)rÈ   r   Ú_getRandomNumber©r   rP  r   r   r   Útest_usesSuppliedRandomFunction,
  s
    
þz1RandomNumberTests.test_usesSuppliedRandomFunctionc                 C   s   |   ttjdd¡ dS )zŽ
        L{_getRandomNumber} raises L{ValueError} if the number of bits
        passed to L{_getRandomNumber} is not a multiple of 8.
        Né	   )r  Ú
ValueErrorr   rQ  r8   r   r   r   Útest_rejectsNonByteMultiples:
  s      þz.RandomNumberTests.test_rejectsNonByteMultiplesc                    s:   t dƒt dƒt dƒg‰ ‡ fdd„}|  t |d¡d¡ dS )zã
        If the random byte generator passed to L{_generateX} produces bytes
        which would result in 0 or 1 being returned, these bytes are
        discarded and another attempt is made to produce a larger value.
        r   rH   é   c                    s   ˆ   d¡|  S ©Nr   ©ÚpoprO  ©Zresultsr   r   rP  K
  s    z4RandomNumberTests.test_excludesSmall.<locals>.randomr)  N©rU   rÈ   r   Z
_generateXrR  r   r[  r   Útest_excludesSmallD
  s    
þz$RandomNumberTests.test_excludesSmallc                    s4   t dƒt dƒg‰ ‡ fdd„}|  t |d¡d¡ dS )zø
        If the random byte generator passed to L{_generateX} produces bytes
        which would result in C{(2 ** bits) - 1} being returned, these bytes
        are discarded and another attempt is made to produce a smaller
        value.
        rn   r  c                    s   ˆ   d¡|  S rX  rY  rO  r[  r   r   rP  Z
  s    z4RandomNumberTests.test_excludesLarge.<locals>.randomr)  Nr\  rR  r   r[  r   Útest_excludesLargeR
  s    
þz$RandomNumberTests.test_excludesLargeN)
r   r   r   rD   r¨   r©   rS  rV  r]  r^  r   r   r   r   rN  #
  s   
rN  )]rD   Z
__future__r   r   r×  rÀ   rÍ   r3  Ztwisted.python.reflectr   r   r   r¨   Ztwisted.conch.sshr   r   r	   r
   Ztwisted.conch.testr   Zcryptography.hazmat.backendsr   Z)cryptography.hazmat.primitives.asymmetricr   Zcryptography.exceptionsr   Zhashlibr   r   r    r!   r"   Ztwistedr#   rÉ   Ztwisted.trialr$   Ztwisted.internetr%   Ztwisted.protocolsr&   Ztwisted.pythonr'   Ztwisted.python.randbytesr)   Ztwisted.python.compatr*   r+   rU   r,   r-   r.   Ztwisted.testr/   Ztwisted.conch.errorr0   r   r1   ÚobjectrE   rb   Z
SSHServicerl   r   rx   rŠ   r   ZTestCaser   rª   r®   r±   r³   r´   rV  r`  rb  rc  rd  r{  r~  rÁ  rÑ  rÒ  rÓ  rÜ  rû  r  r  r  r   r5  rN  r   r   r   r   Ú<module>   sÎ   JB'.:


	      
 þ	
 þ	
 þ	c  #x
 þ	
 þ	  y
 þ	
 þ	xrs