1

你们中的一些人可能还记得一个与此非常相似的问题,因为我寻求您的帮助,用 C 编写原始 util(使用 libssh2 和 openssl)。我现在正试图将它移植到 python 并卡在一个意想不到的地方。在 30 分钟内移植了大约 80% 的核心和功能,然后花了 10 个小时以上,仍然没有完成那个 ONE 功能,所以我再次在这里寻求您的帮助:)

整个源代码(约 130 行,应该易于阅读,不复杂)可在此处获得:http: //pastebin.com/Udm6Ehu3

连接、开启 SSL、握手、身份验证甚至发送(加密)命令都可以正常工作(我可以从路由器日志中看到我使用正确的用户名和密码登录)。

问题出在隧道场景中的 ftp_read 上(否则来自 self.proxy 的为 None)。一种尝试是这样的:

def ftp_read(self, trim=False):
  if self.proxy is None:
    temp = self.s.read(READBUFF)
  else:
    while True:
      try:
        temp = self.sock.bio_read(READBUFF)
      except Exception, e:
        print type(e)
        if type(e) == SSL.WantReadError:
          try:
            self.chan.send(self.sock.bio_read(10240))
          except Exception, e:
            print type(e)
          self.chan.send(self.sock.bio_read(10240))
        elif type(e) == SSL.WantWriteError:
          self.chan.send(self.sock.bio_read(10240))

但我最终陷入了阻塞等待生物读取(或 ftp_write 函数中的通道读取)或异常 OpenSSL.SSL.WantReadError 的问题,具有讽刺意味的是,这正是我想要处理的。

如果我注释掉 ftp_read 调用,代理方案工作正常(登录,发送命令没问题),如前所述。因此,在未加密的读/写和加密的读/写中,我只是缺少加密的读隧道。

我现在已经花了 12 个小时以上,感觉我无处可去,所以任何想法都非常感谢。

编辑:我不是要求某人为我编写函数,所以如果您对 SSL(尤其是 BIO)了解一两件事,并且您可以在我的隧道和 BIO 之间的交互中看到一个明显的缺陷,这就足够了一个答案:) 喜欢:也许 ftp_write 返回的数据比请求的 10240 字节多(或者只发送两个文本(“blabla\n”,“command done.\n”)),所以它没有正确刷新。这可能是真的,但显然我不能依赖 pyOpenSSL 中的 .want_write()/.want_read() 来报告除 0 字节之外的任何内容。

4

1 回答 1

0

好的,所以我想我设法解决了。

sarnold,你会喜欢这个更新的版本:

  def ftp_read(self, trim=False):
    if self.proxy is None:
      temp = self.s.read(READBUFF)
    else:
      temp = ""
      while True:
        try:
          temp += self.sock.recv(READBUFF)
          break
        except Exception, e:
          if type(e) == SSL.WantReadError:
            self.ssl_wants_read()
          elif type(e) == SSL.WantWriteError:
            self.ssl_wants_write()

其中 ssl_wants_* 是:

  def ssl_wants_read(self):
    try:
      self.chan.send(self.sock.bio_read(10240))
    except Exception, e:
      chan_output = None
    chan_output = self.chan.recv(10240)
    self.sock.bio_write(chan_output)

  def ssl_wants_write(self):
    self.chan.send(self.sock.bio_read(10240))

感谢您的输入,萨诺德。它使事情变得更清晰,更容易使用。但是,我的问题似乎是一个错过的错误处理(过早地脱离 SSL.WantReadError 异常)。

于 2011-04-09T12:13:31.897 回答