def startTLS(self, contextFactory=None): """ Initiates a 'STLS' request and negotiates the TLS / SSL Handshake. @type contextFactory: C{ssl.ClientContextFactory} @param contextFactory: The context factory with which to negotiate TLS. If C{None}, try to create a new one. @return: A Deferred which fires when the transport has been secured according to the given contextFactory, or which fails if the transport cannot be secured. """ tls = interfaces.ITLSTransport(self.transport, None) if tls is None: return defer.fail( TLSError("POP3Client transport does not implement " "interfaces.ITLSTransport")) if contextFactory is None: contextFactory = self._getContextFactory() if contextFactory is None: return defer.fail( TLSError("POP3Client requires a TLS context to " "initiate the STLS handshake")) d = self.capabilities() d.addCallback(self._startTLS, contextFactory, tls) return d
def _login(self, caps, username, password): """ Continue the process of logging in to the server. This callback function runs after the server capabilities are received. If the server provided a challenge in the greeting, proceed with an APOP login. Otherwise, if the server and the transport support encrypted communication, try to switch to TLS and then complete the login process with the L{_loginTLS} callback function. Otherwise, if insecure authentication is allowed, do a plaintext login. Otherwise, fail with an L{InsecureAuthenticationDisallowed} error. @type caps: L{dict} mapping L{bytes} to L{list} of L{bytes} and/or L{bytes} to L{None} @param caps: The server capabilities. @type username: L{bytes} @param username: The username with which to log in. @type password: L{bytes} @param password: The password with which to log in. @rtype: L{Deferred <defer.Deferred>} which successfully fires with L{bytes} @return: A deferred which fires when the login process is complete. On a successful login, it returns the server's response minus the status indicator. """ if self.serverChallenge is not None: return self._apop(username, password, self.serverChallenge) tryTLS = b"STLS" in caps # If our transport supports switching to TLS, we might want to # try to switch to TLS. tlsableTransport = interfaces.ITLSTransport(self.transport, None) is not None # If our transport is not already using TLS, we might want to # try to switch to TLS. nontlsTransport = interfaces.ISSLTransport(self.transport, None) is None if not self.startedTLS and tryTLS and tlsableTransport and nontlsTransport: d = self.startTLS() d.addCallback(self._loginTLS, username, password) return d elif self.startedTLS or not nontlsTransport or self.allowInsecureLogin: return self._plaintext(username, password) else: return defer.fail(InsecureAuthenticationDisallowed())
def _login(self, caps, username, password): if self.serverChallenge is not None: return self._apop(username, password, self.serverChallenge) tryTLS = 'STLS' in caps #If our transport supports switching to TLS, we might want to try to switch to TLS. tlsableTransport = interfaces.ITLSTransport(self.transport, None) is not None # If our transport is not already using TLS, we might want to try to switch to TLS. nontlsTransport = interfaces.ISSLTransport(self.transport, None) is None if not self.startedTLS and tryTLS and tlsableTransport and nontlsTransport: d = self.startTLS() d.addCallback(self._loginTLS, username, password) return d elif self.startedTLS or not nontlsTransport or self.allowInsecureLogin: return self._plaintext(username, password) else: return defer.fail(InsecureAuthenticationDisallowed())
def startTLS(self, contextFactory=None): """ Switch to encrypted communication using TLS. The first step of switching to encrypted communication is obtaining the server's capabilities. When that is complete, the L{_startTLS} callback function continues the switching process. @type contextFactory: L{None} or L{ClientContextFactory <twisted.internet.ssl.ClientContextFactory>} @param contextFactory: The context factory with which to negotiate TLS. If not provided, try to create a new one. @rtype: L{Deferred <defer.Deferred>} which successfully results in L{dict} mapping L{bytes} to L{list} of L{bytes} and/or L{bytes} to L{None} or fails with L{TLSError} @return: A deferred which fires when the transport has been secured according to the given context factory with the server capabilities, or which fails with a TLS error if the transport cannot be secured. """ tls = interfaces.ITLSTransport(self.transport, None) if tls is None: return defer.fail(TLSError( "POP3Client transport does not implement " "interfaces.ITLSTransport")) if contextFactory is None: contextFactory = self._getContextFactory() if contextFactory is None: return defer.fail(TLSError( "POP3Client requires a TLS context to " "initiate the STLS handshake")) d = self.capabilities() d.addCallback(self._startTLS, contextFactory, tls) return d