упаковка ssh туннеля в ssl с openssl (python) почти закончена - PullRequest
1 голос
/ 09 апреля 2011

Некоторые из вас могут вспомнить вопрос, очень похожий на этот, поскольку я искал вашу помощь в написании оригинального утилиты на C (с использованием libssh2 и openssl). Я сейчас пытаюсь перенести его на python и застрял в неожиданном месте. За 30 минут портировали около 80% ядра и функциональности, а затем потратили 10 часов + и еще не завершили эту ОДНУ функцию, поэтому я снова здесь, чтобы попросить вас о помощи еще раз:)

Весь источник (~ 130 строк, должен быть легко читаемым, а не сложным) доступен здесь: http://pastebin.com/Udm6Ehu3

Команды подключения, включения SSL, квитирования, аутентификации и даже отправки (зашифрованные) работают нормально (из журнала маршрутизаторов видно, что я вхожу в систему с правильным именем пользователя и паролем).

Проблема с ftp_read в туннельном сценарии (иначе из self.proxy нет). Одна попытка была такой:

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), и вы можете увидеть очевидный недостаток в моем взаимодействии между tunnel и BIO, этого будет достаточно в качестве ответа :) Например: возможно, ftp_write возвращает больше данных, чем запрошенные 10240 байт (или просто отправляет два текста ("blabla \ n", "command done. \ n")), так что неправильно покраснел. Который может быть верным, но, очевидно, я не могу полагаться на .want_write () /. Want_read () из pyOpenSSL, чтобы сообщать о чем-либо, кроме 0 доступных байтов.

1 Ответ

0 голосов
/ 09 апреля 2011

Хорошо, я думаю, мне удалось разобраться.

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).

...