【问题标题】:SSL handshake failures when no data was sent over Twisted TLSConnection未通过 Twisted TLSConnection 发送数据时 SSL 握手失败
【发布时间】:2011-06-23 22:47:05
【问题描述】:

我开始考虑通过扩展当前的 Twisted FTP 来实现显式 FTP。

大部分代码都是直截了当的,实现 AUTH、PBSZ、PROT 很容易,而且我得到了一个工作安全的控制通道。

我的问题在于数据通道。

客户端错误是:SSL routines', 'SSL3_READ_BYTES', 'ssl handshake failure'

似乎只有在通过数据通道发送某些数据时才调用 SSL 握手和关闭。 这会影响发送空文件或列出空文件夹的情况,因为在关闭连接之前,客户端会调用 SSL 关闭。

我正在寻找一些建议,以了解在未发送数据时我应该如何以及在何处搜索从 Twisted TLS 修复 TLS 握手。

此代码在列出非空文件夹时有效...但如果文件夹不包含文件或文件夹,则会失败。

非常感谢!

def getDTPPort(self, factory):
    """
    Return a port for passive access, using C{self.passivePortRange}
    attribute.
    """
    for portn in self.passivePortRange:
        try:
            if self.protected_data:
                dtpPort = reactor.listenSSL(
                    port=portn, factory=factory,
                    contextFactory=self.ssl_context)
            else:
                dtpPort = self.listenFactory(portn, factory)

        except error.CannotListenError:
            continue
        else:
            return dtpPort
    raise error.CannotListenError('', portn,
        "No port available in range %s" %
        (self.passivePortRange,))

更新 1

由于 cmets 格式不正确,我将更新此文本:

所以我最终得到了:

def getDTPPort(self, factory):
    """
    Return a port for passive access, using C{self.passivePortRange}
    attribute.
    """
    for portn in self.passivePortRange:
        try:
            if self.protected_data:
                tls_factory = TLSMemoryBIOFactory(
                    contextFactory=self.ssl_context,
                    isClient=False,
                    wrappedFactory=factory)
                dtpPort = reactor.listenTCP(
                    port=portn, factory=tls_factory)
            else:
                dtpPort = self.listenFactory(portn, factory)

        except error.CannotListenError:
            continue
        else:
            return dtpPort
    raise error.CannotListenError('', portn,
        "No port available in range %s" %
        (self.passivePortRange,))

更新 2

问题是由于握手仍在运行时关闭连接造成的。 我不知道如何检查 SSL 握手已完成的空连接。

所以我最终得到了这个愚蠢的代码

def loseConnection(self):
    """
    Send a TLS close alert and close the underlying connection.
    """
    self.disconnecting = True

    def close_connection():
        if not self._writeBlockedOnRead:
            self._tlsConnection.shutdown()
            self._flushSendBIO()
            self.transport.loseConnection()

    # If we don't know if the handshake was done, we wait for a bit
    # and the close the connection.
    # This is done to avoid closing the connection in the middle of a
    # handshake.
    if not self._handshakeDone:
        reactor.callLater(0.1, close_connection)
    else:
        close_connection()

【问题讨论】:

    标签: twisted ssl ftps


    【解决方案1】:

    SSL 握手由 pyOpenSSL Connection 对象的 do_handshake 方法发起。它也可以通过sendrecv 调用隐式启动。 reactor.connectSSLreactor.listenSSL 设置的传输依赖于后者。所以你的结论是正确的 - 如果没有通过连接发送数据,则永远不会执行握手。

    但是,一旦建立连接,twisted.protocols.tls 就会调用 do_handshake。如果您改为使用该 API 设置您的 SSL 服务器,我认为您的问题会得到解决。

    还有一个reimplement the former using the latter 的计划,因为后者似乎总体上效果更好。

    【讨论】:

    • 非常感谢您提供详细信息。我看到了TLSMemoryBIOProtocol,但我不确定它的用途是什么,并且想知道为什么默认情况下不使用它。你是英雄:)
    猜你喜欢
    • 2018-07-28
    • 2012-10-11
    • 2015-03-16
    • 2021-12-28
    • 2018-10-17
    • 2016-04-29
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多