Your IP : 172.28.240.42


Current Path : /usr/lib/python2.7/dist-packages/twisted/protocols/
Upload File :
Current File : //usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyc


Nc@sdZddlmZmZmZddlmZmZmZyeeeeWn7e	k
rZ
ee
dkrnednXddl
mZddlmZddlmZdd	lmZdd
lmZmZddlmZmZddlmZdd
lmZddlmZddl m!Z!m"Z"de#fdYZ$de#fdYZ%de!fdYZ&de"fdYZ'dS(s
Implementation of a TLS transport (L{ISSLTransport}) as an
L{IProtocol<twisted.internet.interfaces.IProtocol>} layered on top of any
L{ITransport<twisted.internet.interfaces.ITransport>} implementation, based on
U{OpenSSL<http://www.openssl.org>}'s memory BIO features.

L{TLSMemoryBIOFactory} is a L{WrappingFactory} which wraps protocols created by
the factory it wraps with L{TLSMemoryBIOProtocol}.  L{TLSMemoryBIOProtocol}
intercedes between the underlying transport and the wrapped protocol to
implement SSL and TLS.  Typical usage of this module looks like this::

    from twisted.protocols.tls import TLSMemoryBIOFactory
    from twisted.internet.protocol import ServerFactory
    from twisted.internet.ssl import PrivateCertificate
    from twisted.internet import reactor

    from someapplication import ApplicationProtocol

    serverFactory = ServerFactory()
    serverFactory.protocol = ApplicationProtocol
    certificate = PrivateCertificate.loadPEM(certPEMData)
    contextFactory = certificate.options()
    tlsFactory = TLSMemoryBIOFactory(contextFactory, False, serverFactory)
    reactor.listenTCP(12345, tlsFactory)
    reactor.run()

This API offers somewhat more flexibility than
L{twisted.internet.interfaces.IReactorSSL}; for example, a L{TLSMemoryBIOProtocol}
instance can use another instance of L{TLSMemoryBIOProtocol} as its transport,
yielding TLS over TLS - useful to implement onion routing.  It can also be used
to run TLS over unusual transports, such as UNIX sockets and stdio.
i(tErrortZeroReturnErrort
WantReadError(tTLSv1_METHODtContextt
Connections3argument must be an int, or have a fileno() method.s7twisted.protocols.tls requires pyOpenSSL 0.10 or newer.(t
implements(tFailure(tlog(tsafe_str(t
ISystemHandlet
ISSLTransport(t
IPushProducertILoggingContext(tCONNECTION_LOST(tProtocol(t	cooperate(tProtocolWrappertWrappingFactoryt_PullToPushcBs]eZdZeeeZdZdZdZ	dZ
dZdZdZ
RS(s
    An adapter that converts a non-streaming to a streaming producer.

    Because of limitations of the producer API, this adapter requires the
    cooperation of the consumer. When the consumer's C{registerProducer} is
    called with a non-streaming producer, it must wrap it with L{_PullToPush}
    and then call C{startStreaming} on the resulting object. When the
    consumer's C{unregisterProducer} is called, it must call
    C{stopStreaming} on the L{_PullToPush} instance.

    If the underlying producer throws an exception from C{resumeProducing},
    the producer will be unregistered from the consumer.

    @ivar _producer: the underling non-streaming producer.

    @ivar _consumer: the consumer with which the underlying producer was
                     registered.

    @ivar _finished: C{bool} indicating whether the producer has finished.

    @ivar _coopTask: the result of calling L{cooperate}, the task driving the
                     streaming producer.
    cCs||_||_dS(N(t	_producert	_consumer(tselftpullProducertconsumer((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt__init__[s	ccsxtry|jjWnltjddt|jfy|jjWqtjddt|jft|_	dSXnXdVqWdS(s
        A generator that calls C{resumeProducing} on the underlying producer
        forever.

        If C{resumeProducing} throws an exception, the producer is
        unregistered, which should result in streaming stopping.
        s%%s failed, producing will be stopped:s!%s failed to unregister producer:N(
tTrueRtresumeProducingRterrtNoneR	RtunregisterProducert	_finished(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt_pull`s			cCst|j|_dS(s
        This should be called by the consumer when the producer is registered.

        Start streaming data to the consumer.
        N(RR t	_coopTask(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pytstartStreaming|scCs'|jr
dSt|_|jjdS(s
        This should be called by the consumer when the producer is unregistered.

        Stop streaming data to the consumer.
        N(RRR!tstop(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt
stopStreamings		cCs|jjdS(N(R!tpause(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pytpauseProducingscCs|jjdS(N(R!tresume(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRscCs|j|jjdS(N(R$Rt
stopProducing(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR(s
(t__name__t
__module__t__doc__RRtFalseRRR R"R$R&RR((((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR>s
					
		t_ProducerMembranecBsBeZdZeeeZdZdZdZ	dZ
RS(s
    Stand-in for producer registered with a L{TLSMemoryBIOProtocol} transport.

    Ensures that producer pause/resume events from the undelying transport are
    coordinated with pause/resume events from the TLS layer.

    @ivar _producer: The application-layer producer.
    cCs
||_dS(N(R(Rtproducer((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRscCs'|jr
dSt|_|jjdS(sP
        C{pauseProducing} the underlying producer, if it's not paused.
        N(t_producerPausedRRR&(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR&s		cCs'|js
dSt|_|jjdS(sM
        C{resumeProducing} the underlying producer, if it's paused.
        N(R/R,RR(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRs		cCs|jjdS(s
        C{stopProducing} the underlying producer.

        There is only a single source for this event, so it's simply passed
        on.
        N(RR((R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR(s(R)R*R+RRR,R/RR&RR((((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR-s
		
	
tTLSMemoryBIOProtocolcBseZdZeeedZeZ	eZ
eZdZe
dZdZdZdZdZdZdZdZd	Zd
ZdZdZd
ZdZdZdZRS(s
    L{TLSMemoryBIOProtocol} is a protocol wrapper which uses OpenSSL via a
    memory BIO to encrypt bytes written to it before sending them on to the
    underlying transport and decrypts bytes received from the underlying
    transport before delivering them to the wrapped protocol.

    In addition to producer events from the underlying transport, the need to
    wait for reads before a write can proceed means the
    L{TLSMemoryBIOProtocol} may also want to pause a producer. Pause/resume
    events are therefore merged using the L{_ProducerMembrane}
    wrapper. Non-streaming (pull) producers are supported by wrapping them
    with L{_PullToPush}.

    @ivar _tlsConnection: The L{OpenSSL.SSL.Connection} instance which is
        encrypted and decrypting this connection.

    @ivar _lostTLSConnection: A flag indicating whether connection loss has
        already been dealt with (C{True}) or not (C{False}). TLS disconnection
        is distinct from the underlying connection being lost.

    @ivar _writeBlockedOnRead: A flag indicating whether further writing must
        wait for data to be received (C{True}) or not (C{False}).

    @ivar _appSendBuffer: A C{list} of C{str} of application-level (cleartext)
        data which is waiting for C{_writeBlockedOnRead} to be reset to
        C{False} so it can be passed to and perhaps accepted by
        C{_tlsConnection.send}.

    @ivar _connectWrapped: A flag indicating whether or not to call
        C{makeConnection} on the wrapped protocol.  This is for the reactor's
        L{twisted.internet.interfaces.ITLSTransport.startTLS} implementation,
        since it has a protocol which it has already called C{makeConnection}
        on, and which has no interest in a new transport.  See #3821.

    @ivar _handshakeDone: A flag indicating whether or not the handshake is
        known to have completed successfully (C{True}) or not (C{False}).  This
        is used to control error reporting behavior.  If the handshake has not
        completed, the underlying L{OpenSSL.SSL.Error} will be passed to the
        application's C{connectionLost} method.  If it has completed, any
        unexpected L{OpenSSL.SSL.Error} will be turned into a
        L{ConnectionLost}.  This is weird; however, it is simply an attempt at
        a faithful re-implementation of the behavior provided by
        L{twisted.internet.ssl}.

    @ivar _reason: If an unexpected L{OpenSSL.SSL.Error} occurs which causes
        the connection to be lost, it is saved here.  If appropriate, this may
        be used as the reason passed to the application protocol's
        C{connectionLost} method.

    @ivar _producer: The current producer registered via C{registerProducer},
        or C{None} if no producer has been registered or a previous one was
        unregistered.
    cCs tj|||||_dS(N(RRt_connectWrapped(RtfactorytwrappedProtocolR1((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRscCs|jS(si
        Return the L{OpenSSL.SSL.Connection} object being used to encrypt and
        decrypt this connection.

        This is done for the benefit of L{twisted.internet.ssl.Certificate}'s
        C{peerFromTransport} and C{hostFromTransport} methods only.  A
        different system handle may be returned by future versions of this
        method.
        (t_tlsConnection(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt	getHandles
cCs|jjj}t|d|_|jjr@|jjn
|jjg|_	t
j|||jj||j
rtj||ny|jjWntk
r|jnXdS(s
        Connect this wrapper to the given transport and initialize the
        necessary L{OpenSSL.SSL.Connection} with a memory BIO.
        N(R2t_contextFactoryt
getContextRRR4t	_isClienttset_connect_statetset_accept_statet_appSendBufferRtmakeConnectiontregisterProtocolR1Rtdo_handshakeRt
_flushSendBIO(Rt	transportt
tlsContext((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR< s
		
cCs>y|jjd}Wntk
r)nX|jj|dS(sh
        Read any bytes out of the send BIO and write them to the underlying
        transport.
        iiNi(R4tbio_readRR@twrite(Rtbytes((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR?Ds

cCsx|jsy|jjd}Wntk
r6Pqtk
r]|j|jdqtk
r}|j	ddkr|j	ddkrt
t}n	t
}|j|j|qXt
|_tj||qW|jdS(	se
        Try to receive any application-level bytes which are now available
        because of a previous write into the receive BIO.  This will take
        care of delivering any application-level bytes which are received to
        the protocol, as well as handling of the various exceptions which
        can come from trying to get such bytes.
        iiiiisUnexpected EOFNi(t_lostTLSConnectionR4trecvRRt_shutdownTLSt_tlsShutdownFinishedRRtargsRRR?Rt_handshakeDoneRtdataReceived(RRDtetfailure((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt_flushReceiveBIORs"


&	
	cCs|jj||jrt|_|j}g|_x|D]}|j|q;W|jr|jr|jdkr|j	n|j
dk	r|j
jqn|jdS(s
        Deliver any received bytes to the receive BIO and then read and deliver
        to the application any application-level data which becomes available
        as a result of this.
        N(
R4t	bio_writet_writeBlockedOnReadR,R;t_writet
disconnectingR.RRGRRRN(RRDt
appSendBuffer((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRKs				

cCs3|jj}|j|r/|jjndS(sQ
        Initiate, or reply to, the shutdown handshake of the TLS layer.
        N(R4tshutdownR?R@tloseConnection(RtshutdownSuccess((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRGs
cCs#||_t|_|jjdS(sl
        Called when TLS connection has gone away; tell underlying transport to
        disconnect.
        N(t_reasonRRER@RU(Rtreason((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRHs		cCsX|js,|jj|jt|_n|jp8|}d|_tj||dS(s
        Handle the possible repetition of calls to this method (due to either
        the underlying transport going away or due to an error at the TLS
        layer) and make sure the base implementation only gets invoked once.
        N(	RER4tbio_shutdownRNRRWRRtconnectionLost(RRX((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRZs	

	cCs@|jr
dSt|_|jr<|jdkr<|jndS(sM
        Send a TLS close alert and close the underlying connection.
        N(RRRRPRRRG(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRUs
		cCs-|jr|jdkrdS|j|dS(s
        Process the given application bytes and send any resulting TLS traffic
        which arrives in the send BIO.

        If C{loseConnection} was called, subsequent calls to C{write} will
        drop the bytes on the floor.
        N(RRRRRQ(RRD((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRCscCs|jr
dS|}x|ry|jj|}Wnktk
r~t|_|jj||jdk	rz|jj
nPqtk
r|jt
PqXt|_|j||}qWdS(s^
        Process the given application bytes and send any resulting TLS traffic
        which arrives in the send BIO.

        This may be called by C{dataReceived} with bytes that were buffered
        before C{loseConnection} was called, which is why this function
        doesn't check for disconnection but accepts the bytes regardless.
        N(RER4tsendRRRPR;tappendRRR&RRHRRJR?(RRDt
leftToSendtsent((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRQs$			
	
	
cCs|jdj|dS(s}
        Write a sequence of application bytes by joining them into one string
        and passing them to L{write}.
        tN(RCtjoin(Rtiovec((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt
writeSequencescCs
|jjS(N(R4tget_peer_certificate(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pytgetPeerCertificatescCs[|st||}}nt|}|jj|t||_|sW|jndS(N(RR-R@tregisterProducerRRR"(RR.t	streamingtstreamingProducer((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRes	cCskt|jjtr(|jjjnd|_t|_|jj|j	rg|j
rg|jndS(N(t
isinstanceRRR$RR,R/R@RRRRPRG(R((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR+s		
N(R)R*R+RR
RRRWR,RJRERPRRRR5R<R?RNRKRGRHRZRURCRQRbRdReR(((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyR0s.5
	
	$		5							&			tTLSMemoryBIOFactorycBs,eZdZeZeZdZdZRS(s:
    L{TLSMemoryBIOFactory} adds TLS to connections.

    @ivar _contextFactory: The TLS context factory which will be used to define
        certain TLS connection parameters.

    @ivar _isClient: A flag which is C{True} if this is a client TLS
        connection, C{False} if it is a server TLS connection.
    cCs&tj||||_||_dS(N(RRR6R8(RtcontextFactorytisClienttwrappedFactory((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRFs	cCs>tj|jr$|jj}n|jjj}d|fS(s
        Annotate the wrapped factory's log prefix with some text indicating TLS
        is in use.

        @rtype: C{str}
        s%s (TLS)(R
t
providedByRlt	logPrefixt	__class__R)(RRn((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRnLs(	R)R*R+R0tprotocolR,tnoisyRRn(((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyRi8s
		N((R+tOpenSSL.SSLRRRRRRRt	TypeErrorRLtstrtImportErrortzope.interfaceRttwisted.python.failureRttwisted.pythonRttwisted.python.reflectR	ttwisted.internet.interfacesR
RRR
ttwisted.internet.mainRttwisted.internet.protocolRttwisted.internet.taskRttwisted.protocols.policiesRRtobjectRR-R0Ri(((s9/usr/lib/python2.7/dist-packages/twisted/protocols/tls.pyt<module>$s.b0i