0

現在のツイストFTPを拡張して、明示的なFTPの実装を検討し始めます。

ほとんどのコードは単純で、AUTH、PBSZ、PROTの実装は簡単で、安全な制御チャネルが機能していました。

私の問題はデータチャネルにあります。

クライアント側のエラーは次のとおりです。SSL routines', 'SSL3_READ_BYTES', 'ssl handshake failure'

SSLハンドシェイクとシャットダウンは、一部のデータがデータチャネルを介して送信された場合にのみ呼び出されるようです。これは、接続を閉じる前にクライアントがSSLシャットダウンを呼び出すため、空のファイルを送信したり、空のフォルダーを一覧表示したりする場合に影響します。

データが送信されないときにTwistedTLSから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

コメントの形式が適切でないため、このテキストを更新します。

だから私は結局:

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()
4

1 に答える 1

2

SSLハンドシェイクはdo_handshake、pyOpenSSLConnectionオブジェクトのメソッドによって開始されます。sendまたはrecv呼び出しによって暗黙的に開始することもできます。後者によって設定され、後者reactor.connectSSLreactor.listenSSL依存するトランスポート。したがって、結論は正しいです。接続を介してデータが送信されない場合、ハンドシェイクは実行されません。

ただし、接続が確立されるとすぐにtwisted.protocols.tls呼び出します。do_handshake代わりにそのAPIを使用してSSLサーバーをセットアップすると、問題が解決したことがわかると思います。

後者の方が一般的にうまく機能しているように見えるので、後者を使用して前者を再実装する計画もあります。

于 2011-02-09T12:31:09.857 に答える